diff --git a/.gitignore b/.gitignore
index 1639e9a..920c6bd 100644
--- a/.gitignore
+++ b/.gitignore
@@ -45,3 +45,8 @@ Thumbs.db
build/
dist/
+
+plug-ins/ARTv1/
+plug-ins/ARTv1_Origin/
+plug-ins/ARTv2/
+plug-ins/ARTv2_Origin/
diff --git a/2023/scripts/animation_tools/mgpicker/MGPicker_Program/Plug-ins/MGPicker_2017x64.mll b/2023/scripts/animation_tools/mgpicker/MGPicker_Program/Plug-ins/MGPicker_2017x64.mll
deleted file mode 100644
index e7657f1..0000000
Binary files a/2023/scripts/animation_tools/mgpicker/MGPicker_Program/Plug-ins/MGPicker_2017x64.mll and /dev/null differ
diff --git a/2023/scripts/animation_tools/mgpicker/MGPicker_Program/Plug-ins/MGPicker_2018x64.mll b/2023/scripts/animation_tools/mgpicker/MGPicker_Program/Plug-ins/MGPicker_2018x64.mll
deleted file mode 100644
index af0b394..0000000
Binary files a/2023/scripts/animation_tools/mgpicker/MGPicker_Program/Plug-ins/MGPicker_2018x64.mll and /dev/null differ
diff --git a/2023/scripts/animation_tools/mgpicker/MGPicker_Program/Plug-ins/MGPicker_2019x64.mll b/2023/scripts/animation_tools/mgpicker/MGPicker_Program/Plug-ins/MGPicker_2019x64.mll
deleted file mode 100644
index 7243098..0000000
Binary files a/2023/scripts/animation_tools/mgpicker/MGPicker_Program/Plug-ins/MGPicker_2019x64.mll and /dev/null differ
diff --git a/2023/scripts/animation_tools/mgpicker/MGPicker_Program/Plug-ins/MGPicker_2020x64.mll b/2023/scripts/animation_tools/mgpicker/MGPicker_Program/Plug-ins/MGPicker_2020x64.mll
deleted file mode 100644
index 896efed..0000000
Binary files a/2023/scripts/animation_tools/mgpicker/MGPicker_Program/Plug-ins/MGPicker_2020x64.mll and /dev/null differ
diff --git a/2023/scripts/animation_tools/mgpicker/MGPicker_Program/Plug-ins/MGPicker_2022x64.mll b/2023/scripts/animation_tools/mgpicker/MGPicker_Program/Plug-ins/MGPicker_2022x64.mll
deleted file mode 100644
index f70eef9..0000000
Binary files a/2023/scripts/animation_tools/mgpicker/MGPicker_Program/Plug-ins/MGPicker_2022x64.mll and /dev/null differ
diff --git a/2023/scripts/animation_tools/mgpicker/MGPicker_Program/Plug-ins/MGPicker_2024x64.mll b/2023/scripts/animation_tools/mgpicker/MGPicker_Program/Plug-ins/MGPicker_2024x64.mll
deleted file mode 100644
index 401e107..0000000
Binary files a/2023/scripts/animation_tools/mgpicker/MGPicker_Program/Plug-ins/MGPicker_2024x64.mll and /dev/null differ
diff --git a/2023/scripts/animation_tools/mgpicker/MGPicker_Program/Plug-ins/MGPicker_2025x64.mll b/2023/scripts/animation_tools/mgpicker/MGPicker_Program/Plug-ins/MGPicker_2025x64.mll
deleted file mode 100644
index fd01df6..0000000
Binary files a/2023/scripts/animation_tools/mgpicker/MGPicker_Program/Plug-ins/MGPicker_2025x64.mll and /dev/null differ
diff --git a/2023/scripts/animation_tools/mgpicker/MGPicker_Program/Plug-ins/MGPicker_2026x64.mll b/2023/scripts/animation_tools/mgpicker/MGPicker_Program/Plug-ins/MGPicker_2026x64.mll
deleted file mode 100644
index 95c8337..0000000
Binary files a/2023/scripts/animation_tools/mgpicker/MGPicker_Program/Plug-ins/MGPicker_2026x64.mll and /dev/null differ
diff --git a/2023/scripts/modeling_tools/gs_curvetools/LICENSE.txt b/2023/scripts/modeling_tools/gs_curvetools/LICENSE.txt
deleted file mode 100644
index 98c8beb..0000000
--- a/2023/scripts/modeling_tools/gs_curvetools/LICENSE.txt
+++ /dev/null
@@ -1,210 +0,0 @@
-"""
-GS CurveTools License:
-This collection of code named GS CurveTools is a property of George Sladkovsky (Yehor Sladkovskyi)
-and can not be copied or distributed without his written permission.
-
-GS CurveTools v1.3.8 Personal
-Copyright 2024, George Sladkovsky (Yehor Sladkovskyi)
-All Rights Reserved
-
-UI font is Roboto that is licensed under the Apache 2.0 License:
-http://www.apache.org/licenses/LICENSE-2.0
-
-Autodesk Maya is a property of Autodesk, Inc:
-https://www.autodesk.com/
-
-Social Media and Contact Links:
-
-Discord Server: https://discord.gg/f4DH6HQ
-Online Store: https://sladkovsky3d.artstation.com/store
-Online Documentation: https://gs-curvetools.readthedocs.io/
-Twitch Channel: https://www.twitch.tv/videonomad
-YouTube Channel: https://www.youtube.com/c/GeorgeSladkovsky
-ArtStation Portfolio: https://www.artstation.com/sladkovsky3d
-Contact Email: george.sladkovsky@gmail.com
-
-"""
-
-https://www.artstation.com/marketplace-product-eula
-
-Marketplace Product & Services Agreement
-
-End User Agreement
-
-This Marketplace End User Agreement applies to all downloadable products and professional services (e.g. mentorships, personal training, portfolio reviews) sold via the ArtStation Marketplace, unless a custom agreement or license is provided by the seller.
-
-The EUA is an agreement between the buyer and the seller providing the goods or services.
-
-PLEASE READ THIS DOCUMENT CAREFULLY. IT SIGNIFICANTLY ALTERS YOUR LEGAL RIGHTS AND REMEDIES.
-
-BY CLICKING “I AGREE” OR DOWNLOADING OR USING THE DIGITAL PRODUCT OR RECEIVING THE PROFESSIONAL SERVICES TO WHICH THIS AGREEMENT RELATES YOU ACCEPT ALL OF THIS AGREEMENT’S TERMS, INCLUDING THE DISCLAIMERS OF WARRANTIES AND LIMITATIONS ON DAMAGES, USE AND TRANSFERABILITY. IF YOU DO NOT ACCEPT THIS AGREEMENT’S TERMS, DO NOT DOWNLOAD, INSTALL OR USE THE DIGITAL PRODUCT OR RECEIVE OR USE THE PROFESSIONAL SERVICES.
-
-This end-user agreement (“Agreement”) is a legally binding agreement between you, the licensee and customer (“you” or “your”), and the provider (“we” or “us” or “our”) of the digital products (“Products”) or instructional, training, mentorship or other professional service packages (“Professional Services”) that you purchase through the ArtStation Marketplace, regarding your rights and obligations regarding those Products and Professional Services.
-
-1. Your Status
-In this Agreement, “you” means the person or entity acquiring rights in the Products or purchasing Professional Services. That may be a natural person, or a corporate or business entity or organization.
-
-(a) If you are a natural person then you must be, and you confirm that you are, at least 13 years old. If you are between 13 years and the age of majority in your jurisdiction of residence, you confirm that your parent or legal guardian has reviewed and agrees to this Agreement and is happy for you to access and use the Product or receive the Professional Services.
-
-(b) If you are a corporate entity then: (i) the rights granted under this Agreement are granted to that entity; (ii) you represent and warrant that the individual completing and accepting this Agreement is an authorized your representative and has the authority to legally bind that you to the Agreement; and (iii) to the extent that one or more of your employees are granted any rights in the Product or to receive Professional Services under this Agreement, you will ensure that your employees comply with this Agreement and you will be responsible and liable for any breach of this Agreement by any employee.
-
-2. ArtStation
-ArtStation is a division of Epic Games, Inc., You acknowledge and agree that Epic is a third-party beneficiary of this Agreement and therefore will be entitled to directly enforce and rely upon any provision in this Agreement that confers a benefit on, or rights in favour of, Epic. In addition, you authorize Epic to act as your authorized representative to file a lawsuit or other formal action against a licensor in a court or with any other governmental authority if Epic knows or suspects that a licensor breached any representations or warranties under this Agreement. The foregoing authorization is nonexclusive, and Epic shall be under no obligation to pursue any claim. Epic will not initiate any such action on your behalf without first consulting with and obtaining your approval.
-
-Products
-The following sections 3 through 9 apply to any Products you acquire from us through the ArtStation Marketplace:
-
-3. Product Licence
-Subject to this Agreement’s terms and conditions, we hereby grant you a limited, non-exclusive, worldwide, non-transferable right and licence to (which will be perpetual unless the licence terminates as set out in this Agreement): (a) download the Product; and (b) copy and use the Product. We reserve all rights not expressly granted to you under this Agreement.
-
-4. Licence Scope and Restrictions
-(a) Tutorials
-You are purchasing ONE licence to create ONE copy of the Product for use by you only (or, if you are a corporate entity, for use by a single authorized employee).
-
-If this Product is bundled with a stock digital asset then you receive a limited personal use licence regarding that stock digital asset, and you may use that stock digital asset for your personal use only. You will not use that stock digital asset in any commercial manner unless you purchase a separate commercial licence.
-
-(b) Installable Tools
-You may purchase one or more licences for the Product. A single licence allows you to install the Product on a single computer at a time for use by a single authorized user. If you are a corporate entity and the authorized employee completing the transaction on your behalf purchases multiple licences, you may choose to store the Product on a single server or shared hard drive for use by a single authorized employee at a time for each licence purchased.
-
-Provided that you comply with the restrictions on users set out above, you may use the Product on an unlimited number of projects.
-
-(c) Stock Assets
-Subject to the restrictions set out in this Agreement, you may copy, use, modify, adapt, translate, distribute, publicly display, transmit, broadcast, and create derivative works from the Product in works you create (“Works”), which may include things like films, videos, multi-media projects, computer games, models, images, publications, broadcasts, documents, and presentations.
-
-If you are a corporate entity, you may make the Product available for use by your employees in accordance with this Agreement (for example, by storing the Product on a network server).
-
-You may only share the Product with external people or entities where:
-- You are collaborating with the external parties in the creation of your Work and you need to share the Product for that purpose, provided that any external party that receives the Product may only use it in your Work and must secure and limit access to the Product for that purpose;
-- You are working as a contractor for a client in the creation of a Work and need to share the Product with your client, or any external parties working with your client, provided that your client and any such external parties may use the Product only for your client’s Work, and all parties secure and limit access to the Product for that purpose.
-
-For any other use of the Product by any other party, that party must purchase a licence to the Product.
-
-In addition to any other restrictions in this Agreement, you will not:
-- publish, sell, license, offer or make available for sale or licensing, or otherwise distribute the Product except as part of a Work or through a form of sharing that is authorized in this Agreement; or
-- publish, distribute or make available the Product through any online clearinghouse platform.
-
-FURTHER SPECIFIC TERMS
-In addition to the restrictions set out above, the following terms and conditions apply to the following forms of commercial licences for the Product:
-
-Standard Commercial Licence
-If you have purchased a Standard Commercial licence then you may exercise your rights under that licence:
-- for personal use on an unlimited number of personal projects that are not used or distributed in any commercial manner; and
-- respect to one commercial Work, with up to a maximum of, as applicable, 2,000 sales of the Work or 20,000 monthly views of the Work.
-
-Extended Commercial Licence
-If you have purchased an Extended Commercial licence then you may exercise your rights under that licence:
-- for personal use on an unlimited number of personal projects that are not used or distributed in any commercial manner; and
-- with respect to any number of commercial Works, with no limit on sales or views.
-
-5. Additional Restrictions
-Except as expressly permitted under this Agreement, you will not:
-
-(a) make any copy of the Product except for archival or backup purposes;
-
-(b) circumvent or disable any access control technology, security device, procedure, protocol, or technological protection mechanism that may be included or established in or as part of the Product;
-
-(c) hack, reverse engineer, decompile, disassemble, modify or create derivative works of the Product or any part of the Product;
-
-(d) publish, sell distribute or otherwise make the Product available to others to use, download or copy;
-
-(e) transfer or sub-license the Product or any rights under this Agreement to any third party, whether voluntarily or by operation of law;
-
-(f) use the Product for any purpose that may be defamatory, threatening, abusive, harmful or invasive of anyone’s privacy, or that may otherwise violate any law or give rise to civil or other liability;
-
-(g) misrepresent yourself as the creator or owner of the Property;
-
-(h) remove or modify any proprietary notice, symbol or label in or on the Product;
-
-(i) directly or indirectly assist, facilitate or encourage any third party to carry on any activity prohibited by this Agreement.
-
-6. Proprietary Rights
-The Product is protected by copyright laws and international copyright treaties, as well as other intellectual property laws and treaties. You are licensing the Product and the right to access, install and use the Product in accordance with this Agreement, not buying the Product. As between you and us, we own all right, title and interest in and to the Product, and you are not acquiring any ownership of or rights in the Product except the limited rights granted under this Agreement.
-
-7. No Epic Support
-You acknowledge and agree that you are licensing the Product from us (the Provider), not from Epic, and that Epic has no obligation to support the Product.
-
-8. Interruptions and Errors
-Your use of the Product might be interrupted and might not be free of errors.
-
-9. Updates
-We have no obligation to update the Product.
-
-Professional Services
-The following sections 10 and 11 apply to any Professional Services you purchase from us through the ArtStation Marketplace:
-
-10. Provision of Professional Services
-We will provide the Professional Services directly to you and, subject to this Agreement, will assume all responsibility for all aspects of the Professional Services. We represent and warrant that we have the right to offer and provide the Professional Services and that we have appropriate qualifications and experience to provide the Professional Services.
-
-11. Epic is not Involved
-You acknowledge and agree that:
-
-(a) Epic is only a provider of the online ArtStation Marketplace where you purchased the Professional Services, and does not provide or exercise any control or oversight over us or the Professional Services, and is not responsible for us or the Professional Services or any shortcomings in them, including any damages, losses or legal issues caused by us or the Professional Services;
-
-(b) this Agreement (and any dispute under it) is an agreement between us and you only, and not with Epic, and Epic is not a party to this Agreement;
-
-(c) we are not Epic’s employee, agent or subcontractor;
-
-(d) Epic does not have any obligation to attempt to resolve any dispute between us and you; and
-
-(e) we will provide the Professional Services directly to you, and we (and not Epic) are solely responsible for the Professional Services, and Epic has no obligation or liability to you with respect to the Professional Services.
-
-Both Products and Services
-The following sections 12 through 25 apply to all Products or Services you purchase from us through the ArtStation Marketplace:
-
-12. Disclaimer
-ANY PRODUCTS OR PROFESSIONAL SERVICES ARE PROVIDED ON AN “AS IS” AND “AS AVAILABLE” BASIS, WITHOUT ANY REPRESENTATIONS, WARRANTIES OR CONDITIONS OF ANY KIND.
-
-TO THE FULLEST EXTENT PERMITTED BY APPLICABLE LAW WE DISCLAIM, AND YOU WAIVE (WITH REGARD TO US AND ALSO TO EPIC, ITS AFFILIATES, AND ITS AND THEIR LICENSORS AND SERVICE PROVIDERS (COLLECTIVELY, THE “EPIC PARTIES”), ALL TERMS, CONDITIONS, GUARANTEES, REPRESENTATIONS AND WARRANTIES (EXPRESS, IMPLIED, STATUTORY AND OTHERWISE), IN RESPECT OF THE PRODUCTS AND PROFESSIONAL SERVICES, INCLUDING THOSE OF MERCHANTABILITY, NON-INFRINGEMENT, TITLE, QUALITY AND FITNESS FOR A PARTICULAR PURPOSE.
-
-NEITHER WE NOR ANY OF THE EPIC PARTIES REPRESENT OR WARRANT THAT: (A) ANY PRODUCT OR PROFESSIONAL SERVICE IS ACCURATE, COMPLETE, RELIABLE, CURRENT OR ERROR-FREE; (B) ANY PRODUCT OR PROFESSIONAL SERVICE WILL MEET YOUR REQUIREMENTS OR EXPECTATIONS; (C) ANY PRODUCT OR PROFESSIONAL SERVICES IS FREE OF VIRUSES OR OTHER HARMFUL COMPONENTS; OR (D) ANY DEFECTS IN ANY PRODUCT OR PROFESSIONAL SERVICE WILL BE CORRECTED.
-
-13. Exclusion and Limitation of Liability
-(a) YOU DOWNLOAD, INSTALL AND OTHERWISE USE ALL PRODUCTS, AND RECEIVE AND USE ALL PROFESSIONAL SERVICES, AT YOUR OWN RISK. YOU AGREE TO, AND HEREBY DO:
-
-(i) WAIVE ANY CLAIMS THAT YOU MAY HAVE AGAINST US OR THE EPIC PARTIES OR OUR RESPECTIVE DIRECTORS, OFFICERS, EMPLOYEES, AGENTS, REPRESENTATIVES, LICENSORS, SUCCESSORS AND ASSIGNS (COLLECTIVELY THE “RELEASEES”) ARISING FROM OR RELATING TO ANY PRODUCTS OR PROFESSIONAL SERVICES, AND
-
-(ii) RELEASE THE RELEASEES FROM ANY LIABILITY FOR ANY LOSS, DAMAGE, EXPENSE OR INJURY ARISING FROM OR RELATING TO YOUR USE OF ANY PRODUCT OR PROFESSIONAL SERVICE, WHETHER ARISING IN TORT (INCLUDING NEGLIGENCE), CONTRACT OR OTHERWISE, EVEN IF THE RELEASEES ARE EXPRESSLY ADVISED OF THE POSSIBILITY OF SUCH LOSS, INJURY OR DAMAGE AND EVEN IF THAT LOSS, INJURY OR DAMAGE IS FORESEEABLE.
-
-(b) NEITHER WE NOR THE EPIC PARTIES WILL BE LIABLE FOR ANY LOSSES, DAMAGES, CLAIMS OR EXPENSES THAT CONSTITUTE: (I) LOSS OF INTEREST, PROFIT, BUSINESS, CUSTOMERS OR REVENUE; (II) BUSINESS INTERRUPTIONS; (III) COST OF REPLACEMENT PRODUCTS OR SERVICES; OR (IV) LOSS OF OR DAMAGE TO REPUTATION OR GOODWILL.
-
-(c) NEITHER WE NOR THE EPIC PARTIES WILL BE LIABLE FOR ANY LOSSES, DAMAGES, CLAIMS OR EXPENSES THAT CONSTITUTE INCIDENTAL, CONSEQUENTIAL, SPECIAL, PUNITIVE, EXEMPLARY, MULTIPLE OR INDIRECT DAMAGES, EVEN IF WE HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH LOSSES, DAMAGES, CLAIMS OR EXPENSES.
-
-(d) MAXIMUM LIABILITY: IF, DESPITE THE LIMITATIONS SET OUT ABOVE, WE OR ANY EPIC PARTY BECOME LIABLE TO YOU IN RESPECT OF ANY PRODUCT OR PROFESSIONAL SERVICE OR OTHERWISE UNDER THIS AGREEMENT, THE ENTIRE CUMULATIVE LIABILITY OF US AND THE EPIC PARTIES, AND YOUR EXCLUSIVE AND CUMULATIVE REMEDY, FOR ANY DAMAGES (REGARDLESS OF THE CAUSE OR FORM OR ACTION), WILL BE LIMITED TO CAD$10.
-
-14. Indemnity
-As a condition of your use of any Product or any Professional Services, you agree to hold harmless and indemnify the Releasees from any liability for any loss or damage to any third party resulting from your access to, installation or use of the Product or your receipt and use of the Professional Services.
-
-15. Term and Termination
-This Agreement is effective until terminated. Your rights under this Agreement will terminate automatically without notice if: (a) you breach any terms of this Agreement; or (b) you do not complete payment for the Product or Professional Services, or any payment you make is refunded, reversed or cancelled for any reason. Upon this Agreement’s termination, you will cease all use of the Product and destroy all copies, full or partial, of the Product in your possession. Sections 11 through 25 will survive the termination of this Agreement.
-
-16. Compliance with Laws
-You will comply with all applicable laws when using any Product or Professional Services (including intellectual property and export control laws).
-
-17. Entire Agreement
-This Agreement supersedes all prior agreements of the parties regarding the Product or Professional Services, and constitutes the whole agreement with respect to the Product or Professional Services.
-
-18. Disputes
-If you have any concerns about the Product or Professional Services, please contact us through our ArtStation Marketplace account and we will work with you to try to resolve the issue. You acknowledge and agree that any such dispute is between you and us, and that Epic will not be involved in the dispute and has no obligation to try to resolve the dispute.
-
-19. Persons Bound
-This Agreement will enure to the benefit of and be binding upon the parties and their heirs, executors, administrators, legal representatives, lawful successors and permitted assigns.
-
-20. Assignment
-We may assign this Agreement without notice to you. You may not assign this Agreement or any of your rights under it without our prior written consent, which we will not withhold unreasonably.
-
-21. Waiver
-No waiver, delay, or failure to act by us regarding any particular default or omission will prejudice or impair any of our rights or remedies regarding that or any subsequent default or omission that are not expressly waived in writing.
-
-22. Applicable Law and Jurisdiction
-You agree that this Agreement will be deemed to have been made and executed in the State of North Carolina, U.S.A., and any dispute will be resolved in accordance with the laws of North Carolina, excluding that body of law related to choice of laws, and of the United States of America. Any action or proceeding brought to enforce the terms of this Agreement or to adjudicate any dispute must be brought in the Superior Court of Wake County, State of North Carolina or the United States District Court for the Eastern District of North Carolina. You agree to the exclusive jurisdiction and venue of these courts. You waive any claim of inconvenient forum and any right to a jury trial. The Convention on Contracts for the International Sale of Goods will not apply. Any law or regulation which provides that the language of a contract shall be construed against the drafter will not apply to this Agreement.
-
-23. Legal Effect
-This Agreement describes certain legal rights. You may have other rights under the laws of your country. This Agreement does not change your rights under the laws of your country if the laws of your country do not permit it to do so.
-
-24. Interpretation
-In this Agreement, "we", "us", and "our" refer to the licensor of the Product alone and never refer to the combination of you and that licensor (that combination is referred to as "the parties"), or the combination of you or the licensor with Epic.
-
-25. Artificial Intelligence
-For purposes of this Agreement, “Generative AI Programs” means artificial intelligence, machine learning, deep learning, neural networks, or similar technologies designed to automate the generation of or aid in the creation of new content, including but not limited to audio, visual, or text-based content.
-
-We (the licensor of the Product) represent and warrant that where the Product was created using Generative AI Programs, we have applied the “CreatedWithAI” tag. Under this Agreement, a Product is considered to be created using Generative AI Programs where a material portion of a Product is generated with Generative AI Programs, whether characters, backgrounds, or other material elements. A Product is not considered to be created using Generative AI Programs merely for use of features that solely operate on a Product (e.g., AI-based upscaling or content-aware fill).
diff --git a/2023/scripts/modeling_tools/gs_curvetools/README.txt b/2023/scripts/modeling_tools/gs_curvetools/README.txt
deleted file mode 100644
index 95b782d..0000000
--- a/2023/scripts/modeling_tools/gs_curvetools/README.txt
+++ /dev/null
@@ -1,35 +0,0 @@
-GS CurveTools installation
-
-1. Copy gs_curvetools folder to {Path to Documents}\Documents\Maya\{Maya Version}\scripts\
-
- Example of the final folder structure:
-
- Documents\Maya\2022\scripts\gs_curvetools\fonts
- Documents\Maya\2022\scripts\gs_curvetools\icons
- Documents\Maya\2022\scripts\gs_curvetools\utils
- Documents\Maya\2022\scripts\gs_curvetools\__init__.py
- Documents\Maya\2022\scripts\gs_curvetools\core.py
- Documents\Maya\2022\scripts\gs_curvetools\init.py
- Documents\Maya\2022\scripts\gs_curvetools\LICENSE.txt
- Documents\Maya\2022\scripts\gs_curvetools\main.py
- Documents\Maya\2022\scripts\gs_curvetools\README.txt
-
-2. Run Maya
-
-3. Copy and paste this line to "Python" command box and press "Enter":
-
-import gs_curvetools.init as ct_init;from imp import reload;reload(ct_init);ct_init.Init();
-
-IMPORTANT: There should be no spaces or tabs before this command!
-
-4. Look for GS tab on your Shelf
-
-5. Click CT UI button to run the menu. Click again to hide the menu.
-
-NOTES:
->> To reset to factory defaults click CT with "refresh" arrow button.
->> To stop all scripts and close the menu press CT DEL button.
->> You can use middle-mouse button drag to move the buttons to any tab.
->> All the hotkeys are available in Hotkey Editor > Custom Scripts > GS > GS_CurveTools.
->> Always repeat initialization steps when updating the plug-in to a new version.
->> You can always repeat initialization steps if you lost control buttons or shelf.
diff --git a/2023/scripts/modeling_tools/gs_curvetools/__init__.pyc b/2023/scripts/modeling_tools/gs_curvetools/__init__.pyc
deleted file mode 100644
index fb5e811..0000000
Binary files a/2023/scripts/modeling_tools/gs_curvetools/__init__.pyc and /dev/null differ
diff --git a/2023/scripts/modeling_tools/gs_curvetools/core/__init__.pyc b/2023/scripts/modeling_tools/gs_curvetools/core/__init__.pyc
deleted file mode 100644
index 77bb669..0000000
Binary files a/2023/scripts/modeling_tools/gs_curvetools/core/__init__.pyc and /dev/null differ
diff --git a/2023/scripts/modeling_tools/gs_curvetools/core/advanced_visibility.pyc b/2023/scripts/modeling_tools/gs_curvetools/core/advanced_visibility.pyc
deleted file mode 100644
index 9cac443..0000000
Binary files a/2023/scripts/modeling_tools/gs_curvetools/core/advanced_visibility.pyc and /dev/null differ
diff --git a/2023/scripts/modeling_tools/gs_curvetools/core/attributes.pyc b/2023/scripts/modeling_tools/gs_curvetools/core/attributes.pyc
deleted file mode 100644
index 8ba33ef..0000000
Binary files a/2023/scripts/modeling_tools/gs_curvetools/core/attributes.pyc and /dev/null differ
diff --git a/2023/scripts/modeling_tools/gs_curvetools/core/constants.pyc b/2023/scripts/modeling_tools/gs_curvetools/core/constants.pyc
deleted file mode 100644
index 113460f..0000000
Binary files a/2023/scripts/modeling_tools/gs_curvetools/core/constants.pyc and /dev/null differ
diff --git a/2023/scripts/modeling_tools/gs_curvetools/core/conversion.pyc b/2023/scripts/modeling_tools/gs_curvetools/core/conversion.pyc
deleted file mode 100644
index f0ea3b0..0000000
Binary files a/2023/scripts/modeling_tools/gs_curvetools/core/conversion.pyc and /dev/null differ
diff --git a/2023/scripts/modeling_tools/gs_curvetools/core/create.pyc b/2023/scripts/modeling_tools/gs_curvetools/core/create.pyc
deleted file mode 100644
index 45c5332..0000000
Binary files a/2023/scripts/modeling_tools/gs_curvetools/core/create.pyc and /dev/null differ
diff --git a/2023/scripts/modeling_tools/gs_curvetools/core/curve_control.pyc b/2023/scripts/modeling_tools/gs_curvetools/core/curve_control.pyc
deleted file mode 100644
index 16f5509..0000000
Binary files a/2023/scripts/modeling_tools/gs_curvetools/core/curve_control.pyc and /dev/null differ
diff --git a/2023/scripts/modeling_tools/gs_curvetools/core/fixes.pyc b/2023/scripts/modeling_tools/gs_curvetools/core/fixes.pyc
deleted file mode 100644
index 4234801..0000000
Binary files a/2023/scripts/modeling_tools/gs_curvetools/core/fixes.pyc and /dev/null differ
diff --git a/2023/scripts/modeling_tools/gs_curvetools/core/functions.pyc b/2023/scripts/modeling_tools/gs_curvetools/core/functions.pyc
deleted file mode 100644
index 8ab56fe..0000000
Binary files a/2023/scripts/modeling_tools/gs_curvetools/core/functions.pyc and /dev/null differ
diff --git a/2023/scripts/modeling_tools/gs_curvetools/core/gs_math.pyc b/2023/scripts/modeling_tools/gs_curvetools/core/gs_math.pyc
deleted file mode 100644
index f09af65..0000000
Binary files a/2023/scripts/modeling_tools/gs_curvetools/core/gs_math.pyc and /dev/null differ
diff --git a/2023/scripts/modeling_tools/gs_curvetools/core/hotkeys.pyc b/2023/scripts/modeling_tools/gs_curvetools/core/hotkeys.pyc
deleted file mode 100644
index 26a535b..0000000
Binary files a/2023/scripts/modeling_tools/gs_curvetools/core/hotkeys.pyc and /dev/null differ
diff --git a/2023/scripts/modeling_tools/gs_curvetools/core/import_export.pyc b/2023/scripts/modeling_tools/gs_curvetools/core/import_export.pyc
deleted file mode 100644
index 6a3c2a6..0000000
Binary files a/2023/scripts/modeling_tools/gs_curvetools/core/import_export.pyc and /dev/null differ
diff --git a/2023/scripts/modeling_tools/gs_curvetools/core/layers.pyc b/2023/scripts/modeling_tools/gs_curvetools/core/layers.pyc
deleted file mode 100644
index a5cf36f..0000000
Binary files a/2023/scripts/modeling_tools/gs_curvetools/core/layers.pyc and /dev/null differ
diff --git a/2023/scripts/modeling_tools/gs_curvetools/core/options.pyc b/2023/scripts/modeling_tools/gs_curvetools/core/options.pyc
deleted file mode 100644
index e6542c7..0000000
Binary files a/2023/scripts/modeling_tools/gs_curvetools/core/options.pyc and /dev/null differ
diff --git a/2023/scripts/modeling_tools/gs_curvetools/core/sliders.pyc b/2023/scripts/modeling_tools/gs_curvetools/core/sliders.pyc
deleted file mode 100644
index fe370f2..0000000
Binary files a/2023/scripts/modeling_tools/gs_curvetools/core/sliders.pyc and /dev/null differ
diff --git a/2023/scripts/modeling_tools/gs_curvetools/core/style.pyc b/2023/scripts/modeling_tools/gs_curvetools/core/style.pyc
deleted file mode 100644
index 0ac640b..0000000
Binary files a/2023/scripts/modeling_tools/gs_curvetools/core/style.pyc and /dev/null differ
diff --git a/2023/scripts/modeling_tools/gs_curvetools/core/toggle_color.pyc b/2023/scripts/modeling_tools/gs_curvetools/core/toggle_color.pyc
deleted file mode 100644
index 69632fa..0000000
Binary files a/2023/scripts/modeling_tools/gs_curvetools/core/toggle_color.pyc and /dev/null differ
diff --git a/2023/scripts/modeling_tools/gs_curvetools/core/tooltips.md b/2023/scripts/modeling_tools/gs_curvetools/core/tooltips.md
deleted file mode 100644
index 09957a1..0000000
--- a/2023/scripts/modeling_tools/gs_curvetools/core/tooltips.md
+++ /dev/null
@@ -1,951 +0,0 @@
-
-
-
-
-
-# importCurves
-Imports Curves that were Exported using the Export Button.
-NOTE: Only import files that were exported using Export Curves button.
-WARNING: This operation is NOT undoable!
-
-# exportCurves
-Exports selected curves into a .curves (or .ma) file. Can then be Imported using Import Curves.
-
-# changeScaleFactor
-Opens a window that controls the Scale Factor and Precision Scale.
-***
-Scale factor determines the initial size of the created curve and adjusts other parameters.
-Scale factor is stored in a global preset, in the scene and on each curve.
-Priority of scale factors Curve>Scene>Global.
-Setting the appropriate scale factor before starting a project can help to have a good initial Width and size of the cards.
-***
-Precision Scale controls the world scale of the curve without changing the curve appearance, CV positions and other parameters.
-Lowering the Precision scale (from 1.0 to 0.05 for example) helps to fix the geometry deformation on very small curves.
-The default value of 0.05 should be sufficient for most cases. Values lower than 0.01 can affect performance.
-***
-Normalize Selected and Normalize Selected to Default will change the Scale Factor and Precision Scale of the selected curves, without changing their appearance or CV positions.
-Normalize Selected to Default will reset the slider values to default (0.5 and 0.05) and Normalize Selected will use the current slider values.
-
-# normalizeSelectedButton
-Normalize selected curves to the chosen slider values.
-Normalization will not change the CV positions or geometry appearance, but the selected objects will have new Scale Factor and Precision Scale applied.
-
-# normalizeSelectedToDefaultButton
-Normalize selected curves to the default slider values (0.5, 0.05).
-Resets the slider values to the default.
-Normalization will not change the CV positions or geometry appearance, but the selected objects will have new Scale Factor and Precision Scale applied.
-
-# saveScaleFactorAndPrecisionScaleButton
-Saves the selected slider values to the global storage and to the current scene.
-New scenes will automatically have these Scale Factor and Precision Scale values.
-NOTE: This will not apply the new values to already existing objects. See Normalize buttons.
-
-# saveScaleFactorAndPrecisionScaleButtonAndClose
-Saves the selected slider values to the global storage and to the current scene.
-New scenes will automatically have these Scale Factor and Precision Scale values.
-Closes the window after save.
-NOTE: This will not apply the new values to already existing objects. See Normalize buttons.
-
-# closePrecisionScaleWindow
-Close this window without save
-
-# globalCurveThickness
-Opens a window that controls the thickness of the curves in the scene as well as the global curve thickness preset across the scenes.
-
-# setAOSettings
-Manually sets the recommended AO settings for older Maya versions.
-These AO settings are needed to use the "See Through" or "Toggle Always on Top" functions.
-Are applied automatically by those functions.
-
-# setTransparencySettings
-Sets recommended transparency settings for Maya viewport.
-***
-Simple Transparency is fast but very inaccurate render mode. Only suitable for simple, one layer hair.
-Object Sorting Transparency has average performance impact and quality. Can have issues on complex multi-layered grooms.
-Depth Transparency - these are the optimal settings for the highest quality of the hair cards preview. Can have performance impact on slower systems.
-
-# convertToWarpCard
-Converts selection to Warp Cards.
-Compatible attributes are retained.
-
-# convertToWarpTube
-Converts selection to Warp Tubes.
-Compatible attributes are retained.
-
-# convertToExtrudeCard
-Converts selection to Extrude Cards.
-Compatible attributes are retained.
-
-# convertToExtrudeTube
-Converts selection to Extrude Tubes.
-Compatible attributes are retained.
-
-# duplicateUnparentCurves
-Duplicates selected NURBS curves and unparents them (parents them to the world).
-Original curves are not deleted.
-Can be used to easily extract and export curves from GS CurveTools objects.
-
-# syncCurveColor
-Toggles the syncing of the curve color to the layer color.
-
-# colorizedRegroup
-Toggles the colorization of the regrouped layers when Regroup by Layer function is used.
-
-# colorOnlyDiffuse
-Colorize only the diffuse component of the card material.
-Alpha will stay the same.
-
-# checkerPattern
-Toggles the use of the checker pattern when the Color mode is enabled.
-
-# ignoreLastLayer
-Toggles the filtering (All, Curve, Geo) and Extraction (Extract All) of the last layer. If enabled, the last layer is ignored.
-NOTE: Last layer is typically used for templates, so it is ignored by default.
-
-# ignoreTemplateCollections
-Ignores the filtering (All, Curve, Geo) and Extraction (Extract All) of all the collections that have "template" in their name. Case insensitive.
-
-# groupTemplateCollections
-Collections that have "template" in their name (case insensitive) will be grouped together into "CT_Templates" group by Regroup By Layer function.
-
-# syncOutlinerLayerVis
-Syncs the outliner and layer visibility. If enabled, hiding the layer will also hide the curve groups in the outliner.
-
-# keepCurveAttributes
-If enabled, the attributes that are stored in the curve will be restored if the curve that was duplicated (on its own, without the geo) is used to create other cards or tubes.
-If disabled, the attributes will be ignored and reset.
-Example:
-1. Create a card and change its twist value.
-2. Ctrl+D and Shift+P the curve (not the curve group).
-3. Click Curve Card and the twist value will be restored on a newly created card.
-
-# boundCurvesFollowParent
-Will ensure that moving a parent curve in a Bound Object (Bound Group) will also move all the child curves along with it to a new layer. Recommended to keep this enabled.
-
-# massBindOption
-Will bind selected hair clump (or geometry) to all selected "empty" curves.
-
-# bindDuplicatesCurves
-Will automatically duplicate the curves before binding them to the curve, leaving old curves behind with no edits.
-
-# bindFlipUVs
-Enabling this option will flip the UVs of the original cards before binding them to the curve.
-It will also automatically flip the bound geo and rotate it 90 deg.
-This option will also flip the UVs back when using Unbind for better workflow.
-Disabling this option will result in an old Bind/Unbind behaviour.
-
-# unpackDeleteOriginalObject
-Unpack (Shift + Click on Unbind) will delete the original Bind object.
-
-# unpackCVMatch
-Unpack (Shift + Click on Unbind) will match the CVs of the original Bind object.
-
-# addBetweenBlendAttributes
-Enables blending of the attributes when using Add Cards/Tubes or Fill functions.
-
-# fillCreateCurvesOnly
-When enabled Fill function will only create curves (not the geo).
-
-# convertInstances
-Will automatically convert instanced curves to normal curves before any other function is applied.
-
-# replacingCurveLayerSelection
-Will disable additive selection for the layers. When holding Ctrl and clicking on a new layer, old layer will be deselected automatically.
-
-# useAutoRefineOnNewCurves
-Automatically enables auto-refine on the new curves.
-
-# flipUVsAfterMirror
-Enabling this option will flip the UVs horizontally after mirroring the cards to achieve exact mirroring.
-
-# enableTooltips
-Will toggle the visibility of these tooltips you are reading right now.
-
-# showLayerCollectionsMenu
-Shows layer collections menu widget.
-
-# importIntoANewCollection
-If enabled, all the imported curves will be placed into a new "Imported Curves" layer collection.
-If disabled, all the imported curves will be placed into the "Main" layer collection
-
-# layerNumbersOnly
-Layers will use only numbers if enabled.
-
-# convertToNewLayerSystem
-Converts all the layers in the scene to a new layer system that is hidden from the Channel Box Display Layers window.
-Layers can still be accessed from Window->Relationship Editors->Display Layer window.
-
-# updateLayers
-Utility function that will manually update all layers. Used for if layers are correct for some reason.
-
-# resetToDefaults
-Resets every option and the GS CurveTools to the default "factory" state.
-
-# maya2020UVFix
-This function will fix any broken UVs when trying to open old scenes in Maya 2020 or 2022 or when opening scenes in 2020 and 2022 when using Maya Binary file type. This will have no effect on older versions of Maya (<2020). This bug is native to Maya and thus can’t be fixed in GS CurveTools plug-in.
-
-# mayaFixBrokenGraphs
-This function will attempt to fix all the broken graphs in the scene.
-Use if one of the graphs (Width, Twist or Profile) is in a broken state.
-
-# convertBezierToNurbs
-Converts the selected Bezier curves to NURBS curves.
-Bezier curves are not supported by the GS CurveTools.
-
-# maya2020TwistAttribute
-This function will fix any broken cards created in Maya 2020.4 before v1.2.2 update.
-
-# maya2020UnbindFix
-This function will fix any cards that are not unbinding properly and were created before v1.2.3 update in Maya 2020.4.
-
-# deleteAllAnimationKeys
-This function will delete all the animation keys on all the curves present in the scene.
-This can fix deformation issues when using duplicate or other GS CurveTools functions.
-Some functions (like duplicate) will delete the keys automatically, however the keys can still cause issues.
-
-
-
-# warpSwitch
-Advanced cards and tubes suitable for longer hair.
-Additional options and controls.
-Slower than Extrude (viewport performance).
-Can have issues on very small scales.
-
-# extrudeSwitch
-Simple cards and tubes suitable for shorter hair and brows.
-Has limited controls.
-Much faster than Warp (viewport performance).
-Better for small scales.
-
-# newCard
-Creates a new Card in the middle of the world. Used at the beginning of the project to create templates.
-
-# newTube
-Creates a new Tube in the middle of the world. Used at the beginning of the project to create templates.
-
-# curveCard
-Converts selected Maya curve to CurveTools Card.
-
-# curveTube
-Converts selected Maya curve to CurveTools Tube.
-
-# gsBind
-Binds selection to a single curve. Creates a Bind Group. Selection options:
-1. Single "empty" curve (default Maya curve) and single combined geometry.
-2. Single "empty" curve (default Maya curve) and any number of Curve Cards and Curve Tubes.
-***
-Shift + Click will duplicate the original curves/geo before binding it to the empty curve.
-Same option is available in the Options menu (Duplicate Curves Before Bind).
-
-# gsUnbind
-Normal Click:
-UnBinds geometry or Cards/Tubes from selected Bound object.
-Geometry and Cards/Tubes will be placed at the origin.
-***
-Shift + Click:
-Will UNPACK the selected Bind object in-place.
-Unpack will attempt to create an in-place approximation of the cards and tubes that Bind object consists of.
-Basically it will extract the geometry and create cards (or tubes) based on that geometry.
-The original Bind object will be deleted in the process. Optionally, you can keep it (toggle in the options menu).
-This operation is not procedural, so you will not be able to return back to the Bind object after (unlike regular UnBind).
-WARNING: Unpack is not a 1 to 1 conversion. It will try its best to approximate the shape, but complex twists and bends will not be captured.
-
-# addCards
-Creates Cards in-between selected Cards based on the Add slider value.
-Bound objects are NOT supported.
-NOTE: Selection order defines the direction of added Cards if more than 2 initial Cards are selected.
-
-# addTubes
-Creates Tubes in-between selected Tubes based on the Add slider value.
-Bound objects are NOT supported.
-NOTE: Selection order defines the direction of added Tubes if more than 2 initial Tubes are selected.
-
-# gsFill
-Creates Cards/Tubes or Bound Groups in between selected Cards/Tubes or Bound Groups based on the Add slider value.
-NOTE 1: Selection order defines the direction of added curves if more than 2 initial curves are selected.
-NOTE 2: The type of Card or Tube or Bound Group is defined by the previous curve in the selection chain.
-NOTE 3: Options -> Fill Creates Only Curves option will make the Fill function create only NURBS curves, but not the geo.
-
-# gsSubdivide
-Subdivides selected curve into multiple curves based on the Add slider value
-Shift + Click subdivides selected curve but does not delete the original curve
-
-# gsEdgeToCurve
-Converts selected geometry edges to curves.
-Multiple unconnected edge groups can be selected at the same time.
-***
-Key Combinations:
-Shift + Click will create a curve without the curvature (first degree curve or simply a line)
-
-# gsGeoToCurve
-Opens the Geo-to-Curve UI
-Geo to Curve algorithm will attempt to generate GS CurveTools cards and tubes from selected geometry.
-Selected geometry should be either one-sided cards or regular tubes without caps (or both).
-Multi-selection compatible, but selected geometries should be separate objects and not one combined object.
-
-# layerCollectionsComboBox
-Layer collections drop-down menu.
-Allows to separate the project into different layer collections, up to 80 layers in each collection.
-Has additional functionality in marking menu (Hold RMB):
-***
-Marking menu:
-1. Clear - will delete all the cards from the current layer. Undoable operation.
-2. Merge Up, Merge Down - merge all the cards from the current layer to the layer above or below it.
-3. Copy, Paste - will copy all the cards from the current layer and paste them to the layer that user selects.
-4. Move Up, Move Down - will rearrange the current layer collections by moving the currently selected collection up or down in the list.
-5. Rename - will rename the current layer collection
-
-# layerCollectionsPlus
-Add additional layer collection after the current one.
-
-# layerCollectionsMinus
-Remove current layer collection. All the cards from the removed collection will be merged one layer UP.
-
-# gsAllFilter
-Layer filter. Controls the visibility of all objects in all layers:
-Normal click will show all curves and geometry in all layers.
-Shift + Click will hide all curves and geometry in all layers
-Ctrl + Click will show all the curves and geometry in all layers and all collections.
-Ctrl + Shift + Click will hide all curves and geometry in all layers and all collections.
-
-# gsCurveFilter
-Layer filter. Hides all geometry and shows all the curves in all layers.
-Ctrl + Click will do the same thing, but for all layers and all collections.
-NOTE: Holding RMB will open a marking menu with Toggle Always on Top function as well as "Auto-Hide Inactive Curves" function.
-Toggle Always on Top function will toggle the Always on Top feature that will show the curve component always on top. The effect is different in different Maya versions
-Auto-Hide Inactive Curves will hide all the curve components on all inactive layer collections when switching between collections.
-
-# gsGeoFilter
-Layer filter. Hides all curves and shows only geometry.
-Ctrl + Click will do the same thing, but for all layers and all collections.
-
-# colorMode
-Color mode toggle. Enables colors for each layer and (optionally) UV checker material.
-NOTE: Checker pattern can be disabled in the Options menu
-
-# curveGrp0
-Curve Layers that are used for organization of the cards and tubes in the scene.
-Selected layer (white outline) will be used to store newly created cards.
-Holding RMB will open a marking menu with all the functions of current layer.
-***
-Key Combinations:
-Shift + Click: additively select the contents of the layers.
-Ctrl + Click: exclusively select the contents of the layer.
-Alt + Click: show/hide selected layer.
-Ctrl + Shift: show/hide curve component on selected layer.
-Ctrl + Alt: show/hide geo component for the selected layer.
-Shift + Alt + Click: isolate select the layer.
-Shift + Ctrl + Alt + Click: enable Always on Top for each layer (only for Maya 2022+).
-***
-Layer MMB Dragging:
-MMB + Drag: move the contents of one layer to another layer. Combine if target layer has contents.
-MMB + Shift + Drag: copy the contents of one layer to another layer. Copy and Add if target layer has contents.
-
-# gsExtractSelected
-Extracts (Duplicates) the geometry component from the selected curves:
-***
-Key Combinations:
-Normal click will extract geometry and combine it.
-Shift + Click will extract geometry as individual cards.
-Ctrl + Click will extract geometry, combine it, open export menu and delete the extracted geo after export.
-Shift + Ctrl click will extract geometry, open export menu and delete the extracted geo after export.
-
-# gsExtractAll
-Extracts (Duplicates) the geometry component from all layers and collections. Original layers are HIDDEN, NOT deleted:
-Last Layer in the current Collection is ignored by default. Can be changed in the options.
-Collections with "template" in their name (case insensitive) will be ignored by default. Can be changed in the options.
-***
-Key Combinations:
-Normal click will extract geometry and combine it.
-Shift + Click will extract geometry as individual cards grouped by layers.
-Ctrl + Click will extract geometry, combine it, open export menu and delete the extracted geo after export.
-Shift + Ctrl click will extract geometry, open export menu and delete the extracted geo after export.
-
-# gsSelectCurve
-Selects the curve components of the selected Curve Cards/Tubes.
-NOTE: Useful during the selection in the outliner.
-
-# gsSelectGeo
-Selects the geometry component of the selected Curve Cards/Tubes.
-NOTE: Useful for quick assignment of the materials.
-
-# gsSelectGroup
-Selects the group component of the selected Curve Cards/Tubes.
-NOTE: Useful when you are deleting curves from viewport selection.
-
-# gsGroupCurves
-Groups the selected curves and assigns the name from Group Name input field (or default name if empty).
-
-# gsRegroupByLayer
-Regroups all the curves based on their layer number, group names and collection names.
-Group names can be changed in the Layer Names & Colors menu.
-Groups can be colorized if the "Colorize Regrouped Layers" is enabled in the Options menu.
-Collections with "template" in their name will be grouped under "CT_Templates". Can be changed in the options.
-
-# gsGroupNameTextField
-The name used by the Group Curves function.
-If empty, uses the default name.
-
-# gsCustomLayerNamesAndColors
-Opens a menu where group names and colors can be changed and stored in a global preset.
-
-# gsTransferAttributes
-Transfers attributes from the FIRST selected curve to ALL the other curves in the selection.
-NOTE: Shift + Click transfers the attributes from the LAST selected curve to ALL others.
-NOTE2: Holding RMB on this button opens a marking menu with Copy-Paste and Filter functionality
-
-# gsTransferUVs
-Transfers UVs from the FIRST selected curve to ALL the other curves in the selection.
-NOTE: Shift + Click transfers the UVs from the LAST selected curve to ALL others.
-NOTE2: Holding RMB on this button opens a marking menu with Copy-Paste and Filter functionality
-
-# gsResetPivot
-Resets the pivot on all selected curves to the default position (root CV).
-
-# gsRebuildWithCurrentValue
-Rebuild selected curves using current rebuild slider value
-
-# gsResetRebuildSliderRange
-Reset rebuild slider range (1 to 50)
-
-# gsDuplicateCurve
-Duplicates all the selected curves and selects them.
-NOTE: You can select either NURBS curve component, geometry component or group to duplicate.
-
-# gsRandomizeCurve
-Opens a window where different attributes of the selected curves can be randomized:
-1. Enable the sections of interest and change the parameters.
-2. Dragging the sliders in each section enables a PREVIEW of the randomization. Releasing the slider will reset the curves.
-3. Click Randomize if you wish to apply the current randomization.
-
-# gsExtendCurve
-Lengthens a selected curves based on the Factor slider.
-
-# gsReduceCurve
-Shortens the selected curves based on the Factor slider.
-
-# gsSmooth
-Smoothes selected curves or curve CVs based on the Factor slider.
-NOTE 1: At least 3 CVs should be selected for component smoothing.
-NOTE 2: Holding RMB will open a marking menu where you can select a stronger smoothing algorithm.
-
-# mirrorX
-Mirrors or Flips all the selected curves on the World X axis.
-
-# mirrorY
-Mirrors or Flips all the selected curves on the World Y axis.
-
-# mirrorZ
-Mirrors or Flips all the selected curves on the World Z axis.
-
-# gsControlCurve
-Adds a Control Curve Deformer to the selected curves. Can be used to adjust groups of curves.
-NOTE 1: Should NOT be used to permanently control clumps of cards. Use Bind instead.
-
-# gsApplyControlCurve
-Applies the Control Curve Deformer.
-Either the Control Curve or any controlled Curves can be selected for this to work.
-
-# gsCurveControlWindow
-Opens a Curve Control Window. Contains all the available controls for curves.
-
-# gsUVEditorMain
-Opens a UV editor that can be used to setup and adjust UVs on multiple cards.
-NOTE 1: Lambert material with PNG, JPG/JPEG or TIF/TIFF (LZW or No Compression) texture file is recommended. TGA (24bit and no RLE) is also supported.
-NOTE 2: Make sure to select the curves or the group, not the geo, to adjust the UVs.
-NOTE 3: Using default Maya UV editor will break GS CurveTools Cards, Tubes and Bound Groups.
-NOTE 4: Default UV editor can be used when custom geometry is used in a Bound Groups.
-
-
-
-
-# gsLayerSelector
-Shows the Layer of the selected curve.
-Selecting different layer will change the layer of all the selected curves.
-
-# gsColorPicker
-Layer/Card Color Picker.
-
-# gsCurveColorPicker
-Curve Color Picker.
-
-# selectedObjectName
-Selected object name. Editing this field will rename all the selected objects.
-
-# lineWidth
-Controls the thickness of the selected curves.
-
-# gsBindAxisAuto
-Automatic selection of the bind Axis (recommended).
-NOTE: Change to manual X, Y, Z axis if bind operation result is not acceptable.
-
-# AxisFlip
-Flips the direction of the bound geometry.
-
-# editOrigObj
-Temporarily disables curve bind and shows the original objects.
-Used to adjust the objects after the bind.
-To add or remove from the Bound group use Unbind.
-
-# selectOriginalCurves
-Selects the original curves that were attached to a bind curve.
-Allows to edit their attributes without using Unbind or Edit Original Objects
-
-# twistCurveFrame
-Advanced twist control graph. Allows for precise twisting of the geometry along the curve. Click to expand.
-
-# Magnitude
-Twist multiplier. The larger the values, the more the twist. Default is 0.5.
-
-# gsTwistGraphResetButton
-Resets the graph to the default state.
-
-# gsTwistGraphPopOut
-Opens a larger graph in a separate window that is synced to the main graph.
-
-# widthLockSwitch
-Links/Unlinks the X and Z width sliders.
-If linked, the sliders will move as one.
-
-# LengthLock
-Locks/Unlocks the length slider.
-When Locked the geometry is stretched to the length of the curve and the slider is ignored.
-
-# widthCurveFrame
-Advanced width control graph. Allows for precise scaling of the geometry along the curve. Click to expand.
-
-# gsWidthGraphResetButton
-Resets the graph to the default state.
-
-# gsWidthGraphPopOut
-Opens a larger graph in a separate window that is synced to the main graph.
-
-# profileCurveGraph
-Advanced control over the profile of the card. Modifies the profile applied by the Profile slider. Click to expand.
-Add or remove points and change them to increase or decrease the Profile value along the curve.
-
-# autoEqualizeSwitchOn
-Locks the points horizontally to equal intervals to avoid geometry deformation.
-
-# autoEqualizeSwitchOff
-Unlocks the points and allows for the full control.
-
-# equalizeCurveButton
-Snaps the points to the equal horizontal intervals.
-
-# gsResetProfileGraphButton
-Resets the curve to the default state.
-
-# gsProfileGraphPopOut
-Opens a larger graph in a separate window that is synced to the main graph.
-
-# reverseNormals
-Reverses the normals on the selected cards/tubes.
-
-# orientToNormalsFrame
-Orient selected cards/tubes to the normals of the selected geo.
-
-# gsOrientToNormalsSelectTarget
-Set selected mesh as a target for the algorithm.
-
-# orientRefreshViewport
-Toggles the viewport update during the alignment process.
-Disabling can speed up the process.
-
-# gsOrientToNormals
-Starts the alignment process.
-Will align the selected cards to the normals of the selected geometry.
-
-# flipUV
-Flips the UVs of the card/tube horizontally.
-
-# resetControlSliders
-Resets the range of the sliders to the default state.
-
-# UVFrame
-Legacy controls for the UVs. Just use the new UV Editor.
-
-# solidifyFrame
-Expands controls that control the thickness of the cards/tubes.
-
-# solidify
-Toggles the thickness of the geometry.
-
-
-
-# lengthDivisions
-Change the length divisions of the selected cards/tubes.
-
-# dynamicDivisions
-Toggles the dynamic divisions mode.
-Dynamic divisions will change the divisions of the cards/tubes based on the length of the curves.
-In dynamic divisions mode, L-Div slider will control the density of the divisions, not the fixed divisions count.
-
-# widthDivisions
-Change the width divisions of the selected cards/tubes.
-
-# Orientation
-Change the orientation of the card/tube around the curve.
-
-# Twist
-Smoothly twist the entire geometry card/tube. Twists the tip of the card.
-
-# invTwist
-Smoothly twist the entire geometry card. Twists the root of the card.
-
-# Width
-Change the width of the selected card.
-
-# Taper
-Linearly changes the width of the card/tube along the length of the curve.
-
-# WidthX
-Change the width of the tube along the X axis.
-
-# WidthZ
-Change the width of the tube along the Z axis.
-
-# Length
-Change the length of the attached geometry. Works only when Length Unlock button is checked.
-
-# Offset
-Offset the geometry along the curve.
-
-# Profile
-Change the profile of the card along the length of the curve uniformly.
-
-# profileSmoothing
-Smoothing will smooth the profile transition.
-
-# otherFrame
-Other less used options
-
-# curveRefine
-Controls the number of "virtual" vertices on the curve. These are the vertices that are used to calculate the geometry deformation.
-Zero (0) value will disable the refinement and the geometry will be attached directly to the curve. The fastest option.
-Larger refine values means smoother geometry that is a closer fit to the curve.
-Only increase past 20 if you need additional precision or if there are any visual glitches with the geometry.
-Large refine values can cause significant performance drop, lag and other issues on smaller curve sizes.
-Recommended values are:
-20 for curves with less than 20 CVs.
-0 (disabled) or same as the number of CVs for curves with more than 20 CVs.
-
-# autoRefine
-Enables auto-refine for selected curves. Recommended to keep this on.
-Manual refinement can be helpful if the geometry deformation is wrong or not precise enough.
-
-# samplingAccuracy
-Increases the sampling accuracy of the deformer that attaches the geometry to a curve.
-Larger values = more precise geometry fit to a curve and more lag.
-
-# surfaceNormals
-Changes the smoothing angle of the normals of the geometry.
-
-# gsIterationsSlider
-Controls the number of iterations per card.
-
-# gsMinimumAngle
-Controls the target angle difference between the normal of the mesh and the card.
-
-# solidifyThickness
-Controls the amount of thickness on the geometry.
-
-# solidifyDivisions
-Controls the number of divisions on the solidify extrusion.
-
-# solidifyScaleX
-Changes the scale on the X axis.
-
-# solidifyScaleY
-Changes the scale on the Y axis.
-
-# solidifyOffset
-Controls the offset of the solidify extrusion.
-
-# solidifyNormals
-Controls the smoothing angle for normals of the solidify extrusion.
-
-# geometryHighlight
-If enabled, selecting the curve will also highlight the geometry component that is attached to that curve.
-Works only on GS CurveTools curves and geo.
-
-# curveHighlight
-If enabled, selected curves and their components will be additionally highlighted for better visibility.
-The curves and components will be in X-Ray mode by default.
-Colors and transparency values can be changes in the menu below.
-
-# gsSelectedCVColor
-Selected CV highlight color
-
-# gsSelectedCVAlpha
-Selected CV highlight transparency (alpha)
-
-# gsDeselectedCVColor
-Deselected CV highlight color
-
-# gsDeselectedCVAlpha
-Deselected CV highlight transparency (alpha)
-
-# curveVisibility
-Toggle selected curves highlight
-
-# gsCurveHighlightColor
-Selected curve highlight color
-
-# gsCurveHighlightAlpha
-Selected curve highlight transparency (alpha)
-
-# hullVisibility
-Toggle hull visibility.
-Hull is a line that connects all the CVs on the curve.
-
-# gsHullHighlightColor
-Hull highlight color
-
-# gsHullHighlightAlpha
-Hull highlight transparency (alpha)
-
-# advancedVisibilityFrame
-Better highlights for selected curves and components.
-
-# lazyUpdate
-Enables lazy update for selected curves.
-Lazy update can slightly increase the performance of the highlight,
-however it has some visual drawbacks (curve highlight can fail to update when switching curves in component selection mode)
-
-# alwaysOnTop
-Toggles X-Ray (always on top) drawing for highlighted components.
-Disabling this defeats the purpose of the advanced visibility, but hey, it's your choice.
-
-# curveDistanceColor
-Toggles the distance color effect on the curve highlight.
-Distance color darkens the curve color the further it is from the camera.
-
-# cvDistanceColor
-Toggles the distance color effect on the CV highlight.
-Distance color darkens the CVs color the further it is from the camera.
-
-# hullDistanceColor
-Toggles the distance color effect on the hull highlight.
-Distance color darkens the hull color the further it is from the camera.
-
-# gsDistanceColorMinValue
-Distance color minimum.
-This value is the minimum allowed color multiplier for the Distance Color effect.
-The lower this value, the darker further parts of the curve will be.
-Black at 0.0
-Original color at 1.0
-
-# gsDistanceColorMaxValue
-Distance color maximum.
-This value is the maximum allowed color multiplier for the Distance Color effect.
-The higher this value, the brighter closest parts of the curve will be.
-Black at 0.0
-Original color at 1.0
-
-# CVocclusion
-Toggles the experimental CV occlusion mode (hull is affected as well)
-When the appropriate mesh name is added to Occluder Mesh input field,
-this function will automatically hide CVs and hull lines that are behind this mesh (even in X-Ray mode).
-Warning: enabling this mode can negatively impart viewport performance.
-
-# gsSelectOccluderButton
-This button adds the selected mesh name to the Occluder Mesh input field.
-
-# gsOccluderMeshName
-Type the full path for the occluder mesh here, or use the "Select Occluder" button on the left <-
-
-
-
-
-# gsGenerateLayerColorGradient
-Generate a color gradient for the layer colors.
-Rows control the number of Rows to generate.
-Left color picker sets the initial color.
-Right color picker sets the final color.
-
-# gsRandomizeLayerColors
-Generate random colors for the layers.
-SatMin controls the minimum allowed saturation.
-SatMax controls the maximum allowed saturation.
-
-# gsResetAllLayerColors
-Resets all the color swatches to the default color.
-
-# gsGetCurrentSceneLayers
-Populates the menu with the names and colors stored in the scene.
-
-# gsSetAsCurrentSceneLayers
-Applies the names and colors from the menu to the scene.
-
-# gsLoadGlobalLayerPreset
-Load the global names and colors preset to the menu.
-NOTE: Don't forget to Set to Scene before closing the menu.
-
-# gsSaveGlobalLayerPreset
-Saves the current names and colors from the menu to the global preset.
-
-
-
-# gsUVSelect
-Enables the selection of the UVs.
-Drag to draw a box selection.
-
-# gsUVMove
-Enables the Move tool.
-Move the selected UVs or move individual UVs if nothing is selected.
-
-# gsUVRotate
-Enables the Rotation of the selected UVs.
-Hold LMB and drag anywhere in the viewport to rotate the selected UVs.
-Rotation pivot is the center of the individual unscaled UV.
-
-# gsUVScale
-Enables the Scaling of the selected UVs.
-Hold LMB and drag in the viewport to scale the card Horizontally of Vertically.
-Repeated hotkey click will toggle between Horizontal and Vertical scaling.
-
-# gsUVHorizontalScale
-Horizontal scaling mode selector.
-
-# gsUVVerticalScale
-Vertical scaling mode selector.
-
-# gsDrawUVs
-Enables the UVs Drawing Tool:
-1. Select UVs using Selection Mode.
-2. Enable the UV Drawing Tool.
-3. Draw a UV Rectangle anywhere in the viewport to create/move the UVs there.
-
-# gsHorizontalFlipUV
-Flips the selected UVs horizontally.
-Flipped UVs have the blue circle indicator inside the root rectangle.
-
-# gsVerticalFlipUV
-Flips the selected UVs vertically.
-
-# gsResetUVs
-Resets the selected UVs to the default 0,1 rectangle.
-
-# gsSyncSelectionUVs
-Syncs selection between UV editor and Maya Viewport.
-
-# gsRandomizeUVs
-Randomize selected UV positions between already existing UV positions.
-***
-Normal click will keep the overall density distribution of the UVs.
-This means that if there is one card in one position and twenty cards in the other,
-it will keep this distribution of 1 to 20.
-***
-Shift+Click will ignore the original density distribution
-and simply randomize the UVs between the original positions.
-
-# gsFocusUVs
-Focuses on the selected UVs or on all the UVs if nothing is selected.
-
-# gsUVIsolateSelect
-Hides all the unselected UVs and shows only the selected ones.
-
-# gsUVShowAll
-Shows all the hidden UVs.
-
-# UVEditorUseTransforms
-Use "Coverage" and "Translate Frame" parameters from place2dTexture node for texture.
-Offset is not supported.
-Diffuse and Alpha channel MUST have the same coverage and translate frame values.
-
-# UVEditorTransparencyToggle
-Enable texture map transparency using Alpha map from Transparency plug in the material node
-
-# UVEditorBGColorPicker
-Background Color
-
-# UVEditorGridColorPicker
-Grid Color
-
-# UVEditorFrameColorPicker
-Frame Color
-
-# UVEditorUVFrameSelectedColorPicker
-Selected UV frame color
-
-# UVEditorUVFrameDeselectedColorPicker
-Deselected UV frame color
-
-# UVEditorUVCardFillColorPicker
-UV frame background color
-
-
-
-# gsGeoToCurve_outputTypeSwitch
-Controls the output of Geo-to-Curve algorithm
-
-# gsGeoToCurve_generateAuto
-Automatically determine the final object type (card or tube) based on the selected geometry.
-
-# gsGeoToCurve_generateCards
-Generate cards from selected geometry (one-sided cards or tubes)
-
-# gsGeoToCurve_generateTubes
-Generate tubes from selected geometry (one-sided cards or tubes)
-
-# gsGeoToCurve_generateCurves
-Generate curves from selected geometry (one-sided cards or tubes)
-
-# gsGeoToCurve_cardType
-Controls the type of generated objects (Warp or Extrude)
-
-# gsGeoToCurve_warp
-Generate Warp cards or tubes
-
-# gsGeoToCurve_extrude
-Generate Extrude cards or tubes
-
-# gsGeoToCurve_matchAttributes
-Controls which attributes on the new cards/tubes should be approximated from the original geometry.
-NOTE: This process is not perfect and final result can be inaccurate.
-
-# gsGeoToCurve_orientation
-Match orientation attribute during the generation process
-
-# gsGeoToCurve_width
-Match orientation attribute during the generation process
-
-# gsGeoToCurve_taper
-Match taper attribute during the generation process
-
-# gsGeoToCurve_twist
-Match twist attribute during the generation process
-
-# gsGeoToCurve_profile
-Match profile attribute during the generation process
-
-# gsGeoToCurve_material
-Copy material (shader) from the original geometry
-
-# gsGeoToCurve_UVs
-Tries to approximate the UVs from the original geometry
-NOTE: Matches the bounding box of the UVs. Rotated and deformed UVs are not matched precisely.
-
-# gsGeoToCurve_UVMatchOptions
-Controls UV matching behaviour
-
-# gsGeoToCurve_verticalFlip
-Vertically flip matched UVs
-
-# gsGeoToCurve_horizontalFlip
-Horizontally flip matched UVs
-
-# gsGeoToCurve_reverseCurve
-Reverse generated curve direction
-Root CV should be generated near the scalp of the model.
-Enable or disable if resulting card direction and taper are reversed.
-
-# gsGeoToCurve_convertSelected
-Convert selected geometry to cards, tubes or curves based on the selected options.
-Newly created procedural objects will be placed in the currently selected layer.
-NOTE: if the currently selected layer is hidden (grayed out), the newly created objects will be hidden as well.
diff --git a/2023/scripts/modeling_tools/gs_curvetools/core/tooltips.pyc b/2023/scripts/modeling_tools/gs_curvetools/core/tooltips.pyc
deleted file mode 100644
index 16d19a6..0000000
Binary files a/2023/scripts/modeling_tools/gs_curvetools/core/tooltips.pyc and /dev/null differ
diff --git a/2023/scripts/modeling_tools/gs_curvetools/core/ui.pyc b/2023/scripts/modeling_tools/gs_curvetools/core/ui.pyc
deleted file mode 100644
index 0440b3f..0000000
Binary files a/2023/scripts/modeling_tools/gs_curvetools/core/ui.pyc and /dev/null differ
diff --git a/2023/scripts/modeling_tools/gs_curvetools/core/updates.pyc b/2023/scripts/modeling_tools/gs_curvetools/core/updates.pyc
deleted file mode 100644
index 6951c25..0000000
Binary files a/2023/scripts/modeling_tools/gs_curvetools/core/updates.pyc and /dev/null differ
diff --git a/2023/scripts/modeling_tools/gs_curvetools/core/utils.pyc b/2023/scripts/modeling_tools/gs_curvetools/core/utils.pyc
deleted file mode 100644
index 84c957e..0000000
Binary files a/2023/scripts/modeling_tools/gs_curvetools/core/utils.pyc and /dev/null differ
diff --git a/2023/scripts/modeling_tools/gs_curvetools/core/uv_editor.pyc b/2023/scripts/modeling_tools/gs_curvetools/core/uv_editor.pyc
deleted file mode 100644
index 8aa14e4..0000000
Binary files a/2023/scripts/modeling_tools/gs_curvetools/core/uv_editor.pyc and /dev/null differ
diff --git a/2023/scripts/modeling_tools/gs_curvetools/core/wrap.pyc b/2023/scripts/modeling_tools/gs_curvetools/core/wrap.pyc
deleted file mode 100644
index 7db9614..0000000
Binary files a/2023/scripts/modeling_tools/gs_curvetools/core/wrap.pyc and /dev/null differ
diff --git a/2023/scripts/modeling_tools/gs_curvetools/fonts/Roboto-Bold.ttf b/2023/scripts/modeling_tools/gs_curvetools/fonts/Roboto-Bold.ttf
deleted file mode 100644
index 3742457..0000000
Binary files a/2023/scripts/modeling_tools/gs_curvetools/fonts/Roboto-Bold.ttf and /dev/null differ
diff --git a/2023/scripts/modeling_tools/gs_curvetools/fonts/Roboto-Italic.ttf b/2023/scripts/modeling_tools/gs_curvetools/fonts/Roboto-Italic.ttf
deleted file mode 100644
index c9df607..0000000
Binary files a/2023/scripts/modeling_tools/gs_curvetools/fonts/Roboto-Italic.ttf and /dev/null differ
diff --git a/2023/scripts/modeling_tools/gs_curvetools/fonts/Roboto-Regular.ttf b/2023/scripts/modeling_tools/gs_curvetools/fonts/Roboto-Regular.ttf
deleted file mode 100644
index 2b6392f..0000000
Binary files a/2023/scripts/modeling_tools/gs_curvetools/fonts/Roboto-Regular.ttf and /dev/null differ
diff --git a/2023/scripts/modeling_tools/gs_curvetools/icons/drop-down-arrow.png b/2023/scripts/modeling_tools/gs_curvetools/icons/drop-down-arrow.png
deleted file mode 100644
index 4452f34..0000000
Binary files a/2023/scripts/modeling_tools/gs_curvetools/icons/drop-down-arrow.png and /dev/null differ
diff --git a/2023/scripts/modeling_tools/gs_curvetools/icons/gsCurveToolsIcon_logo.png b/2023/scripts/modeling_tools/gs_curvetools/icons/gsCurveToolsIcon_logo.png
deleted file mode 100644
index 2dda8c9..0000000
Binary files a/2023/scripts/modeling_tools/gs_curvetools/icons/gsCurveToolsIcon_logo.png and /dev/null differ
diff --git a/2023/scripts/modeling_tools/gs_curvetools/icons/gsCurveToolsIcon_reset.png b/2023/scripts/modeling_tools/gs_curvetools/icons/gsCurveToolsIcon_reset.png
deleted file mode 100644
index a72f685..0000000
Binary files a/2023/scripts/modeling_tools/gs_curvetools/icons/gsCurveToolsIcon_reset.png and /dev/null differ
diff --git a/2023/scripts/modeling_tools/gs_curvetools/icons/gsCurveToolsIcon_reset_legacy.png b/2023/scripts/modeling_tools/gs_curvetools/icons/gsCurveToolsIcon_reset_legacy.png
deleted file mode 100644
index d40254d..0000000
Binary files a/2023/scripts/modeling_tools/gs_curvetools/icons/gsCurveToolsIcon_reset_legacy.png and /dev/null differ
diff --git a/2023/scripts/modeling_tools/gs_curvetools/icons/gsCurveToolsIcon_stop.png b/2023/scripts/modeling_tools/gs_curvetools/icons/gsCurveToolsIcon_stop.png
deleted file mode 100644
index 14be446..0000000
Binary files a/2023/scripts/modeling_tools/gs_curvetools/icons/gsCurveToolsIcon_stop.png and /dev/null differ
diff --git a/2023/scripts/modeling_tools/gs_curvetools/icons/gsCurveToolsIcon_stop_legacy.png b/2023/scripts/modeling_tools/gs_curvetools/icons/gsCurveToolsIcon_stop_legacy.png
deleted file mode 100644
index df5a67e..0000000
Binary files a/2023/scripts/modeling_tools/gs_curvetools/icons/gsCurveToolsIcon_stop_legacy.png and /dev/null differ
diff --git a/2023/scripts/modeling_tools/gs_curvetools/icons/gsCurveToolsIcon_ui.png b/2023/scripts/modeling_tools/gs_curvetools/icons/gsCurveToolsIcon_ui.png
deleted file mode 100644
index 5e0b410..0000000
Binary files a/2023/scripts/modeling_tools/gs_curvetools/icons/gsCurveToolsIcon_ui.png and /dev/null differ
diff --git a/2023/scripts/modeling_tools/gs_curvetools/icons/gsCurveToolsIcon_ui_legacy.png b/2023/scripts/modeling_tools/gs_curvetools/icons/gsCurveToolsIcon_ui_legacy.png
deleted file mode 100644
index e5bc3dc..0000000
Binary files a/2023/scripts/modeling_tools/gs_curvetools/icons/gsCurveToolsIcon_ui_legacy.png and /dev/null differ
diff --git a/2023/scripts/modeling_tools/gs_curvetools/icons/marking.png b/2023/scripts/modeling_tools/gs_curvetools/icons/marking.png
deleted file mode 100644
index 2835c8b..0000000
Binary files a/2023/scripts/modeling_tools/gs_curvetools/icons/marking.png and /dev/null differ
diff --git a/2023/scripts/modeling_tools/gs_curvetools/icons/mod.png b/2023/scripts/modeling_tools/gs_curvetools/icons/mod.png
deleted file mode 100644
index deb0c16..0000000
Binary files a/2023/scripts/modeling_tools/gs_curvetools/icons/mod.png and /dev/null differ
diff --git a/2023/scripts/modeling_tools/gs_curvetools/icons/reset.png b/2023/scripts/modeling_tools/gs_curvetools/icons/reset.png
deleted file mode 100644
index 4cba961..0000000
Binary files a/2023/scripts/modeling_tools/gs_curvetools/icons/reset.png and /dev/null differ
diff --git a/2023/scripts/modeling_tools/gs_curvetools/icons/sliderLock_en_reversed.png b/2023/scripts/modeling_tools/gs_curvetools/icons/sliderLock_en_reversed.png
deleted file mode 100644
index 8c2813c..0000000
Binary files a/2023/scripts/modeling_tools/gs_curvetools/icons/sliderLock_en_reversed.png and /dev/null differ
diff --git a/2023/scripts/modeling_tools/gs_curvetools/icons/sliderLock_reversed.png b/2023/scripts/modeling_tools/gs_curvetools/icons/sliderLock_reversed.png
deleted file mode 100644
index 638a116..0000000
Binary files a/2023/scripts/modeling_tools/gs_curvetools/icons/sliderLock_reversed.png and /dev/null differ
diff --git a/2023/scripts/modeling_tools/gs_curvetools/init.pyc b/2023/scripts/modeling_tools/gs_curvetools/init.pyc
deleted file mode 100644
index 7127cd1..0000000
Binary files a/2023/scripts/modeling_tools/gs_curvetools/init.pyc and /dev/null differ
diff --git a/2023/scripts/modeling_tools/gs_curvetools/main.pyc b/2023/scripts/modeling_tools/gs_curvetools/main.pyc
deleted file mode 100644
index d426ff7..0000000
Binary files a/2023/scripts/modeling_tools/gs_curvetools/main.pyc and /dev/null differ
diff --git a/2023/scripts/modeling_tools/gs_curvetools/plugins/2018/cv_manip.mll b/2023/scripts/modeling_tools/gs_curvetools/plugins/2018/cv_manip.mll
deleted file mode 100644
index 0078219..0000000
Binary files a/2023/scripts/modeling_tools/gs_curvetools/plugins/2018/cv_manip.mll and /dev/null differ
diff --git a/2023/scripts/modeling_tools/gs_curvetools/plugins/2019/cv_manip.mll b/2023/scripts/modeling_tools/gs_curvetools/plugins/2019/cv_manip.mll
deleted file mode 100644
index 93736ce..0000000
Binary files a/2023/scripts/modeling_tools/gs_curvetools/plugins/2019/cv_manip.mll and /dev/null differ
diff --git a/2023/scripts/modeling_tools/gs_curvetools/plugins/2020/cv_manip.mll b/2023/scripts/modeling_tools/gs_curvetools/plugins/2020/cv_manip.mll
deleted file mode 100644
index 8e34d98..0000000
Binary files a/2023/scripts/modeling_tools/gs_curvetools/plugins/2020/cv_manip.mll and /dev/null differ
diff --git a/2023/scripts/modeling_tools/gs_curvetools/plugins/2022/cv_manip.mll b/2023/scripts/modeling_tools/gs_curvetools/plugins/2022/cv_manip.mll
deleted file mode 100644
index eff0140..0000000
Binary files a/2023/scripts/modeling_tools/gs_curvetools/plugins/2022/cv_manip.mll and /dev/null differ
diff --git a/2023/scripts/modeling_tools/gs_curvetools/plugins/2023/cv_manip.mll b/2023/scripts/modeling_tools/gs_curvetools/plugins/2023/cv_manip.mll
deleted file mode 100644
index 047dc3c..0000000
Binary files a/2023/scripts/modeling_tools/gs_curvetools/plugins/2023/cv_manip.mll and /dev/null differ
diff --git a/2023/scripts/modeling_tools/gs_curvetools/plugins/2024/cv_manip.mll b/2023/scripts/modeling_tools/gs_curvetools/plugins/2024/cv_manip.mll
deleted file mode 100644
index 2a1dd2a..0000000
Binary files a/2023/scripts/modeling_tools/gs_curvetools/plugins/2024/cv_manip.mll and /dev/null differ
diff --git a/2023/scripts/modeling_tools/gs_curvetools/plugins/2025/cv_manip.mll b/2023/scripts/modeling_tools/gs_curvetools/plugins/2025/cv_manip.mll
deleted file mode 100644
index dff851b..0000000
Binary files a/2023/scripts/modeling_tools/gs_curvetools/plugins/2025/cv_manip.mll and /dev/null differ
diff --git a/2023/scripts/modeling_tools/gs_curvetools/plugins/__init__.pyc b/2023/scripts/modeling_tools/gs_curvetools/plugins/__init__.pyc
deleted file mode 100644
index 9823762..0000000
Binary files a/2023/scripts/modeling_tools/gs_curvetools/plugins/__init__.pyc and /dev/null differ
diff --git a/2023/scripts/modeling_tools/gs_curvetools/plugins/cv_manip.py b/2023/scripts/modeling_tools/gs_curvetools/plugins/cv_manip.py
deleted file mode 100644
index 54c1f4c..0000000
--- a/2023/scripts/modeling_tools/gs_curvetools/plugins/cv_manip.py
+++ /dev/null
@@ -1,93 +0,0 @@
-"""
-CV Manipulator (highlighting) plug-in entry point for Mac
-
-GS CurveTools License:
-This collection of code named GS CurveTools is a property of George Sladkovsky (Yehor Sladkovskyi)
-and can not be copied or distributed without his written permission.
-
-GS CurveTools v1.3.8 Personal
-Copyright 2024, George Sladkovsky (Yehor Sladkovskyi)
-All Rights Reserved
-
-UI font is Roboto that is licensed under the Apache 2.0 License:
-http://www.apache.org/licenses/LICENSE-2.0
-
-Autodesk Maya is a property of Autodesk, Inc:
-https://www.autodesk.com/
-
-Social Media and Contact Links:
-
-Discord Server: https://discord.gg/f4DH6HQ
-Online Store: https://sladkovsky3d.artstation.com/store
-Online Documentation: https://gs-curvetools.readthedocs.io/
-Twitch Channel: https://www.twitch.tv/videonomad
-YouTube Channel: https://www.youtube.com/c/GeorgeSladkovsky
-ArtStation Portfolio: https://www.artstation.com/sladkovsky3d
-Contact Email: george.sladkovsky@gmail.com
-
-"""
-
-# pylint: disable-all
-
-import sys
-
-try:
- from importlib import reload
-except ImportError:
- from imp import reload
-
-import maya.api.OpenMaya as om
-import maya.api.OpenMayaRender as omr
-
-from gs_curvetools.plugins import cv_manip_src # type: ignore
-
-reload(cv_manip_src)
-
-# API parameters
-maya_useNewAPI = True
-
-
-# ------------ Init & UnInit Plugin ------------
-def initializePlugin(obj):
- plugin = om.MFnPlugin(obj, "GeorgeSladkovsky", "1.3", "Any")
- try:
- plugin.registerNode(
- "GSCT_CurveTools_DrawManagerNode",
- cv_manip_src.DrawManagerNode.id,
- cv_manip_src.DrawManagerNode.creator,
- cv_manip_src.DrawManagerNode.initialize,
- om.MPxNode.kLocatorNode,
- cv_manip_src.DrawManagerNode.drawDbClassification,
- )
- except BaseException:
- sys.stderr.write("Failed to register node\n")
- raise
-
- try:
- omr.MDrawRegistry.registerDrawOverrideCreator(
- cv_manip_src.DrawManagerNode.drawDbClassification,
- cv_manip_src.DrawManagerNode.drawRegistrantId,
- cv_manip_src.DrawOverride.creator,
- )
- except BaseException:
- sys.stderr.write("Failed to register override\n")
- raise
-
-
-def uninitializePlugin(obj):
- om.MMessage.removeCallbacks(cv_manip_src.CALLBACK_IDS)
- cv_manip_src.CALLBACK_IDS = []
- plugin = om.MFnPlugin(obj)
- try:
- plugin.deregisterNode(cv_manip_src.DrawManagerNode.id)
- except BaseException:
- sys.stderr.write("Failed to deregister node\n")
- raise
-
- try:
- omr.MDrawRegistry.deregisterGeometryOverrideCreator(
- cv_manip_src.DrawManagerNode.drawDbClassification, cv_manip_src.DrawManagerNode.drawRegistrantId
- )
- except BaseException:
- sys.stderr.write("Failed to deregister override\n")
- raise
diff --git a/2023/scripts/modeling_tools/gs_curvetools/plugins/cv_manip_src.pyc b/2023/scripts/modeling_tools/gs_curvetools/plugins/cv_manip_src.pyc
deleted file mode 100644
index 20a4145..0000000
Binary files a/2023/scripts/modeling_tools/gs_curvetools/plugins/cv_manip_src.pyc and /dev/null differ
diff --git a/2023/scripts/rigging_tools/ngskintools2/README.md b/2023/scripts/rigging_tools/ngskintools2/README.md
deleted file mode 100644
index 1d112fa..0000000
--- a/2023/scripts/rigging_tools/ngskintools2/README.md
+++ /dev/null
@@ -1,61 +0,0 @@
-# ngSkinTools2 模块
-
-ngSkinTools2 是一个强大的 Maya 蒙皮权重编辑工具。
-
-## 📁 文件夹结构
-
-```
-ngskintools2/ # ngSkinTools2 核心模块
-├── __init__.py # 模块初始化(原始)
-├── launcher.py # 启动器脚本(新增)
-├── api/ # API 接口
-├── ui/ # 用户界面
-├── operations/ # 操作功能
-└── README.md # 本文档
-```
-
-## 🚀 使用方法
-
-### 从工具架启动
-
-1. 打开 Maya
-2. 切换到 **Nexus_Rigging** 工具架
-3. 点击 **ngSkin** 按钮
-
-### 从 Python 启动
-
-```python
-from rigging_tools.ngskintools2 import launcher
-launcher.LaunchNgSkinTools()
-```
-
-### 直接使用 ngSkinTools2 API
-
-```python
-from rigging_tools.ngskintools2 import open_ui
-open_ui()
-```
-
-## ✨ 主要功能
-
-- 高级权重绘制和编辑
-- 权重镜像和传递
-- 多层权重管理
-- 权重导入/导出
-- 影响对象管理
-
-## 📝 注意事项
-
-- 自动检测 Maya 版本并加载对应插件
-- 支持 Maya 2018-2026 版本
-- 如果当前版本没有完全匹配的插件,会自动使用向下兼容的版本
-- 建议在绑定工作流程中使用
-
-## 🔧 版本兼容性
-
-启动器会自动检测当前 Maya 版本并加载对应的插件:
-- **完全匹配**:优先使用与 Maya 版本完全匹配的插件
-- **向下兼容**:如果没有完全匹配,使用小于等于当前版本的最高版本插件
-- **兜底策略**:如果当前版本比所有可用插件都旧,使用最旧的可用插件
-
-支持的 Maya 版本:2018, 2019, 2020, 2022, 2023, 2024, 2025, 2026
diff --git a/2023/scripts/rigging_tools/ngskintools2/api/influenceMapping.py b/2023/scripts/rigging_tools/ngskintools2/api/influenceMapping.py
index 40d1cb4..7a82137 100644
--- a/2023/scripts/rigging_tools/ngskintools2/api/influenceMapping.py
+++ b/2023/scripts/rigging_tools/ngskintools2/api/influenceMapping.py
@@ -432,7 +432,7 @@ class InfluenceMappingConfig(Object):
return
if axis is not None and not isinstance(axis, int):
- raise Exception("invalid axis type, need int")
+ raise Exception("无效的轴类型,需要整数")
self.__mirror_axis = axis
@@ -487,10 +487,10 @@ class InfluenceMapping(Object):
def __init__(self):
self.config = InfluenceMappingConfig() # type:InfluenceMappingConfig
- "assigned config"
+ "分配的配置"
self.influences = [] # type: list[InfluenceInfo]
- "Source influences list. Can be assigned to result of :py:meth:`Layers.list_influences`"
+ "源影响列表. 可以分配给结果 :py:meth:`Layers.list_influences`"
self.destinationInfluences = None
self.calculatedMapping = None
@@ -498,7 +498,7 @@ class InfluenceMapping(Object):
def calculate(self):
mirror_mode = self.config.mirror_axis is not None
- log.info("calculate influence mapping, mirror mode: %s", mirror_mode)
+ log.info("计算影响映射,镜像模式: %s", mirror_mode)
if self.destinationInfluences is None:
self.destinationInfluences = self.influences
diff --git a/2023/scripts/rigging_tools/ngskintools2/api/layers.py b/2023/scripts/rigging_tools/ngskintools2/api/layers.py
index 9f4dc4e..5de8c37 100644
--- a/2023/scripts/rigging_tools/ngskintools2/api/layers.py
+++ b/2023/scripts/rigging_tools/ngskintools2/api/layers.py
@@ -56,7 +56,7 @@ class LayerEffects(Object):
mirror_mask = mirror_dq = mirror_weights = everything
logger.info(
- "configure mirror: layer %s mask %r weights %r dq %r direction %r",
+ "配置镜像: 图层 %s 遮罩 %r 权重 %r dq %r 方向 %r",
self.__layer.name,
mirror_mask,
mirror_weights,
@@ -103,7 +103,7 @@ class Layer(Object):
@classmethod
def load(cls, mesh, layer_id):
if layer_id < 0:
- raise Exception("invalid layer ID: %s" % layer_id)
+ raise Exception("无效图层 ID: %s" % layer_id)
result = Layer(mesh, layer_id)
result.reload()
return result
@@ -112,7 +112,7 @@ class Layer(Object):
self.mesh = mesh
self.id = id
self.effects = LayerEffects(self) # type: LayerEffects
- "configure effects for this layer"
+ "配置此图层的效果"
self.__state = None
if state is not None:
diff --git a/2023/scripts/rigging_tools/ngskintools2/api/mirror.py b/2023/scripts/rigging_tools/ngskintools2/api/mirror.py
index e9f0e37..041df27 100644
--- a/2023/scripts/rigging_tools/ngskintools2/api/mirror.py
+++ b/2023/scripts/rigging_tools/ngskintools2/api/mirror.py
@@ -63,7 +63,7 @@ class Mirror(Object):
"""
:type mapping: map[int] -> int
"""
- log.info("mapping updated: %r", mapping)
+ log.info("映射已更新: %r", mapping)
mapping_as_string = ','.join(str(k) + "," + str(v) for (k, v) in list(mapping.items()))
plugin.ngst2Layers(self.target, configureMirrorMapping=True, influencesMapping=mapping_as_string)
@@ -119,7 +119,7 @@ class Mirror(Object):
existing_ref_mesh = self.get_reference_mesh()
if existing_ref_mesh:
cmds.select(existing_ref_mesh)
- raise Exception("symmetry mesh already configured for %s: %s" % (str(sc), existing_ref_mesh))
+ raise Exception("对称网格已配置为 %s: %s" % (str(sc), existing_ref_mesh))
def get_shape(node):
return cmds.listRelatives(node, shapes=True)[0]
@@ -177,7 +177,7 @@ def set_reference_mesh_from_selection():
selection = cmds.ls(sl=True, long=True)
if len(selection) != 2:
- log.debug("wrong selection size")
+ log.debug("错误的选择尺寸")
return
m = Mirror(selection[1])
diff --git a/2023/scripts/rigging_tools/ngskintools2/api/session.py b/2023/scripts/rigging_tools/ngskintools2/api/session.py
index 4423c92..094a1fb 100644
--- a/2023/scripts/rigging_tools/ngskintools2/api/session.py
+++ b/2023/scripts/rigging_tools/ngskintools2/api/session.py
@@ -83,7 +83,7 @@ class Session(Object):
@signal.on(self.events.targetChanged)
def on_target_change():
- log.info("target changed: clearing target context")
+ log.info("目标已更改:清除目标上下文")
self.context.selected_layers.set([])
self.events.nodeSelectionChanged.emit()
diff --git a/2023/scripts/rigging_tools/ngskintools2/api/target_info.py b/2023/scripts/rigging_tools/ngskintools2/api/target_info.py
index c5ea229..67b987b 100644
--- a/2023/scripts/rigging_tools/ngskintools2/api/target_info.py
+++ b/2023/scripts/rigging_tools/ngskintools2/api/target_info.py
@@ -67,7 +67,7 @@ def add_influences(influences, target):
def long_names(names):
result = set(cmds.ls(names, long=True))
if len(result) != len(names):
- raise Exception("could not convert to a list of influences names: " + str(names))
+ raise Exception("无法转换为影响名称列表: " + str(names))
return result
existing = long_names([i.name if not i.path else i.path for i in list_influences(skin_cluster)])
diff --git a/2023/scripts/rigging_tools/ngskintools2/api/tools.py b/2023/scripts/rigging_tools/ngskintools2/api/tools.py
index c10a304..228ed97 100644
--- a/2023/scripts/rigging_tools/ngskintools2/api/tools.py
+++ b/2023/scripts/rigging_tools/ngskintools2/api/tools.py
@@ -103,7 +103,7 @@ def merge_layers(layers):
# verify that all layers are from the same parent
for i, j in zip(layers[:-1], layers[1:]):
if i.mesh != j.mesh:
- raise Exception("layers are not from the same mesh")
+ raise Exception("层不是来自同一个网格")
result = plugin.ngst2tools(
tool="mergeLayers",
diff --git a/2023/scripts/rigging_tools/ngskintools2/api/transfer.py b/2023/scripts/rigging_tools/ngskintools2/api/transfer.py
index 9c175c9..87c70b5 100644
--- a/2023/scripts/rigging_tools/ngskintools2/api/transfer.py
+++ b/2023/scripts/rigging_tools/ngskintools2/api/transfer.py
@@ -49,7 +49,7 @@ class LayersTransfer(Object):
def calc_influences_mapping_as_flat_list(self):
mapping_pairs = list(self.influences_mapping.asIntIntMapping(self.influences_mapping.calculate()).items())
if len(mapping_pairs) == 0:
- raise Exception("no mapping between source and destination influences")
+ raise Exception("源和目标影响之间没有映射")
# convert dict to flat array
return list(itertools.chain.from_iterable(mapping_pairs))
diff --git a/2023/scripts/rigging_tools/ngskintools2/decorators.py b/2023/scripts/rigging_tools/ngskintools2/decorators.py
index f2f03b2..92a7f0d 100644
--- a/2023/scripts/rigging_tools/ngskintools2/decorators.py
+++ b/2023/scripts/rigging_tools/ngskintools2/decorators.py
@@ -54,12 +54,12 @@ class Undo(Object):
self.name = name
def __enter__(self):
- log.debug("UNDO chunk %r: start", self.name)
+ log.debug("UNDO chunk %r: 开始", self.name)
cmds.undoInfo(openChunk=True, chunkName=self.name)
return self
def __exit__(self, _type, value, traceback):
- log.debug("UNDO chunk %r: end", self.name)
+ log.debug("UNDO chunk %r: 结束", self.name)
cmds.undoInfo(closeChunk=True)
diff --git a/2023/scripts/rigging_tools/ngskintools2/docs/Resources/appstore-combined.min.css b/2023/scripts/rigging_tools/ngskintools2/docs/Resources/appstore-combined.min.css
deleted file mode 100644
index 6fa4209..0000000
--- a/2023/scripts/rigging_tools/ngskintools2/docs/Resources/appstore-combined.min.css
+++ /dev/null
@@ -1,9 +0,0 @@
-/*!
- * Bootstrap v2.3.2
- *
- * Copyright 2013 Twitter, Inc
- * Licensed under the Apache License v2.0
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Designed and built with all the love in the world by @mdo and @fat.
- */.clearfix{*zoom:1}.clearfix:before,.clearfix:after{display:table;line-height:0;content:""}.clearfix:after{clear:both}.hide-text{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.input-block-level{display:block;width:100%;min-height:30px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}article,aside,details,figcaption,figure,footer,header,hgroup,nav,section{display:block}audio,canvas,video{display:inline-block;*display:inline;*zoom:1}audio:not([controls]){display:none}html{font-size:100%;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}a:focus{outline:thin dotted #333;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}a:hover,a:active{outline:0}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sup{top:-0.5em}sub{bottom:-0.25em}img{width:auto\9;height:auto;max-width:100%;vertical-align:middle;border:0;-ms-interpolation-mode:bicubic}#map_canvas img,.google-maps img{max-width:none}button,input,select,textarea{margin:0;font-size:100%;vertical-align:middle}button,input{*overflow:visible;line-height:normal}button::-moz-focus-inner,input::-moz-focus-inner{padding:0;border:0}button,html input[type="button"],input[type="reset"],input[type="submit"]{cursor:pointer;-webkit-appearance:button}label,select,button,input[type="button"],input[type="reset"],input[type="submit"],input[type="radio"],input[type="checkbox"]{cursor:pointer}input[type="search"]{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;-webkit-appearance:textfield}input[type="search"]::-webkit-search-decoration,input[type="search"]::-webkit-search-cancel-button{-webkit-appearance:none}textarea{overflow:auto;vertical-align:top}@media print{*{color:#000!important;text-shadow:none!important;background:transparent!important;box-shadow:none!important}a,a:visited{text-decoration:underline}a[href]:after{content:" (" attr(href) ")"}abbr[title]:after{content:" (" attr(title) ")"}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100%!important}@page{margin:.5cm}p,h2,h3{orphans:3;widows:3}h2,h3{page-break-after:avoid}}body{margin:0;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;line-height:20px;color:#333;background-color:#fff}a{color:#08c;text-decoration:none}a:hover,a:focus{color:#005580;text-decoration:underline}.img-rounded{-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px}.img-polaroid{padding:4px;background-color:#fff;border:1px solid #ccc;border:1px solid rgba(0,0,0,0.2);-webkit-box-shadow:0 1px 3px rgba(0,0,0,0.1);-moz-box-shadow:0 1px 3px rgba(0,0,0,0.1);box-shadow:0 1px 3px rgba(0,0,0,0.1)}.img-circle{-webkit-border-radius:500px;-moz-border-radius:500px;border-radius:500px}.row{margin-left:-20px;*zoom:1}.row:before,.row:after{display:table;line-height:0;content:""}.row:after{clear:both}[class*="span"]{float:left;min-height:1px;margin-left:20px}.container,.navbar-static-top .container,.navbar-fixed-top .container,.navbar-fixed-bottom .container{width:940px}.span12{width:940px}.span11{width:860px}.span10{width:780px}.span9{width:700px}.span8{width:620px}.span7{width:540px}.span6{width:460px}.span5{width:380px}.span4{width:300px}.span3{width:220px}.span2{width:140px}.span1{width:60px}.offset12{margin-left:980px}.offset11{margin-left:900px}.offset10{margin-left:820px}.offset9{margin-left:740px}.offset8{margin-left:660px}.offset7{margin-left:580px}.offset6{margin-left:500px}.offset5{margin-left:420px}.offset4{margin-left:340px}.offset3{margin-left:260px}.offset2{margin-left:180px}.offset1{margin-left:100px}.row-fluid{width:100%;*zoom:1}.row-fluid:before,.row-fluid:after{display:table;line-height:0;content:""}.row-fluid:after{clear:both}.row-fluid [class*="span"]{display:block;float:left;width:100%;min-height:30px;margin-left:2.127659574468085%;*margin-left:2.074468085106383%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.row-fluid [class*="span"]:first-child{margin-left:0}.row-fluid .controls-row [class*="span"]+[class*="span"]{margin-left:2.127659574468085%}.row-fluid .span12{width:100%;*width:99.94680851063829%}.row-fluid .span11{width:91.48936170212765%;*width:91.43617021276594%}.row-fluid .span10{width:82.97872340425532%;*width:82.92553191489361%}.row-fluid .span9{width:74.46808510638297%;*width:74.41489361702126%}.row-fluid .span8{width:65.95744680851064%;*width:65.90425531914893%}.row-fluid .span7{width:57.44680851063829%;*width:57.39361702127659%}.row-fluid .span6{width:48.93617021276595%;*width:48.88297872340425%}.row-fluid .span5{width:40.42553191489362%;*width:40.37234042553192%}.row-fluid .span4{width:31.914893617021278%;*width:31.861702127659576%}.row-fluid .span3{width:23.404255319148934%;*width:23.351063829787233%}.row-fluid .span2{width:14.893617021276595%;*width:14.840425531914894%}.row-fluid .span1{width:6.382978723404255%;*width:6.329787234042553%}.row-fluid .offset12{margin-left:104.25531914893617%;*margin-left:104.14893617021275%}.row-fluid .offset12:first-child{margin-left:102.12765957446808%;*margin-left:102.02127659574467%}.row-fluid .offset11{margin-left:95.74468085106382%;*margin-left:95.6382978723404%}.row-fluid .offset11:first-child{margin-left:93.61702127659574%;*margin-left:93.51063829787232%}.row-fluid .offset10{margin-left:87.23404255319149%;*margin-left:87.12765957446807%}.row-fluid .offset10:first-child{margin-left:85.1063829787234%;*margin-left:84.99999999999999%}.row-fluid .offset9{margin-left:78.72340425531914%;*margin-left:78.61702127659572%}.row-fluid .offset9:first-child{margin-left:76.59574468085106%;*margin-left:76.48936170212764%}.row-fluid .offset8{margin-left:70.2127659574468%;*margin-left:70.10638297872339%}.row-fluid .offset8:first-child{margin-left:68.08510638297872%;*margin-left:67.9787234042553%}.row-fluid .offset7{margin-left:61.70212765957446%;*margin-left:61.59574468085106%}.row-fluid .offset7:first-child{margin-left:59.574468085106375%;*margin-left:59.46808510638297%}.row-fluid .offset6{margin-left:53.191489361702125%;*margin-left:53.085106382978715%}.row-fluid .offset6:first-child{margin-left:51.063829787234035%;*margin-left:50.95744680851063%}.row-fluid .offset5{margin-left:44.68085106382979%;*margin-left:44.57446808510638%}.row-fluid .offset5:first-child{margin-left:42.5531914893617%;*margin-left:42.4468085106383%}.row-fluid .offset4{margin-left:36.170212765957444%;*margin-left:36.06382978723405%}.row-fluid .offset4:first-child{margin-left:34.04255319148936%;*margin-left:33.93617021276596%}.row-fluid .offset3{margin-left:27.659574468085104%;*margin-left:27.5531914893617%}.row-fluid .offset3:first-child{margin-left:25.53191489361702%;*margin-left:25.425531914893618%}.row-fluid .offset2{margin-left:19.148936170212764%;*margin-left:19.04255319148936%}.row-fluid .offset2:first-child{margin-left:17.02127659574468%;*margin-left:16.914893617021278%}.row-fluid .offset1{margin-left:10.638297872340425%;*margin-left:10.53191489361702%}.row-fluid .offset1:first-child{margin-left:8.51063829787234%;*margin-left:8.404255319148938%}[class*="span"].hide,.row-fluid [class*="span"].hide{display:none}[class*="span"].pull-right,.row-fluid [class*="span"].pull-right{float:right}.container{margin-right:auto;margin-left:auto;*zoom:1}.container:before,.container:after{display:table;line-height:0;content:""}.container:after{clear:both}.container-fluid{padding-right:20px;padding-left:20px;*zoom:1}.container-fluid:before,.container-fluid:after{display:table;line-height:0;content:""}.container-fluid:after{clear:both}p{margin:0 0 10px}.lead{margin-bottom:20px;font-size:21px;font-weight:200;line-height:30px}small{font-size:85%}strong{font-weight:bold}em{font-style:italic}cite{font-style:normal}.muted{color:#999}a.muted:hover,a.muted:focus{color:#808080}.text-warning{color:#c09853}a.text-warning:hover,a.text-warning:focus{color:#a47e3c}.text-error{color:#b94a48}a.text-error:hover,a.text-error:focus{color:#953b39}.text-info{color:#3a87ad}a.text-info:hover,a.text-info:focus{color:#2d6987}.text-success{color:#468847}a.text-success:hover,a.text-success:focus{color:#356635}.text-left{text-align:left}.text-right{text-align:right}.text-center{text-align:center}h1,h2,h3,h4,h5,h6{margin:10px 0;font-family:inherit;font-weight:bold;line-height:20px;color:inherit;text-rendering:optimizelegibility}h1 small,h2 small,h3 small,h4 small,h5 small,h6 small{font-weight:normal;line-height:1;color:#999}h1,h2,h3{line-height:40px}h1{font-size:38.5px}h2{font-size:31.5px}h3{font-size:24.5px}h4{font-size:17.5px}h5{font-size:14px}h6{font-size:11.9px}h1 small{font-size:24.5px}h2 small{font-size:17.5px}h3 small{font-size:14px}h4 small{font-size:14px}.page-header{padding-bottom:9px;margin:20px 0 30px;border-bottom:1px solid #eee}ul,ol{padding:0;margin:0 0 10px 25px}ul ul,ul ol,ol ol,ol ul{margin-bottom:0}li{line-height:20px}ul.unstyled,ol.unstyled{margin-left:0;list-style:none}ul.inline,ol.inline{margin-left:0;list-style:none}ul.inline>li,ol.inline>li{display:inline-block;*display:inline;padding-right:5px;padding-left:5px;*zoom:1}dl{margin-bottom:20px}dt,dd{line-height:20px}dt{font-weight:bold}dd{margin-left:10px}.dl-horizontal{*zoom:1}.dl-horizontal:before,.dl-horizontal:after{display:table;line-height:0;content:""}.dl-horizontal:after{clear:both}.dl-horizontal dt{float:left;width:160px;overflow:hidden;clear:left;text-align:right;text-overflow:ellipsis;white-space:nowrap}.dl-horizontal dd{margin-left:180px}hr{margin:20px 0;border:0;border-top:1px solid #eee;border-bottom:1px solid #fff}abbr[title],abbr[data-original-title]{cursor:help;border-bottom:1px dotted #999}abbr.initialism{font-size:90%;text-transform:uppercase}blockquote{padding:0 0 0 15px;margin:0 0 20px;border-left:5px solid #eee}blockquote p{margin-bottom:0;font-size:17.5px;font-weight:300;line-height:1.25}blockquote small{display:block;line-height:20px;color:#999}blockquote small:before{content:'\2014 \00A0'}blockquote.pull-right{float:right;padding-right:15px;padding-left:0;border-right:5px solid #eee;border-left:0}blockquote.pull-right p,blockquote.pull-right small{text-align:right}blockquote.pull-right small:before{content:''}blockquote.pull-right small:after{content:'\00A0 \2014'}q:before,q:after,blockquote:before,blockquote:after{content:""}address{display:block;margin-bottom:20px;font-style:normal;line-height:20px}code,pre{padding:0 3px 2px;font-family:Monaco,Menlo,Consolas,"Courier New",monospace;font-size:12px;color:#333;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}code{padding:2px 4px;color:#d14;white-space:nowrap;background-color:#f7f7f9;border:1px solid #e1e1e8}pre{display:block;padding:9.5px;margin:0 0 10px;font-size:13px;line-height:20px;word-break:break-all;word-wrap:break-word;white-space:pre;white-space:pre-wrap;background-color:#f5f5f5;border:1px solid #ccc;border:1px solid rgba(0,0,0,0.15);-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}pre.prettyprint{margin-bottom:20px}pre code{padding:0;color:inherit;white-space:pre;white-space:pre-wrap;background-color:transparent;border:0}.pre-scrollable{max-height:340px;overflow-y:scroll}form{margin:0 0 20px}fieldset{padding:0;margin:0;border:0}legend{display:block;width:100%;padding:0;margin-bottom:20px;font-size:21px;line-height:40px;color:#333;border:0;border-bottom:1px solid #e5e5e5}legend small{font-size:15px;color:#999}label,input,button,select,textarea{font-size:14px;font-weight:normal;line-height:20px}input,button,select,textarea{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif}label{display:block;margin-bottom:5px}select,textarea,input[type="text"],input[type="password"],input[type="datetime"],input[type="datetime-local"],input[type="date"],input[type="month"],input[type="time"],input[type="week"],input[type="number"],input[type="email"],input[type="url"],input[type="search"],input[type="tel"],input[type="color"],.uneditable-input{display:inline-block;height:20px;padding:4px 6px;margin-bottom:10px;font-size:14px;line-height:20px;color:#555;vertical-align:middle;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}input,textarea,.uneditable-input{width:206px}textarea{height:auto}textarea,input[type="text"],input[type="password"],input[type="datetime"],input[type="datetime-local"],input[type="date"],input[type="month"],input[type="time"],input[type="week"],input[type="number"],input[type="email"],input[type="url"],input[type="search"],input[type="tel"],input[type="color"],.uneditable-input{background-color:#fff;border:1px solid #ccc;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-webkit-transition:border linear .2s,box-shadow linear .2s;-moz-transition:border linear .2s,box-shadow linear .2s;-o-transition:border linear .2s,box-shadow linear .2s;transition:border linear .2s,box-shadow linear .2s}textarea:focus,input[type="text"]:focus,input[type="password"]:focus,input[type="datetime"]:focus,input[type="datetime-local"]:focus,input[type="date"]:focus,input[type="month"]:focus,input[type="time"]:focus,input[type="week"]:focus,input[type="number"]:focus,input[type="email"]:focus,input[type="url"]:focus,input[type="search"]:focus,input[type="tel"]:focus,input[type="color"]:focus,.uneditable-input:focus{border-color:rgba(82,168,236,0.8);outline:0;outline:thin dotted \9;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(82,168,236,0.6);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(82,168,236,0.6);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(82,168,236,0.6)}input[type="radio"],input[type="checkbox"]{margin:4px 0 0;margin-top:1px \9;*margin-top:0;line-height:normal}input[type="file"],input[type="image"],input[type="submit"],input[type="reset"],input[type="button"],input[type="radio"],input[type="checkbox"]{width:auto}select,input[type="file"]{height:30px;*margin-top:4px;line-height:30px}select{width:220px;background-color:#fff;border:1px solid #ccc}select[multiple],select[size]{height:auto}select:focus,input[type="file"]:focus,input[type="radio"]:focus,input[type="checkbox"]:focus{outline:thin dotted #333;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.uneditable-input,.uneditable-textarea{color:#999;cursor:not-allowed;background-color:#fcfcfc;border-color:#ccc;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,0.025);-moz-box-shadow:inset 0 1px 2px rgba(0,0,0,0.025);box-shadow:inset 0 1px 2px rgba(0,0,0,0.025)}.uneditable-input{overflow:hidden;white-space:nowrap}.uneditable-textarea{width:auto;height:auto}input:-moz-placeholder,textarea:-moz-placeholder{color:#999}input:-ms-input-placeholder,textarea:-ms-input-placeholder{color:#999}input::-webkit-input-placeholder,textarea::-webkit-input-placeholder{color:#999}.radio,.checkbox{min-height:20px;padding-left:20px}.radio input[type="radio"],.checkbox input[type="checkbox"]{float:left;margin-left:-20px}.controls>.radio:first-child,.controls>.checkbox:first-child{padding-top:5px}.radio.inline,.checkbox.inline{display:inline-block;padding-top:5px;margin-bottom:0;vertical-align:middle}.radio.inline+.radio.inline,.checkbox.inline+.checkbox.inline{margin-left:10px}.input-mini{width:60px}.input-small{width:90px}.input-medium{width:150px}.input-large{width:210px}.input-xlarge{width:270px}.input-xxlarge{width:530px}input[class*="span"],select[class*="span"],textarea[class*="span"],.uneditable-input[class*="span"],.row-fluid input[class*="span"],.row-fluid select[class*="span"],.row-fluid textarea[class*="span"],.row-fluid .uneditable-input[class*="span"]{float:none;margin-left:0}.input-append input[class*="span"],.input-append .uneditable-input[class*="span"],.input-prepend input[class*="span"],.input-prepend .uneditable-input[class*="span"],.row-fluid input[class*="span"],.row-fluid select[class*="span"],.row-fluid textarea[class*="span"],.row-fluid .uneditable-input[class*="span"],.row-fluid .input-prepend [class*="span"],.row-fluid .input-append [class*="span"]{display:inline-block}input,textarea,.uneditable-input{margin-left:0}.controls-row [class*="span"]+[class*="span"]{margin-left:20px}input.span12,textarea.span12,.uneditable-input.span12{width:926px}input.span11,textarea.span11,.uneditable-input.span11{width:846px}input.span10,textarea.span10,.uneditable-input.span10{width:766px}input.span9,textarea.span9,.uneditable-input.span9{width:686px}input.span8,textarea.span8,.uneditable-input.span8{width:606px}input.span7,textarea.span7,.uneditable-input.span7{width:526px}input.span6,textarea.span6,.uneditable-input.span6{width:446px}input.span5,textarea.span5,.uneditable-input.span5{width:366px}input.span4,textarea.span4,.uneditable-input.span4{width:286px}input.span3,textarea.span3,.uneditable-input.span3{width:206px}input.span2,textarea.span2,.uneditable-input.span2{width:126px}input.span1,textarea.span1,.uneditable-input.span1{width:46px}.controls-row{*zoom:1}.controls-row:before,.controls-row:after{display:table;line-height:0;content:""}.controls-row:after{clear:both}.controls-row [class*="span"],.row-fluid .controls-row [class*="span"]{float:left}.controls-row .checkbox[class*="span"],.controls-row .radio[class*="span"]{padding-top:5px}input[disabled],select[disabled],textarea[disabled],input[readonly],select[readonly],textarea[readonly]{cursor:not-allowed;background-color:#eee}input[type="radio"][disabled],input[type="checkbox"][disabled],input[type="radio"][readonly],input[type="checkbox"][readonly]{background-color:transparent}.control-group.warning .control-label,.control-group.warning .help-block,.control-group.warning .help-inline{color:#c09853}.control-group.warning .checkbox,.control-group.warning .radio,.control-group.warning input,.control-group.warning select,.control-group.warning textarea{color:#c09853}.control-group.warning input,.control-group.warning select,.control-group.warning textarea{border-color:#c09853;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.control-group.warning input:focus,.control-group.warning select:focus,.control-group.warning textarea:focus{border-color:#a47e3c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #dbc59e;-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #dbc59e;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #dbc59e}.control-group.warning .input-prepend .add-on,.control-group.warning .input-append .add-on{color:#c09853;background-color:#fcf8e3;border-color:#c09853}.control-group.error .control-label,.control-group.error .help-block,.control-group.error .help-inline{color:#b94a48}.control-group.error .checkbox,.control-group.error .radio,.control-group.error input,.control-group.error select,.control-group.error textarea{color:#b94a48}.control-group.error input,.control-group.error select,.control-group.error textarea{border-color:#b94a48;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.control-group.error input:focus,.control-group.error select:focus,.control-group.error textarea:focus{border-color:#953b39;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #d59392;-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #d59392;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #d59392}.control-group.error .input-prepend .add-on,.control-group.error .input-append .add-on{color:#b94a48;background-color:#f2dede;border-color:#b94a48}.control-group.success .control-label,.control-group.success .help-block,.control-group.success .help-inline{color:#468847}.control-group.success .checkbox,.control-group.success .radio,.control-group.success input,.control-group.success select,.control-group.success textarea{color:#468847}.control-group.success input,.control-group.success select,.control-group.success textarea{border-color:#468847;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.control-group.success input:focus,.control-group.success select:focus,.control-group.success textarea:focus{border-color:#356635;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #7aba7b;-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #7aba7b;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #7aba7b}.control-group.success .input-prepend .add-on,.control-group.success .input-append .add-on{color:#468847;background-color:#dff0d8;border-color:#468847}.control-group.info .control-label,.control-group.info .help-block,.control-group.info .help-inline{color:#3a87ad}.control-group.info .checkbox,.control-group.info .radio,.control-group.info input,.control-group.info select,.control-group.info textarea{color:#3a87ad}.control-group.info input,.control-group.info select,.control-group.info textarea{border-color:#3a87ad;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.control-group.info input:focus,.control-group.info select:focus,.control-group.info textarea:focus{border-color:#2d6987;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #7ab5d3;-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #7ab5d3;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #7ab5d3}.control-group.info .input-prepend .add-on,.control-group.info .input-append .add-on{color:#3a87ad;background-color:#d9edf7;border-color:#3a87ad}input:focus:invalid,textarea:focus:invalid,select:focus:invalid{color:#b94a48;border-color:#ee5f5b}input:focus:invalid:focus,textarea:focus:invalid:focus,select:focus:invalid:focus{border-color:#e9322d;-webkit-box-shadow:0 0 6px #f8b9b7;-moz-box-shadow:0 0 6px #f8b9b7;box-shadow:0 0 6px #f8b9b7}.form-actions{padding:19px 20px 20px;margin-top:20px;margin-bottom:20px;background-color:#f5f5f5;border-top:1px solid #e5e5e5;*zoom:1}.form-actions:before,.form-actions:after{display:table;line-height:0;content:""}.form-actions:after{clear:both}.help-block,.help-inline{color:#595959}.help-block{display:block;margin-bottom:10px}.help-inline{display:inline-block;*display:inline;padding-left:5px;vertical-align:middle;*zoom:1}.input-append,.input-prepend{display:inline-block;margin-bottom:10px;font-size:0;white-space:nowrap;vertical-align:middle}.input-append input,.input-prepend input,.input-append select,.input-prepend select,.input-append .uneditable-input,.input-prepend .uneditable-input,.input-append .dropdown-menu,.input-prepend .dropdown-menu,.input-append .popover,.input-prepend .popover{font-size:14px}.input-append input,.input-prepend input,.input-append select,.input-prepend select,.input-append .uneditable-input,.input-prepend .uneditable-input{position:relative;margin-bottom:0;*margin-left:0;vertical-align:top;-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0}.input-append input:focus,.input-prepend input:focus,.input-append select:focus,.input-prepend select:focus,.input-append .uneditable-input:focus,.input-prepend .uneditable-input:focus{z-index:2}.input-append .add-on,.input-prepend .add-on{display:inline-block;width:auto;height:20px;min-width:16px;padding:4px 5px;font-size:14px;font-weight:normal;line-height:20px;text-align:center;text-shadow:0 1px 0 #fff;background-color:#eee;border:1px solid #ccc}.input-append .add-on,.input-prepend .add-on,.input-append .btn,.input-prepend .btn,.input-append .btn-group>.dropdown-toggle,.input-prepend .btn-group>.dropdown-toggle{vertical-align:top;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.input-append .active,.input-prepend .active{background-color:#a9dba9;border-color:#46a546}.input-prepend .add-on,.input-prepend .btn{margin-right:-1px}.input-prepend .add-on:first-child,.input-prepend .btn:first-child{-webkit-border-radius:4px 0 0 4px;-moz-border-radius:4px 0 0 4px;border-radius:4px 0 0 4px}.input-append input,.input-append select,.input-append .uneditable-input{-webkit-border-radius:4px 0 0 4px;-moz-border-radius:4px 0 0 4px;border-radius:4px 0 0 4px}.input-append input+.btn-group .btn:last-child,.input-append select+.btn-group .btn:last-child,.input-append .uneditable-input+.btn-group .btn:last-child{-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0}.input-append .add-on,.input-append .btn,.input-append .btn-group{margin-left:-1px}.input-append .add-on:last-child,.input-append .btn:last-child,.input-append .btn-group:last-child>.dropdown-toggle{-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0}.input-prepend.input-append input,.input-prepend.input-append select,.input-prepend.input-append .uneditable-input{-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.input-prepend.input-append input+.btn-group .btn,.input-prepend.input-append select+.btn-group .btn,.input-prepend.input-append .uneditable-input+.btn-group .btn{-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0}.input-prepend.input-append .add-on:first-child,.input-prepend.input-append .btn:first-child{margin-right:-1px;-webkit-border-radius:4px 0 0 4px;-moz-border-radius:4px 0 0 4px;border-radius:4px 0 0 4px}.input-prepend.input-append .add-on:last-child,.input-prepend.input-append .btn:last-child{margin-left:-1px;-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0}.input-prepend.input-append .btn-group:first-child{margin-left:0}input.search-query{padding-right:14px;padding-right:4px \9;padding-left:14px;padding-left:4px \9;margin-bottom:0;-webkit-border-radius:15px;-moz-border-radius:15px;border-radius:15px}.form-search .input-append .search-query,.form-search .input-prepend .search-query{-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.form-search .input-append .search-query{-webkit-border-radius:14px 0 0 14px;-moz-border-radius:14px 0 0 14px;border-radius:14px 0 0 14px}.form-search .input-append .btn{-webkit-border-radius:0 14px 14px 0;-moz-border-radius:0 14px 14px 0;border-radius:0 14px 14px 0}.form-search .input-prepend .search-query{-webkit-border-radius:0 14px 14px 0;-moz-border-radius:0 14px 14px 0;border-radius:0 14px 14px 0}.form-search .input-prepend .btn{-webkit-border-radius:14px 0 0 14px;-moz-border-radius:14px 0 0 14px;border-radius:14px 0 0 14px}.form-search input,.form-inline input,.form-horizontal input,.form-search textarea,.form-inline textarea,.form-horizontal textarea,.form-search select,.form-inline select,.form-horizontal select,.form-search .help-inline,.form-inline .help-inline,.form-horizontal .help-inline,.form-search .uneditable-input,.form-inline .uneditable-input,.form-horizontal .uneditable-input,.form-search .input-prepend,.form-inline .input-prepend,.form-horizontal .input-prepend,.form-search .input-append,.form-inline .input-append,.form-horizontal .input-append{display:inline-block;*display:inline;margin-bottom:0;vertical-align:middle;*zoom:1}.form-search .hide,.form-inline .hide,.form-horizontal .hide{display:none}.form-search label,.form-inline label,.form-search .btn-group,.form-inline .btn-group{display:inline-block}.form-search .input-append,.form-inline .input-append,.form-search .input-prepend,.form-inline .input-prepend{margin-bottom:0}.form-search .radio,.form-search .checkbox,.form-inline .radio,.form-inline .checkbox{padding-left:0;margin-bottom:0;vertical-align:middle}.form-search .radio input[type="radio"],.form-search .checkbox input[type="checkbox"],.form-inline .radio input[type="radio"],.form-inline .checkbox input[type="checkbox"]{float:left;margin-right:3px;margin-left:0}.control-group{margin-bottom:10px}legend+.control-group{margin-top:20px;-webkit-margin-top-collapse:separate}.form-horizontal .control-group{margin-bottom:20px;*zoom:1}.form-horizontal .control-group:before,.form-horizontal .control-group:after{display:table;line-height:0;content:""}.form-horizontal .control-group:after{clear:both}.form-horizontal .control-label{float:left;width:160px;padding-top:5px;text-align:right}.form-horizontal .controls{*display:inline-block;*padding-left:20px;margin-left:180px;*margin-left:0}.form-horizontal .controls:first-child{*padding-left:180px}.form-horizontal .help-block{margin-bottom:0}.form-horizontal input+.help-block,.form-horizontal select+.help-block,.form-horizontal textarea+.help-block,.form-horizontal .uneditable-input+.help-block,.form-horizontal .input-prepend+.help-block,.form-horizontal .input-append+.help-block{margin-top:10px}.form-horizontal .form-actions{padding-left:180px}table{max-width:100%;background-color:transparent;border-collapse:collapse;border-spacing:0}.table{width:100%;margin-bottom:20px}.table th,.table td{padding:8px;line-height:15px;text-align:left;vertical-align:top;border-top:1px solid #ddd}.table th{font-weight:bold}.table thead th{vertical-align:bottom}.table caption+thead tr:first-child th,.table caption+thead tr:first-child td,.table colgroup+thead tr:first-child th,.table colgroup+thead tr:first-child td,.table thead:first-child tr:first-child th,.table thead:first-child tr:first-child td{border-top:0}.table tbody+tbody{border-top:2px solid #ddd}.table .table{background-color:#fff}.table-condensed th,.table-condensed td{padding:4px 5px}.table-bordered{border:1px solid #ddd;border-collapse:separate;*border-collapse:collapse;border-left:0;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.table-bordered th,.table-bordered td{border-left:1px solid #ddd}.table-bordered caption+thead tr:first-child th,.table-bordered caption+tbody tr:first-child th,.table-bordered caption+tbody tr:first-child td,.table-bordered colgroup+thead tr:first-child th,.table-bordered colgroup+tbody tr:first-child th,.table-bordered colgroup+tbody tr:first-child td,.table-bordered thead:first-child tr:first-child th,.table-bordered tbody:first-child tr:first-child th,.table-bordered tbody:first-child tr:first-child td{border-top:0}.table-bordered thead:first-child tr:first-child>th:first-child,.table-bordered tbody:first-child tr:first-child>td:first-child,.table-bordered tbody:first-child tr:first-child>th:first-child{-webkit-border-top-left-radius:4px;border-top-left-radius:4px;-moz-border-radius-topleft:4px}.table-bordered thead:first-child tr:first-child>th:last-child,.table-bordered tbody:first-child tr:first-child>td:last-child,.table-bordered tbody:first-child tr:first-child>th:last-child{-webkit-border-top-right-radius:4px;border-top-right-radius:4px;-moz-border-radius-topright:4px}.table-bordered thead:last-child tr:last-child>th:first-child,.table-bordered tbody:last-child tr:last-child>td:first-child,.table-bordered tbody:last-child tr:last-child>th:first-child,.table-bordered tfoot:last-child tr:last-child>td:first-child,.table-bordered tfoot:last-child tr:last-child>th:first-child{-webkit-border-bottom-left-radius:4px;border-bottom-left-radius:4px;-moz-border-radius-bottomleft:4px}.table-bordered thead:last-child tr:last-child>th:last-child,.table-bordered tbody:last-child tr:last-child>td:last-child,.table-bordered tbody:last-child tr:last-child>th:last-child,.table-bordered tfoot:last-child tr:last-child>td:last-child,.table-bordered tfoot:last-child tr:last-child>th:last-child{-webkit-border-bottom-right-radius:4px;border-bottom-right-radius:4px;-moz-border-radius-bottomright:4px}.table-bordered tfoot+tbody:last-child tr:last-child td:first-child{-webkit-border-bottom-left-radius:0;border-bottom-left-radius:0;-moz-border-radius-bottomleft:0}.table-bordered tfoot+tbody:last-child tr:last-child td:last-child{-webkit-border-bottom-right-radius:0;border-bottom-right-radius:0;-moz-border-radius-bottomright:0}.table-bordered caption+thead tr:first-child th:first-child,.table-bordered caption+tbody tr:first-child td:first-child,.table-bordered colgroup+thead tr:first-child th:first-child,.table-bordered colgroup+tbody tr:first-child td:first-child{-webkit-border-top-left-radius:4px;border-top-left-radius:4px;-moz-border-radius-topleft:4px}.table-bordered caption+thead tr:first-child th:last-child,.table-bordered caption+tbody tr:first-child td:last-child,.table-bordered colgroup+thead tr:first-child th:last-child,.table-bordered colgroup+tbody tr:first-child td:last-child{-webkit-border-top-right-radius:4px;border-top-right-radius:4px;-moz-border-radius-topright:4px}.table-striped tbody>tr:nth-child(odd)>td,.table-striped tbody>tr:nth-child(odd)>th{background-color:#f9f9f9}.table-hover tbody tr:hover>td,.table-hover tbody tr:hover>th{background-color:#f5f5f5}table td[class*="span"],table th[class*="span"],.row-fluid table td[class*="span"],.row-fluid table th[class*="span"]{display:table-cell;float:none;margin-left:0}.table td.span1,.table th.span1{float:none;width:44px;margin-left:0}.table td.span2,.table th.span2{float:none;width:124px;margin-left:0}.table td.span3,.table th.span3{float:none;width:204px;margin-left:0}.table td.span4,.table th.span4{float:none;width:284px;margin-left:0}.table td.span5,.table th.span5{float:none;width:364px;margin-left:0}.table td.span6,.table th.span6{float:none;width:444px;margin-left:0}.table td.span7,.table th.span7{float:none;width:524px;margin-left:0}.table td.span8,.table th.span8{float:none;width:604px;margin-left:0}.table td.span9,.table th.span9{float:none;width:684px;margin-left:0}.table td.span10,.table th.span10{float:none;width:764px;margin-left:0}.table td.span11,.table th.span11{float:none;width:844px;margin-left:0}.table td.span12,.table th.span12{float:none;width:924px;margin-left:0}.table tbody tr.success>td{background-color:#dff0d8}.table tbody tr.error>td{background-color:#f2dede}.table tbody tr.warning>td{background-color:#fcf8e3}.table tbody tr.info>td{background-color:#d9edf7}.table-hover tbody tr.success:hover>td{background-color:#d0e9c6}.table-hover tbody tr.error:hover>td{background-color:#ebcccc}.table-hover tbody tr.warning:hover>td{background-color:#faf2cc}.table-hover tbody tr.info:hover>td{background-color:#c4e3f3}[class^="icon-"],[class*=" icon-"]{display:inline-block;width:14px;height:14px;margin-top:1px;*margin-right:.3em;line-height:14px;vertical-align:text-top;background-image:url("../img/glyphicons-halflings.png");background-position:14px 14px;background-repeat:no-repeat}.icon-white,.nav-pills>.active>a>[class^="icon-"],.nav-pills>.active>a>[class*=" icon-"],.nav-list>.active>a>[class^="icon-"],.nav-list>.active>a>[class*=" icon-"],.navbar-inverse .nav>.active>a>[class^="icon-"],.navbar-inverse .nav>.active>a>[class*=" icon-"],.dropdown-menu>li>a:hover>[class^="icon-"],.dropdown-menu>li>a:focus>[class^="icon-"],.dropdown-menu>li>a:hover>[class*=" icon-"],.dropdown-menu>li>a:focus>[class*=" icon-"],.dropdown-menu>.active>a>[class^="icon-"],.dropdown-menu>.active>a>[class*=" icon-"],.dropdown-submenu:hover>a>[class^="icon-"],.dropdown-submenu:focus>a>[class^="icon-"],.dropdown-submenu:hover>a>[class*=" icon-"],.dropdown-submenu:focus>a>[class*=" icon-"]{background-image:url("../img/glyphicons-halflings-white.png")}.icon-glass{background-position:0 0}.icon-music{background-position:-24px 0}.icon-search{background-position:-48px 0}.icon-envelope{background-position:-72px 0}.icon-heart{background-position:-96px 0}.icon-star{background-position:-120px 0}.icon-star-empty{background-position:-144px 0}.icon-user{background-position:-168px 0}.icon-film{background-position:-192px 0}.icon-th-large{background-position:-216px 0}.icon-th{background-position:-240px 0}.icon-th-list{background-position:-264px 0}.icon-ok{background-position:-288px 0}.icon-remove{background-position:-312px 0}.icon-zoom-in{background-position:-336px 0}.icon-zoom-out{background-position:-360px 0}.icon-off{background-position:-384px 0}.icon-signal{background-position:-408px 0}.icon-cog{background-position:-432px 0}.icon-trash{background-position:-456px 0}.icon-home{background-position:0 -24px}.icon-file{background-position:-24px -24px}.icon-time{background-position:-48px -24px}.icon-road{background-position:-72px -24px}.icon-download-alt{background-position:-96px -24px}.icon-download{background-position:-120px -24px}.icon-upload{background-position:-144px -24px}.icon-inbox{background-position:-168px -24px}.icon-play-circle{background-position:-192px -24px}.icon-repeat{background-position:-216px -24px}.icon-refresh{background-position:-240px -24px}.icon-list-alt{background-position:-264px -24px}.icon-lock{background-position:-287px -24px}.icon-flag{background-position:-312px -24px}.icon-headphones{background-position:-336px -24px}.icon-volume-off{background-position:-360px -24px}.icon-volume-down{background-position:-384px -24px}.icon-volume-up{background-position:-408px -24px}.icon-qrcode{background-position:-432px -24px}.icon-barcode{background-position:-456px -24px}.icon-tag{background-position:0 -48px}.icon-tags{background-position:-25px -48px}.icon-book{background-position:-48px -48px}.icon-bookmark{background-position:-72px -48px}.icon-print{background-position:-96px -48px}.icon-camera{background-position:-120px -48px}.icon-font{background-position:-144px -48px}.icon-bold{background-position:-167px -48px}.icon-italic{background-position:-192px -48px}.icon-text-height{background-position:-216px -48px}.icon-text-width{background-position:-240px -48px}.icon-align-left{background-position:-264px -48px}.icon-align-center{background-position:-288px -48px}.icon-align-right{background-position:-312px -48px}.icon-align-justify{background-position:-336px -48px}.icon-list{background-position:-360px -48px}.icon-indent-left{background-position:-384px -48px}.icon-indent-right{background-position:-408px -48px}.icon-facetime-video{background-position:-432px -48px}.icon-picture{background-position:-456px -48px}.icon-pencil{background-position:0 -72px}.icon-map-marker{background-position:-24px -72px}.icon-adjust{background-position:-48px -72px}.icon-tint{background-position:-72px -72px}.icon-edit{background-position:-96px -72px}.icon-share{background-position:-120px -72px}.icon-check{background-position:-144px -72px}.icon-move{background-position:-168px -72px}.icon-step-backward{background-position:-192px -72px}.icon-fast-backward{background-position:-216px -72px}.icon-backward{background-position:-240px -72px}.icon-play{background-position:-264px -72px}.icon-pause{background-position:-288px -72px}.icon-stop{background-position:-312px -72px}.icon-forward{background-position:-336px -72px}.icon-fast-forward{background-position:-360px -72px}.icon-step-forward{background-position:-384px -72px}.icon-eject{background-position:-408px -72px}.icon-chevron-left{background-position:-432px -72px}.icon-chevron-right{background-position:-456px -72px}.icon-plus-sign{background-position:0 -96px}.icon-minus-sign{background-position:-24px -96px}.icon-remove-sign{background-position:-48px -96px}.icon-ok-sign{background-position:-72px -96px}.icon-question-sign{background-position:-96px -96px}.icon-info-sign{background-position:-120px -96px}.icon-screenshot{background-position:-144px -96px}.icon-remove-circle{background-position:-168px -96px}.icon-ok-circle{background-position:-192px -96px}.icon-ban-circle{background-position:-216px -96px}.icon-arrow-left{background-position:-240px -96px}.icon-arrow-right{background-position:-264px -96px}.icon-arrow-up{background-position:-289px -96px}.icon-arrow-down{background-position:-312px -96px}.icon-share-alt{background-position:-336px -96px}.icon-resize-full{background-position:-360px -96px}.icon-resize-small{background-position:-384px -96px}.icon-plus{background-position:-408px -96px}.icon-minus{background-position:-433px -96px}.icon-asterisk{background-position:-456px -96px}.icon-exclamation-sign{background-position:0 -120px}.icon-gift{background-position:-24px -120px}.icon-leaf{background-position:-48px -120px}.icon-fire{background-position:-72px -120px}.icon-eye-open{background-position:-96px -120px}.icon-eye-close{background-position:-120px -120px}.icon-warning-sign{background-position:-144px -120px}.icon-plane{background-position:-168px -120px}.icon-calendar{background-position:-192px -120px}.icon-random{width:16px;background-position:-216px -120px}.icon-comment{background-position:-240px -120px}.icon-magnet{background-position:-264px -120px}.icon-chevron-up{background-position:-288px -120px}.icon-chevron-down{background-position:-313px -119px}.icon-retweet{background-position:-336px -120px}.icon-shopping-cart{background-position:-360px -120px}.icon-folder-close{width:16px;background-position:-384px -120px}.icon-folder-open{width:16px;background-position:-408px -120px}.icon-resize-vertical{background-position:-432px -119px}.icon-resize-horizontal{background-position:-456px -118px}.icon-hdd{background-position:0 -144px}.icon-bullhorn{background-position:-24px -144px}.icon-bell{background-position:-48px -144px}.icon-certificate{background-position:-72px -144px}.icon-thumbs-up{background-position:-96px -144px}.icon-thumbs-down{background-position:-120px -144px}.icon-hand-right{background-position:-144px -144px}.icon-hand-left{background-position:-168px -144px}.icon-hand-up{background-position:-192px -144px}.icon-hand-down{background-position:-216px -144px}.icon-circle-arrow-right{background-position:-240px -144px}.icon-circle-arrow-left{background-position:-264px -144px}.icon-circle-arrow-up{background-position:-288px -144px}.icon-circle-arrow-down{background-position:-312px -144px}.icon-globe{background-position:-336px -144px}.icon-wrench{background-position:-360px -144px}.icon-tasks{background-position:-384px -144px}.icon-filter{background-position:-408px -144px}.icon-briefcase{background-position:-432px -144px}.icon-fullscreen{background-position:-456px -144px}.dropup,.dropdown{position:relative}.dropdown-toggle{*margin-bottom:-3px}.dropdown-toggle:active,.open .dropdown-toggle{outline:0}.caret{display:inline-block;width:0;height:0;vertical-align:top;border-top:4px solid #000;border-right:4px solid transparent;border-left:4px solid transparent;content:""}.dropdown .caret{margin-top:8px;margin-left:2px}.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:160px;padding:5px 0;margin:2px 0 0;list-style:none;background-color:#fff;border:1px solid #ccc;border:1px solid rgba(0,0,0,0.2);*border-right-width:2px;*border-bottom-width:2px;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0,0,0,0.2);-moz-box-shadow:0 5px 10px rgba(0,0,0,0.2);box-shadow:0 5px 10px rgba(0,0,0,0.2);-webkit-background-clip:padding-box;-moz-background-clip:padding;background-clip:padding-box}.dropdown-menu.pull-right{right:0;left:auto}.dropdown-menu .divider{*width:100%;height:1px;margin:9px 1px;*margin:-5px 0 5px;overflow:hidden;background-color:#e5e5e5;border-bottom:1px solid #fff}.dropdown-menu>li>a{display:block;padding:3px 20px;clear:both;font-weight:normal;line-height:20px;color:#333;white-space:nowrap}.dropdown-menu>li>a:hover,.dropdown-menu>li>a:focus,.dropdown-submenu:hover>a,.dropdown-submenu:focus>a{color:#fff;text-decoration:none;background-color:#0081c2;background-image:-moz-linear-gradient(top,#08c,#0077b3);background-image:-webkit-gradient(linear,0 0,0 100%,from(#08c),to(#0077b3));background-image:-webkit-linear-gradient(top,#08c,#0077b3);background-image:-o-linear-gradient(top,#08c,#0077b3);background-image:linear-gradient(to bottom,#08c,#0077b3);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc',endColorstr='#ff0077b3',GradientType=0)}.dropdown-menu>.active>a,.dropdown-menu>.active>a:hover,.dropdown-menu>.active>a:focus{color:#fff;text-decoration:none;background-color:#0081c2;background-image:-moz-linear-gradient(top,#08c,#0077b3);background-image:-webkit-gradient(linear,0 0,0 100%,from(#08c),to(#0077b3));background-image:-webkit-linear-gradient(top,#08c,#0077b3);background-image:-o-linear-gradient(top,#08c,#0077b3);background-image:linear-gradient(to bottom,#08c,#0077b3);background-repeat:repeat-x;outline:0;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc',endColorstr='#ff0077b3',GradientType=0)}.dropdown-menu>.disabled>a,.dropdown-menu>.disabled>a:hover,.dropdown-menu>.disabled>a:focus{color:#999}.dropdown-menu>.disabled>a:hover,.dropdown-menu>.disabled>a:focus{text-decoration:none;cursor:default;background-color:transparent;background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.open{*z-index:1000}.open>.dropdown-menu{display:block}.dropdown-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:990}.pull-right>.dropdown-menu{right:0;left:auto}.dropup .caret,.navbar-fixed-bottom .dropdown .caret{border-top:0;border-bottom:4px solid #000;content:""}.dropup .dropdown-menu,.navbar-fixed-bottom .dropdown .dropdown-menu{top:auto;bottom:100%;margin-bottom:1px}.dropdown-submenu{position:relative}.dropdown-submenu>.dropdown-menu{top:0;left:100%;margin-top:-6px;margin-left:-1px;-webkit-border-radius:0 6px 6px 6px;-moz-border-radius:0 6px 6px 6px;border-radius:0 6px 6px 6px}.dropdown-submenu:hover>.dropdown-menu{display:block}.dropup .dropdown-submenu>.dropdown-menu{top:auto;bottom:0;margin-top:0;margin-bottom:-2px;-webkit-border-radius:5px 5px 5px 0;-moz-border-radius:5px 5px 5px 0;border-radius:5px 5px 5px 0}.dropdown-submenu>a:after{display:block;float:right;width:0;height:0;margin-top:5px;margin-right:-10px;border-color:transparent;border-left-color:#ccc;border-style:solid;border-width:5px 0 5px 5px;content:" "}.dropdown-submenu:hover>a:after{border-left-color:#fff}.dropdown-submenu.pull-left{float:none}.dropdown-submenu.pull-left>.dropdown-menu{left:-100%;margin-left:10px;-webkit-border-radius:6px 0 6px 6px;-moz-border-radius:6px 0 6px 6px;border-radius:6px 0 6px 6px}.dropdown .dropdown-menu .nav-header{padding-right:20px;padding-left:20px}.typeahead{z-index:1051;margin-top:2px;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.well{min-height:20px;padding:19px;margin-bottom:20px;background-color:#f5f5f5;border:1px solid #e3e3e3;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.05);box-shadow:inset 0 1px 1px rgba(0,0,0,0.05)}.well blockquote{border-color:#ddd;border-color:rgba(0,0,0,0.15)}.well-large{padding:24px;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px}.well-small{padding:9px;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.fade{opacity:0;-webkit-transition:opacity .15s linear;-moz-transition:opacity .15s linear;-o-transition:opacity .15s linear;transition:opacity .15s linear}.fade.in{opacity:1}.collapse{position:relative;height:0;overflow:hidden;-webkit-transition:height .35s ease;-moz-transition:height .35s ease;-o-transition:height .35s ease;transition:height .35s ease}.collapse.in{height:auto}.close{float:right;font-size:20px;font-weight:bold;line-height:20px;color:#000;text-shadow:0 1px 0 #fff;opacity:.2;filter:alpha(opacity=20)}.close:hover,.close:focus{color:#000;text-decoration:none;cursor:pointer;opacity:.4;filter:alpha(opacity=40)}button.close{padding:0;cursor:pointer;background:transparent;border:0;-webkit-appearance:none}.btn{display:inline-block;*display:inline;padding:4px 12px;margin-bottom:0;*margin-left:.3em;font-size:14px;line-height:20px;color:#333;text-align:center;text-shadow:0 1px 1px rgba(255,255,255,0.75);vertical-align:middle;cursor:pointer;background-color:#f5f5f5;*background-color:#e6e6e6;background-image:-moz-linear-gradient(top,#fff,#e6e6e6);background-image:-webkit-gradient(linear,0 0,0 100%,from(#fff),to(#e6e6e6));background-image:-webkit-linear-gradient(top,#fff,#e6e6e6);background-image:-o-linear-gradient(top,#fff,#e6e6e6);background-image:linear-gradient(to bottom,#fff,#e6e6e6);background-repeat:repeat-x;border:1px solid #ccc;*border:0;border-color:#e6e6e6 #e6e6e6 #bfbfbf;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);border-bottom-color:#b3b3b3;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff',endColorstr='#ffe6e6e6',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);*zoom:1;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05)}.btn:hover,.btn:focus,.btn:active,.btn.active,.btn.disabled,.btn[disabled]{color:#333;background-color:#e6e6e6;*background-color:#d9d9d9}.btn:active,.btn.active{background-color:#ccc \9}.btn:first-child{*margin-left:0}.btn:hover,.btn:focus{color:#333;text-decoration:none;background-position:0 -15px;-webkit-transition:background-position .1s linear;-moz-transition:background-position .1s linear;-o-transition:background-position .1s linear;transition:background-position .1s linear}.btn:focus{outline:thin dotted #333;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.btn.active,.btn:active{background-image:none;outline:0;-webkit-box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05)}.btn.disabled,.btn[disabled]{cursor:default;background-image:none;opacity:.65;filter:alpha(opacity=65);-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}.btn-large{padding:11px 19px;font-size:17.5px;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px}.btn-large [class^="icon-"],.btn-large [class*=" icon-"]{margin-top:4px}.btn-small{padding:2px 10px;font-size:11.9px;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.btn-small [class^="icon-"],.btn-small [class*=" icon-"]{margin-top:0}.btn-mini [class^="icon-"],.btn-mini [class*=" icon-"]{margin-top:-1px}.btn-mini{padding:0 6px;font-size:10.5px;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.btn-block{display:block;width:100%;padding-right:0;padding-left:0;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.btn-block+.btn-block{margin-top:5px}input[type="submit"].btn-block,input[type="reset"].btn-block,input[type="button"].btn-block{width:100%}.btn-primary.active,.btn-warning.active,.btn-danger.active,.btn-success.active,.btn-info.active,.btn-inverse.active{color:rgba(255,255,255,0.75)}.btn-primary{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#006dcc;*background-color:#04c;background-image:-moz-linear-gradient(top,#08c,#04c);background-image:-webkit-gradient(linear,0 0,0 100%,from(#08c),to(#04c));background-image:-webkit-linear-gradient(top,#08c,#04c);background-image:-o-linear-gradient(top,#08c,#04c);background-image:linear-gradient(to bottom,#08c,#04c);background-repeat:repeat-x;border-color:#04c #04c #002a80;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc',endColorstr='#ff0044cc',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.btn-primary:hover,.btn-primary:focus,.btn-primary:active,.btn-primary.active,.btn-primary.disabled,.btn-primary[disabled]{color:#fff;background-color:#04c;*background-color:#003bb3}.btn-primary:active,.btn-primary.active{background-color:#039 \9}.btn-warning{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#faa732;*background-color:#f89406;background-image:-moz-linear-gradient(top,#fbb450,#f89406);background-image:-webkit-gradient(linear,0 0,0 100%,from(#fbb450),to(#f89406));background-image:-webkit-linear-gradient(top,#fbb450,#f89406);background-image:-o-linear-gradient(top,#fbb450,#f89406);background-image:linear-gradient(to bottom,#fbb450,#f89406);background-repeat:repeat-x;border-color:#f89406 #f89406 #ad6704;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffbb450',endColorstr='#fff89406',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.btn-warning:hover,.btn-warning:focus,.btn-warning:active,.btn-warning.active,.btn-warning.disabled,.btn-warning[disabled]{color:#fff;background-color:#f89406;*background-color:#df8505}.btn-warning:active,.btn-warning.active{background-color:#c67605 \9}.btn-danger{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#da4f49;*background-color:#bd362f;background-image:-moz-linear-gradient(top,#ee5f5b,#bd362f);background-image:-webkit-gradient(linear,0 0,0 100%,from(#ee5f5b),to(#bd362f));background-image:-webkit-linear-gradient(top,#ee5f5b,#bd362f);background-image:-o-linear-gradient(top,#ee5f5b,#bd362f);background-image:linear-gradient(to bottom,#ee5f5b,#bd362f);background-repeat:repeat-x;border-color:#bd362f #bd362f #802420;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffee5f5b',endColorstr='#ffbd362f',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.btn-danger:hover,.btn-danger:focus,.btn-danger:active,.btn-danger.active,.btn-danger.disabled,.btn-danger[disabled]{color:#fff;background-color:#bd362f;*background-color:#a9302a}.btn-danger:active,.btn-danger.active{background-color:#942a25 \9}.btn-success{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#5bb75b;*background-color:#51a351;background-image:-moz-linear-gradient(top,#62c462,#51a351);background-image:-webkit-gradient(linear,0 0,0 100%,from(#62c462),to(#51a351));background-image:-webkit-linear-gradient(top,#62c462,#51a351);background-image:-o-linear-gradient(top,#62c462,#51a351);background-image:linear-gradient(to bottom,#62c462,#51a351);background-repeat:repeat-x;border-color:#51a351 #51a351 #387038;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff62c462',endColorstr='#ff51a351',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.btn-success:hover,.btn-success:focus,.btn-success:active,.btn-success.active,.btn-success.disabled,.btn-success[disabled]{color:#fff;background-color:#51a351;*background-color:#499249}.btn-success:active,.btn-success.active{background-color:#408140 \9}.btn-info{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#49afcd;*background-color:#2f96b4;background-image:-moz-linear-gradient(top,#5bc0de,#2f96b4);background-image:-webkit-gradient(linear,0 0,0 100%,from(#5bc0de),to(#2f96b4));background-image:-webkit-linear-gradient(top,#5bc0de,#2f96b4);background-image:-o-linear-gradient(top,#5bc0de,#2f96b4);background-image:linear-gradient(to bottom,#5bc0de,#2f96b4);background-repeat:repeat-x;border-color:#2f96b4 #2f96b4 #1f6377;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de',endColorstr='#ff2f96b4',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.btn-info:hover,.btn-info:focus,.btn-info:active,.btn-info.active,.btn-info.disabled,.btn-info[disabled]{color:#fff;background-color:#2f96b4;*background-color:#2a85a0}.btn-info:active,.btn-info.active{background-color:#24748c \9}.btn-inverse{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#363636;*background-color:#222;background-image:-moz-linear-gradient(top,#444,#222);background-image:-webkit-gradient(linear,0 0,0 100%,from(#444),to(#222));background-image:-webkit-linear-gradient(top,#444,#222);background-image:-o-linear-gradient(top,#444,#222);background-image:linear-gradient(to bottom,#444,#222);background-repeat:repeat-x;border-color:#222 #222 #000;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff444444',endColorstr='#ff222222',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.btn-inverse:hover,.btn-inverse:focus,.btn-inverse:active,.btn-inverse.active,.btn-inverse.disabled,.btn-inverse[disabled]{color:#fff;background-color:#222;*background-color:#151515}.btn-inverse:active,.btn-inverse.active{background-color:#080808 \9}button.btn,input[type="submit"].btn{*padding-top:3px;*padding-bottom:3px}button.btn::-moz-focus-inner,input[type="submit"].btn::-moz-focus-inner{padding:0;border:0}button.btn.btn-large,input[type="submit"].btn.btn-large{*padding-top:7px;*padding-bottom:7px}button.btn.btn-small,input[type="submit"].btn.btn-small{*padding-top:3px;*padding-bottom:3px}button.btn.btn-mini,input[type="submit"].btn.btn-mini{*padding-top:1px;*padding-bottom:1px}.btn-link,.btn-link:active,.btn-link[disabled]{background-color:transparent;background-image:none;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}.btn-link{color:#08c;cursor:pointer;border-color:transparent;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.btn-link:hover,.btn-link:focus{color:#005580;text-decoration:underline;background-color:transparent}.btn-link[disabled]:hover,.btn-link[disabled]:focus{color:#333;text-decoration:none}.btn-group{position:relative;display:inline-block;*display:inline;*margin-left:.3em;font-size:0;white-space:nowrap;vertical-align:middle;*zoom:1}.btn-group:first-child{*margin-left:0}.btn-group+.btn-group{margin-left:5px}.btn-toolbar{margin-top:10px;margin-bottom:10px;font-size:0}.btn-toolbar>.btn+.btn,.btn-toolbar>.btn-group+.btn,.btn-toolbar>.btn+.btn-group{margin-left:5px}.btn-group>.btn{position:relative;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.btn-group>.btn+.btn{margin-left:-1px}.btn-group>.btn,.btn-group>.dropdown-menu,.btn-group>.popover{font-size:14px}.btn-group>.btn-mini{font-size:10.5px}.btn-group>.btn-small{font-size:11.9px}.btn-group>.btn-large{font-size:17.5px}.btn-group>.btn:first-child{margin-left:0;-webkit-border-bottom-left-radius:4px;border-bottom-left-radius:4px;-webkit-border-top-left-radius:4px;border-top-left-radius:4px;-moz-border-radius-bottomleft:4px;-moz-border-radius-topleft:4px}.btn-group>.btn:last-child,.btn-group>.dropdown-toggle{-webkit-border-top-right-radius:4px;border-top-right-radius:4px;-webkit-border-bottom-right-radius:4px;border-bottom-right-radius:4px;-moz-border-radius-topright:4px;-moz-border-radius-bottomright:4px}.btn-group>.btn.large:first-child{margin-left:0;-webkit-border-bottom-left-radius:6px;border-bottom-left-radius:6px;-webkit-border-top-left-radius:6px;border-top-left-radius:6px;-moz-border-radius-bottomleft:6px;-moz-border-radius-topleft:6px}.btn-group>.btn.large:last-child,.btn-group>.large.dropdown-toggle{-webkit-border-top-right-radius:6px;border-top-right-radius:6px;-webkit-border-bottom-right-radius:6px;border-bottom-right-radius:6px;-moz-border-radius-topright:6px;-moz-border-radius-bottomright:6px}.btn-group>.btn:hover,.btn-group>.btn:focus,.btn-group>.btn:active,.btn-group>.btn.active{z-index:2}.btn-group .dropdown-toggle:active,.btn-group.open .dropdown-toggle{outline:0}.btn-group>.btn+.dropdown-toggle{*padding-top:5px;padding-right:8px;*padding-bottom:5px;padding-left:8px;-webkit-box-shadow:inset 1px 0 0 rgba(255,255,255,0.125),inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:inset 1px 0 0 rgba(255,255,255,0.125),inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 1px 0 0 rgba(255,255,255,0.125),inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05)}.btn-group>.btn-mini+.dropdown-toggle{*padding-top:2px;padding-right:5px;*padding-bottom:2px;padding-left:5px}.btn-group>.btn-small+.dropdown-toggle{*padding-top:5px;*padding-bottom:4px}.btn-group>.btn-large+.dropdown-toggle{*padding-top:7px;padding-right:12px;*padding-bottom:7px;padding-left:12px}.btn-group.open .dropdown-toggle{background-image:none;-webkit-box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05)}.btn-group.open .btn.dropdown-toggle{background-color:#e6e6e6}.btn-group.open .btn-primary.dropdown-toggle{background-color:#04c}.btn-group.open .btn-warning.dropdown-toggle{background-color:#f89406}.btn-group.open .btn-danger.dropdown-toggle{background-color:#bd362f}.btn-group.open .btn-success.dropdown-toggle{background-color:#51a351}.btn-group.open .btn-info.dropdown-toggle{background-color:#2f96b4}.btn-group.open .btn-inverse.dropdown-toggle{background-color:#222}.btn .caret{margin-top:8px;margin-left:0}.btn-large .caret{margin-top:6px}.btn-large .caret{border-top-width:5px;border-right-width:5px;border-left-width:5px}.btn-mini .caret,.btn-small .caret{margin-top:8px}.dropup .btn-large .caret{border-bottom-width:5px}.btn-primary .caret,.btn-warning .caret,.btn-danger .caret,.btn-info .caret,.btn-success .caret,.btn-inverse .caret{border-top-color:#fff;border-bottom-color:#fff}.btn-group-vertical{display:inline-block;*display:inline;*zoom:1}.btn-group-vertical>.btn{display:block;float:none;max-width:100%;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.btn-group-vertical>.btn+.btn{margin-top:-1px;margin-left:0}.btn-group-vertical>.btn:first-child{-webkit-border-radius:4px 4px 0 0;-moz-border-radius:4px 4px 0 0;border-radius:4px 4px 0 0}.btn-group-vertical>.btn:last-child{-webkit-border-radius:0 0 4px 4px;-moz-border-radius:0 0 4px 4px;border-radius:0 0 4px 4px}.btn-group-vertical>.btn-large:first-child{-webkit-border-radius:6px 6px 0 0;-moz-border-radius:6px 6px 0 0;border-radius:6px 6px 0 0}.btn-group-vertical>.btn-large:last-child{-webkit-border-radius:0 0 6px 6px;-moz-border-radius:0 0 6px 6px;border-radius:0 0 6px 6px}.alert{padding:8px 35px 8px 14px;margin-bottom:20px;text-shadow:0 1px 0 rgba(255,255,255,0.5);background-color:#fcf8e3;border:1px solid #fbeed5;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.alert,.alert h4{color:#c09853}.alert h4{margin:0}.alert .close{position:relative;top:-2px;right:-21px;line-height:20px}.alert-success{color:#468847;background-color:#dff0d8;border-color:#d6e9c6}.alert-success h4{color:#468847}.alert-danger,.alert-error{color:#b94a48;background-color:#f2dede;border-color:#eed3d7}.alert-danger h4,.alert-error h4{color:#b94a48}.alert-info{color:#3a87ad;background-color:#d9edf7;border-color:#bce8f1}.alert-info h4{color:#3a87ad}.alert-block{padding-top:14px;padding-bottom:14px}.alert-block>p,.alert-block>ul{margin-bottom:0}.alert-block p+p{margin-top:5px}.nav{margin-bottom:20px;margin-left:0;list-style:none}.nav>li>a{display:block}.nav>li>a:hover,.nav>li>a:focus{text-decoration:none;background-color:#eee}.nav>li>a>img{max-width:none}.nav>.pull-right{float:right}.nav-header{display:block;padding:3px 15px;font-size:11px;font-weight:bold;line-height:20px;color:#999;text-shadow:0 1px 0 rgba(255,255,255,0.5);text-transform:uppercase}.nav li+.nav-header{margin-top:9px}.nav-list{padding-right:15px;padding-left:15px;margin-bottom:0}.nav-list>li>a,.nav-list .nav-header{margin-right:-15px;margin-left:-15px;text-shadow:0 1px 0 rgba(255,255,255,0.5)}.nav-list>li>a{padding:3px 15px}.nav-list>.active>a,.nav-list>.active>a:hover,.nav-list>.active>a:focus{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.2);background-color:#08c}.nav-list [class^="icon-"],.nav-list [class*=" icon-"]{margin-right:2px}.nav-list .divider{*width:100%;height:1px;margin:9px 1px;*margin:-5px 0 5px;overflow:hidden;background-color:#e5e5e5;border-bottom:1px solid #fff}.nav-tabs,.nav-pills{*zoom:1}.nav-tabs:before,.nav-pills:before,.nav-tabs:after,.nav-pills:after{display:table;line-height:0;content:""}.nav-tabs:after,.nav-pills:after{clear:both}.nav-tabs>li,.nav-pills>li{float:left}.nav-tabs>li>a,.nav-pills>li>a{padding-right:12px;padding-left:12px;margin-right:2px;line-height:14px}.nav-tabs{border-bottom:1px solid #ddd}.nav-tabs>li{margin-bottom:-1px}.nav-tabs>li>a{padding-top:8px;padding-bottom:8px;line-height:20px;border:1px solid transparent;-webkit-border-radius:4px 4px 0 0;-moz-border-radius:4px 4px 0 0;border-radius:4px 4px 0 0}.nav-tabs>li>a:hover,.nav-tabs>li>a:focus{border-color:#eee #eee #ddd}.nav-tabs>.active>a,.nav-tabs>.active>a:hover,.nav-tabs>.active>a:focus{color:#555;cursor:default;background-color:#fff;border:1px solid #ddd;border-bottom-color:transparent}.nav-pills>li>a{padding-top:8px;padding-bottom:8px;margin-top:2px;margin-bottom:2px;-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px}.nav-pills>.active>a,.nav-pills>.active>a:hover,.nav-pills>.active>a:focus{color:#fff;background-color:#08c}.nav-stacked>li{float:none}.nav-stacked>li>a{margin-right:0}.nav-tabs.nav-stacked{border-bottom:0}.nav-tabs.nav-stacked>li>a{border:1px solid #ddd;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.nav-tabs.nav-stacked>li:first-child>a{-webkit-border-top-right-radius:4px;border-top-right-radius:4px;-webkit-border-top-left-radius:4px;border-top-left-radius:4px;-moz-border-radius-topright:4px;-moz-border-radius-topleft:4px}.nav-tabs.nav-stacked>li:last-child>a{-webkit-border-bottom-right-radius:4px;border-bottom-right-radius:4px;-webkit-border-bottom-left-radius:4px;border-bottom-left-radius:4px;-moz-border-radius-bottomright:4px;-moz-border-radius-bottomleft:4px}.nav-tabs.nav-stacked>li>a:hover,.nav-tabs.nav-stacked>li>a:focus{z-index:2;border-color:#ddd}.nav-pills.nav-stacked>li>a{margin-bottom:3px}.nav-pills.nav-stacked>li:last-child>a{margin-bottom:1px}.nav-tabs .dropdown-menu{-webkit-border-radius:0 0 6px 6px;-moz-border-radius:0 0 6px 6px;border-radius:0 0 6px 6px}.nav-pills .dropdown-menu{-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px}.nav .dropdown-toggle .caret{margin-top:6px;border-top-color:#08c;border-bottom-color:#08c}.nav .dropdown-toggle:hover .caret,.nav .dropdown-toggle:focus .caret{border-top-color:#005580;border-bottom-color:#005580}.nav-tabs .dropdown-toggle .caret{margin-top:8px}.nav .active .dropdown-toggle .caret{border-top-color:#fff;border-bottom-color:#fff}.nav-tabs .active .dropdown-toggle .caret{border-top-color:#555;border-bottom-color:#555}.nav>.dropdown.active>a:hover,.nav>.dropdown.active>a:focus{cursor:pointer}.nav-tabs .open .dropdown-toggle,.nav-pills .open .dropdown-toggle,.nav>li.dropdown.open.active>a:hover,.nav>li.dropdown.open.active>a:focus{color:#fff;background-color:#999;border-color:#999}.nav li.dropdown.open .caret,.nav li.dropdown.open.active .caret,.nav li.dropdown.open a:hover .caret,.nav li.dropdown.open a:focus .caret{border-top-color:#fff;border-bottom-color:#fff;opacity:1;filter:alpha(opacity=100)}.tabs-stacked .open>a:hover,.tabs-stacked .open>a:focus{border-color:#999}.tabbable{*zoom:1}.tabbable:before,.tabbable:after{display:table;line-height:0;content:""}.tabbable:after{clear:both}.tab-content{overflow:auto}.tabs-below>.nav-tabs,.tabs-right>.nav-tabs,.tabs-left>.nav-tabs{border-bottom:0}.tab-content>.tab-pane,.pill-content>.pill-pane{display:none}.tab-content>.active,.pill-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{-webkit-border-radius:0 0 4px 4px;-moz-border-radius:0 0 4px 4px;border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:hover,.tabs-below>.nav-tabs>li>a:focus{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:hover,.tabs-below>.nav-tabs>.active>a:focus{border-color:transparent #ddd #ddd #ddd}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{min-width:74px;margin-right:0;margin-bottom:3px}.tabs-left>.nav-tabs{float:left;margin-right:19px;border-right:1px solid #ddd}.tabs-left>.nav-tabs>li>a{margin-right:-1px;-webkit-border-radius:4px 0 0 4px;-moz-border-radius:4px 0 0 4px;border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:hover,.tabs-left>.nav-tabs>li>a:focus{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs .active>a,.tabs-left>.nav-tabs .active>a:hover,.tabs-left>.nav-tabs .active>a:focus{border-color:#ddd transparent #ddd #ddd;*border-right-color:#fff}.tabs-right>.nav-tabs{float:right;margin-left:19px;border-left:1px solid #ddd}.tabs-right>.nav-tabs>li>a{margin-left:-1px;-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:hover,.tabs-right>.nav-tabs>li>a:focus{border-color:#eee #eee #eee #ddd}.tabs-right>.nav-tabs .active>a,.tabs-right>.nav-tabs .active>a:hover,.tabs-right>.nav-tabs .active>a:focus{border-color:#ddd #ddd #ddd transparent;*border-left-color:#fff}.nav>.disabled>a{color:#999}.nav>.disabled>a:hover,.nav>.disabled>a:focus{text-decoration:none;cursor:default;background-color:transparent}.navbar{*position:relative;*z-index:2;margin-bottom:20px;overflow:visible}.navbar-inner{min-height:40px;padding-right:20px;padding-left:20px;background-color:#fafafa;background-image:-moz-linear-gradient(top,#fff,#f2f2f2);background-image:-webkit-gradient(linear,0 0,0 100%,from(#fff),to(#f2f2f2));background-image:-webkit-linear-gradient(top,#fff,#f2f2f2);background-image:-o-linear-gradient(top,#fff,#f2f2f2);background-image:linear-gradient(to bottom,#fff,#f2f2f2);background-repeat:repeat-x;border:1px solid #d4d4d4;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff',endColorstr='#fff2f2f2',GradientType=0);*zoom:1;-webkit-box-shadow:0 1px 4px rgba(0,0,0,0.065);-moz-box-shadow:0 1px 4px rgba(0,0,0,0.065);box-shadow:0 1px 4px rgba(0,0,0,0.065)}.navbar-inner:before,.navbar-inner:after{display:table;line-height:0;content:""}.navbar-inner:after{clear:both}.navbar .container{width:auto}.nav-collapse.collapse{height:auto;overflow:visible}.navbar .brand{display:block;float:left;padding:10px 20px 10px;margin-left:-20px;font-size:20px;font-weight:200;color:#777;text-shadow:0 1px 0 #fff}.navbar .brand:hover,.navbar .brand:focus{text-decoration:none}.navbar-text{margin-bottom:0;line-height:40px;color:#777}.navbar-link{color:#777}.navbar-link:hover,.navbar-link:focus{color:#333}.navbar .divider-vertical{height:40px;margin:0 9px;border-right:1px solid #fff;border-left:1px solid #f2f2f2}.navbar .btn,.navbar .btn-group{margin-top:5px}.navbar .btn-group .btn,.navbar .input-prepend .btn,.navbar .input-append .btn,.navbar .input-prepend .btn-group,.navbar .input-append .btn-group{margin-top:0}.navbar-form{margin-bottom:0;*zoom:1}.navbar-form:before,.navbar-form:after{display:table;line-height:0;content:""}.navbar-form:after{clear:both}.navbar-form input,.navbar-form select,.navbar-form .radio,.navbar-form .checkbox{margin-top:5px}.navbar-form input,.navbar-form select,.navbar-form .btn{display:inline-block;margin-bottom:0}.navbar-form input[type="image"],.navbar-form input[type="checkbox"],.navbar-form input[type="radio"]{margin-top:3px}.navbar-form .input-append,.navbar-form .input-prepend{margin-top:5px;white-space:nowrap}.navbar-form .input-append input,.navbar-form .input-prepend input{margin-top:0}.navbar-search{position:relative;float:left;margin-top:5px;margin-bottom:0}.navbar-search .search-query{padding:4px 14px;margin-bottom:0;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:13px;font-weight:normal;line-height:1;-webkit-border-radius:15px;-moz-border-radius:15px;border-radius:15px}.navbar-static-top{position:static;margin-bottom:0}.navbar-static-top .navbar-inner{-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.navbar-fixed-top,.navbar-fixed-bottom{position:fixed;right:0;left:0;z-index:1030;margin-bottom:0}.navbar-fixed-top .navbar-inner,.navbar-static-top .navbar-inner{border-width:0 0 1px}.navbar-fixed-bottom .navbar-inner{border-width:1px 0 0}.navbar-fixed-top .navbar-inner,.navbar-fixed-bottom .navbar-inner{padding-right:0;padding-left:0;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.navbar-static-top .container,.navbar-fixed-top .container,.navbar-fixed-bottom .container{width:940px}.navbar-fixed-top{top:0}.navbar-fixed-top .navbar-inner,.navbar-static-top .navbar-inner{-webkit-box-shadow:0 1px 10px rgba(0,0,0,0.1);-moz-box-shadow:0 1px 10px rgba(0,0,0,0.1);box-shadow:0 1px 10px rgba(0,0,0,0.1)}.navbar-fixed-bottom{bottom:0}.navbar-fixed-bottom .navbar-inner{-webkit-box-shadow:0 -1px 10px rgba(0,0,0,0.1);-moz-box-shadow:0 -1px 10px rgba(0,0,0,0.1);box-shadow:0 -1px 10px rgba(0,0,0,0.1)}.navbar .nav{position:relative;left:0;display:block;float:left;margin:0 10px 0 0}.navbar .nav.pull-right{float:right;margin-right:0}.navbar .nav>li{float:left}.navbar .nav>li>a{float:none;padding:10px 15px 10px;color:#777;text-decoration:none;text-shadow:0 1px 0 #fff}.navbar .nav .dropdown-toggle .caret{margin-top:8px}.navbar .nav>li>a:focus,.navbar .nav>li>a:hover{color:#333;text-decoration:none;background-color:transparent}.navbar .nav>.active>a,.navbar .nav>.active>a:hover,.navbar .nav>.active>a:focus{color:#555;text-decoration:none;background-color:#e5e5e5;-webkit-box-shadow:inset 0 3px 8px rgba(0,0,0,0.125);-moz-box-shadow:inset 0 3px 8px rgba(0,0,0,0.125);box-shadow:inset 0 3px 8px rgba(0,0,0,0.125)}.navbar .btn-navbar{display:none;float:right;padding:7px 10px;margin-right:5px;margin-left:5px;color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#ededed;*background-color:#e5e5e5;background-image:-moz-linear-gradient(top,#f2f2f2,#e5e5e5);background-image:-webkit-gradient(linear,0 0,0 100%,from(#f2f2f2),to(#e5e5e5));background-image:-webkit-linear-gradient(top,#f2f2f2,#e5e5e5);background-image:-o-linear-gradient(top,#f2f2f2,#e5e5e5);background-image:linear-gradient(to bottom,#f2f2f2,#e5e5e5);background-repeat:repeat-x;border-color:#e5e5e5 #e5e5e5 #bfbfbf;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2f2f2',endColorstr='#ffe5e5e5',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.075);-moz-box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.075);box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.075)}.navbar .btn-navbar:hover,.navbar .btn-navbar:focus,.navbar .btn-navbar:active,.navbar .btn-navbar.active,.navbar .btn-navbar.disabled,.navbar .btn-navbar[disabled]{color:#fff;background-color:#e5e5e5;*background-color:#d9d9d9}.navbar .btn-navbar:active,.navbar .btn-navbar.active{background-color:#ccc \9}.navbar .btn-navbar .icon-bar{display:block;width:18px;height:2px;background-color:#f5f5f5;-webkit-border-radius:1px;-moz-border-radius:1px;border-radius:1px;-webkit-box-shadow:0 1px 0 rgba(0,0,0,0.25);-moz-box-shadow:0 1px 0 rgba(0,0,0,0.25);box-shadow:0 1px 0 rgba(0,0,0,0.25)}.btn-navbar .icon-bar+.icon-bar{margin-top:3px}.navbar .nav>li>.dropdown-menu:before{position:absolute;top:-7px;left:9px;display:inline-block;border-right:7px solid transparent;border-bottom:7px solid #ccc;border-left:7px solid transparent;border-bottom-color:rgba(0,0,0,0.2);content:''}.navbar .nav>li>.dropdown-menu:after{position:absolute;top:-6px;left:10px;display:inline-block;border-right:6px solid transparent;border-bottom:6px solid #fff;border-left:6px solid transparent;content:''}.navbar-fixed-bottom .nav>li>.dropdown-menu:before{top:auto;bottom:-7px;border-top:7px solid #ccc;border-bottom:0;border-top-color:rgba(0,0,0,0.2)}.navbar-fixed-bottom .nav>li>.dropdown-menu:after{top:auto;bottom:-6px;border-top:6px solid #fff;border-bottom:0}.navbar .nav li.dropdown>a:hover .caret,.navbar .nav li.dropdown>a:focus .caret{border-top-color:#333;border-bottom-color:#333}.navbar .nav li.dropdown.open>.dropdown-toggle,.navbar .nav li.dropdown.active>.dropdown-toggle,.navbar .nav li.dropdown.open.active>.dropdown-toggle{color:#555;background-color:#e5e5e5}.navbar .nav li.dropdown>.dropdown-toggle .caret{border-top-color:#777;border-bottom-color:#777}.navbar .nav li.dropdown.open>.dropdown-toggle .caret,.navbar .nav li.dropdown.active>.dropdown-toggle .caret,.navbar .nav li.dropdown.open.active>.dropdown-toggle .caret{border-top-color:#555;border-bottom-color:#555}.navbar .pull-right>li>.dropdown-menu,.navbar .nav>li>.dropdown-menu.pull-right{right:0;left:auto}.navbar .pull-right>li>.dropdown-menu:before,.navbar .nav>li>.dropdown-menu.pull-right:before{right:12px;left:auto}.navbar .pull-right>li>.dropdown-menu:after,.navbar .nav>li>.dropdown-menu.pull-right:after{right:13px;left:auto}.navbar .pull-right>li>.dropdown-menu .dropdown-menu,.navbar .nav>li>.dropdown-menu.pull-right .dropdown-menu{right:100%;left:auto;margin-right:-1px;margin-left:0;-webkit-border-radius:6px 0 6px 6px;-moz-border-radius:6px 0 6px 6px;border-radius:6px 0 6px 6px}.navbar-inverse .navbar-inner{background-color:#1b1b1b;background-image:-moz-linear-gradient(top,#222,#111);background-image:-webkit-gradient(linear,0 0,0 100%,from(#222),to(#111));background-image:-webkit-linear-gradient(top,#222,#111);background-image:-o-linear-gradient(top,#222,#111);background-image:linear-gradient(to bottom,#222,#111);background-repeat:repeat-x;border-color:#252525;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff222222',endColorstr='#ff111111',GradientType=0)}.navbar-inverse .brand,.navbar-inverse .nav>li>a{color:#999;text-shadow:0 -1px 0 rgba(0,0,0,0.25)}.navbar-inverse .brand:hover,.navbar-inverse .nav>li>a:hover,.navbar-inverse .brand:focus,.navbar-inverse .nav>li>a:focus{color:#fff}.navbar-inverse .brand{color:#999}.navbar-inverse .navbar-text{color:#999}.navbar-inverse .nav>li>a:focus,.navbar-inverse .nav>li>a:hover{color:#fff;background-color:transparent}.navbar-inverse .nav .active>a,.navbar-inverse .nav .active>a:hover,.navbar-inverse .nav .active>a:focus{color:#fff;background-color:#111}.navbar-inverse .navbar-link{color:#999}.navbar-inverse .navbar-link:hover,.navbar-inverse .navbar-link:focus{color:#fff}.navbar-inverse .divider-vertical{border-right-color:#222;border-left-color:#111}.navbar-inverse .nav li.dropdown.open>.dropdown-toggle,.navbar-inverse .nav li.dropdown.active>.dropdown-toggle,.navbar-inverse .nav li.dropdown.open.active>.dropdown-toggle{color:#fff;background-color:#111}.navbar-inverse .nav li.dropdown>a:hover .caret,.navbar-inverse .nav li.dropdown>a:focus .caret{border-top-color:#fff;border-bottom-color:#fff}.navbar-inverse .nav li.dropdown>.dropdown-toggle .caret{border-top-color:#999;border-bottom-color:#999}.navbar-inverse .nav li.dropdown.open>.dropdown-toggle .caret,.navbar-inverse .nav li.dropdown.active>.dropdown-toggle .caret,.navbar-inverse .nav li.dropdown.open.active>.dropdown-toggle .caret{border-top-color:#fff;border-bottom-color:#fff}.navbar-inverse .navbar-search .search-query{color:#fff;background-color:#515151;border-color:#111;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,0.1),0 1px 0 rgba(255,255,255,0.15);-moz-box-shadow:inset 0 1px 2px rgba(0,0,0,0.1),0 1px 0 rgba(255,255,255,0.15);box-shadow:inset 0 1px 2px rgba(0,0,0,0.1),0 1px 0 rgba(255,255,255,0.15);-webkit-transition:none;-moz-transition:none;-o-transition:none;transition:none}.navbar-inverse .navbar-search .search-query:-moz-placeholder{color:#ccc}.navbar-inverse .navbar-search .search-query:-ms-input-placeholder{color:#ccc}.navbar-inverse .navbar-search .search-query::-webkit-input-placeholder{color:#ccc}.navbar-inverse .navbar-search .search-query:focus,.navbar-inverse .navbar-search .search-query.focused{padding:5px 15px;color:#333;text-shadow:0 1px 0 #fff;background-color:#fff;border:0;outline:0;-webkit-box-shadow:0 0 3px rgba(0,0,0,0.15);-moz-box-shadow:0 0 3px rgba(0,0,0,0.15);box-shadow:0 0 3px rgba(0,0,0,0.15)}.navbar-inverse .btn-navbar{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#0e0e0e;*background-color:#040404;background-image:-moz-linear-gradient(top,#151515,#040404);background-image:-webkit-gradient(linear,0 0,0 100%,from(#151515),to(#040404));background-image:-webkit-linear-gradient(top,#151515,#040404);background-image:-o-linear-gradient(top,#151515,#040404);background-image:linear-gradient(to bottom,#151515,#040404);background-repeat:repeat-x;border-color:#040404 #040404 #000;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff151515',endColorstr='#ff040404',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.navbar-inverse .btn-navbar:hover,.navbar-inverse .btn-navbar:focus,.navbar-inverse .btn-navbar:active,.navbar-inverse .btn-navbar.active,.navbar-inverse .btn-navbar.disabled,.navbar-inverse .btn-navbar[disabled]{color:#fff;background-color:#040404;*background-color:#000}.navbar-inverse .btn-navbar:active,.navbar-inverse .btn-navbar.active{background-color:#000 \9}.breadcrumb{padding:8px 15px;margin:0 0 20px;list-style:none;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.breadcrumb>li{display:inline-block;*display:inline;text-shadow:0 1px 0 #fff;*zoom:1}.breadcrumb>li>.divider{padding:0 5px;color:#ccc}.breadcrumb>.active{color:#999}.pagination{margin:20px 0}.pagination ul{display:inline-block;*display:inline;margin-bottom:0;margin-left:0;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;*zoom:1;-webkit-box-shadow:0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:0 1px 2px rgba(0,0,0,0.05);box-shadow:0 1px 2px rgba(0,0,0,0.05)}.pagination ul>li{display:inline}.pagination ul>li>a,.pagination ul>li>span{float:left;padding:4px 12px;line-height:20px;text-decoration:none;background-color:#fff;border:1px solid #ddd;border-left-width:0}.pagination ul>li>a:hover,.pagination ul>li>a:focus,.pagination ul>.active>a,.pagination ul>.active>span{background-color:#f5f5f5}.pagination ul>.active>a,.pagination ul>.active>span{color:#999;cursor:default}.pagination ul>.disabled>span,.pagination ul>.disabled>a,.pagination ul>.disabled>a:hover,.pagination ul>.disabled>a:focus{color:#999;cursor:default;background-color:transparent}.pagination ul>li:first-child>a,.pagination ul>li:first-child>span{border-left-width:1px;-webkit-border-bottom-left-radius:4px;border-bottom-left-radius:4px;-webkit-border-top-left-radius:4px;border-top-left-radius:4px;-moz-border-radius-bottomleft:4px;-moz-border-radius-topleft:4px}.pagination ul>li:last-child>a,.pagination ul>li:last-child>span{-webkit-border-top-right-radius:4px;border-top-right-radius:4px;-webkit-border-bottom-right-radius:4px;border-bottom-right-radius:4px;-moz-border-radius-topright:4px;-moz-border-radius-bottomright:4px}.pagination-centered{text-align:center}.pagination-right{text-align:right}.pagination-large ul>li>a,.pagination-large ul>li>span{padding:11px 19px;font-size:17.5px}.pagination-large ul>li:first-child>a,.pagination-large ul>li:first-child>span{-webkit-border-bottom-left-radius:6px;border-bottom-left-radius:6px;-webkit-border-top-left-radius:6px;border-top-left-radius:6px;-moz-border-radius-bottomleft:6px;-moz-border-radius-topleft:6px}.pagination-large ul>li:last-child>a,.pagination-large ul>li:last-child>span{-webkit-border-top-right-radius:6px;border-top-right-radius:6px;-webkit-border-bottom-right-radius:6px;border-bottom-right-radius:6px;-moz-border-radius-topright:6px;-moz-border-radius-bottomright:6px}.pagination-mini ul>li:first-child>a,.pagination-small ul>li:first-child>a,.pagination-mini ul>li:first-child>span,.pagination-small ul>li:first-child>span{-webkit-border-bottom-left-radius:3px;border-bottom-left-radius:3px;-webkit-border-top-left-radius:3px;border-top-left-radius:3px;-moz-border-radius-bottomleft:3px;-moz-border-radius-topleft:3px}.pagination-mini ul>li:last-child>a,.pagination-small ul>li:last-child>a,.pagination-mini ul>li:last-child>span,.pagination-small ul>li:last-child>span{-webkit-border-top-right-radius:3px;border-top-right-radius:3px;-webkit-border-bottom-right-radius:3px;border-bottom-right-radius:3px;-moz-border-radius-topright:3px;-moz-border-radius-bottomright:3px}.pagination-small ul>li>a,.pagination-small ul>li>span{padding:2px 10px;font-size:11.9px}.pagination-mini ul>li>a,.pagination-mini ul>li>span{padding:0 6px;font-size:10.5px}.pager{margin:20px 0;text-align:center;list-style:none;*zoom:1}.pager:before,.pager:after{display:table;line-height:0;content:""}.pager:after{clear:both}.pager li{display:inline}.pager li>a,.pager li>span{display:inline-block;padding:5px 14px;background-color:#fff;border:1px solid #ddd;-webkit-border-radius:15px;-moz-border-radius:15px;border-radius:15px}.pager li>a:hover,.pager li>a:focus{text-decoration:none;background-color:#f5f5f5}.pager .next>a,.pager .next>span{float:right}.pager .previous>a,.pager .previous>span{float:left}.pager .disabled>a,.pager .disabled>a:hover,.pager .disabled>a:focus,.pager .disabled>span{color:#999;cursor:default;background-color:#fff}.modal-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1040;background-color:#000}.modal-backdrop.fade{opacity:0}.modal-backdrop,.modal-backdrop.fade.in{opacity:.8;filter:alpha(opacity=80)}.modal{position:fixed;top:10%;left:50%;z-index:1050;width:560px;margin-left:-280px;background-color:#fff;border:1px solid #999;border:1px solid rgba(0,0,0,0.3);*border:1px solid #999;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;outline:0;-webkit-box-shadow:0 3px 7px rgba(0,0,0,0.3);-moz-box-shadow:0 3px 7px rgba(0,0,0,0.3);box-shadow:0 3px 7px rgba(0,0,0,0.3);-webkit-background-clip:padding-box;-moz-background-clip:padding-box;background-clip:padding-box}.modal.fade{top:-25%;-webkit-transition:opacity .3s linear,top .3s ease-out;-moz-transition:opacity .3s linear,top .3s ease-out;-o-transition:opacity .3s linear,top .3s ease-out;transition:opacity .3s linear,top .3s ease-out}.modal.fade.in{top:20%}.modal-header{padding:9px 15px;border-bottom:1px solid #eee}.modal-header .close{margin-top:2px}.modal-header h3{margin:0;line-height:30px}.modal-body{position:relative;max-height:400px;padding:15px;overflow-y:auto}.modal-form{margin-bottom:0}.modal-footer{padding:14px 15px 15px;margin-bottom:0;text-align:right;background-color:#f5f5f5;border-top:1px solid #ddd;-webkit-border-radius:0 0 6px 6px;-moz-border-radius:0 0 6px 6px;border-radius:0 0 6px 6px;*zoom:1;-webkit-box-shadow:inset 0 1px 0 #fff;-moz-box-shadow:inset 0 1px 0 #fff;box-shadow:inset 0 1px 0 #fff}.modal-footer:before,.modal-footer:after{display:table;line-height:0;content:""}.modal-footer:after{clear:both}.modal-footer .btn+.btn{margin-bottom:0;margin-left:5px}.modal-footer .btn-group .btn+.btn{margin-left:-1px}.modal-footer .btn-block+.btn-block{margin-left:0}.tooltip{position:absolute;z-index:1030;display:block;font-size:11px;line-height:1.4;opacity:0;filter:alpha(opacity=0);visibility:visible}.tooltip.in{opacity:.8;filter:alpha(opacity=80)}.tooltip.top{padding:5px 0;margin-top:-3px}.tooltip.right{padding:0 5px;margin-left:3px}.tooltip.bottom{padding:5px 0;margin-top:3px}.tooltip.left{padding:0 5px;margin-left:-3px}.tooltip-inner{max-width:200px;padding:8px;color:#fff;text-align:center;text-decoration:none;background-color:#000;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.tooltip-arrow{position:absolute;width:0;height:0;border-color:transparent;border-style:solid}.tooltip.top .tooltip-arrow{bottom:0;left:50%;margin-left:-5px;border-top-color:#000;border-width:5px 5px 0}.tooltip.right .tooltip-arrow{top:50%;left:0;margin-top:-5px;border-right-color:#000;border-width:5px 5px 5px 0}.tooltip.left .tooltip-arrow{top:50%;right:0;margin-top:-5px;border-left-color:#000;border-width:5px 0 5px 5px}.tooltip.bottom .tooltip-arrow{top:0;left:50%;margin-left:-5px;border-bottom-color:#000;border-width:0 5px 5px}.popover{position:absolute;top:0;left:0;z-index:1010;display:none;max-width:276px;padding:1px;text-align:left;white-space:normal;background-color:#fff;border:1px solid #ccc;border:1px solid rgba(0,0,0,0.2);-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0,0,0,0.2);-moz-box-shadow:0 5px 10px rgba(0,0,0,0.2);box-shadow:0 5px 10px rgba(0,0,0,0.2);-webkit-background-clip:padding-box;-moz-background-clip:padding;background-clip:padding-box}.popover.top{margin-top:-10px}.popover.right{margin-left:10px}.popover.bottom{margin-top:10px}.popover.left{margin-left:-10px}.popover-title{padding:8px 14px;margin:0;font-size:14px;font-weight:normal;line-height:18px;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;-webkit-border-radius:5px 5px 0 0;-moz-border-radius:5px 5px 0 0;border-radius:5px 5px 0 0}.popover-title:empty{display:none}.popover-content{padding:9px 14px}.popover .arrow,.popover .arrow:after{position:absolute;display:block;width:0;height:0;border-color:transparent;border-style:solid}.popover .arrow{border-width:11px}.popover .arrow:after{border-width:10px;content:""}.popover.top .arrow{bottom:-11px;left:50%;margin-left:-11px;border-top-color:#999;border-top-color:rgba(0,0,0,0.25);border-bottom-width:0}.popover.top .arrow:after{bottom:1px;margin-left:-10px;border-top-color:#fff;border-bottom-width:0}.popover.right .arrow{top:50%;left:-11px;margin-top:-11px;border-right-color:#999;border-right-color:rgba(0,0,0,0.25);border-left-width:0}.popover.right .arrow:after{bottom:-10px;left:1px;border-right-color:#fff;border-left-width:0}.popover.bottom .arrow{top:-11px;left:50%;margin-left:-11px;border-bottom-color:#999;border-bottom-color:rgba(0,0,0,0.25);border-top-width:0}.popover.bottom .arrow:after{top:1px;margin-left:-10px;border-bottom-color:#fff;border-top-width:0}.popover.left .arrow{top:50%;right:-11px;margin-top:-11px;border-left-color:#999;border-left-color:rgba(0,0,0,0.25);border-right-width:0}.popover.left .arrow:after{right:1px;bottom:-10px;border-left-color:#fff;border-right-width:0}.thumbnails{margin-left:-20px;list-style:none;*zoom:1}.thumbnails:before,.thumbnails:after{display:table;line-height:0;content:""}.thumbnails:after{clear:both}.row-fluid .thumbnails{margin-left:0}.thumbnails>li{float:left;margin-bottom:20px;margin-left:20px}.thumbnail{display:block;padding:4px;line-height:20px;border:1px solid #ddd;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;-webkit-box-shadow:0 1px 3px rgba(0,0,0,0.055);-moz-box-shadow:0 1px 3px rgba(0,0,0,0.055);box-shadow:0 1px 3px rgba(0,0,0,0.055);-webkit-transition:all .2s ease-in-out;-moz-transition:all .2s ease-in-out;-o-transition:all .2s ease-in-out;transition:all .2s ease-in-out}a.thumbnail:hover,a.thumbnail:focus{border-color:#08c;-webkit-box-shadow:0 1px 4px rgba(0,105,214,0.25);-moz-box-shadow:0 1px 4px rgba(0,105,214,0.25);box-shadow:0 1px 4px rgba(0,105,214,0.25)}.thumbnail>img{display:block;max-width:100%;margin-right:auto;margin-left:auto}.thumbnail .caption{padding:9px;color:#555}.media,.media-body{overflow:hidden;*overflow:visible;zoom:1}.media,.media .media{margin-top:15px}.media:first-child{margin-top:0}.media-object{display:block}.media-heading{margin:0 0 5px}.media>.pull-left{margin-right:10px}.media>.pull-right{margin-left:10px}.media-list{margin-left:0;list-style:none}.label,.badge{display:inline-block;padding:2px 4px;font-size:11.844px;font-weight:bold;line-height:14px;color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);white-space:nowrap;vertical-align:baseline;background-color:#999}.label{-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.badge{padding-right:9px;padding-left:9px;-webkit-border-radius:9px;-moz-border-radius:9px;border-radius:9px}.label:empty,.badge:empty{display:none}a.label:hover,a.label:focus,a.badge:hover,a.badge:focus{color:#fff;text-decoration:none;cursor:pointer}.label-important,.badge-important{background-color:#b94a48}.label-important[href],.badge-important[href]{background-color:#953b39}.label-warning,.badge-warning{background-color:#f89406}.label-warning[href],.badge-warning[href]{background-color:#c67605}.label-success,.badge-success{background-color:#468847}.label-success[href],.badge-success[href]{background-color:#356635}.label-info,.badge-info{background-color:#3a87ad}.label-info[href],.badge-info[href]{background-color:#2d6987}.label-inverse,.badge-inverse{background-color:#333}.label-inverse[href],.badge-inverse[href]{background-color:#1a1a1a}.btn .label,.btn .badge{position:relative;top:-1px}.btn-mini .label,.btn-mini .badge{top:0}@-webkit-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@-moz-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@-ms-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@-o-keyframes progress-bar-stripes{from{background-position:0 0}to{background-position:40px 0}}@keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}.progress{height:20px;margin-bottom:20px;overflow:hidden;background-color:#f7f7f7;background-image:-moz-linear-gradient(top,#f5f5f5,#f9f9f9);background-image:-webkit-gradient(linear,0 0,0 100%,from(#f5f5f5),to(#f9f9f9));background-image:-webkit-linear-gradient(top,#f5f5f5,#f9f9f9);background-image:-o-linear-gradient(top,#f5f5f5,#f9f9f9);background-image:linear-gradient(to bottom,#f5f5f5,#f9f9f9);background-repeat:repeat-x;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5',endColorstr='#fff9f9f9',GradientType=0);-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,0.1);-moz-box-shadow:inset 0 1px 2px rgba(0,0,0,0.1);box-shadow:inset 0 1px 2px rgba(0,0,0,0.1)}.progress .bar{float:left;width:0;height:100%;font-size:12px;color:#fff;text-align:center;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#0e90d2;background-image:-moz-linear-gradient(top,#149bdf,#0480be);background-image:-webkit-gradient(linear,0 0,0 100%,from(#149bdf),to(#0480be));background-image:-webkit-linear-gradient(top,#149bdf,#0480be);background-image:-o-linear-gradient(top,#149bdf,#0480be);background-image:linear-gradient(to bottom,#149bdf,#0480be);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff149bdf',endColorstr='#ff0480be',GradientType=0);-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,0.15);-moz-box-shadow:inset 0 -1px 0 rgba(0,0,0,0.15);box-shadow:inset 0 -1px 0 rgba(0,0,0,0.15);-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;-webkit-transition:width .6s ease;-moz-transition:width .6s ease;-o-transition:width .6s ease;transition:width .6s ease}.progress .bar+.bar{-webkit-box-shadow:inset 1px 0 0 rgba(0,0,0,0.15),inset 0 -1px 0 rgba(0,0,0,0.15);-moz-box-shadow:inset 1px 0 0 rgba(0,0,0,0.15),inset 0 -1px 0 rgba(0,0,0,0.15);box-shadow:inset 1px 0 0 rgba(0,0,0,0.15),inset 0 -1px 0 rgba(0,0,0,0.15)}.progress-striped .bar{background-color:#149bdf;background-image:-webkit-gradient(linear,0 100%,100% 0,color-stop(0.25,rgba(255,255,255,0.15)),color-stop(0.25,transparent),color-stop(0.5,transparent),color-stop(0.5,rgba(255,255,255,0.15)),color-stop(0.75,rgba(255,255,255,0.15)),color-stop(0.75,transparent),to(transparent));background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-moz-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);-webkit-background-size:40px 40px;-moz-background-size:40px 40px;-o-background-size:40px 40px;background-size:40px 40px}.progress.active .bar{-webkit-animation:progress-bar-stripes 2s linear infinite;-moz-animation:progress-bar-stripes 2s linear infinite;-ms-animation:progress-bar-stripes 2s linear infinite;-o-animation:progress-bar-stripes 2s linear infinite;animation:progress-bar-stripes 2s linear infinite}.progress-danger .bar,.progress .bar-danger{background-color:#dd514c;background-image:-moz-linear-gradient(top,#ee5f5b,#c43c35);background-image:-webkit-gradient(linear,0 0,0 100%,from(#ee5f5b),to(#c43c35));background-image:-webkit-linear-gradient(top,#ee5f5b,#c43c35);background-image:-o-linear-gradient(top,#ee5f5b,#c43c35);background-image:linear-gradient(to bottom,#ee5f5b,#c43c35);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffee5f5b',endColorstr='#ffc43c35',GradientType=0)}.progress-danger.progress-striped .bar,.progress-striped .bar-danger{background-color:#ee5f5b;background-image:-webkit-gradient(linear,0 100%,100% 0,color-stop(0.25,rgba(255,255,255,0.15)),color-stop(0.25,transparent),color-stop(0.5,transparent),color-stop(0.5,rgba(255,255,255,0.15)),color-stop(0.75,rgba(255,255,255,0.15)),color-stop(0.75,transparent),to(transparent));background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-moz-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent)}.progress-success .bar,.progress .bar-success{background-color:#5eb95e;background-image:-moz-linear-gradient(top,#62c462,#57a957);background-image:-webkit-gradient(linear,0 0,0 100%,from(#62c462),to(#57a957));background-image:-webkit-linear-gradient(top,#62c462,#57a957);background-image:-o-linear-gradient(top,#62c462,#57a957);background-image:linear-gradient(to bottom,#62c462,#57a957);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff62c462',endColorstr='#ff57a957',GradientType=0)}.progress-success.progress-striped .bar,.progress-striped .bar-success{background-color:#62c462;background-image:-webkit-gradient(linear,0 100%,100% 0,color-stop(0.25,rgba(255,255,255,0.15)),color-stop(0.25,transparent),color-stop(0.5,transparent),color-stop(0.5,rgba(255,255,255,0.15)),color-stop(0.75,rgba(255,255,255,0.15)),color-stop(0.75,transparent),to(transparent));background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-moz-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent)}.progress-info .bar,.progress .bar-info{background-color:#4bb1cf;background-image:-moz-linear-gradient(top,#5bc0de,#339bb9);background-image:-webkit-gradient(linear,0 0,0 100%,from(#5bc0de),to(#339bb9));background-image:-webkit-linear-gradient(top,#5bc0de,#339bb9);background-image:-o-linear-gradient(top,#5bc0de,#339bb9);background-image:linear-gradient(to bottom,#5bc0de,#339bb9);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de',endColorstr='#ff339bb9',GradientType=0)}.progress-info.progress-striped .bar,.progress-striped .bar-info{background-color:#5bc0de;background-image:-webkit-gradient(linear,0 100%,100% 0,color-stop(0.25,rgba(255,255,255,0.15)),color-stop(0.25,transparent),color-stop(0.5,transparent),color-stop(0.5,rgba(255,255,255,0.15)),color-stop(0.75,rgba(255,255,255,0.15)),color-stop(0.75,transparent),to(transparent));background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-moz-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent)}.progress-warning .bar,.progress .bar-warning{background-color:#faa732;background-image:-moz-linear-gradient(top,#fbb450,#f89406);background-image:-webkit-gradient(linear,0 0,0 100%,from(#fbb450),to(#f89406));background-image:-webkit-linear-gradient(top,#fbb450,#f89406);background-image:-o-linear-gradient(top,#fbb450,#f89406);background-image:linear-gradient(to bottom,#fbb450,#f89406);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffbb450',endColorstr='#fff89406',GradientType=0)}.progress-warning.progress-striped .bar,.progress-striped .bar-warning{background-color:#fbb450;background-image:-webkit-gradient(linear,0 100%,100% 0,color-stop(0.25,rgba(255,255,255,0.15)),color-stop(0.25,transparent),color-stop(0.5,transparent),color-stop(0.5,rgba(255,255,255,0.15)),color-stop(0.75,rgba(255,255,255,0.15)),color-stop(0.75,transparent),to(transparent));background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-moz-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent)}.accordion{margin-bottom:20px}.accordion-group{margin-bottom:2px;border:1px solid #e5e5e5;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.accordion-heading{border-bottom:0}.accordion-heading .accordion-toggle{display:block;padding:8px 15px}.accordion-toggle{cursor:pointer}.accordion-inner{padding:9px 15px;border-top:1px solid #e5e5e5}.carousel{position:relative;margin-bottom:20px;line-height:1}.carousel-inner{position:relative;width:100%;overflow:hidden}.carousel-inner>.item{position:relative;display:none;-webkit-transition:.6s ease-in-out left;-moz-transition:.6s ease-in-out left;-o-transition:.6s ease-in-out left;transition:.6s ease-in-out left}.carousel-inner>.item>img,.carousel-inner>.item>a>img{display:block;line-height:1}.carousel-inner>.active,.carousel-inner>.next,.carousel-inner>.prev{display:block}.carousel-inner>.active{left:0}.carousel-inner>.next,.carousel-inner>.prev{position:absolute;top:0;width:100%}.carousel-inner>.next{left:100%}.carousel-inner>.prev{left:-100%}.carousel-inner>.next.left,.carousel-inner>.prev.right{left:0}.carousel-inner>.active.left{left:-100%}.carousel-inner>.active.right{left:100%}.carousel-control{position:absolute;top:40%;left:15px;width:40px;height:40px;margin-top:-20px;font-size:60px;font-weight:100;line-height:30px;color:#fff;text-align:center;background:#222;border:3px solid #fff;-webkit-border-radius:23px;-moz-border-radius:23px;border-radius:23px;opacity:.5;filter:alpha(opacity=50)}.carousel-control.right{right:15px;left:auto}.carousel-control:hover,.carousel-control:focus{color:#fff;text-decoration:none;opacity:.9;filter:alpha(opacity=90)}.carousel-indicators{position:absolute;top:15px;right:15px;z-index:5;margin:0;list-style:none}.carousel-indicators li{display:block;float:left;width:10px;height:10px;margin-left:5px;text-indent:-999px;background-color:#ccc;background-color:rgba(255,255,255,0.25);border-radius:5px}.carousel-indicators .active{background-color:#fff}.carousel-caption{position:absolute;right:0;bottom:0;left:0;padding:15px;background:#333;background:rgba(0,0,0,0.75)}.carousel-caption h4,.carousel-caption p{line-height:20px;color:#fff}.carousel-caption h4{margin:0 0 5px}.carousel-caption p{margin-bottom:0}.hero-unit{padding:60px;margin-bottom:30px;font-size:18px;font-weight:200;line-height:30px;color:inherit;background-color:#eee;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px}.hero-unit h1{margin-bottom:0;font-size:60px;line-height:1;letter-spacing:-1px;color:inherit}.hero-unit li{line-height:30px}.pull-right{float:right}.pull-left{float:left}.hide{display:none}.show{display:block}.invisible{visibility:hidden}.affix{position:fixed}article,aside,details,figcaption,figure,footer,header,hgroup,nav,section{display:block}audio,canvas,video{display:inline-block;*display:inline;*zoom:1}audio:not([controls]){display:none}[hidden]{display:none}html{font-size:100%;overflow-y:scroll;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}body{margin:0;font-size:13px;line-height:1.231}body,button,input,select,textarea{font-family:sans-serif;color:#222}::-moz-selection{background:#7c85d8;color:#fff;text-shadow:none}::selection{background:#7c85d8;color:#fff;text-shadow:none}a{color:#08e}a:visited{color:#08e}a:hover{color:#04e}a:focus{outline:thin dotted}a:hover,a:active{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:bold}blockquote{margin:1em 40px}dfn{font-style:italic}hr{display:block;height:1px;border:0;border-top:1px solid #ccc;margin:1em 0;padding:0}ins{background:#ff9;color:#000;text-decoration:none}mark{background:#ff0;color:#000;font-style:italic;font-weight:bold}pre,code,kbd,samp{font-family:monospace,monospace;_font-family:'courier new',monospace;font-size:1em}pre{white-space:pre;white-space:pre-wrap;word-wrap:break-word}q{quotes:none}q:before,q:after{content:"";content:none}small{font-size:85%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-0.5em}sub{bottom:-0.25em}ul,ol{margin:0;padding:0 0 0 20px}dd{margin:0 0 0 40px}nav ul,nav ol{list-style:none;list-style-image:none;margin:0;padding:2px 0 0}img{border:0;-ms-interpolation-mode:bicubic;vertical-align:middle}svg:not(:root){overflow:hidden}figure{margin:0}form{margin:0}fieldset{border:0;margin:0;padding:0}label{cursor:pointer}legend{border:0;*margin-left:-7px;padding:0}button,input,select,textarea{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle}button,input{line-height:normal;*overflow:visible}table button,table input{*overflow:auto}button,input[type="button"],input[type="reset"],input[type="submit"]{cursor:pointer;-webkit-appearance:button}input[type="checkbox"],input[type="radio"]{box-sizing:border-box}input[type="search"]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}input[type="search"]::-webkit-search-decoration{-webkit-appearance:none}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}textarea{overflow:auto;vertical-align:top;resize:none}input:invalid,textarea:invalid{background-color:#f0dddd}table{border-collapse:collapse;border-spacing:0}td{vertical-align:top}.ir{display:block;border:0;text-indent:-999em;overflow:hidden;background-color:transparent;background-repeat:no-repeat;text-align:left;direction:ltr}.ir br{display:none}.hidden{display:none!important;visibility:hidden}.visuallyhidden{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.visuallyhidden.focusable:active,.visuallyhidden.focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}.invisible{visibility:hidden}.clearfix:before,.clearfix:after{content:"";display:table}.clearfix:after{clear:both}.clearfix{zoom:1}@media print{*{background:transparent!important;color:black!important;text-shadow:none!important;filter:none!important;-ms-filter:none!important}a,a:visited{text-decoration:underline}a[href]:after{content:" (" attr(href) ")"}abbr[title]:after{content:" (" attr(title) ")"}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100%!important}@page{margin:.5cm}p,h2,h3{orphans:3;widows:3}h2,h3{page-break-after:avoid}}.ui-resizable{position:relative}.ui-resizable-handle{position:absolute;font-size:.1px;z-index:99999;display:block}.ui-resizable-disabled .ui-resizable-handle,.ui-resizable-autohide .ui-resizable-handle{display:none}.ui-resizable-n{cursor:n-resize;height:7px;width:100%;top:-5px;left:0}.ui-resizable-s{cursor:s-resize;height:7px;width:100%;bottom:-5px;left:0}.ui-resizable-e{cursor:e-resize;cursor:col-resize;width:5px;right:-2px;top:0;height:100%}.ui-resizable-w{cursor:w-resize;width:7px;left:-5px;top:0;height:100%}.ui-resizable-se{cursor:se-resize;width:12px;height:12px;right:1px;bottom:1px}.ui-resizable-sw{cursor:sw-resize;width:9px;height:9px;left:-5px;bottom:-5px}.ui-resizable-nw{cursor:nw-resize;width:9px;height:9px;left:-5px;top:-5px}.ui-resizable-ne{cursor:ne-resize;width:9px;height:9px;right:-5px;top:-5px}.ui-button{display:inline-block;position:relative;padding:0;margin:0;text-decoration:none!important;cursor:pointer;text-align:center;zoom:1;overflow:hidden;color:#2a2a2a;background:#d8d8d8 url(../images/buttons/ui-button.png) repeat-x left top;border:1px solid #a8a8a8;border-bottom-color:#9e9e9e;font-size:12px;height:24px;-moz-box-shadow:0 1px 0 rgba(0,0,0,0.05);-webkit-box-shadow:0 1px 0 rgba(0,0,0,0.05);box-shadow:0 1px 0 rgba(0,0,0,0.05);-moz-border-radius:2px;-webkit-border-radius:2px;border-radius:2px}input.ui-button{border-color:#888}.ie7 .ui-button{overflow:visible}a.ui-button,span.ui-button{height:22px;line-height:22px;color:#2a2a2a}input.ui-button,.ui-button .ui-button-text{line-height:23px;color:#2a2a2a;text-shadow:0 1px 1px #f2f2f2;padding:0 10px}.ui-button-text-only .ui-button-text{padding:0 20px}button.ui-button::-moz-focus-inner{border:0;padding:0}.ie7 input.ui-button,.ie7 button.ui-button .ui-button-text{line-height:20px}.ie9 .ui-button .ui-button-text{line-height:24px}.ui-button:focus{outline:0 none}.ui-button:focus,.ui-button:hover,.ui-state-focus,.ui-state-hover{background-position:left -40px}.ui-custom-active,.ui-custom-active:focus,.ui-custom-active:hover,.ui-state-active,.ui-state-active:focus,.ui-state-active:hover,.ui-button:active{background-position:left -120px;border-color:#909090}.ui-button[disabled],.ui-button[disabled]:hover,.ui-button.default[disabled],.ui-custom-active[disabled],.ui-button[disabled]:active{background-position:left top;border-color:#999;cursor:default;-moz-box-shadow:0 1px 0 rgba(0,0,0,0.05);-webkit-box-shadow:0 1px 0 rgba(0,0,0,0.05);box-shadow:0 1px 0 rgba(0,0,0,0.05)}input.ui-button[disabled],input.ui-button[disabled]:hover{border-color:#ccc;color:#999;text-shadow:0 0 transparent}.ui-button.transparent[disabled]:hover{background:none!important;border-color:transparent!important;-moz-box-shadow:0 0 transparent!important;-webkit-box-shadow:0 0 transparent!important;box-shadow:0 0 transparent!important}.ui-button[disabled] .ui-button-text,.ui-button[disabled]:hover .ui-button-text,.ui-custom-active[disabled] .ui-button-text,.ui-button[disabled]:active .ui-button-text{color:#777;text-shadow:0 1px 1px #ddd}.ui-button.default{border-color:#2e52bc;-moz-box-shadow:0 0 3px #2e52bc,0 0 2px #2e52bc;-webkit-box-shadow:0 0 3px #2e52bc,0 0 2px #2e52bc;box-shadow:0 0 3px #2e52bc,0 0 2px #2e52bc}.ui-button-medium,a.ui-button-medium,span.ui-button-medium{height:30px;background-image:url(../images/buttons/ui-button-medium.png)}a.ui-button-medium,span.ui-button-medium{height:28px;line-height:28px}.ui-button-medium .ui-button-text{line-height:28px}.ie7 button.ui-button.ui-button-medium .ui-button-text{line-height:26px}.ie9 .ui-button-medium .ui-button-text{line-height:28px}.ui-button-medium-blue,a.ui-button-medium-blue,span.ui-button-medium-blue{font-weight:bold;font-size:14px;border-color:#2e6dc5;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;-moz-box-shadow:0 1px 0 rgba(0,0,0,0.15);-webkit-box-shadow:0 1px 0 rgba(0,0,0,0.15);box-shadow:0 1px 0 rgba(0,0,0,0.15)}.ui-button-medium-blue:active,.ui-button-medium-blue.ui-custom-active{border-color:#1e5be6}.cssgradients .ui-button-medium-blue{background:-webkit-gradient(linear,left top,left bottom,from(#699bdc),to(#3464b1));background:-moz-linear-gradient(#699bdc,#3464b1);background:-webkit-linear-gradient(#699bdc,#3464b1)}.cssgradients .ui-button-medium-blue:hover,.cssgradients .ui-button-medium-blue:focus{background:-webkit-gradient(linear,left top,left bottom,from(#7ca9e8),to(#4575c1));background:-moz-linear-gradient(#7ca9e8,#4575c1);background:-webkit-linear-gradient(#7ca9e8,#4575c1)}.cssgradients .ui-button-medium-blue:active,.cssgradients .ui-button-medium-blue.ui-custom-active{background:-webkit-gradient(linear,left top,left bottom,from(#5e8bca),to(#2757a3));background:-moz-linear-gradient(#5e8bca,#2757a3);background:-webkit-linear-gradient(#5e8bca,#2757a3)}.no-cssgradients .ui-button-medium-blue{background-color:#5b88c8;background-image:url(../images/buttons/btn_blue_28.png)}.no-cssgradients .ui-button-medium-blue:focus,.no-cssgradients .ui-button-medium-blue:hover{background-position:0 -30px}.no-cssgradients .ui-button-medium-blue:active{background-position:0 -60px}.ui-button-medium-blue .ui-button-text{line-height:26px;color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.60);font-size:14px;letter-spacing:-0.01em;padding:0}.ui-button-small,span.ui-button-small{height:16px;line-height:15px;background-image:url(../images/buttons/ui-button-small.png)}.ui-button-icon-only .ui-button-text{height:16px;display:block}span.ui-button-thin{height:21px;line-height:22px}.ui-button-thin .ui-button-text{line-height:20px}.ui-button-small.ui-button-icon-only{width:16px}.ui-button.transparent{min-width:0;background-image:none;background-color:transparent;border-color:transparent;-moz-box-shadow:0 0 transparent;-webkit-box-shadow:0 0 transparent;box-shadow:0 0 transparent}.ui-button.transparent:focus,.ui-button.transparent:hover,.ui-button.transparent:active,.ui-custom-active.transparent{background-color:#d8d8d8;background-image:url(../images/buttons/ui-button.png);-moz-box-shadow:0 1px 0 rgba(0,0,0,0.05);-webkit-box-shadow:0 1px 0 rgba(0,0,0,0.05);box-shadow:0 1px 0 rgba(0,0,0,0.05)}.ui-button-medium.ui-button.transparent:focus,.ui-button-medium.ui-button.transparent:hover,.ui-button-medium.ui-button.transparent:active,.ui-button-medium.ui-custom-active.transparent{background-image:url(../images/buttons/ui-button-medium.png);-moz-box-shadow:0 1px 0 rgba(0,0,0,0.05);-webkit-box-shadow:0 1px 0 rgba(0,0,0,0.05);box-shadow:0 1px 0 rgba(0,0,0,0.05)}.ui-button-small.ui-button.transparent:focus,.ui-button-small.ui-button.transparent:hover,.ui-button-small.ui-button.transparent:active,.ui-button-small.ui-custom-active.transparent{background-image:url(../images/buttons/ui-button-small.png);-moz-box-shadow:0 1px 0 rgba(0,0,0,0.05);-webkit-box-shadow:0 1px 0 rgba(0,0,0,0.05);box-shadow:0 1px 0 rgba(0,0,0,0.05)}.ui-button-small.ui-button.transparent:active,.ui-button-small.ui-custom-active.transparent{background-color:#a7a7a7;outline:0 none}.ui-button.transparent:focus,.ui-button.transparent:hover{border-color:#a8a8a8;border-bottom-color:#9e9e9e;-moz-box-shadow:0 1px 0 rgba(0,0,0,0.05);-webkit-box-shadow:0 1px 0 rgba(0,0,0,0.05);box-shadow:0 1px 0 rgba(0,0,0,0.05)}.ui-button.transparent:active,.ui-state-active.transparent,.ui-state-active.transparent:focus,.ui-state-active.transparent:hover,.ui-custom-active.transparent,.ui-custom-active.transparent:focus,.ui-custom-active.transparent:hover{border-color:#909090;-moz-box-shadow:0 1px 0 rgba(0,0,0,0.05);-webkit-box-shadow:0 1px 0 rgba(0,0,0,0.05);box-shadow:0 1px 0 rgba(0,0,0,0.05)}.ui-button.transparent .ui-button-text{padding:0 10px}.ui-button.ui-plain-button:focus,.ui-button.ui-plain-button:hover{border-color:#e0e0e0;border-top-color:#e7e7e7;border-bottom-color:#ddd;background:#e7e7e7;background:-webkit-gradient(linear,left top,left bottom,from(#e7e7e7),to(#ddd));background:-moz-linear-gradient(#e7e7e7,#ddd);background:-webkit-linear-gradient(#e7e7e7,#ddd);-moz-box-shadow:0 0 transparent;-webkit-box-shadow:0 0 transparent;box-shadow:0 0 transparent}.ui-button.ui-plain-button:active,.ui-custom-active.ui-plain-button:focus,.ui-custom-active.ui-plain-button:hover,.ui-custom-active.ui-plain-button{border-color:#b2b2b2;border-top-color:#b7b7b7;border-bottom-color:#a8a8a8;background:#b7b7b7;background:-webkit-gradient(linear,left top,left bottom,from(#b7b7b7),to(#a8a8a8));background:-moz-linear-gradient(#b7b7b7,#a8a8a8);background:-webkit-linear-gradient(#b7b7b7,#a8a8a8);-moz-box-shadow:0 0 transparent;-webkit-box-shadow:0 0 transparent;box-shadow:0 0 transparent}.ui-button.selected,.ui-button.selected:focus,.ui-button.selected:active,.ui-button.selected:hover,.ui-state-focus.selected,.ui-state-hover.selected{background-image:url(../images/buttons/ui-button.png);background-position:left -80px;border-color:#404e69;background-color:#536587}.ui-icon{display:block;text-indent:-99999px;overflow:hidden;background-repeat:no-repeat;width:16px;height:16px}.ui-button-medium .ui-icon{width:24px;height:24px;margin-left:4px}.ui-button-icon-only .ui-icon,.ui-button-text-icon-primary .ui-icon,.ui-button-text-icon-secondary .ui-icon,.ui-button-text-icons .ui-icon,.ui-button-icons-only .ui-icon,.ui-button .spinner{position:absolute;top:50%;margin-top:-8px}.ui-button-icon-only .ui-icon{left:50%;margin-left:-8px}.ui-button-text-icon-primary .ui-button-icon-primary,.ui-button-icons-only .ui-button-icon-primary{position:static;margin-top:0;float:left}.ui-button-text-icon-secondary .ui-button-icon-secondary,.ui-button-text-icons .ui-button-icon-secondary,.ui-button-icons-only .ui-button-icon-secondary{right:.5em}.ui-button-text-icons .ui-button-icon-secondary,.ui-button-icons-only .ui-button-icon-secondary{right:.5em}.ui-button-icons-only .ui-icon{margin-left:0!important}.ui-icon-menu{background-image:url(../images/buttons/btn_popup_sort.png);background-position:right 7px}.ui-icon-add{background-image:url("../images/icons/ico_add.png");background-position:center center}.ui-icon-addressbook{background-image:url("../images/buttons/addressBook.png");background-position:left center}.ui-icon-addressbook:hover{background-position:-22px center}.ui-icon-grid-view{background-image:url("../images/icons/ico_view_modes.png");margin-top:-7px!important}.selected .ui-icon-grid-view{background-position:0 -25px}.ui-icon-list-view{background-image:url("../images/icons/ico_view_modes.png");background-position:-24px 0;margin-top:-7px!important}.selected .ui-icon-list-view{background-position:-23px -25px}.ui-icon-upload{background-image:url(../images/buttons/upload.png);margin-left:4px;margin-right:-4px;height:17px!important;margin-top:3px!important}.ui-icon-new-folder{background-image:url(../images/buttons/new_folder.png);background-position:left bottom;margin-left:3px;margin-right:-3px;margin-top:3px!important;height:18px!important;width:18px!important}.ui-icon-back{background-image:url('../images/buttons/back_button.png');background-position:8px 0;margin-top:2px!important}.ui-icon-empty-trash{background-image:url(../images/buttons/empty_trash.png);height:18px!important;width:18px;margin-left:5px;margin-top:3px!important}.ui-icon-drop-down{background-image:url(../images/buttons/btn_drop_down.png);background-position:50% 6px}.ui-icon-up-button{background-image:url(../images/icons/ico_up_button.png);background-position:2px 1px}.ui-icon-comment{background-image:url("../images/icons/ico_comment.png");background-position:center center}.ie7 .ui-icon-comment,.ie9 .ui-icon-comment{margin-top:-7px!important}.ie8 .ui-icon-comment{margin-top:-9px!important}.ui-icon-comment+.ui-button-text{height:19px}.ui-icon-actions{background-image:url("../images/buttons/btn_file_actions.png");background-position:-20px 0;width:16px!important;height:17px!important;left:4px}.ui-icon-categories{background-image:url("../images/buttons/btn_file_actions.png");background-position:-40px 0;width:18px!important;height:18px!important;left:3px;margin-top:-8px!important}.ui-icon-comments{background-image:url("../images/buttons/btn_file_actions.png");background-position:-100px -41px;width:18px;margin-left:3px;margin-top:4px!important}.ui-icon-actions-big{background-image:url("../images/buttons/btn_file_actions.png");background-position:-20px 0;width:16px!important;height:17px!important;left:4px!important;top:3px!important;position:relative!important}.ui-icon-categories-big{background-image:url("../images/buttons/btn_file_actions.png");background-position:-40px 0;width:18px!important;height:18px!important;left:3px!important;top:3px!important;position:relative!important}.ui-button.ui-button-text-icon-primary .ui-button-text{padding-left:5px;vertical-align:middle}.ui-button-medium.ui-button.ui-button-text-icon-primary .ui-button-text{padding-left:4px;line-height:28px}.ui-button.ui-button-text-icon-secondary .ui-button-text{padding-right:16px}.ui-button.with_spinner{padding-left:6px}.ui-button .spinner{margin-top:-11px}.ui-icon-wrench{background:url('../images/buttons/wrench.png') no-repeat 0 0;left:4px!important}.ui-menu{display:block;float:left;list-style:none outside none;margin:0;padding:0}.ui-autocomplete{border:1px solid #666;border-top:0 none;background-color:white}.ui-menu .ui-menu-item{clear:left;float:left;margin:0;padding:0;width:100%;overflow:hidden}.ui-autocomplete .ui-menu-item a{display:block;padding:5px;cursor:pointer}.ui-autocomplete .ui-menu-item a:focus,.ui-autocomplete .ui-menu-item a:hover,.ui-autocomplete .ui-menu-item a.ui-state-hover{color:#222;background-position:top left}.ui-autocomplete .ui-menu-item a.ui-state-hover{background:#f2f2f2}#fancybox-loading{position:fixed;top:50%;left:50%;width:40px;height:40px;margin-top:-20px;margin-left:-20px;cursor:pointer;overflow:hidden;z-index:1104;display:none}#fancybox-loading div{position:absolute;top:0;left:0;width:40px;height:480px;background-image:url('../images/layout/fancybox/fancybox.png')}#fancybox-overlay{position:absolute;top:0;left:0;width:100%;z-index:1100;display:none}#fancybox-tmp{padding:0;margin:0;border:0;overflow:auto;display:none}#fancybox-wrap{position:absolute;top:0;left:0;padding:20px;z-index:1101;outline:0;display:none}#fancybox-outer{position:relative;width:100%;height:100%;background:#fff}#fancybox-content{width:0;height:0;padding:0;outline:0;position:relative;overflow:hidden;z-index:1102;border:0 solid #fff}#fancybox-hide-sel-frame{position:absolute;top:0;left:0;width:100%;height:100%;background:transparent;z-index:1101}#fancybox-close{position:absolute;top:-15px;right:-15px;width:30px;height:30px;background:transparent url('../images/layout/fancybox/fancybox.png') -40px 0;cursor:pointer;z-index:1103;display:none}#fancybox-error{color:#444;font:normal 12px/20px Arial;padding:14px;margin:0}#fancybox-img{width:100%;height:100%;padding:0;margin:0;border:0;outline:0;line-height:0;vertical-align:top}#fancybox-frame{width:100%;height:100%;border:0;display:block}#fancybox-left,#fancybox-right{position:absolute;bottom:0;height:100%;width:35%;cursor:pointer;outline:0;background:transparent url('../images/layout/fancybox/blank.gif');z-index:1102;display:none}#fancybox-left{left:0}#fancybox-right{right:0}#fancybox-left-ico,#fancybox-right-ico{position:absolute;top:50%;left:-9999px;width:30px;height:30px;margin-top:-15px;cursor:pointer;z-index:1102;display:block}#fancybox-left-ico{background-image:url('../images/layout/fancybox/fancybox.png');background-position:-40px -30px}#fancybox-right-ico{background-image:url('../images/layout/fancybox/fancybox.png');background-position:-40px -60px}#fancybox-left:hover,#fancybox-right:hover{visibility:visible}#fancybox-left:hover span{left:20px}#fancybox-right:hover span{left:auto;right:20px}.fancybox-bg{position:absolute;padding:0;margin:0;border:0;width:20px;height:20px;z-index:1001}#fancybox-bg-n{top:-20px;left:0;width:100%;background-image:url('../images/layout/fancybox/fancybox-x.png')}#fancybox-bg-ne{top:-20px;right:-20px;background-image:url('../images/layout/fancybox/fancybox.png');background-position:-40px -162px}#fancybox-bg-e{top:0;right:-20px;height:100%;background-image:url('../images/layout/fancybox/fancybox-y.png');background-position:-20px 0}#fancybox-bg-se{bottom:-20px;right:-20px;background-image:url('../images/layout/fancybox/fancybox.png');background-position:-40px -182px}#fancybox-bg-s{bottom:-20px;left:0;width:100%;background-image:url('../images/layout/fancybox/fancybox-x.png');background-position:0 -20px}#fancybox-bg-sw{bottom:-20px;left:-20px;background-image:url('../images/layout/fancybox/fancybox.png');background-position:-40px -142px}#fancybox-bg-w{top:0;left:-20px;height:100%;background-image:url('../images/layout/fancybox/fancybox-y.png')}#fancybox-bg-nw{top:-20px;left:-20px;background-image:url('../images/layout/fancybox/fancybox.png');background-position:-40px -122px}#fancybox-title{font-family:Helvetica;font-size:12px;z-index:1102}.fancybox-title-inside{padding-bottom:10px;text-align:center;color:#333;background:#fff;position:relative}.fancybox-title-outside{padding-top:10px;color:#fff}.fancybox-title-over{position:absolute;bottom:0;left:0;color:#FFF;text-align:left}#fancybox-title-over{padding:10px;background-image:url('../images/layout/fancybox/fancy_title_over.png');display:block}.fancybox-title-float{position:absolute;left:0;bottom:-20px;height:32px}#fancybox-title-float-wrap{border:0;border-collapse:collapse;width:auto}#fancybox-title-float-wrap td{border:0;white-space:nowrap}#fancybox-title-float-left{padding:0 0 0 15px;background:url('../images/layout/fancybox/fancybox.png') -40px -90px no-repeat}#fancybox-title-float-main{color:#FFF;line-height:29px;font-weight:bold;padding:0 0 3px 0;background:url('../images/layout/fancybox/fancybox-x.png') 0 -40px}#fancybox-title-float-right{padding:0 0 0 15px;background:url('../images/layout/fancybox/fancybox.png') -55px -90px no-repeat}.fancybox-ie6 #fancybox-close{background:transparent;filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='../images/layout/fancybox/fancy_close.png',sizingMethod='scale')}.fancybox-ie6 #fancybox-left-ico{background:transparent;filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='../images/layout/fancybox/fancy_nav_left.png',sizingMethod='scale')}.fancybox-ie6 #fancybox-right-ico{background:transparent;filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='../images/layout/fancybox/fancy_nav_right.png',sizingMethod='scale')}.fancybox-ie6 #fancybox-title-over{background:transparent;filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='../images/layout/fancybox/fancy_title_over.png',sizingMethod='scale');zoom:1}.fancybox-ie6 #fancybox-title-float-left{background:transparent;filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='../images/layout/fancybox/fancy_title_left.png',sizingMethod='scale')}.fancybox-ie6 #fancybox-title-float-main{background:transparent;filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='../images/layout/fancybox/fancy_title_main.png',sizingMethod='scale')}.fancybox-ie6 #fancybox-title-float-right{background:transparent;filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='../images/layout/fancybox/fancy_title_right.png',sizingMethod='scale')}.fancybox-ie6 #fancybox-bg-w,.fancybox-ie6 #fancybox-bg-e,.fancybox-ie6 #fancybox-left,.fancybox-ie6 #fancybox-right,#fancybox-hide-sel-frame{height:expression(this.parentNode.clientHeight+"px")}#fancybox-loading.fancybox-ie6{position:absolute;margin-top:0;top:expression((-20+(document.documentElement.clientHeight ? document.documentElement.clientHeight/2:document.body.clientHeight/2)+(ignoreMe = document.documentElement.scrollTop ? document.documentElement.scrollTop:document.body.scrollTop))+'px')}#fancybox-loading.fancybox-ie6 div{background:transparent;filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='../images/layout/fancybox/fancy_loading.png',sizingMethod='scale')}.fancybox-ie .fancybox-bg{background:transparent!important}.fancybox-ie #fancybox-bg-n{filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='../images/layout/fancybox/fancy_shadow_n.png',sizingMethod='scale')}.fancybox-ie #fancybox-bg-ne{filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='../images/layout/fancybox/fancy_shadow_ne.png',sizingMethod='scale')}.fancybox-ie #fancybox-bg-e{filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='../images/layout/fancybox/fancy_shadow_e.png',sizingMethod='scale')}.fancybox-ie #fancybox-bg-se{filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='../images/layout/fancybox/fancy_shadow_se.png',sizingMethod='scale')}.fancybox-ie #fancybox-bg-s{filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='../images/layout/fancybox/fancy_shadow_s.png',sizingMethod='scale')}.fancybox-ie #fancybox-bg-sw{filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='../images/layout/fancybox/fancy_shadow_sw.png',sizingMethod='scale')}.fancybox-ie #fancybox-bg-w{filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='../images/layout/fancybox/fancy_shadow_w.png',sizingMethod='scale')}.fancybox-ie #fancybox-bg-nw{filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='../images/layout/fancybox/fancy_shadow_nw.png',sizingMethod='scale')}.jcarousel-skin-tango .jcarousel-container{background:#FFF;border:1px solid #cecece;-moz-border-radius:0 0 4px 4px;-webkit-border-radius:0 0 4px 4px;border-radius:0 0 4px 4px}.jcarousel-skin-tango .jcarousel-item.jcarousel-item-horizontal.jcarousel-item-selected{border:solid 2px #09c}.jcarousel-skin-tango .jcarousel-container-horizontal{padding:15px 23px 15px 22px}.jcarousel-skin-tango .jcarousel-clip{overflow:hidden}.jcarousel-skin-tango .jcarousel-clip-horizontal{height:90px;width:843px}.jcarousel-skin-tango .jcarousel-item{width:93px;height:70px}.jcarousel-skin-tango .jcarousel-item-horizontal{margin:0 10px;padding:3px;border:solid 1px #ccc;background:#fafafa}.jcarousel-skin-tango .jcarousel-item-horizontal:hover,.jcarousel-skin-tango .jcarousel-item-horizontal:focus{padding:2px;border:solid 2px #bfbfbf}.jcarousel-skin-tango .jcarousel-direction-rtl .jcarousel-item-horizontal{margin-left:10px;margin-right:0}.jcarousel-skin-tango .jcarousel-item-vertical{margin-bottom:10px}.jcarousel-skin-tango .jcarousel-item-placeholder{background:#fff;color:#000}.jcarousel-skin-tango .jcarousel-next-horizontal{position:absolute;top:32px;right:5px;width:12px;height:16px;cursor:pointer;background:transparent url(../images/icons/carousel/icon_slideshow_triangle.png) no-repeat 0 -60px}.jcarousel-skin-tango .jcarousel-next-horizontal:hover,.jcarousel-skin-tango .jcarousel-next-horizontal:focus,.jcarousel-skin-tango .jcarousel-next-horizontal:active{background-position:0 -100px}.jcarousel-skin-tango .jcarousel-next-disabled-horizontal,.jcarousel-skin-tango .jcarousel-next-disabled-horizontal:hover,.jcarousel-skin-tango .jcarousel-next-disabled-horizontal:focus,.jcarousel-skin-tango .jcarousel-next-disabled-horizontal:active{cursor:default;background:0}.jcarousel-skin-tango .jcarousel-prev-horizontal{position:absolute;top:32px;left:5px;width:12px;height:16px;cursor:pointer;background:transparent url(../images/icons/carousel/icon_slideshow_triangle.png) no-repeat 0 0}.jcarousel-skin-tango .jcarousel-prev-horizontal:hover,.jcarousel-skin-tango .jcarousel-prev-horizontal:focus,.jcarousel-skin-tango .jcarousel-prev-horizontal:active{background-position:0 -40px}.jcarousel-skin-tango .jcarousel-prev-disabled-horizontal,.jcarousel-skin-tango .jcarousel-prev-disabled-horizontal:hover,.jcarousel-skin-tango .jcarousel-prev-disabled-horizontal:focus,.jcarousel-skin-tango .jcarousel-prev-disabled-horizontal:active{cursor:default;background:0}.about_contents div,.about_contents span,.about_contents object,.about_contents p,.about_contents strong,.about_contents ul,.about_contents li,.about_contents label,.about_contents header,.about_contents section{background:none repeat scroll 0 0 transparent;border:0 none;font-size:100%;margin:0;outline:0 none;padding:0;vertical-align:baseline}.about_contents{width:500px}.about_contents header{background-color:#000;height:28px;border-radius:6px 6px 0 0;border-bottom:1px solid #333;color:#fff;font-size:13px;font-weight:bold;padding:10px 0 0 10px}.about_contents .about_banner{background:url("../images/layout/Exchangebanner.png") no-repeat scroll 0 0 transparent;height:74px}.about_contents .about_banner p{font-size:16px;color:#fff;text-shadow:0 2px 2px rgba(0,0,0,0.65);width:344px;padding-top:18px;padding-left:30px}.about_contents .about_content{height:212px;overflow-y:scroll;overflow-x:hidden;background-color:#eee;font-size:9px;color:#2a2a2a}.about_contents .margin_top{height:20px;left:0;position:absolute;right:0;top:113px;width:483px;background-color:#eee}.about_contents .margin_bottom{bottom:0;height:15px;left:0;position:absolute;right:0;width:483px;border-bottom:20px solid #eee;background:-webkit-gradient(linear,left top,left bottom,from(rgba(238,238,238,0)),to(rgba(238,238,238,1)));background:-webkit-linear-gradient(rgba(238,238,238,0),rgba(238,238,238,1));background:-moz-linear-gradient(rgba(238,238,238,0),rgba(238,238,238,1));background:-ms-linear-gradient(rgba(238,238,238,0),rgba(238,238,238,1))}.no-cssgradients .about_contents .margin_bottom{background:url("../images/layout/about_box_gradient_fade.png") repeat-x 0 0 transparent}.about_contents div.about_terms{margin-left:15px;margin-right:20px;padding-top:20px}.about_contents .about_terms p{margin-bottom:15px}.about_contents .about_terms p a{color:#06e}.about_contents .about_wrapper{padding-bottom:30px}.no_border{border:0!important;border-radius:6px 6px 0 0!important}.dropdown,.dropdown div,.dropdown li,.dropdown div::after{-webkit-transition:all 150ms ease-in-out;-moz-transition:all 150ms ease-in-out;-ms-transition:all 150ms ease-in-out;transition:all 150ms ease-in-out}.dropdown .selected::after,.dropdown.scrollable div::after{-webkit-pointer-events:none;-moz-pointer-events:none;-ms-pointer-events:none;pointer-events:none}.dropdown{position:relative;width:200px;border:1px solid #ccc;cursor:pointer;background:#fff;border-radius:3px;-webkit-user-select:none;-moz-user-select:none;user-select:none}.dropdown.open{z-index:2}.dropdown:hover{box-shadow:0 0 5px rgba(82,168,236,0.8);border:solid 1px #52a8ec}.dropdown.focus{box-shadow:0 0 5px rgba(51,102,248,.4)}.dropdown .carat{position:absolute;right:12px;top:50%;margin-top:-4px;border:6px solid transparent;border-top:8px solid #000}.dropdown.open .carat{margin-top:-10px;border-top:6px solid transparent;border-bottom:8px solid #000}.dropdown.disabled .carat{border-top-color:#999}.dropdown .old{position:absolute;left:0;top:0;height:0;width:0;overflow:hidden}.dropdown select{position:absolute;left:0;top:0}.dropdown.touch .old{width:100%;height:100%}.dropdown.touch select{width:100%;height:100%;opacity:0}.dropdown .selected,.dropdown li{display:block;font-size:12px;line-height:1;color:#000;padding:9px 12px;overflow:hidden;white-space:nowrap}.dropdown.disabled .selected{color:#999}.dropdown .selected::after{content:'';position:absolute;right:0;top:0;bottom:0;width:60px;border-radius:0 2px 2px 0;box-shadow:inset -55px 0 25px -20px #fff}.dropdown div{position:absolute;height:0;left:-1px;right:-1px;top:100%;margin-top:-1px;background:#fff;border:1px solid #ccc;border-top:1px solid #eee;border-radius:0 0 3px 3px;overflow:hidden;opacity:0}.dropdown.open div{opacity:1;z-index:2}.dropdown.scrollable div::after{content:'';position:absolute;left:0;right:0;bottom:0;height:50px;box-shadow:inset 0 -50px 30px -35px #fff}.dropdown.scrollable.bottom div::after{opacity:0}.dropdown ul{position:absolute;left:0;top:0;height:100%;width:100%;list-style:none;overflow:hidden}.dropdown.scrollable.open ul{overflow-y:auto}.dropdown li{list-style:none;padding:8px 12px}.dropdown li.focus{background:#d24a67;position:relative;z-index:3;color:#fff}.dropdown li.active{font-weight:700}.bootstrap-tagsinput{display:inline-block;padding-right:6px;color:#555;vertical-align:middle;border-radius:4px;max-width:200px;line-height:22px;position:relative;top:-1px}.bootstrap-tagsinput input{display:none;border:0;box-shadow:none;background-color:transparent;padding:0;margin:0;width:auto!important;max-width:inherit}.bootstrap-tagsinput input:focus{border:0;box-shadow:none}.bootstrap-tagsinput .tag{margin-right:2px;color:#666;padding:5px 5px 5px 5px;font-size:12px;background:white;text-shadow:none;font-weight:lighter}.bootstrap-tagsinput .tag [data-role="remove"]{margin-left:2px;cursor:pointer;font-size:15px;color:#aaa;position:relative;top:0}.bootstrap-tagsinput .tag [data-role="remove"]:after{content:"| x";padding:0 2px}.bootstrap-tagsinput .tag [data-role="remove"]:hover{box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05)}.bootstrap-tagsinput .tag [data-role="remove"]:hover:active{box-shadow:inset 0 3px 5px rgba(0,0,0,0.125)}.search-page span{font-family:Arial;color:#666}.search-page a{font-size:12px;color:#29abe2}.overview-title{min-width:1220px}.search-page .overview-title{border-bottom:1px solid #CCC;font-size:16px;height:36px;left:0;padding:10px 0 6px 0;-moz-box-align:initial;-moz-box-pack:initial;-ms-flex-align:start;-webkit-box-pack:initial;-webkit-box-align:baseline;-ms-flex-pack:inherit}.overview-title>div>a{font-size:16px;font-weight:bold;color:#666}.overview-title div:first-child{padding-top:7px;margin-left:30px}.overview-title .emphasized{font-weight:bold;color:#333}.overview-title .view-selection input{display:none}.overview-title .view-selection input+label{padding:0}.overview-title .view-selection input:checked+label{background:#DDD;border-radius:5px}.search-page .list-display-options{height:50px;left:0;-moz-box-align:initial;-ms-flex-align:start;position:relative}.widget-element-app-search-list-view.widget-hoverable{width:auto;height:auto}.widget-element-app-search-list-view{padding:15px 10px;border:1px solid #e3e3e3;width:initial}.widget-element-app-search-list-view:nth-child(2n){margin-left:-5px}.widget-element-app-search-list-view:nth-child(n+2){margin-top:-5px}.list-display-options .list-display-option-left{left:0;margin-top:18px;position:absolute}.list-display-option-left span{color:#29abe2}.list-header-fancy .list-display-options .list-display-option-left{margin-top:0}.list-display-options .list-display-option-right{position:absolute;right:0;margin-top:10px;display:block;align-items:baseline;width:auto;min-width:400px;text-align:right}.list-display-option-right span{color:#29abe2}.list-display-option-right .dropdown{width:50px;height:24px;float:right;margin-left:4px;text-align:left;border:1px solid #b3b3b3;border-radius:3px}.list-display-option-right .dropdown .selected{padding:6px}.list-display-option-right .dropdown .selected::after{box-shadow:none}.list-display-options input{width:16px;margin-bottom:0;height:16px;border:1px solid #b3b3b3}.list-display-options select{width:70px}.list-display-options span{font-size:12px}.filter-catalog-container{width:200px;margin-right:5px}a.filter-catalog-show-more{color:#808080}.filter-catalog-seperator{height:1px;background:#AAA}.filter-catalog span{width:120px;flex-shrink:0;-webkit-flex-shrink:0;-ms-flex:0 0 auto;font-size:12px;padding-right:5px}.filter-title label{height:24px;width:16px;padding:0;border:0}.filter-catalog label[class="radio"]{margin-right:25px}.filter-catalog .radio{position:relative;bottom:1px;font-size:12px;display:inline-block}.filter-catalog input{position:absolute;left:0;top:-1px}.filter-catalog .filter-catalog-item label{font-size:12px}.filter-catalog .filter-title{margin-top:20px;margin-bottom:5px}.filter-catalog .filter-title span{font-size:14px;color:#29abe2}.filter-catalog .filter-catalog-item{line-height:20px;position:relative;padding-left:20px;margin-bottom:5px;color:#808080;font-size:12px}.filter-catalog-container .filter-tag-input{margin-top:10px}.filter-catalog-container .bootstrap-tagsinput .tag{margin-top:5px;margin-right:5px;background:#29abe2;color:white;white-space:normal}.bootstrap-tagsinput .tag [data-role="remove"]{color:white}.bootstrap-tagsinput .tag [data-role="remove"]:after{content:"x"}#clear-all-tags{margin-top:6px;display:inline-block}.view-selection{float:right;margin-right:3px}.view-selection input{width:0;height:0;visibility:collapse}.view-selection .btn{padding:0;height:24px;width:24px;border:0}.search-page span.message-with-link{color:#29abe2}.show_all{cursor:pointer;color:#369} html,body{background-color:#f8f8f8}.bold{font-weight:bold}.float-left{float:left}.float-right{float:right}.busy{cursor:progress}.hidden{display:none}body a{cursor:pointer}body a:focus{outline:0}.min-size{min-width:975px}.clear{clear:both;display:block;overflow:hidden;visibility:hidden;width:0;height:0}.highlight-text{color:#29abe2!important}.display-table{display:table!important}.display-table .row{display:table-row!important}.display-table .cell{display:table-cell!important}.text-center-align-container{text-align:center}.text-right-align-container{text-align:right}.vertical-top-align-container>*{vertical-align:top}.vertical-middle-align-container>*{vertical-align:middle}.vertical-bottom-align-container>*{vertical-align:bottom}.inline-container>*{display:inline-block}.inline{display:inline}.inline-block{display:inline-block}.block{display:block!important}.message-with-link,.message-with-link a{font-size:12px;color:#29abe2}.message-with-link a{font-weight:normal;text-decoration:underline!important}.thin-border{border:solid 1px #CCC}.color-blue1{color:#29abe2}a.flat-button:visited,.flat-button{color:white;width:auto;text-align:center;font-size:14px;border-radius:6px;border:0;padding:4px 20px;margin:1px;-webkit-transition:opacity .8s;-moz-transition:opacity .8s;-o-transition:opacity .8s;transition:opacity .8s;display:inline-block}.flat-button-slim{font-size:12px;line-height:14px}.flat-button[disabled]{opacity:.5}.flat-button[disabled]:hover{cursor:not-allowed;opacity:.5}.flat-button:hover{color:white;cursor:pointer;opacity:.8;-webkit-transition:opacity .2s;-moz-transition:opacity .2s;-o-transition:opacity .2s;transition:opacity .2s}.flat-button:active{opacity:1}.flat-button.flat-button-normal{background:#29abe2}.flat-button.app-os-lang-btn{background:#dcdcdc}.flat-button.flat-button-emphasis{background:#0071bc}.flat-button.flat-button-radio{min-width:100px}.flat-button.flat-button-radio input[type=radio]{display:none;border-radius:0}.flat-button.flat-button-radio input:checked+span{background:#29abe2;color:white;border-color:transparent}.flat-button.flat-button-radio input+span{background:#f2f2f2;display:inline-block;color:black;min-width:100px;padding:7px 15px;border:1px #ccc solid;width:100%}.flat-button.flat-button-group{width:100%;background:#e6e6e6;color:black;border-radius:0;border:1px #b8b8b8 solid;margin:5px 5px;padding:5px 3px}.flat-button.flat-button-group-active{background:#29abe2;color:white;border-radius:0;border-style:none}.flat-button.flat-button-positive{background:#77bb68}.flat-button.flat-button-negative{color:#29abe2;background:white;border:1px #29abe2 solid}.flat-button.flat-button-warning{background:#fcb237}.table{color:#595959;font-size:12px}.table .color-bar-left{border-left:5px solid #e6e6e6}.color-bar-right{display:inline-block;width:5px!important;padding:0!important;height:20px;right:30px;position:relative}.table th,.table td{padding:5px 10px;border:0;vertical-align:middle;text-align:center}.table.left-align th,.table.left-align td{text-align:left}.table td:first-child~td{border-left:solid 1px #e6e6e6}.table th{background:#e6e6e6}.table th .order-arrow{float:right;color:#4d4d4d;display:block}.table th .order-arrow.up:after{content:"▴"}.table th .order-arrow.down:after{content:"▾"}.table tr{border-bottom:solid 1px #29abe2;background:white}.table .show-all:hover~div{visibility:visible}.table .show-all-container{border:solid 1px #29abe2;background:white;position:absolute;padding:5px 10px;visibility:hidden}.table .show-all-container ul{padding:0;margin:0}.table .show-all-container ul li{padding:3px}.table .show-all-container i{display:block;background:url(../images/icons/dialog-arrow.png) no-repeat;width:15px;height:6px;position:absolute;top:-6px;left:23px}a{text-decoration:none!important}h1,h2,h3,h4,h5,h6{font-weight:bold;font-size:100%;margin:0;padding:0;line-height:normal}ul,ol,li,dl,dd,dt{list-style:none}li{line-height:normal}.nomarginpadding{margin:0;padding:0}.detail-main .description ul,.developer-submit-product ul,.helpdoc-page ul,.detail-main .description ol,.developer-submit-product ol,.helpdoc-page ol{padding-left:17px}.detail-main .description ul li,.developer-submit-product ul li,.helpdoc-page ul li{list-style:disc}.detail-main .description ol li,.developer-submit-product ol li,.helpdoc-page ol li{list-style:decimal}.details-main .seller{float:left}body,button,input,select,textarea{font-family:Arial,Verdana,Sans-Serif}.overlay_text{color:#999;line-height:18px;font-weight:normal!important;position:absolute;cursor:text!important;text-shadow:none!important}.spinner{width:16px;height:16px;background:url(../images/icons/spinner_16.png) no-repeat left top}.spinned{display:none!important}.spinner_container{padding-left:20px;line-height:24px;position:relative;cursor:wait;white-space:nowrap;display:inline-block}.spinner_container .spinner{position:absolute;top:4px;left:0}.popup_menu.flat_menu .spinner_container{padding-left:25px;padding-right:3px}.popup_menu.flat_menu .spinner_container .spinner{left:5px}.local_spinner{padding-left:31px}.local_spinner .spinner{left:9px}.line-separator{height:1px;width:100%;background:#CCC;margin:6px 0 6px 0}.sub-title{font-size:12px;color:black;display:inline-block}#flash_message{z-index:11203;position:fixed;left:50%;padding:11px 30px 9px 50px;color:#fff;font-size:14px;cursor:default;text-shadow:0 1px 0 #000;text-shadow:0 1px 0 rgba(0,0,0,0.85);border:1px solid #75a3ff;border-color:rgba(117,163,255,0.7);background-color:#1e3559;background:-webkit-gradient(linear,left top,left bottom,from(#1e3559),to(#172944));background:-webkit-linear-gradient(#1e3559,#172944);background:-moz-linear-gradient(#1e3559,#172944);-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px}#flash_message img,#flash_message .spinner{position:absolute;left:26px;top:13px}#flash_message #off_button_div{width:24px;height:24px;position:absolute;right:5px;top:8px;background-image:url(../images/buttons/close_24.png);cursor:pointer}#flash_message.success{background:#1e3559 url(../images/icons/flash_success.png) no-repeat 26px 13px;background:url(../images/icons/flash_success.png) no-repeat 26px 13px,-webkit-gradient(linear,left top,left bottom,from(#1e3559),to(#172944));background:url(../images/icons/flash_success.png) no-repeat 26px 13px,-webkit-linear-gradient(#1e3559,#172944);background:url(../images/icons/flash_success.png) no-repeat 26px 13px,-moz-linear-gradient(#1e3559,#172944)}#flash_message.error{background:#1e3559 url(../images/icons/error_16.png) no-repeat 26px 13px;background:url(../images/icons/error_16.png) no-repeat 26px 13px,-webkit-gradient(linear,left top,left bottom,from(#1e3559),to(#172944));background:url(../images/icons/error_16.png) no-repeat 26px 13px,-webkit-linear-gradient(#1e3559,#172944);background:url(../images/icons/error_16.png) no-repeat 26px 13px,-moz-linear-gradient(#1e3559,#172944)}.header-icon{width:18px!important;height:23px!important;margin:0 10px 0 5px!important;position:relative;top:-4px}.icon-my-downloads{background:url('../images/icons/mydownloads_idle.png') no-repeat!important}li.disabled .icon-my-downloads{background:url('../images/icons/mydownloads_disabled.png')!important}li:hover .icon-my-downloads{background:url('../images/icons/mydownloads_hover.png') no-repeat!important}.icon-my-uploads{background:url('../images/icons/myuploads_idle.png') no-repeat!important}li.disabled .icon-my-uploads{background:url('../images/icons/myuploads_disabled.png') no-repeat!important}li:hover .icon-my-uploads{background:url('../images/icons/myuploads_hover.png') no-repeat!important}.main-middle-content{width:1280px;margin-left:auto;margin-right:auto;margin-top:15px;display:flex;padding-bottom:15px}.left-mainmiddlecontent{width:190px;margin-right:15px;float:left}.navigation-content .navigation-header,.filter-catalog-container .filter-catalog-title{border:1px solid #d3d3d3;min-height:30px;text-align:center;line-height:30px;background:#e6e6e6;font-size:18px;color:#4d4d4d}.navigation-content .navigation-a{position:relative;margin:0;padding:0}.dropdown-menu-store,.navigation-content .navigation-a .popover{min-width:190px}.navigation-content li{text-align:left;min-height:25px;line-height:24px;color:#808080}.first-a{margin-left:35px}.sub-a{margin-left:5px}.second-a{margin-left:5px}.navigation-content .navigation-a-li{border-bottom:1px solid #838383;position:relative}.navigation-content li:hover{background:#29abe2;color:White}.navigation-content li a{font-size:12px;color:inherit}.navigation-content .btn-group .dropdown-toggle{width:189px}.apps-wrapper{margin:0 auto}.right-mainmiddlecontent{min-height:500px;width:1050px;padding-left:14px;float:left;border-left:1px solid #b3b3b3}.apps-content .apps-section .show-all{float:right;font-size:13px;text-decoration:none}.apps-section h2{margin-bottom:10px;margin-top:10px;color:#777;line-height:40px;font-size:24px;font-family:Arial}.apps-content .apps-carousel{width:1051px;padding:10px 0}.apps-content .apps-carousel h2{margin-bottom:12px}.apps-content .apps-carousel-box{float:left}.short-carousel-wrapper .apps-carousel-box{width:525px}.long-carousel-wrapper .apps-carousel-box{width:100%}.apps-carousel .apps-carousel-box .carousel .carousel-item-ul{margin:0;padding:0}.short-carousel-wrapper .apps-carousel-box-not-first h2{margin-left:10px}.widget-title{height:40px;overflow:hidden;text-overflow:ellipsis}ul.apps-list .s-price-cont{float:left!important;height:18px}ul.apps-list .s-price-cont>span.price,ul.apps-list .s-price-cont .sr-subscriberonly{color:#29abe2!important;font-size:12px!important}ul.apps-list .badge-hover-stub div{text-align:left}ul.apps-list li{background-color:rgba(255,255,255,0.7);cursor:pointer}ul.apps-list li:hover,#result-list .widget-element-app-layout:hover{-moz-box-shadow:0 0 5px rgba(170,170,170,0.4);-webkit-box-shadow:0 0 5px rgba(170,170,170,0.4);-ms-box-shadow:0 0 5px rgba(170,170,170,0.4);box-shadow:0 0 5px rgba(170,170,170,0.4);background-color:rgba(255,255,255,1)}ul.apps-list li img,ul.apps-list li .product-data-container{float:left}ul.apps-list li .product-data-container{padding-left:10px;width:90px}ul.apps li.small-widget-element .product-data-container{max-width:85px}ul.apps li.middle-widget-element .product-data-container{max-width:128px}ul.apps li.large-widget-element .product-data-container{max-width:110px}ul.apps-list li .product-data-container .seller{color:grey}ul.apps-list li.large-widget-element .product-data-container .seller{font-size:11px;height:17px}ul.apps-list li.middle-widget-element .product-data-container .seller,ul.apps-list li.small-widget-element .product-data-container .seller{font-size:12px;height:14px;line-height:13px}ul.apps-list li.small-widget-element .product-data-container .product-rating-small{margin:0}ul.apps-list li .product-data-image{float:left}ul.apps-list li.large-widget-element{width:260px;height:90px}ul.apps-list li.middle-widget-element{width:208px}ul.apps-list li.small-widget-element{width:165px;height:72px}.apps-section-middle ul.apps-list li.small-widget-element{margin:12px 12px 0}.apps-content .apps-section-last{margin-bottom:0;padding-bottom:27px}ul.apps-list li.large-widget-element .product-data-image{margin-left:5px}ul.apps-list li.middle-widget-element .product-data-image,ul.apps-list li.small-widget-element .product-data-image{margin-left:3px}ul.apps-list li h3{color:#444;font-weight:bold;font-family:Arial}ul.apps-list li .product-comment{margin:0;font-size:12px;width:13px!important}ul.apps-list li.large-widget-element h3{line-height:14px;font-size:12px;color:#4d4d4d;height:30px}ul.apps-list li.middle-widget-element h3,ul.apps-list li.small-widget-element h3{line-height:15px;font-size:12px}ul.apps-list li.large-widget-element .ellipsis{width:160px!important}ul.apps-list li.middle-widget-element .ellipsis{width:125px!important}ul.apps-list li.small-widget-element .ellipsis{width:85px!important}ul.apps-list li.large-widget-element h3.ellipsis{white-space:normal!important}ul.apps-list .product-data-image img{-o-border-radius:5px;-ms-border-radius:5px;-moz-border-radius:5px;-webkit-border-radius:5px;border-radius:5px;border:1px solid #e3e3e3}ul.apps-list li.large-widget-element img{width:80px;height:80px}ul.apps-list li.middle-widget-element img,ul.apps-list li.small-widget-element img{width:60px;height:60px}.long-carousel-wrapper #carousel-slider-widget-layout-0{padding-right:0}.short-carousel-wrapper #carousel-slider-widget-layout-1{padding-left:5px;border-left:1px solid #ccc}.long-carousel-wrapper #carousel-slider-widget-layout-1{padding-left:0}.short-carousel-wrapper .carousel-slider-widget-sub-layout{width:525px}.long-carousel-wrapper .carousel-slider-widget-sub-layout{width:1030px}.carousel-slider-widget{margin:0 13px 0 12px}.carousel-slider-widget .carousel-inner{overflow:visible}.carousel-slider-widget .carousel-inner .item{height:auto;overflow:visible}.carousel-slider-widget .carousel-control{top:55%!important;width:12px!important;height:20px!important;background-position:center!important;background-repeat:no-repeat!important}.carousel-slider-widget .left.carousel-control{left:-15px;background:url('../images/buttons/Arrow_Left.png')}.carousel-slider-widget .right.carousel-control{right:-15px;background:url('../images/buttons/Arrow_Right.png')}.carousel-slider-widget .carousel-item-ul{float:left}.apps-list-big .widget-element-app-content{height:80px}#header #base{max-width:1205px;min-width:1110px;padding:4px 0;margin:0 auto}#header .branding{color:#CCC;text-decoration:none;float:left;position:relative;top:7px;line-height:16px;border:0}#header .branding h1{margin:0;padding:0;line-height:27px;font-size:22px}#header .language-changer{float:left;margin:10px 0 0 20px}#header .btn-group .dropdown-toggle:focus{outline:0}#header .dropdown-toggle{background-color:transparent;border:1px solid #ccc;box-shadow:none;-webkit-box-shadow:none;-moz-box-shadhow:none}#header .language-changer .dropdown-menu>li:hover{background-color:#0081c2}#header .language-changer .dropdown-menu{border-radius:6px;-webkit-border-radius:6px;-moz-border-radius:6px}#logged_user_name{cursor:default;padding-right:10px;color:#29abe2;background:url("../images/icons/menu_arrow_blue.png") no-repeat right center}nav.user-panel .signin_link{cursor:pointer;color:#29abe2}nav.user-panel .drop_down ul,#neck .drop_down ul{background-color:#000;background-color:rgba(0,0,0,0.75);border:1px solid #222;border-color:rgba(204,204,204,0.33);padding:5px 5px 3px;margin:0;white-space:nowrap;min-width:0;position:absolute;right:0;top:90%;z-index:9999;line-height:1.75;list-style-type:none;visibility:hidden}.product-info .drop_down ul{background-color:#f2f2f2;border-color:#555;border-style:solid;border-width:1px;padding:0 0 3px 0;margin-top:0;white-space:nowrap;min-width:0;position:absolute;z-index:9999;line-height:1.75;list-style-type:none;visibility:hidden}.product-info .drop_down .details_link{cursor:default;padding-right:10px;background:url(../images/buttons/btn_popup_sort.png) no-repeat right 7px}#neck .drop_down ul{left:0;top:25px;width:150px;background-color:#d7d7d7;border:1px solid #222;border-color:rgba(204,204,204,0.33);padding:5px;margin:0;white-space:nowrap;min-width:0;-moz-border-radius:2px;-webkit-border-radius:2px;border-radius:2px;position:absolute;z-index:9999;line-height:1;list-style-type:none;visibility:hidden}nav.user-panel .drop_down ul li,#neck .drop_down ul li{padding-top:5px;padding-bottom:0;margin-top:5px;border-top:1px solid #383838;height:auto!important;line-height:normal!important}nav.user-panel .drop_down ul li:first-child,#neck .drop_down ul li:first-child{border:0 none;padding:0;margin:0}.product-info .drop_down ul li{padding-left:3px;padding-right:3px;padding-top:3px}.drop_down a{padding:0 5px;text-decoration:none;cursor:pointer}.product-info a.details_link,.product-info .drop_down{float:left}.product-info .drop_down a{padding-right:5px}nav.user-panel .drop_down a{display:block;line-height:22px!important;height:22px!important;font-size:12px;color:#fff!important;filter:alpha(opacity=100)!important;-moz-opacity:1!important;-khtml-opacity:1!important;opacity:1!important;padding:0;border:none!important}.product-info .drop_down a,#neck .drop_down a{display:block;line-height:22px;font-size:12px;-moz-border-radius:2px;-webkit-border-radius:2px;border-radius:2px;color:#000!important}.product-info .drop_down a:hover{color:#fff!important}nav.user-panel .drop_down a:hover,.product-info .drop_down a:hover,#neck .drop_down a:hover{background:#29abe2}nav.user-panel li.drop_down:hover,#neck span.drop_down:hover{position:relative;z-index:599;cursor:default}.product-info .drop_down :hover{z-index:599;cursor:default}nav.user-panel li.drop_down:hover>ul,.product-info .drop_down:hover>ul,#neck span.drop_down:hover>ul{visibility:visible}.bannertext{left:250px;position:absolute;right:150px;text-align:center;top:11px;color:#dc0719;font-style:italic;overflow:hidden;white-space:nowrap}.error_page{margin:20px auto}#neck .neck-content{height:50px;width:100%;margin:auto;padding-top:15px}#neck .breadcrumb{float:left;padding:0;margin-right:10px;margin-left:20px;margin-bottom:0}#neck .breadcrumb>a,#neck .breadcrumb>span:not(.breadcrumb-divider){display:inline-block;vertical-align:-2px;font-size:20px}#neck .breadcrumb .breadcrumb-divider{color:#111}#neck .breadcrumb a:link,#neck .breadcrumb a:visited{color:#343434}#neck .breadcrumb a:hover,#neck .breadcrumb a:active{color:#06e}#neck .breadcrumb .home{display:inline-block;width:22px;height:22px;background:url(../images/icons/icon_home.svg) no-repeat;vertical-align:-4px}#neck .breadcrumb span.drop_down{padding:0 12px 0 10px}#neck .breadcrumb span span.arrow{background:url(../images/buttons/btn_popup_sort.png) no-repeat right 6px;padding:0 10px 0 0}#my-drafts .details_link,#my-drafts .details_link:hover,#my-drafts .details_link:active,#my-drafts .details_link:visited,#my-publishedlist .details_link,#my-publishedlist .details_link:hover,#my-publishedlist .details_link:active,#my-publishedlist .details_link:visited,#my-published .details_link,#my-published .details_link:hover,#my-published .details_link:active,#my-published .details_link:visited,#detail .app-benefit-notification a:focus{border:0;width:400px;text-align:left;word-wrap:break-word;outline-style:none}.navbar-toolbar #search-plugin{margin-top:9px}#search-plugin .dropdown{float:left}#fancybox-outer{padding:0;background:transparent;-ms-box-shadow:0 0 12px rgba(0,0,0,0.65);-moz-box-shadow:0 0 12px rgba(0,0,0,0.65);-webkit-box-shadow:0 0 12px rgba(0,0,0,0.65);box-shadow:0 0 12px rgba(0,0,0,0.65);-moz-background-clip:padding;-webkit-background-clip:padding;background-clip:padding-box}#fancybox-content{background:transparent;border:1px solid #5b5b5b;-moz-background-clip:padding;-webkit-background-clip:padding;background-clip:padding-box}#fancybox-close{top:10px;right:9px;width:13px;height:13px;background-image:url("../images/buttons/close_13.png");background-position:0 0}.license-add{top:10px;right:9px;width:13px;height:13px;background-image:url("../images/buttons/close_13.png");background-position:0 0;transform:rotate(45deg)}.license-remove{top:10px;right:9px;width:13px;height:13px;background-image:url("../images/buttons/close_13.png");background-position:0 0}#fancybox-close:focus,#fancybox-close:hover{background-position:0 bottom}.license-add:focus,.license-add:hover{background-position:0 bottom}.license-remove:focus,.license-remove:hover{background-position:0 bottom}.img-mask{position:absolute;left:0;top:0;width:100%;height:100%;background-color:rgba(255,255,255,0.7)}.overlay_window{background-color:#f5f5f5}.overlay_window>header{background-color:#e6e6e6;padding:0 10px;height:29px;position:relative}.overlay_window>header h1{overflow:hidden;white-space:nowrap;text-overflow:ellipsis;font-size:14px;font-weight:normal;padding-top:6px}.overlay_window .body_container{border-top:solid 1px #cfcfcf;background-color:#fff}.overlay_window .body{padding:15px;background-color:#f4f4f4}.overlay_window .un-body{margin:0 -15px;padding-bottom:1px;overflow:hidden}.overlay_window .body h2{font-size:16px}.overlay_window .body p{margin-bottom:15px}.overlay_window .body p:last-child{margin-bottom:0}.overlay_window .body label{font-size:12px}.overlay_window .body .title.simple{font-weight:normal}.overlay_window .body .title.error{color:#f00}.overlay_window .body #select_btn{margin-top:10px}.overlay_window .controls{text-align:right}.overlay_window .controls button.close_btn{float:left}.overlay_window .controls.highlighted{padding:10px;margin:0}.overlay_window header .minimize{position:absolute;right:0;top:6px;border-right:1px solid #999;padding:1px 6px 1px 0}.overlay_window header .minimize_btn{cursor:pointer;display:block;height:16px;width:16px;background:url(../images/buttons/btn_minimize.png) no-repeat left top}.overlay_window header .minimize_btn:focus,.overlay_window header .minimize_btn:hover{background-position:left bottom}#download-link-popup{font-size:12px}#download-link-popup>.body_container{padding:15px;text-align:center}#download-link-popup .body_container>span{margin-bottom:5px;display:inline-block}#download-link-popup .body_container>span:last-of-type{font-style:italic;font-size:11px}#main{margin:0 auto;width:1280px}.search-main#main,.detail-main#main,.language-os-selector#main,.boutique#main{padding-left:0}.search-main#main{width:1265px}.search-main #facets-pane{margin-left:30px}.my-uploads-page#main{padding-left:0}.developer-description#main{padding-left:0}#main.search-page,#main.boutique{overflow:auto}.boutique #content{margin-left:120px}#goTop{display:none;position:fixed;right:20px;bottom:145px;width:50px;height:50px;-webkit-transition:opacity .2s;-moz-transition:opacity .2s;-o-transition:opacity .2s;transition:opacity .2s;z-index:9999}#goTop:hover{-moz-opacity:.8;-khtml-opacity:.8;opacity:.8;cursor:pointer}.sort-option{height:25px;background:#fff;margin-right:6px;border-bottom:solid 1px #29abe2}.sort-img-group{width:12px;height:14px;margin-bottom:-3px;display:-moz-inline-box;display:inline-block}.sort-img-group-asc{background:url("../images/icons/up_arrow_idle.png"),url("../images/icons/down_arrow_selected.png") 0 7px;background-repeat:no-repeat}.sort-img-group-desc{background:url("../images/icons/up_arrow_selected.png"),url("../images/icons/down_arrow_idle.png") 0 7px;background-repeat:no-repeat}.sort-option .sort-common{font:12px arial;text-align:center;height:25px;line-height:25px;padding-left:15px;padding-right:15px;margin-right:-4px;display:-moz-inline-box;display:inline-block}.sort-option .sort-common:hover{color:#29abe2;background:#e6e6e6;cursor:pointer}.sort-option .sort-unhightlighted{color:#29abe2;background:#fff}.sort-option .sort-hightlighted{color:#fff;background:#29abe2}.widget-hoverable{width:200px;height:100px}.widget-hoverable{background:white;border:1px solid #e3e3e3}.widget-hoverable .default-area{width:100%;height:100%}.widget-drawer{height:0;width:260px;background:white;border:1px solid #e3e3e3;border-top:0;margin-left:-1px;overflow:hidden;outline:1px solid transparent;-webkit-transform:scaleY(0);-o-transform:scaleY(0);-ms-transform:scaleY(0);transform:scaleY(0);-webkit-transform-origin:top;-o-transform-origin:top;-ms-transform-origin:top;transform-origin:top;overflow:hidden;-webkit-transition:-webkit-transform .3s ease;-webkit-transition:-webkit-transform .3s ease;-webkit-transition:-webkit-transform .3s ease;transition:transform .3s ease}.widget-hoverable:hover .widget-drawer{max-height:120px;position:absolute;height:auto;z-index:999;-webkit-transform:scaleY(1);-o-transform:scaleY(1);-ms-transform:scaleY(1);transform:scaleY(1);box-shadow:0 2px 5px -2px rgba(170,170,170,0.4);-moz-box-shadow:0 2px 5px -2px rgba(170,170,170,0.4);-webkit-box-shadow:0 2px 5px -2px rgba(170,170,170,0.4);-ms-box-shadow:0 2px 5px -2px rgba(170,170,170,0.4)}.widget-drawer span{color:#666;font-size:12px;display:block;word-wrap:break-word;margin:6px}.apps-carousel-section .widget-hoverable{height:80px;margin-right:-5px}.apps-carousel-section .widget-drawer{width:165px}.apps-section-middle ul.apps-list .widget-hoverable{height:70px;width:203px}.apps-section-middle .widget-drawer{width:203px}ul.apps-list li{padding-top:8px}ul.apps-list li.widget-element-app.large-widget-element:not(:nth-child(4n+1)){margin-left:-5px}ul.apps-list li.widget-element-app.large-widget-element:nth-child(n+5){margin-top:-5px}.apps-section-middle ul.apps-list li.widget-element-app:not(:nth-child(5n+1)){margin-left:-5px}.apps-section-middle ul.apps-list li.widget-element-app:nth-child(n+5){margin-top:-5px}#result-list.apps-list-big .s-price-cont{position:absolute;right:auto;bottom:10px;left:310px;width:110px}#result-list.apps-list-big .s-price-cont .price{text-align:left;font-size:12px;color:#29abe2;overflow:hidden;text-overflow:ellipsis}#result-list.apps-list-big .title.ellipsis{width:305px;color:#444;font-weight:bold}#result-list .widget-element-app-layout{background-color:rgba(255,255,255,0.7);cursor:pointer}#result-list.apps-list-big .sr-subscriberonly.ellipsis{width:100px;text-align:left}.search-results h3{color:#4d4d4d;margin:0;font-size:12px;font-weight:bold;line-height:20px}#result-list-new-wrapper #result-list{margin:0;border:0;background-color:transparent}#result-list-new-wrapper ul.apps-list li.small-widget-element{margin:12px 12px 0;border:1px solid #b3b3b3;-ms-border-radius:3px;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px}ul.apps-list-big .product-data-container{float:left;width:411px;position:relative;height:82px;margin-left:8px}ul.apps-list-big .seller{position:absolute;left:230px;top:6px;color:#666;font-size:12px;text-align:right}ul.apps-list-big .rating-wrapper{position:absolute;left:310px;width:110px;top:0}ul.apps-list-big .small-widget-element{-ms-border-radius:18px;-moz-border-radius:18px;-webkit-border-radius:18px;border-radius:18px;border:1px solid #d3d3d3;padding:9px;box-shadow:3px 3px 2px rgba(0,0,0,0.2);-moz-box-shadow:3px 3px 2px rgba(0,0,0,0.2);-webkit-box-shadow:3px 3px 2px rgba(0,0,0,0.2);-ms-box-shadow:3px 3px 2px rgba(0,0,0,0.2)}ul.apps-list-big .small-widget-element .product-data-image{-o-border-radius:18px;-ms-border-radius:18px;-moz-border-radius:18px;-webkit-border-radius:18px;border-radius:18px;width:80px;border:1px solid #aaa}ul.apps-list-big .small-widget-element .product-data-image img{-o-border-radius:18px;-ms-border-radius:18px;-moz-border-radius:18px;-webkit-border-radius:18px;border-radius:18px;width:80px;height:80px}.widget-element-app-search-list-view .product-data-image{width:82px}.widget-element-app-search-list-view img{width:80px;height:80px;-webkit-border-radius:5px;border-radius:5px;border:1px solid #e3e3e3}ul.apps-list .short-description-wrapper{position:absolute;top:73px;word-wrap:break-word;width:150px;color:#666;font-size:12px}ul.apps-list-big .short-description-wrapper{display:block;color:#808080;width:305px;word-wrap:break-word;font-size:11px;height:60px;overflow-y:hidden}#content{width:700px;display:inline;float:left;margin:0 10px}.normal-search#search-form{float:left;width:600px}#search-form .search-form-filter{width:235px;height:22px;float:left;margin:1px 0}#search-form .search-form-keyword{color:#666;font-size:12px;height:16px;line-height:16px;width:90%;margin:0;border:0;background:transparent;margin-top:6px;margin-bottom:6px;-ms-box-shadow:none;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;padding-right:0;padding-left:4px;outline:0}.show-all-wrapper{float:left;line-height:38px;margin-left:10px}#search-form .show_all{font-size:12px;color:#4674a7;float:left;margin-left:8px;line-height:22px;cursor:pointer;width:140px;text-align:right}#search-form .show_all:hover{color:#039}#search-form #show_all_display{float:left;width:100px;height:18px;overflow:hidden;text-overflow:ellipsis}#search-form .search-form-submit,#app-management .app-search .search-form-submit{right:1px;padding:0;background:url(../images/icons/icon_search.png) no-repeat scroll center center transparent;border:0;cursor:pointer;position:relative}#categories-nav{margin-top:10px}ul.dropdown,ul.dropdown li,ul.dropdown ul{list-style:none;margin:0;padding:0}ul.dropdown{position:relative;z-index:597;float:left;width:660px;height:26px;background:#000;padding:0 20px}ul.dropdown li{float:left;line-height:26px;zoom:1;font-size:15px;padding:0 33px 0 0;cursor:default;border:0}ul.dropdown li a{color:#FFF;cursor:pointer}ul.dropdown li:hover{position:relative;z-index:599;cursor:default}ul.dropdown li:hover>ul{visibility:visible}ul.dropdown .dirr span{background:url(../images/icons/menu_arrow_white.png) no-repeat right 8px;padding-right:15px}ul.dropdown ul{visibility:hidden;position:absolute;top:100%;left:0;z-index:598;width:100%;background:#0d0d0d;-moz-box-shadow:2px 2px 2px rgba(24,24,24,0.33);-webkit-box-shadow:2px 2px 2px rgba(24,24,24,0.33);-ms-box-shadow:2px 2px 2px rgba(24,24,24,0.33);box-shadow:2px 2px 2px rgba(24,24,24,0.33)}ul.dropdown ul.nav-1{width:300px;left:0}ul.dropdown ul.nav-2{width:280px;left:0}ul.dropdown ul.nav-3{width:225px;left:-50px}ul.dropdown ul li{float:none;padding:2px 5px}ul.dropdown ul li:hover{background:#507fc1}ul.dropdown ul li a{color:#d9d9d9;font-size:13px}.homepage-module,.detailpage-module{margin-bottom:20px;float:left}.image-homepage{position:relative;min-height:220px}#image-title-homepage{position:absolute;left:23px;top:23px;color:#000;font-size:16px;width:654px;font-weight:bold;text-shadow:0 0 8px rgba(255,255,255,1)}#image-des-homepage{position:absolute;left:23px;top:48px;color:#000;font-size:12px;width:420px;line-height:1.3;text-shadow:0 0 8px rgba(255,255,255,1)}#carousel-slider{height:200px}.carousel-control{background:url('../images/sprite.png');width:35px;height:72px;border:0;zoom:60%}.left.carousel-control{background-position:-50px -50px}.right.carousel-control{background-position:-100px -50px}.carousel-indicators{bottom:15px;right:auto;top:auto;left:60px}.carousel-indicators li{cursor:pointer;border-radius:0;margin-left:20px;width:10px;height:10px;background-color:grey}.carousel-inner .item{width:100%;height:200px;overflow:hidden;background-repeat:no-repeat;background-position:center center}.landing-view #carousel-slider{-moz-box-shadow:0 0 5px rgba(0,0,0,0.4);-webkit-box-shadow:0 0 5px rgba(0,0,0,0.4);-ms-box-shadow:0 0 5px rgba(0,0,0,0.4);box-shadow:0 0 5px rgba(0,0,0,0.4);height:200px}.landing-view .carousel-caption,.home-view .carousel-caption{top:0;padding:35px 0 0 120px;position:absolute;top:0;background:-webkit-linear-gradient(left,rgba(35,35,35,0.8),rgba(35,35,35,0));background:-moz-linear-gradient(left,rgba(35,35,35,0.8),rgba(35,35,35,0));background:-o-linear-gradient(left,rgba(35,35,35,0.8),rgba(35,35,35,0));background:-ms-linear-gradient(left,rgba(35,35,35,0.8),rgba(35,35,35,0));background:linear,left,rgba(35,35,35,0.8),rgba(35,35,35,0);filter:alpha(opacity=80 finishopacity=0 style=1) progid:DXImageTransform.Microsoft.gradient(startColorstr='rgb(35,35,35)',endColorstr='rgb(35,35,35)',GradientType=0)}#landing-container{width:1280px;margin-left:auto;margin-right:auto}#landing-container .button-wrapper{position:absolute;z-index:4;top:150px;right:80px}#landing-container .carousel .button-wrapper button{height:30px;min-width:150px;font-size:14px;color:#fff;font-family:'Open Sans',Arial,'FrutigerNextPro',sans-serif;text-shadow:none;border-radius:0}#landing-container .carousel .button-wrapper .btn-signup{background:#00c000;border:0;margin-right:10px}#landing-container .carousel .button-wrapper .btn-fusion-hero{background:#f89706 url('../images/icons/fusion-download.png') no-repeat center right 10px;border:0;padding-right:35px}#landing-container .carousel .button-wrapper .btn-signin{background:#259fff;border:0}.landing-view .carousel .carousel-inner .item .carousel-caption h2,.home-view .carousel .carousel-inner .item .carousel-caption h2{font-family:'Open Sans',Arial,'FrutigerNextPro',sans-serif;font-size:20px;text-shadow:0 0 10px rgba(0,0,0,0.6);color:#FFF;padding:5px 10px;display:inline-block;font-weight:initial}.landing-view .carousel .carousel-inner .item .carousel-caption pre,.home-view .carousel .carousel-inner .item .carousel-caption pre{line-height:22px;font-family:'Open Sans',Arial,'FrutigerNextPro',sans-serif;font-size:16px;padding:5px 10px;color:#FFF;text-shadow:0 0 10px rgba(0,0,0,0.6);max-width:700px;border:0;background-color:transparent;overflow:hidden;word-wrap:normal;word-break:keep-all}.button-wrapper .signin_link{text-decoration:none}.page-tool-wrapper{width:1220px;margin:0 auto;border-top:1px solid #cecece;overflow:auto}#main .page-tool{margin:10px auto;width:730px;padding:20px 0}#main .page-tool #signup-box{height:48px;width:332px;padding-top:20px;padding-bottom:20px}#main .page-tool #signup-box .text{margin:10px 0 0;color:#666;font-size:12px}#main .overlay-link{margin-right:30px}#main .opening-soon{margin-left:auto;margin-right:auto;width:604px;height:270px;background-repeat:no-repeat;padding:20px;background-image:url("../images/layout/opening_soon_bg.png")}.landing-view #main,.home-view#main{margin:0!important;width:auto!important;background:#f1f0f0}.landing-view #landing-banner #banner-carousel .carousel-list li h1{color:#444;text-shadow:0 0 8px rgba(255,255,255,1);font-size:40px;font-weight:normal;margin:48px 0 0 130px}.landing-view #landing-banner #banner-carousel .carousel-list li h1.maintenance-header{margin-top:100px}.landing-view #landing-banner #banner-carousel .carousel-list li h2{color:#444;text-shadow:0 0 8px rgba(255,255,255,1);font-size:19px;width:600px;font-weight:bold;margin:20px 0 0 130px}.landing-view #landing-banner #banner-carousel .carousel-list li p{color:#444;text-shadow:0 0 8px rgba(255,255,255,1);font-size:14px;width:400px;margin:20px 0 0 130px}.landing-view #landing-banner{margin:0 auto;width:1180px;position:relative}.landing-view #learn-more{width:920px;margin:0 auto 80px auto}.landing-view #landing-banner #banner-carousel{width:1180px;height:400px;position:relative;overflow:hidden}.landing-view #landing-banner #banner-carousel .carousel-list{width:20000em;position:absolute;list-style:none;margin:0;padding:0}.landing-view #landing-banner #banner-carousel .carousel-list li{float:left;width:1180px;height:400px}.landing-view #landing-banner #banner-carousel .carousel-list li.banner-carousel-0{background:url('../images/layout/landing_hero.jpg') no-repeat 0 0}.landing-view #learn-more .maintenance-page{width:435px;margin:54px 0;float:right}.landing-view #learn-more .maintenance-page h1{font-size:16px;font-weight:bold}.landing-view #learn-more .maintenance-page p{font-size:14px}.landing-view #learn-more .maintenance-page{float:none}.landing-view #header #base{min-width:400px}.storenav-button{background:transparent url(../images/buttons/storenav_btn.png?timestamp=20131012) repeat-x 0 0;display:inline-block;margin:0;border:0;min-width:300px;height:45px;color:#555;text-align:center;line-height:45px;font-size:12pt;text-shadow:0 0 8px rgba(255,255,255,1);font-weight:normal;padding:0 10px;-moz-box-shadow:.5px .5px 1px 1px #959595;-webkit-box-shadow:.5px .5px 1px 1px #959595;-ms-box-shadow:.5px .5px 1px 1px #959595;box-shadow:.5px .5px 1px 1px #959595}.storenav-button:hover{background:transparent url(../images/buttons/storenav_btn.png?timestamp=20131012) repeat-x 0 -45px;cursor:pointer}.storenav-button:active,.storenav-button.ui-custom-active{background:transparent url(../images/buttons/storenav_btn.png?timestamp=20131012) repeat-x 0 -90px}a.storenav-button.select-store{color:#fff}.landing-view .dropdown-menu>li>a{line-height:25px}.navbar .dropdown-menu .popover-menu{padding:0;margin:5px 0!important}.navbar .dropdown-menu .popover-menu>li{line-height:25px}.navbar .dropdown-menu .popover-menu>li>a{display:block;padding:0 20px;text-decoration:none;color:black}.navbar .dropdown-menu .popover-menu>li>a:hover{color:white;background-color:#0081c2}.navbar .nav{padding:0}.navbar-header{margin-top:15px}.navbar-brand{background:url(../images/layout/Header_Logo.png) no-repeat;width:241px;height:23px;float:left;text-indent:-9999px;overflow:hidden;background-size:100%}.navbar-default{margin:0;padding:0 20px;border-bottom:1px solid #ccc;background:white}.navbar-toolbar{margin:0;padding:0 20px;background:#f1f0f0}.navbar-default .container{height:50px}.navbar-toolbar .container{height:52px}.navbar-toolbar .navbar{margin:14px 0 11px}.landing-view .navbar-toolbar .navbar{margin:11px 0}.navbar-toolbar .navbar .btn-group{margin-top:0}.btn{background-image:none}.navbar-collapse{height:auto;overflow:visible}.navbar .navbar-nav li{padding:5px 0;height:24px;line-height:24px}.user-panel li.drop_down{padding:0}.navbar .navbar-nav li a{cursor:pointer;padding:0 15px;height:45px;line-height:45px;position:relative;top:-2px;color:#29abe2}.navbar .navbar-nav li a:hover{color:#40cdf5}.login-panel li.depression,.login-panel li.depression{outline:1px solid lightgrey;background:-webkit-gradient(linear,top,bottom,from(#ccc),to(#ededed));background:-webkit-linear-gradient(#ccc,#ededed);background:-moz-linear-gradient(#ccc,#ededed)}.login-panel .depression-panel-myDownloads>li a{border-left:none}.login-panel .depression-panel-myUploads>li.myUploads-li a,.login-panel .depression-panel-myUploads .user-panel{border-left:none}.user-panel{border-left:solid 1px rgba(187,196,198,0.5);padding-left:15px;margin-top:8px}.navbar .navbar-nav li a.a-help-20{border-left:none;padding:0}[class^="icon-"],[class*=" icon-"]{width:20px;height:20px;margin-top:0}.icon-help-20{background:url(../images/icons/help-20x20.png) no-repeat}.search-wrapper .search-box-store-selector{visibility:visible;opacity:0;filter:alpha(opacity=0);-moz-opacity:0;-khtml-opacity:0;position:absolute;top:8px;right:-35px;width:180px}.search-wrapper .nav-search-scope{overflow:hidden;position:relative}.nav-right{float:right;width:auto;display:inline-block}.nav-fill{width:auto;height:35px;position:relative;margin-right:110px}.nav-search-field{position:relative;height:35px}.search-wrapper .search-form-content{border:1px solid lightgrey;background:white}.search-wrapper .search-form-content.active{border-color:#51a7e8;-ms-box-shadow:0 0 5px rgba(81,167,232,0.5);-webkit-box-shadow:0 0 5px rgba(81,167,232,0.5);-moz-box-shadow:0 0 5px rgba(81,167,232,0.5);box-shadow:0 0 5px rgba(81,167,232,0.5)}.search-wrapper .nav-search-scope{position:relative;float:left;height:37px;margin:0;overflow:hidden}.search-wrapper .nav-search-facade{position:relative;float:left;padding:6px 5px 7px 5px;font-size:12px;line-height:14px;margin:5px 0;cursor:pointer;border-left:1px solid lightgrey}.search-wrapper .nav-search-facade .caret{margin-top:5px;margin-left:2px}.search-wrapper .nav-search-submit{position:relative;float:left;height:35px;width:35px;overflow:hidden;cursor:pointer;background:#29abe2}.search-suggestions-box-ul{font:12px Arial;color:#666;position:relative;left:-1px;top:-1px;border:1px solid #ccc;background:#fff;z-index:99;overflow:hidden}.search-suggestions-box-ul li{line-height:25px;cursor:pointer;margin-left:-20px;padding-left:5px}.search-suggestions-box-ul li.selected{background-color:#eee}#search-suggestions-box li:hover{background:#eee}.detail-search-suggestion ul{overflow:hidden;top:0}.detail-search-suggestion li{margin-left:0}.nav-search-submit .nav-input{position:relative;display:block;height:100%;width:100%;line-height:33px;text-indent:-1000px;padding:0;border:0;cursor:pointer;outline:0}.navbar .popover{width:400px;-webkit-border-top-left-radius:0;-webkit-border-bottom-left-radius:0;border-top-left-radius:0;border-bottom-left-radius:0;overflow:hidden}.navbar .popover-content{text-align:center}.navbar .dropdown-menu{-webkit-border-top-right-radius:0;-webkit-border-bottom-right-radius:0;border-top-right-radius:0;border-bottom-right-radius:0;-ms-box-shadow:0 0 5px #000;-webkit-box-shadow:5px 5px 10px rgba(0,0,0,0.2);-moz-box-shadow:5px 5px 10px rgba(0,0,0,0.2);box-shadow:5px 5px 10px rgba(0,0,0,0.2)}.navbar .dropdown-menu>li>a:hover{background-image:none;color:white;background-color:#0081c2;background-color:rgba(0,129,194,0.5)}.navbar .dropdown-menu>li>a.maintainHover{color:white;background-color:#0081c2}#featured-products{margin-top:10px;margin-bottom:10px;background-color:White;border:1px solid #cecece;background-color:white;-moz-border-radius:0 0 4px 4px;-webkit-border-radius:0 0 4px 4px;border-radius:0 0 4px 4px;-ms-box-shadow:0 1px 0 #f1f1f1;-moz-box-shadow:0 1px 0 #f1f1f1;-webkit-box-shadow:0 1px 0 #f1f1f1;box-shadow:0 1px 0 #f1f1f1}#featured-products h2{font-size:16px;color:#404040;font-weight:bold;line-height:28px;height:28px;padding:10px 20px 10px;background-color:white}#featured-products h3{font-size:16px;color:black;margin:7px 0 0;font-weight:normal}#featured-products ul{padding:0 12px 8px;width:674px;color:black;margin:0}#featured-products ul li{position:relative;height:90px;float:left;width:216px;margin:3px 3px 12px 0;padding:0}#featured-products ul li:hover,#featured-products ul li:focus{background:#d5deeb;-moz-border-radius:4px;-webkit-border-radius:4px;border-radius:4px;cursor:pointer}#featured-products ul li:hover a{cursor:pointer}#featured-products ul li:active{background:#9fb3d1}#featured-products .featured_image{width:80px;height:80px;float:left;margin:0 5px 0 0;overflow:hidden}#featured-products ul li div.product-content-container{padding:5px}#featured-products .product-data-container{float:left}#featured-products .product-data-container #product-title{width:120px}#featured-products ul li .title{font-size:12px;color:#000;margin:0}#featured-products ul li .seller,#featured-products ul li .reviews{font-size:10px;color:#808080;display:block}#featured-products ul li .reviews{clear:both}#featured-products ul li .ratingamount{font-size:10px;color:#666;display:block;margin-bottom:3px}#featured-products ul li .price{color:#000;display:block}#featured-products ul li .price.free{color:green}#featured-products ul li .overlay-link{width:100%;height:100%;position:absolute;left:0;top:0;outline:0;z-index:100}#featured-products ul li.clear{height:0}#show_more_all div{text-align:right;padding-top:10px;padding-bottom:20px;padding-right:20px;vertical-align:bottom;font-family:Arial;font-size:12px;color:#4675a8}#show_more_all div a{color:#4675a8}.product-rating-small{float:left;width:65px;height:15px;margin:2px 0 0 0}.product-comment{float:left;height:15px;width:35px;margin:2px 0 0 10px;vertical-align:middle;font:12px arial,Helvetica,sans-serif;color:#808080}.product-comment img{margin:0 0 0 3px}.search-results-stars{float:right}.product-rating-small .star-rating{float:left;width:13px;height:12px;cursor:default;display:block;background:url(../images/icons/star_small.png) no-repeat 0 0;overflow:hidden}.product-rating-small .star-on{background-position:0 -12px!important}.product-rating-small .star-off{background-position:0 0!important}.product-rating-search{float:none}#add-comment .errors{color:red;float:right}#add-comment .not_visible{display:none}#add-comment .error_tag,#add-comment .error{color:red}#add-comment #title{margin-bottom:10px;width:351px;height:16px}#add-comment textarea.error_border,#add-comment input.error_border{border-color:red}#add-comment .comment-rate.error_border{border:1px solid red}.search-page #right{margin-left:20px}#right{width:220px;margin-left:10px;display:inline;float:left}#bestsellers{width:223px}.no-cssgradients #bestsellers h2{background:#e1e1e1 url(../images/layout/backgrounds/bg_h2_title.png) repeat-x 0 0}#bestsellers h2{font-size:16px;font-weight:normal;text-align:center;height:28px;color:#404040;margin:0;padding:0;border:1px solid #cecece;border-bottom:0;line-height:28px;-moz-border-radius:4px 4px 0 0;-webkit-border-radius:4px 4px 0 0;border-radius:4px 4px 0 0;background:-webkit-gradient(linear,left top,left bottom,from(#f0f0f0),to(#e3e3e3));background:-webkit-linear-gradient(#f0f0f0,#e3e3e3);background:-moz-linear-gradient(#f0f0f0,#e3e3e3)}#bestsellers ul{position:relative;top:0;margin:0;padding:0;border:1px solid #cecece;background-color:#fff;-moz-border-radius:0 0 4px 4px;-webkit-border-radius:0 0 4px 4px;border-radius:0 0 4px 4px;-ms-box-shadow:0 1px 0 #f1f1f1;-moz-box-shadow:0 1px 0 #f1f1f1;-webkit-box-shadow:0 1px 0 #f1f1f1;box-shadow:0 1px 0 #f1f1f1}#bestsellers li{border-top:1px solid #d9d9d9;position:relative;height:54px;padding:0;margin:0;display:block}#bestsellers .container{height:42px;width:auto;padding:6px 10px;cursor:pointer}#bestsellers ul li:first-child{border-top:0 none}#bestsellers li:hover,#bestsellers li:focus{background:#d5deeb}#bestsellers li:active{background:#9fb3d1}#bestsellers div.container img.bestseller-icon{width:40px;height:40px;float:left;margin-right:10px;overflow:hidden}#bestsellers .title{color:#000;font:12px arial,Helvetica,sans-serif;margin:0;display:inline-block;width:78px}#bestsellers .description{color:#666;font-size:10px;float:left;margin:0}#bestsellers .price{float:right;font:12px arial,Helvetica,sans-serif;color:#000;vertical-align:bottom}#bestsellers .price.free{color:#008000}#bestsellers .overlay-link{width:100%;height:100%;position:absolute;left:0;top:0;outline:0;z-index:100}.bestsellers-content{float:left;width:150px;height:40px}.leftwing #bestsellers{width:234px}.leftwing .bestsellers-content{width:161px}.leftwing #bestsellers .title{width:89px}.ga-data{text-align:center}.ga-value span{font-size:16px;color:#333}.ga-image-sliders{border-radius:4px;border:1px solid #cecece;overflow-x:hidden;width:348px!important}.ga-image-sliders ul{width:1400px;border:0;height:49px;margin:0;padding:0;background:#e4e4e4;border-bottom:1px solid #cecece}.ga-image-sliders li,.ga-image-sliders li span{width:350px;height:50px}.ga-image-sliders li .ga-title{padding-top:5px;padding-bottom:5px}.ga-image-sliders li .ga-title span{font-size:12px;color:#1c2e84}.ga-image-sliders li{float:left;color:#333;border-top:0}.ga-image-sliders .ga-more-static{height:38px;text-align:center;font-size:15px;background:#f2f2f2}.ga-image-sliders .ga-more-static div{padding-top:10px}.ga-image-sliders .ga-more-static a{font-weight:bold;font-size:12px}.ga-image-sliders .ga-more-static a:link,.ga-image-sliders .ga-more-static a:visited,.ga-image-sliders .ga-more-static a:hover{color:#1c2e84}#quicklinks{float:left;clear:both;padding:0;margin:0 10px 20px 0;display:inline-block;border:1px solid #cecece}#quicklinks a{color:#369}#quicklinks h2{font-size:16px;font-weight:normal;text-align:center;height:28px;color:#333;line-height:28px;-moz-border-radius:4px 4px 0 0;-webkit-border-radius:4px 4px 0 0;border-radius:4px 4px 0 0;background:-webkit-gradient(linear,left top,left bottom,from(#f0f0f0),to(#e3e3e3));background:-webkit-linear-gradient(#f0f0f0,#e3e3e3);background:-moz-linear-gradient(#f0f0f0,#e3e3e3)}#quicklinks ul{padding-left:10px;width:220px;float:left}#quicklinks ul li{padding-bottom:5px}#quicklinks .quicklinks-body{border-top:1px solid #cecece}#facets .facets-constraints .title,#quicklinks li .title{font-size:12px;color:#369;cursor:pointer}#quicklinks li .title{font-size:12px}#quicklinks li.hidden-links{display:none}#facets .facets-constraints .count,#quicklinks li .count{font-size:12px;color:#999}#quicklinks li .count{font-size:11px}#quicklinks .show-all-body{width:210px;padding:10px 10px 10px 12px;border-top:1px solid #cecece}#quicklinks .show-all-body span.show_all{cursor:pointer;font-size:12px;color:#4674a7;font-weight:bold}.no-cssgradients #signup-box{background:#eee}.no-cssgradients #signup-box:hover{background-color:#d9d9d9}#signup-box{float:left;width:205px;text-align:center;color:#222;font-size:11px;padding:13px 8px;background:#e4e4e4;-moz-border-radius:4px;-webkit-border-radius:4px;border-radius:4px;-ms-box-shadow:0 1px 0 #f1f1f1;-moz-box-shadow:0 1px 0 #f1f1f1;-webkit-box-shadow:0 1px 0 #f1f1f1;box-shadow:0 1px 0 #f1f1f1;border:1px solid #cecece;cursor:pointer;display:block}#signup-box .title{margin:0;color:#1c2e84;font-size:14px;font-weight:bold;line-height:1.2}#signup-box .text{margin:5px 0 5px}#signup-box .overlay-link{width:100%;height:100%;position:absolute;left:0;top:0;outline:0;z-index:100}#twitter-widget-0{width:85px!important;float:right}.fb-like{margin-right:2px;float:right}.s-price-cont.s-price-cont-hidden{display:none}.detail-page .detail-module{float:left}.detail-page #content{width:938px;margin:0;margin-bottom:100px}.detail-page #content-wrapper{margin-bottom:10px}.detail-page #detail{padding:10px;background:#fff;border:1px solid #ccc;-moz-border-radius:4px 4px 0 0;-webkit-border-radius:4px 4px 0 0;border-radius:4px 4px 0 0}.detail-page #detail subscriptionDes .subscriptionDes{vertical-align:middle}.detail-page #detail img.subscriptionBadge{float:none;width:24px;height:24px;margin:0}.detail-page #detail .strikeout-price{text-decoration:line-through;vertical-align:middle;padding:0 10px 0 0;cursor:default}.detail-page .description p{word-wrap:break-word;word-break:normal}.detail-page #detail img.product-icon,#app-detail-for-publisher img.product-icon{float:left;height:120px;width:120px;margin:0 15px 5px 0}#app-detail-for-publisher hr{width:960px}.detail-page #detail .title-rating{float:left}.detail-page #detail .icons-cont{width:100%;margin-top:20px}.detail-page #detail .badge-div{float:left}.detail-page #detail .badge-div-visible{visibility:visible}.detail-page #detail .badge-div-hidden{visibility:hidden}.detail-page .badge-div .subscriptionBadge{float:left}.detail-page .purchase-container .caret{border-top:4px solid #fff}#detail-title{margin:0 10px 2px 0;font-size:20px;padding:0;width:80%;color:#4d4d4d;overflow:hidden;text-overflow:Ellipsis;white-space:nowrap;-o-text-overflow:ellipsis;-ms-text-overflow:ellipsis}#detail-social{float:right}#detail .detail-versions-cont .detail-version-cat{float:left;cursor:default;line-height:26px;width:135px}#detail .detail-versions-cont{margin-bottom:10px}#detail .{background:left}.product-rating-big{float:left;width:90px;height:15px;margin:7px 0}.title-rating .product-rating-big{margin:0}.product-rating-big .star-rating{float:left;width:18px;height:16px;cursor:default;display:block;background:url(../images/icons/star_big.png) no-repeat 0 0;overflow:hidden}.product-rating-big .star-on{background-position:0 -16px!important}.product-rating-big .star-off{background-position:0 0!important}.product-rating-search{float:none}.detail-versions-cont .flat-button{border-radius:2px;min-width:150px}.detail-versions-cont .app-version-btn{color:#4d4d4d}#content-wrapper .reviews-count{line-height:32px;margin-left:5px;font-size:12px}#detail .seller{font-size:14px;color:#29abe2}#detail .release-date{font-size:12px;float:right;color:#808080}#detail .description{color:#333;margin:10px 0 10px;font-size:14px;line-height:130%;-ms-word-break:break-word;word-break:break-word;-ms-word-wrap:break-word;word-wrap:break-word}#detail .download-free-notification{clear:both;color:#4675a8;margin:20px 0 20px;font-size:12px;font-weight:bold}#detail .education-free-notification,#detail .app-benefit-notification{clear:both;color:gray;font-size:12px;float:right;font-style:italic}#detail .app-benefit-notification{float:left}#detail .education-free-notification a,#detail .app-benefit-notification a{color:#1a52ad}#detail .description p{margin:0}#detail #extra hr{margin-top:10px;margin-bottom:10px}#detail #extra .detail-versions-cont hr{margin-top:2px;margin-bottom:2px}#extra .purchase-container{height:25px;float:right;max-width:300px;cursor:pointer;margin-bottom:16px}#extra .purchase-container .btn{height:30px;line-height:30px}#extra .version-title{color:#808080;font-size:14px}.price_btn_blue{width:auto;padding:0 20px;border:0;font-size:14px;cursor:pointer;height:25px;text-align:center;line-height:25px;color:#fff}#extra a.price_btn_blue,#extra span.price_btn_blue,#extra a.price_btn_blue:hover{color:white}#detail #detail_testinfo{border:1px solid #00c;padding:5px}#detail .detail_testresult{margin-left:10px;font-style:italic}#extra .purchase_container{display:none}#screenshots .jcarousel-skin-tango .jcarousel-container{background:0;border:0;padding:0 22px}.no-cssgradients #screenshots h2.title,.no-cssgradients .jcarousel-skin-tango{background-color:#f0f0f0}#screenshots ul{height:140px;overflow:hidden;margin:0;padding:0}#screenshots ul li{position:relative}#screenshots .text-container{margin:0 50px 10px;font-size:12px;color:#666}#screenshots .text-container .title{font-weight:bold;line-height:26px}#screenshots ul li span{text-align:center;overflow:hidden;display:block;color:#4d4d4d}#screenshots ul li img{display:block;position:absolute;margin:auto;top:0;bottom:0;left:0;right:0;max-height:74px}.preview-container{height:505px;margin:0 50px 15px 50px;border:1px solid #cecece;position:relative}.preview-container>iframe{width:100%}.preview-container>img,.preview-container>iframe{position:absolute;max-height:100%;max-width:100%;top:0;bottom:0;right:0;left:0;margin:auto;border:0}.preview-next:hover,.preview-prev:hover{opacity:1}.preview-next,.preview-prev{width:20px;height:30px;top:160px;z-index:10;cursor:pointer;position:absolute;opacity:.5}.preview-container .preview-next{background:url(../images/icons/next.png) no-repeat;right:-30px}.preview-container .preview-prev{background:url(../images/icons/prev.png) no-repeat;left:-30px}.preview-overlay{z-index:10;position:relative;height:100%;cursor:pointer}.preview-overlay:hover{background:rgba(0,0,0,0.1) url(../images/icons/zoom.png) no-repeat center;background-size:10%}.video-overlay{background:rgba(0,0,0,0.15) url(../images/buttons/play.png) no-repeat center;height:100%;width:100%;position:absolute;z-index:10;margin:-3px}.video-overlay:hover{cursor:pointer;background:transparent url(../images/buttons/play.png) no-repeat center}.detail-page #right{width:328px;margin-bottom:100px}.side-panel{font-size:12px}.side-panel span#language{word-break:normal}.side-panel h2{font-size:16px;font-weight:normal;padding:0 10px;height:28px;color:#404040;border:1px solid #cecece;line-height:28px;-moz-border-radius:4px 4px 0 0;-webkit-border-radius:4px 4px 0 0;border-radius:4px 4px 0 0;background:-webkit-gradient(linear,left top,left bottom,from(#f0f0f0),to(#e3e3e3));background:-webkit-linear-gradient(#f0f0f0,#e3e3e3);background:-moz-linear-gradient(#f0f0f0,#e3e3e3);text-align:center}.side-panel h3{height:25px;background:-webkit-gradient(linear,left top,left bottom,from(#f0f0f0),to(#e3e3e3));background:-webkit-linear-gradient(#f0f0f0,#e3e3e3);background:-moz-linear-gradient(#f0f0f0,#e3e3e3);font-weight:normal;border:1px solid #cecece;border-bottom:0;border-top:0;line-height:25px;padding:0 8px;color:#000}.side-panel ul.compatible-with-list,ul.subscriber-benefit-product-list{margin:0;padding:0}.side-panel li.hidden-subscriber-benefit-products,li.hidden-compatible-with-list{display:none}.side-panel li.your-subscription{font-weight:bold}.side-panel #purchase{border:1px solid #bfbfbf;background-color:White;padding:10px;margin-bottom:10px;padding-bottom:42px}.side-panel #purchase .price-str{font-size:24px}#purchase .flat-button{width:100%;padding:4px 0}#price-options .flat-button{height:50px;border-radius:0;font-size:24px;color:#29abe2;border:2px solid #29abe2}#price-options .flat-button.selected{color:white}.side-panel .download-info{min-height:15px;padding:5px 0;margin-top:10px}.side-panel .download-info-subscription{padding-bottom:10px}.side-panel .show-more,.show-less{color:#1a52ad;display:inline-block;white-space:nowrap;cursor:pointer}.break-word{word-wrap:break-word;word-break:break-all}.side-panel .download-info .property{float:left}.side-panel .download-info-subscription .property{margin-bottom:10px}.side-panel #show-more-benefit-products,.side-panel #show-less-benefit-products{margin-bottom:10px}.side-panel .download-info .compatible-with-list .compatible-with-list-group{margin-top:8px}.side-panel .download-info .subscriber-benefit-product-list li,.side-panel .download-info .compatible-with-list li{margin:0 0 2px 0}.side-panel .download-info .value{float:right}.side-panel .detail-comptible{padding-bottom:0}.side-panel .promote-item:hover{background:#f0f0f0}.side-panel .promote-item>img{width:50px;height:50px;float:left;margin-right:10px}.side-panel .s-price-cont{float:none;margin-top:5px}.detail-page .product-rating-small{margin-right:5px}.side-panel .product-rating-small{width:auto}.side-panel .ellipsis{width:190px}.side-panel .show-more-apps{margin:5px;float:right}.side-panel .show-more-apps a{color:steelblue}.side-panel.apps-promote-panel{border:1px solid #cecece;background-color:white;padding-bottom:10px}.side-panel.apps-promote-panel H2{border:0;border-bottom:1px solid #cecece;padding:5px;text-align:center;margin-top:0}.side-panel.apps-promote-panel .company-title{font-size:18px}.side-panel.apps-promote-panel .company-numberitem{font-size:14px;color:#4d4d4d}.side-panel.apps-promote-panel .company-number{font-size:18px;font-weight:bold;color:#808080}.side-panel.apps-promote-panel .info-logo{width:80px;height:80px;margin-right:5px;margin-left:10px}.side-panel.apps-promote-panel .promote-item{height:80px;margin-top:5px;margin-bottom:5px;color:#4d4d4d}.side-panel.apps-promote-panel .company-info-cont{height:80px}.side-panel.apps-promote-panel .promote-item .product-title{margin-bottom:20px;font-size:14px;width:220px;font-weight:bold}.side-panel.apps-promote-panel .promote-item .s-price-cont{color:#29abe2}.side-panel.apps-promote-panel .company-info-cont .info-logo{float:left;margin-right:10px}.side-panel.apps-promote-panel .service-list li{font-size:12px;color:#4d4d4d;margin:0 0 10px 10px}.side-panel.apps-promote-panel ul{margin-top:15px}.side-panel.apps-promote-panel .list-title{font-size:18px;color:#4d4d4d;margin:5px 0 5px 10px}.detail-page h2{font-size:18px;margin:10px 0 10px 0;font-weight:normal;text-align:left;height:28px;color:#4d4d4d;border-bottom:0;line-height:28px}#reviews #summary{background-color:white;-moz-border-radius:4px 4px 4px 4px;-webkit-border-radius:4px 4px 4px 4px;border-radius:4px 4px 4px 4px;border:1px solid #cecece;padding:10px;overflow:hidden}#reviews #summary img{width:40px;padding-right:10px;float:left}#reviews #summary .title-author{display:inline-block;float:left}#reviews #summary .title-author span{padding-top:4px;float:left;max-width:100px}#reviews #summary .title-author h3{max-width:100px}#reviews #summary .reviews-info{display:inline-block;padding-left:10px;width:auto;overflow:hidden}#reviews #summary .write-review-link{width:auto;display:inline-block;float:left}.compatible-version{color:grey}.compatible-version-title{font-weight:bold}.reviews-info h3{float:left;line-height:35px;font-size:20px;font-weight:normal;color:#ccc}.get-tech-help{margin:0 5px;color:#1a52ad;line-height:35px}.reviews-info a.get-tech-help:hover{color:#1a52ad}.detail-page span.comment,.detail-page a.comment{padding:8px;margin-right:5px;color:#4d4d4d;cursor:pointer;float:left;border:1px solid #ccc;font-size:14px;width:auto}.detail-page span.noncomment{background:transparent url(../images/icons/comment.png) no-repeat 0 1px;padding-left:20px;margin-left:5px;color:Gray}.detail-page a.comment:hover{color:#3d87ff}#extra .log-in-to-comment span.pending:hover,.detail-page span.pending:hover{color:#1a52ad;cursor:default}.detail-page span.pending,.detail-page a.pending,.detail-page span.pending:hover,.detail-page a.pending:hover{color:#c3c3c3}#reviews #summary .reviews-stars{margin-top:6px}#reviews #summary .reviews-stars .product-rating-small{padding-right:5px}#reviews #summary .reviews-info .averagereview{float:left;margin-right:2px;max-width:190px;width:auto}#reviews #summary .reviews-info .reviews-count{display:block}#comments{width:650px;float:left;padding-bottom:30px}#comments-list{padding:0;margin:0}#comments .add-sub-comments{width:850px}.add-sub-comments .app-publisher{font-weight:bold}#comments .sub-comment-warning,#comments .delete-comment-warnning{color:#f60}#comments .delete-comment-warnning{display:inline}.sub-comment-form textarea{margin-bottom:10px;width:645px}.edit-a-comment-form textarea{margin-bottom:10px;width:600px}#comments .sub-comment-description-warning{border:1px solid #f60;padding:10px}.sub-comment-form-hidden,.sub-comment-link-hidden,.edit-a-comment-hidden,.edit-delete-comment-actions-hidden,.realdelete-cancel-comment-actions-hidden,.sub-comment-hidden,.edit-a-comment-form-hidden{display:none}.comment-action{color:#1a52ad;cursor:pointer}.comment-action:hover{color:#3d87ff;cursor:pointer}.comment-subject{display:block;font-size:13px;color:#595959;font-weight:bold;margin-bottom:10px}.comment-item{margin:20px 0;float:left;width:900px}.comment-item .add-sub-comments{float:left;margin-left:50px}#comments-list hr{width:938px;margin:0;float:left}#comments-list .sub-comment-entity hr{width:888px}.sub-comment-warning{margin-top:10px}.sub-comment-entity{margin-top:15px}.write-a-comment{margin-top:5px;float:left;padding-left:5px}.write-comment-form-submit,.write-a-comment-cancel{margin-right:10px;padding:2px}.sub-comment-description p{margin:0}.sub-comment-description{margin:10px 0;color:#595959}.comment-item .comment-info{float:left;padding-left:5px;width:895px}.comment-item .comment-date{display:inline;color:#a6a6a6;margin-bottom:15px}.comment-item .comment-name{margin-bottom:15px}.comment-item .comment-description{color:#595959}.comment-item .comment-description p{margin-bottom:0}.comment-item .veirified-download{font-size:11px;font-weight:bold;color:#f90}.comment-item .whats-verified-download{font-size:10px;color:#c9c9c9;text-decoration:underline;cursor:pointer}#add-comment{margin-bottom:40px;float:left;background-color:white;-moz-border-radius:4px 4px 4px 4px;-webkit-border-radius:4px 4px 4px 4px;border-radius:4px 4px 4px 4px;border:1px solid #cecece;padding:10px;display:none}#add-comment .title{font-weight:bold;margin-bottom:20px}#add-comment .title a{color:#1f5397}#comment-form .own-rate{float:left;width:260px;text-align:center}#comment-form .own-rate h2{display:inline}#comment-form .own-rate label{font-size:10px;font-weight:bold}#comment-form .own-rate span{font-size:10px}#comment-form .own-rate .product-rating-big{float:none;margin-left:auto;margin-right:auto;padding:10px}#comment-form .own-review{float:left;width:366px;text-align:center}#comment-form .own-review div{position:relative}#comment-form .own-review textarea{margin-top:0;margin-bottom:0;height:65px;width:351px;resize:none}#comment-form input,#comment-form textarea{padding:5px;border:solid 1px #bfbfbf;font-size:13px;font-style:normal;background:white url('../images/bg_form.png') left top repeat-x;background:-webkit-gradient(linear,left top,left 3,from(white),color-stop(1%,#f1f1f1),to(#fcfcfc));background:-moz-linear-gradient(top,white,#f1f1f1 1px,#fcfcfc 2px);box-shadow:rgba(0,0,0,0.1) 0 0 4px;-ms-box-shadow:rgba(0,0,0,0.1) 0 0 4px;-moz-box-shadow:rgba(0,0,0,0.1) 0 0 4px;-webkit-box-shadow:rgba(0,0,0,0.1) 0 0 4px}#comment-form .submit-comment,#comment-form .cancel-comment{width:auto;padding:0 11px;border:0;font-size:14px;color:white;cursor:pointer;height:25px;text-align:center;line-height:25px;margin-top:10px;-moz-box-shadow:none;-webkit-box-shadow:none;-ms-box-shadow:none;box-shadow:none}#comment-form .cancel-comment{margin-right:10px;display:inline-block;margin:0;border:1px solid #797979;white-space:nowrap;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;background-color:#999;-moz-box-shadow:none;-webkit-box-shadow:none}.gradient-button{background:linear-gradient(#6a91df,#314d7b);background:-webkit-gradient(linear,left top,left bottom,from(#6a91df),to(#314d7b));background:-webkit-linear-gradient(#6a91df,#314d7b);background:-moz-linear-gradient(#6a91df,#314d7b);background:-o-linear-gradient(#6a91df,#314d7b);display:inline-block;margin:0;border:1px solid #335080;white-space:nowrap;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;-ms-box-shadow:0 1px 0 rgba(0,0,0,0.4);-moz-box-shadow:0 1px 0 rgba(0,0,0,0.4);-webkit-box-shadow:0 1px 0 rgba(0,0,0,0.4);box-shadow:0 1px 0 rgba(0,0,0,0.4)}.no-cssgradients .gradient-button{background:#314d7b url(../images/icons/bg-gradient-dropdown.png) repeat-x 0 0}a .no-cssgradients .gradient-button:hover,a .no-cssgradients .gradient-button:focus{background-position:0 -26px}.no-cssgradients .gradient-button:active:hover{background-position:0 -32px}.no-cssgradients .gradient-button.disabled{color:#fff;background-position:0 -78px;cursor:default!important}.gradient-button:hover,.gradient-button:focus{background:linear-gradient(#80a1e4,#50688f);background:-webkit-gradient(linear,left top,left bottom,from(#80a1e4),to(#50688f));background:-webkit-linear-gradient(#80a1e4,#50688f);background:-moz-linear-gradient(#80a1e4,#50688f)}.gradient-button:active{background:linear-gradient(#5a7bbe,#2a4269);background:-webkit-gradient(linear,left top,left bottom,from(#5a7bbe),to(#2a4269));background:-webkit-linear-gradient(#5a7bbe,#2a4269);background:-moz-linear-gradient(#5a7bbe,#2a4269)}.gradient-button.disabled{color:#fff;opacity:.3;-moz-opacity:.3;-khtml-opacity:.3;background:linear-gradient(#96b1e9,#577ebc);background:-webkit-gradient(linear,left top,left bottom,from(#96b1e9),to(#577ebc));background:-webkit-linear-gradient(#96b1e9,#577ebc);background:-moz-linear-gradient(#96b1e9,#577ebc);cursor:default!important}.ui-button.disabled{opacity:.8;-moz-opacity:.8;-khtml-opacity:.8}.detail-page .helpdoc-element{margin-top:25px;width:830px}.detail-page .helpdoc-command{margin-top:10px}.detail-page .helpdoc-block{margin-top:10px;width:830px}.detail-page #helpdoc-element-screenshot{width:900px}.detail-page #helpdoc-tag{width:830px}.detail-page #helpdoc-tag a:link,.detail-page #helpdoc-tag a:hover,.detail-page #helpdoc-tag a:visited,.detail-page #helpdoc-tag a:active{float:left;font:12px arial,sans-serif;color:#4675a8;height:16px;padding:0 3px}.detail-page #helpdoc-tag a.helpdoc-breadcrumb{border-right:1px solid black}.detail-page .helpdoc-element a:link,.detail-page .helpdoc-element a:hover,.detail-page .helpdoc-element a:visited,.detail-page .helpdoc-element a:active{color:#4675a8}.detail-page .helpdoc-text{width:830px;word-wrap:break-word;font:12px arial,sans-serif black}.detail-page #helpdoc-head{margin-top:25px;width:830px}.detail-page #helpdoc-head-icon{float:left;width:80px;height:80px;margin-right:15px}.detail-page #helpdoc-head-description{width:735px;float:right}.detail-page #helpdoc-product-title{float:left}.detail-page #helpdoc-product-os{float:right;width:235px;text-align:right;overflow:hidden;font:12px arial,sans-serif black}.detail-page #helpdoc-head hr{margin-top:5px;margin-bottom:2px}.detail-page #helpdoc-head .seller{overflow:hidden;width:735px;font:12px arial,sans-serif #666}.detail-page #helpdoc-head .description{width:735px;margin-top:10px;height:32px;overflow:hidden;word-wrap:break-word}.detail-page a.helpdoc{color:#1a52ad}.detail-page #helpdoc-head .description p{width:735px;margin:0;overflow:hidden}.detail-page #helpdoc-tag{margin-top:10px}.detail-page .helpdoc-element-hidden{display:none}.detail-page .helpdoc-screenshot{float:left;width:215px;height:173px}.detail-page .helpdoc-img-container{width:180px;height:140px;text-align:center;border:1px solid #ccc}.detail-page .helpdoc-img-container:hover{border:1px solid gray}.detail-page .helpdoc-screenshot-img{max-height:130px;max-width:170px}.helpdoc-img-container .helper{display:inline-block;height:100%;vertical-align:middle}.detail-page .helpdoc-screenshot-label{text-align:center;text-overflow:ellipsis;width:180px;height:15px;float:left;overflow:hidden;margin-top:2px;font:12px arial,sans-serif black}.detail-page .helpdoc-table th{background-color:#f2f2f2}.detail-page .helpdoc-table td,.detail-page .helpdoc-table th{border:1px #b3b3b3 solid}.detail-page .helpdoc-version{margin-bottom:420px}.detail-page .helpdoc-table th{height:35px;text-align:left;padding-left:10px}.detail-page #helpdoc-table-command td{height:100px}.detail-page #helpdoc-table-version td{height:70px}.detail-page .helpdoc-table td img{max-width:80px;max-height:80px;margin:10px}.detail-page .helpdoc-table td p{margin-left:10px}.detail-page #helpdoc-head h1{font:bold 18px arial,sans-serif black;width:500px;overflow:hidden}.detail-page .helpdoc-element h1{font:bold 16px arial,sans-serif black;margin-bottom:5px}.detail-page #right-wrapper{color:#4d4d4d}.helpdoc-page #content{width:830px;margin:0 auto 100px auto;float:none;display:block}.detail-main .drawer{margin:0}.detail-main .subscriber-drawer{float:left}.no-result .purchase-panel{display:block}.no-result .purchase-result{display:none}.result-success .purchase-result-success{display:block}.result-success .purchase-result-not-success{display:none}.result-not-success .purchase-result-success{display:none}.result-not-success .purchase-result-not-success{display:block}.purchase-result-not-success-text a{color:red;text-decoration:underline}.multi-purchase-input-error{background:darksalmon!important}.purchase-panel{margin-top:5px}.purchase-panel>.purchase-action{margin-top:5px}.side-panel>span{font-size:14px}.purchase-panel #multi-purchase-btn{width:100%}.price-qty-total>.purchase-subtotal{font-weight:bold;font-size:14px}.purchase-action>.ui-button{width:100px;height:26px;border-radius:3px;font-size:14px;line-height:25px}.qty-purchased-limit>.off-button{background:url(../images/buttons/close_13.png) no-repeat 0 0;width:13px;height:13px;float:right;cursor:pointer}.qty-to-purchase{margin-top:10px}.qty-to-purchase-title{float:left;margin-right:5px;line-height:24px}.price-qty-total .stepper-input{float:left}.purchase-result-success-text{color:green}#multi-purchase-input{max-width:45px;padding:2px;text-align:center;margin-bottom:15px}.purchase-result-not-success-text{color:red}.purchase-result-info{margin:12px 0}.purchase-result-actions a{color:#1a52ad;cursor:pointer}.purchase-result-actions a:hover{color:#3d87ff}.purchase-result{margin-top:5px}.dealer-code{margin-top:10px}.dealer-code-title{float:left;margin-right:24px;line-height:24px}#dealer-code-input{max-width:45px;padding:2px;margin-bottom:4px}.dealer-code .explanation{display:inline-block;font-size:11px;color:#969696}.detail-page .dropdown.dropdown-wishlist{width:100%;margin-top:8px;border:0;box-shadow:none}.purchase-panel>.purchase-action{width:100%;border:0}#purchase>.dropdown-wishlist .dropdown-toggle{border:1px solid #29abe2;color:#29abe2;background:#fff;margin-top:0}.detail-page .purchase-container .dropdown-toggle .caret{border-top:4px solid #29abe2;position:relative;left:30%}.detail-page .purchase-container .dropdown-wishlist .dropdown-menu{border:1px solid #29abe2;color:#29abe2;background:#fff;text-align:center;height:inherit;margin-top:28px;color:#29abe2;border-top:0}.dropdown-wishlist .dropdown-menu>li>a:hover,.dropdown-menu>li>a:focus,.dropdown-submenu:hover>a,.dropdown-submenu:focus>a{background:0}.detail-page .purchase-container .dropdown-wishlist .divider{border-bottom:1px solid #29abe2;background-color:#fff;padding:0}.detail-page .purchase-container .dropdown-wishlist .dropdown-menu a{color:#29abe2}.side-panel .modal-header{border:0}.side-panel .modal-header h3{background:0;color:#29abe2;border:0;font-weight:700}.side-panel .modal-body .img-wrapper{padding-right:10px}.side-panel .modal-body input{width:97%;border:1px solid #29abe2}.side-panel .modal-footer{background:0;border:0}.side-panel .modal-footer .text-info{width:48%;background:0;border:1px solid #29abe2;color:#29abe2}.side-panel .modal-footer .btn-primary{width:49%;background:#29abe2}.side-panel #purchase #wishlistsmodel .price-str{font-size:20px;margin-top:14px}.pagination-content{display:inline-flex;display:-ms-flexbox;padding:0;border:1px solid #b3b3b3;border-radius:7px;background:white;height:24px}.pagination-content li.beginning-dots,.pagination-content li.final-dots{float:left;width:18px;line-height:20px;padding:0 6px;margin:0;text-align:center}.pagination-content li.beginning-dots:hover,.pagination-content li.final-dots:hover{background:0}.pagination-content li.pag,.pagination-content li.prev,.pagination-content li.next{float:left;width:22px;height:22px;line-height:20px;padding:2px 0 0 0;text-align:center;cursor:pointer}.pagination-content li.first{border-top-left-radius:7px;border-bottom-left-radius:7px}.pagination-content li.last{border-top-right-radius:7px;border-bottom-right-radius:7px}.pagination-content li.leftborder-pageitem{border-left:1px solid #b3b3b3}.pagination-content li.pag:hover,.pagination-content li.prev:hover,.pagination-content li.next:hover{background:#DDD;border-color:#999}.pagination-content li.current a{color:#29abe2}.pagination-content li a{color:#808080;display:block}.page_input_container{margin:4px 0 0 20px}.page_input_label{margin:3px 0 0 0;float:left}.page_input_textbox{float:left;height:16px;width:26px;border:1px solid #cecece;margin:0 4px 0 4px;padding:1px;text-align:center;height:10px!important}.page_input_go{float:left;border:1px solid #cecece;padding:2px 5px 1px 5px;height:15px;background:#f7f7f7}.page_input_go span,.page_input_go span:visited,.page_input_go span:hover{color:#4d4d4d}.quick-search-wrapper{margin-bottom:5px;height:22px}.quick-search-wrapper h3{float:left;margin:0 20px 0 0;height:22px;line-height:22px}.quick-search-wrapper .quick-search-form-filter{width:235px;height:22px;float:left}#search-results-extra hr{clear:both;margin:10px 0}.pagination-spinner{float:left;margin:7px;height:16px;width:16px;line-height:16px;display:none}.my-downloads-page#main{margin-bottom:50px}.my-downloads-page #content{width:1000px;display:block;float:none;margin:0 auto}.my-downloads-page .page-title{margin-bottom:30px;margin-left:-132px}.my-downloads-page .description-container{width:200px;word-wrap:break-word;word-break:normal}.my-downloads-page .cancel-subscription{text-align:right}#my-downloads table{margin:10px 0 20px 0;text-align:left;font-size:11px}#my-downloads table td,#my-downloads table thead th{border:0 none;padding:5px;vertical-align:middle}#my-downloads table td{border-left:1px solid #e6e6e6}#my-downloads table td:first-child{border:0}#my-downloads table tr{border-bottom:1px solid #e6e6e6}#my-downloads table td.info-cell{width:170px;min-width:147px}#my-downloads table td.description-cell{width:200px}#my-downloads table td.company-cell,#my-downloads table td.store-cell{width:90px}#my-downloads table td.update-cell{width:80px}#my-downloads table td.purchase-qty-cell{width:100px}#my-downloads table td.info-cell img{width:40px;height:40px;float:left;margin:3px 6px 3px 2px}#my-downloads table td.info-cell .product-info{float:left;width:95px;margin-top:4px}#my-downloads table td.info-cell .product-info a,#my-downloads table td.info-cell .product-info span{display:block;margin-bottom:5px;color:#595959}#my-downloads table td.info-cell .product-info a:focus,#my-downloads table td.info-cell .product-info a:hover{color:#06e}#my-downloads table td.update-cell img{margin:0 2px}#my-downloads table td.update-cell a{color:#1a52ad}#my-downloads table td.update-cell a:hover{color:#3d87ff}#my-downloads table td.help-cell img{margin:0 6px}#my-downloads table caption,#my-downloads h2{font:20px Arial;color:#4d4d4d;margin-bottom:2px;text-align:left}#my-downloads h2{margin-top:10px}#my-downloads h3{font-size:16px;font-weight:normal;color:#333}#my-downloads table thead tr{background:#999}#my-downloads table thead tr th{color:#FFF;text-align:left;font-size:12px}#my-downloads table tbody{color:#595959}#my-downloads table tbody .fullDescription-container p{margin:0 0 5px}#my-downloads table .odd-row{background:#f2f2f2}#my-downloads table .even-row{background:#FFF}.purchase-qty-cell,.purchase-date-cell{text-align:center}.purchase-date-div{width:120px}.purchase-date-span{float:left}.open .purchase-date-more{display:block}.purchase-date-more{display:none}.open .cell-more{display:none}.cell-more{cursor:pointer;display:inline}.open .cell-less{display:inline}.cell-less{cursor:pointer;display:none}td.description-cell .more_less{cursor:pointer;font-weight:bold;text-decoration:underline}.tooltip{display:none;position:absolute;min-height:10px;padding:7px 8px;z-index:84001;color:#666;border:1px solid #808080;border-color:rgba(0,0,0,.5);background-color:#f7f7f7;background:-webkit-gradient(linear,left top,left bottom,from(rgba(255,255,255,0.95)),to(rgba(230,230,230,0.95)));background:-webkit-linear-gradient(rgba(255,255,255,0.95),rgba(230,230,230,0.95));background:-moz-linear-gradient(rgba(255,255,255,0.95),rgba(230,230,230,0.95));-moz-border-radius:2px;-webkit-border-radius:2px;border-radius:2px;-moz-box-shadow:0 1px 2px rgba(0,0,0,.3);-webkit-box-shadow:0 1px 2px rgba(0,0,0,.3);box-shadow:0 1px 2px rgba(0,0,0,.3);-moz-background-clip:padding;-webkit-background-clip:padding;background-clip:padding-box;max-width:200px}.tooltip .pointer{position:absolute;top:-6px;left:5px;width:100%;height:6px;background:url(../images/icons/tooltip_pointer.png) no-repeat left top}.tooltip.right .pointer{left:auto;right:5px;background-position:right top}.tooltip.visible{display:block}.has_tooltip{cursor:help}#my-downloads table thead tr th.sortable{cursor:pointer}#my-downloads table thead tr th:hover,#my-downloads table thead tr th:focus{background:#575757}#my-downloads table thead tr th:active,#my-downloads table thead tr th.current{background:#3d3d3d}#my-downloads .order-arrow{float:right;margin:5px 3px 5px 5px;background:url(../images/icons/sort_arrow.png) no-repeat;height:4px;width:7px;display:none}#my-downloads .up{background-position:0 -4px}#my-downloads .down{background-position:0 0}#my-downloads table thead tr th.current a.order-arrow{display:block}#my-downloads table thead tr .th-titles{float:left;margin-right:2px}.my-uploads-page{padding-top:20px;width:960px}.my-uploads-page label{cursor:default}.my-uploads-page #content{width:960px;margin-left:122px}#my-published table input{cursor:pointer;background-color:transparent;text-decoration:none;border:0;color:blue}.detail-page-for-publisher#main{width:1260px}.detail-page-for-publisher#main>div{display:inline-block;vertical-align:top;width:18%}.detail-page-for-publisher#main .p-detail-tabs{width:1000px;margin-left:20px}.detail-page-for-publisher#main .p-detail-notification{width:98%}.developer-description #content{width:1280px}.developer-description #content div p{text-align:justify;text-justify:inter-word}.developer-description #content .headline{margin:10px 0;color:#29abe2;font-size:18px;font-weight:normal}.developer-description #content .legal-content{border:1px solid #ccc;padding:15px 30px;overflow-y:auto;height:453px;background:white;margin-bottom:20px}.developer-description #content .legal-content p:first-child{margin-top:0}.developer-description #content .sell-notice-level-1{font-size:16px;font-weight:bold;margin:10px 0;color:#4d4d4d}.developer-description #content .sell-notice-level-2{font-size:16px;font-weight:normal;color:#333}.developer-description #content .sell-notice-level-3{font-size:12px;color:#4d4d4d}.developer-description #content .sell-notice-note{font-style:italic;color:#333;font-size:12px}.developer-description #content ul.list-items{padding-left:20px;color:#4d4d4d}.developer-description #content ul.list-items li{margin:0 0 5px 15px;list-style-type:disc}.developer-description #content .actions{margin-bottom:24px;padding:30px 0;height:33px}.developer-description #content .publish-link{width:150px;padding:5px 0;border:0;font-size:14px;cursor:pointer;text-align:center;color:white}.developer-description #content .back,.developer-description #content .signin_link{width:150px;border:0;padding:5px 0;font-size:14px;cursor:pointer;height:25px;text-align:center;color:white}.developer-description #content .publish-link,.developer-description #content .signin_link{float:right}.grey-button{background:linear-gradient(#666,#2e2e2e);background:-webkit-gradient(linear,left top,left bottom,from(#666),to(#2e2e2e));background:-webkit-linear-gradient(#666,#2e2e2e);background:-moz-linear-gradient(#666,#2e2e2e);background:-o-linear-gradient(#666,#2e2e2e);border:1px solid #303030}.no-cssgradients .grey-button{background:#2e2e2e url(../images/icons/bg-gradient-button-gray.png) repeat-x 0 0}.no-cssgradients .grey-button:hover,.no-cssgradients .grey-button:focus{background-position:0 -32px}.no-cssgradients .grey-button:active{background-position:0 -64px}.no-cssgradients .grey-button:disabled{background-position:0 -78px;cursor:default!important}.no-cssgradients .grey-button[disabled],.no-cssgradients .grey-button[disabled]:hover,.no-cssgradients .grey-button[disabled]:active{background-position:0 -96px;cursor:default!important}.grey-button:hover,.grey-button:focus{background:linear-gradient(#808080,#474747);background:-webkit-gradient(linear,left top,left bottom,from(#808080),to(#474747));background:-webkit-linear-gradient(#808080,#474747);background:-moz-linear-gradient(#808080,#474747)}.grey-button:active{background:linear-gradient(#595959,#1f1f1f);background:-webkit-gradient(linear,left top,left bottom,from(#595959),to(#1f1f1f));background:-webkit-linear-gradient(#595959,#1f1f1f);background:-moz-linear-gradient(#595959,#1f1f1f)}.grey-button:disabled{background:linear-gradient(#a6a6a6,#6e6e6e);background:-webkit-gradient(linear,left top,left bottom,from(#a6a6a6),to(#6e6e6e));background:-webkit-linear-gradient(#a6a6a6,#6e6e6e);background:-moz-linear-gradient(#a6a6a6,#6e6e6e);cursor:default!important}.developer-terms-and-conditions #content{width:1280px}.developer-terms-and-conditions #content .headline{margin:10px 0;color:#4d4d4d;font-size:16pt}.developer-terms-and-conditions #content .legal-content{border:1px solid #bfbfbf;background:white;padding:10px;overflow-y:auto;height:553px}.developer-terms-and-conditions #content .legal-content .legal-left{width:49%;float:left;margin-right:10px;padding-right:10px;border-right:solid 1px}.developer-terms-and-conditions #content .legal-content .legal-right{float:left;width:49%}.developer-terms-and-conditions #content .actions{margin-bottom:30px;padding-top:20px}.developer-terms-and-conditions #content p{color:#4d4d4d}.developer-terms-and-conditions #content .legal-content p:first-child{margin-top:0}.publisher-agreement-item-level-1{margin-left:12px;text-indent:-12px}.publisher-agreement-items-level-2-container p{margin-left:22px;text-indent:-22px}.publisher-agreement-items-level-3-container p{margin-left:52px;text-indent:-42px}.developer-terms-and-conditions #content .exhibit-a{margin-top:50px;text-decoration:underline}.eula-term-1-container p{margin-left:15px;padding-left:15px;text-indent:-15px}.eula-term-2-container p{margin-left:30px}.eula-term-3-container p{margin-left:45px}.developer-terms-and-conditions #content .agree-continue{float:right}.developer-terms-and-conditions #content .legal-form{height:25px}.developer-terms-and-conditions #content .legal-form .not-agree{margin-left:10px}.developer-terms-and-conditions #content .continue{padding:0 20px;font-size:14px;cursor:pointer;text-align:center;line-height:25px;color:white;float:left;background:#29abe2;border:1px #29abe2 solid;width:150px;height:25px}.developer-terms-and-conditions #content .cancel{padding:0 20px;font-size:14px;cursor:pointer;text-align:center;line-height:25px;color:#29abe2;float:left;background:white;border:1px #29abe2 solid;width:115px;height:25px}.developer-terms-and-conditions #content .legal-form .fields{margin-top:5px;line-height:25px;float:left;color:#4d4d4d}.developer-terms-and-conditions #legal-agree{float:left}.developer-terms-and-conditions #content .legal-form .label{display:block;float:left;margin-left:8px;background-color:transparent;color:red;font-weight:normal}.developer-terms-and-conditions #content .legal-form .separator{height:25px;width:1px;border-left:1px solid #a6a6a6;margin:0 8px;float:left}.wizard-navigation ul li span.status{position:absolute;top:24px;right:0;z-index:105;padding:0!important}.wizard-navigation ul li span.status.ok{background:transparent url(../images/icons/wizard_nav_ok.png) no-repeat left center;width:13px;height:16px}.developer-submit-product #content{color:#29abe2;width:1080px;padding-bottom:30px;padding-left:80px}.developer-submit-product label{cursor:default;margin:0;display:inline-block}.developer-submit-product #paymentgateway-settings label{display:block}.developer-submit-product .templates{display:none}.developer-submit-product #content h3.wizard-init{text-align:center;margin-top:190px}.developer-submit-product #content h2{color:#29abe2;margin:15px 0 5px;font-size:18px;float:left;font-weight:normal}.developer-submit-product #content .wizard-navigation{overflow:hidden;width:1080px;position:relative}.developer-submit-product #content .wizard-navigation ul{margin:20px 0 0 0;padding:0;height:27px;float:right;list-style:none}.developer-submit-product #content .wizard-navigation ul li{margin:0;padding:0;list-style:none;cursor:default;visibility:collapse;width:0;float:right}.developer-submit-product .topEmphasis{font-family:Arial;font-size:15px;color:#29abe2;font-weight:bold;margin-bottom:10px}.developer-submit-product #promptFlash,.developer-submit-product #promptFlash a,.developer-submit-product #promptFlash a:hover,.developer-submit-product #promptFlash a:active,.developer-submit-product #promptFlash a:visited{font-family:Arial;font-size:11px;color:#4675a8;font-weight:bold;margin-bottom:5px}.developer-submit-product #content .wizard-navigation ul li span{display:block;padding:5px 20px 5px 0;line-height:17px;font-size:14px;font-weight:normal}.developer-submit-product #content .wizard-navigation ul li.active{visibility:visible;width:auto}.developer-submit-product #content .wizard-side{border-top:1px solid #bfbfbf;border-bottom:1px solid #bfbfbf;border-left:1px solid #bfbfbf;width:152px;background-color:#4d4d4c;height:508px;float:left;color:white}.developer-submit-product #content .wizard-side li.add{display:none}.developer-submit-product #content .wizard-side p{padding:0 8px;margin:0;color:#b2b2b2;font-size:10px}.developer-submit-product #content .wizard-side h4{color:white;padding-left:12px;border-bottom:1px solid #333;margin:0;font-weight:bold;font-size:12px;line-height:27px}.developer-submit-product #content .wizard-side h5{color:white;padding:2px 0 2px 22px;margin:0;font-weight:normal;font-size:10px;line-height:13px}.developer-submit-product #content .wizard-side h5.add-language{background:transparent url(../images/icons/add_remove_language.png) no-repeat -400px center}.developer-submit-product #content .wizard-side h5.remove-language{background:transparent url(../images/icons/add_remove_language.png) no-repeat 0 center}.developer-submit-product #content .wizard-side ul{margin:0;padding:0}.developer-submit-product #content .wizard-side ul li{color:white;margin:0;padding:8px}.developer-submit-product #content .wizard-side ul li.selected{color:#fff;font-size:12px;background:#496b9b url(../images/icons/selected_language.png) no-repeat right center;border-bottom:1px solid #333}.developer-submit-product #content .wizard-side ul li.remove,.developer-submit-product #content .wizard-side ul li.template{display:none}.developer-submit-product #content .wizard-side .wizard-progress{height:20px;line-height:20px}.developer-submit-product #content .wizard-side .wizard-progress .progress-bar{width:75px;height:6px;padding:2px;background-color:#b7b7b7;float:left;margin-top:8px;-moz-border-radius:4px;-webkit-border-radius:4px;border-radius:4px}.developer-submit-product #content .wizard-side .wizard-progress .progress-bar .bar{display:block;height:6px;width:0;background-color:#666;-moz-border-radius:4px;-webkit-border-radius:4px;border-radius:4px}.developer-submit-product #VersionListDiv{float:left;padding-bottom:5px;width:100%}.developer-submit-product #content .wizard-side .wizard-progress .progress-bar .bar.red{background-image:-webkit-linear-gradient(bottom,#c0262c 0,#ec1b23 50%,#c0262c 100%);background-image:-moz-linear-gradient(bottom,#c0262c 0,#ec1b23 50%,#c0262c 100%);background-image:-ms-linear-gradient(bottom,#c0262c 0,#ec1b23 50%,#c0262c 100%);background-image:linear-gradient(bottom,#c0262c 0,#ec1b23 50%,#c0262c 100%)}.developer-submit-product #content .wizard-side .wizard-progress .progress-bar .bar.orange{background-image:-webkit-linear-gradient(bottom,#f6721d 0,#f3a22b 50%,#f6721d 100%);background-image:-moz-linear-gradient(bottom,#f6721d 0,#f3a22b 50%,#f6721d 100%);background-image:-ms-linear-gradient(bottom,#f6721d 0,#f3a22b 50%,#f6721d 100%);background-image:linear-gradient(bottom,#f6721d 0,#f3a22b 50%,#f6721d 100%)}.developer-submit-product #content .wizard-side .wizard-progress .progress-bar .bar.green{background-image:-webkit-linear-gradient(bottom,#38b448 0,#8ac53e 50%,#38b448 100%);background-image:-moz-linear-gradient(bottom,#38b448 0,#8ac53e 50%,#38b448 100%);background-image:-ms-linear-gradient(bottom,#38b448 0,#8ac53e 50%,#38b448 100%);background-image:linear-gradient(bottom,#38b448 0,#8ac53e 50%,#38b448 100%)}.developer-submit-product #content .wizard-side .wizard-progress .progress-percentage{float:left;padding:3px 0 0 7px}.developer-submit-product #content .wizard-side .wizard-progress .progress-help{background:url(../images/icons/help.png) no-repeat 0 0;width:16px;height:16px;float:left;margin:5px 0 0 9px}.developer-submit-product #content .wizard-content{border:1px solid #ccc;overflow-y:auto;overflow-x:hidden;width:1040px;padding:0 20px 10px 20px;float:left;background-color:#fff;position:relative}.developer-submit-product .wizard-content input[type="text"],.developer-submit-product .wizard-content textarea{-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.developer-submit-product #content .wizard-actions{margin-top:15px;float:left;width:1080px}.developer-submit-product #content .wizard-actions input[type="button"],.developer-submit-product #content .wizard-actions a{width:auto;padding:0 20px;border:0;font-size:14px;cursor:pointer;height:25px;text-align:center;line-height:25px;color:white}.developer-submit-product #content .wizard-actions .cancel{float:left;color:#29abe2;background:white;border:1px #29abe2 solid;width:150px;height:25px}.developer-submit-product #content .wizard-actions .back{float:left;display:none}.developer-submit-product #content .wizard-actions .save{float:right;width:150px;height:25px}.developer-submit-product #content .wizard-actions .continue{float:right;margin-left:8px;width:150px;height:25px}.developer-submit-product #content .wizard-actions .backtosummary,.developer-submit-product #content .wizard-actions .submit,.developer-submit-product #content .wizard-actions .preview{float:right;display:none;margin-left:8px}.developer-submit-product #content .finish-link{width:auto;padding:0 20px;border:0;font-size:14px;cursor:pointer;height:25px;text-align:center;line-height:25px;color:white}.remindErrorDiv{margin-bottom:10px}.remindErrorDiv .errorRemind a{font-size:13px;font-weight:bold;color:red;padding-bottom:5px;text-decoration:underline}#publish-step2-products .compatibility-des-sep{margin:0}#publish-step2-products .compatibility-des{width:790px}#publish-step2-products .families-products td:first-child{width:200px}#publish-step2-products table.version-grid{width:100%}.fancy-layer-image{content:url(../images/icons/ajax-loader400.gif);width:30px}#fancy-layer{height:100px}#fancy-layer.overlay_window{background:white}.wizard-tab{font-size:12px;position:relative}.no_float{float:none!important}.wizard-tab h4{float:left;margin-bottom:5px}#wizard-help-documentation h4{float:left}#wizard-help-documentation>span.explanation{margin:0}.wizard-tab h4+span.explanation{margin-bottom:5px}.wizard-tab #contact-info+span.explanation{display:inline-block}.wizard-tab span.required{display:inline;color:Red;font-weight:bold}.wizard-tab .explanation{display:inline-block;color:#666;font-weight:normal;font-size:11px}.command_tools .explanation{display:block;color:#666;font-weight:normal;font-size:11px}.command_tools .commandName{width:400px}.command_tools .sub-title{display:block}.command_tools textarea{width:400px}.thumbnail-preview .browse-button{float:left;margin-right:5px;font-size:12px;height:25px;width:150px}.file-info .explanation{display:inline-block;color:#666;font-weight:normal;font-size:11px}#privacyDetail{font-size:15px}#privacyDetail ul{padding:0;margin-left:4px}#privacyDetail li{margin:8px;list-style:none}#publish-step2-products .explanation,#publish-step2-categories .explanation{float:left;display:inline;width:790px}.wizard-tab span.error,#contact-info span.error{display:none;margin:2px 27px 2px 15px;color:#c80000;font-size:11px;background:transparent url(../images/icons/wizard_error.png) no-repeat left center;padding-left:14px}#contact-info span.error{float:none;margin-right:2px;margin-top:4px}.wizard-tab .text span.error{margin:2px 0 2px 0;float:none}#contact-info span.error.visible,.wizard-tab span.error.visible{display:inline}.wizard-tab .separator{display:block;height:10px}#publish-step2-products .separator,#publish-step2-categories .separator{display:inline-block;width:790px;height:20px}.wizard-tab textarea,.wizard-tab input[type="text"]{width:100%;margin-bottom:1px;border:1px solid #bbb;padding:2px;display:block}.wizard-tab .command_tools textarea,.wizard-tab .command_tools input[type="text"]{width:772px}.wizard-tab textarea.error,.wizard-tab input[type="text"].error{border:1px solid #c80000}.wizard-tab textarea{resize:none}#wizard-help-documentation textarea{display:inline}.wizard-tab input[type="radio"]{display:inline}.wizard-tab input[type="checkbox"]{display:inline;margin-right:10px}.wizard-tab #prices label{margin:10px 0;cursor:pointer}.wizard-tab h5{font-weight:normal;margin:0}#app-file>*:not(label){margin-left:0;width:auto}#app-file>textarea{width:97%;margin-top:5px}#app-file>label{font-size:12px}#app-file>label>input{position:relative;top:1px;margin-right:4px}.wizard-tab h4+.file-uploader{margin-top:10px}.wizard-tab .file-uploader .file{width:auto;padding:4px 4px 4px 0;background-color:white;min-height:25px;margin:5px 0}.wizard-tab .file-uploader .file .plupload input{cursor:pointer}.wizard-tab .file-uploader .file .plupload input[disabled]{display:none}.wizard-tab .file-uploader .file .file-info .thumbnail{float:left}.wizard-tab .file-uploader .file .file-info .file-name,.wizard-tab .file-uploader .file .file-info .file-size{float:left;padding:6px 10px 4px}.wizard-tab .file-uploader .file[data-uploader-state="uploading"] .file-info .file-name{max-width:135px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.wizard-tab #app-screenshot.file-uploader .file[data-uploader-state="uploading"],.wizard-tab #app-screenshot.file-uploader .file[data-uploader-state="queuedOnHold"],.wizard-tab #app-screenshot.file-uploader .file[data-uploader-state="uploadedOnHold"],.wizard-tab #app-screenshot.file-uploader .file[data-uploader-state="queued"]{min-height:75px}.wizard-tab .file-uploader .file .file-info .upload-progress{width:280px;height:20px;line-height:20px;position:absolute;right:115px}.wizard-tab .file-uploader .file .file-info .progress-bar{width:230px;height:6px;padding:2px;background-color:white;float:left;margin-top:8px;-moz-border-radius:4px;-webkit-border-radius:4px;border-radius:4px}.wizard-tab .file-uploader .file .file-info .progress-bar .bar{display:block;height:6px;width:0;min-width:1%;background-color:white;background-image:-webkit-linear-gradient(bottom,#29abe2 0,#6ac6ed 50%,#29abe2 100%);background-image:-moz-linear-gradient(bottom,#29abe2 0,#6ac6ed 50%,#29abe2 100%);background-image:-ms-linear-gradient(bottom,#29abe2 0,#6ac6ed 50%,#29abe2 100%);background-image:linear-gradient(bottom,#29abe2 0,#6ac6ed 50%,#29abe2 100%);-moz-border-radius:4px;-webkit-border-radius:4px;border-radius:4px}.wizard-tab .file-uploader .file .file-info .progress-percentage{float:left;padding:3px 0 0 10px}.wizard-tab .upload-button,.wizard-tab .cancel-button,.wizard-tab .remove-button{float:right;width:100px}.wizard-tab .browse-button{float:left;margin-right:5px;font-size:12px;height:25px;width:150px}.wizard-tab .uploader-loading .browse-button{visibility:hidden}#app-screenshot .thumbnail{width:205px;min-height:120px;display:none}.screenshot_tools{position:absolute;right:5px;top:40px;left:219px;bottom:5px}.screenshot_tools .description_container{position:absolute;left:0;right:0}.screenshot_tools input[type="checkbox"]{float:left;margin-right:5px;padding:0}.screenshot_tools .description_container .description{width:519px;margin:0}#wizard-help-documentation .cert-span{margin-top:3px;display:block;float:none;margin-left:0}#wizard-help-documentation .cert-span .cert-explanation{margin-left:23px}#wizard-help-documentation .cert-image{margin-bottom:5px}#wizard-help-documentation h4+span.cert-explanation{margin-top:0;margin-bottom:8px}#wizard-help-documentation .cert-explanation a,#wizard-help-documentation .cert-explanation a:link,#wizard-help-documentation .cert-explanation a:hover,#wizard-help-documentation .cert-explanation a:active,#wizard-help-documentation .cert-explanation a:visited{color:#29abe2}#wizard-file-uploading .errors,wizard-help-documentation .errors{position:relative;float:right}#publish-step2-companyandprice #prices,#publish-step2-companyandprice #applogintypes{display:block;margin:5px 0 5px}#publish-step2-companyandprice input.priceinput{width:150px;display:inline}#wizard-app-information #app-versions{width:100%}#wizard-app-information #app-versions .version .remove,#wizard-help-documentation #app-commands .command .remove-command{background:url(../images/buttons/close_24.png) no-repeat 0 0;width:24px;height:24px;top:-7px;position:absolute;right:-12px;cursor:pointer}#version-changed-input .mceEditor{margin-bottom:10px}#wizard-help-documentation #app-commands .command .remove-command.with_spinner{background:0}.file-info{position:relative}.file-info .remove-button+.with_spinner{display:inline-block;right:5px;position:absolute;top:5px}#wizard-app-information #app-versions .version.template,#wizard-help-documentation #app-commands .template{display:none;position:relative}#wizard-app-information #app-versions .version{margin-top:10px}#wizard-app-information #app-versions .version .number input{width:120px;margin-top:5px}#wizard-app-information #app-versions .version .description textarea{width:560px;margin-top:5px}#wizard-app-information #app-versions .version .number{width:145px;float:left}#wizard-app-information #app-versions .description{float:left;width:100%}#wizard-app-information .new-version{width:auto;margin-top:6px;cursor:pointer;text-align:center}#wizard-app-information #app-versions .version .remove{background:url(../images/buttons/close_24.png) no-repeat 0 0;width:24px;height:24px;top:-7px;position:absolute;right:-12px;cursor:pointer}#wizard-app-information #app-versions .version.template{display:none;position:relative}#publish-step2-companyandprice #payment-settings{display:none}#publish-step2-companyandprice{margin-bottom:14px}#wizard-file-uploading .add-screenshot-container{margin-top:6px}#wizard-file-uploading .add-screenshot-container>*{vertical-align:middle;margin-bottom:10px}.wizard-app-compatibility input[type="checkbox"]{margin:0 5px 0 5px;position:relative;top:2px}table.expandable-grid tr.title{background-color:#e5e5e5;border-bottom:1px solid #797979}table.expandable-grid tr.title td{padding-left:10px;font-size:13px;font-weight:bold;height:30px;line-height:30px}table.expandable-grid tr.expansor{border-bottom:0 solid #797979}table.expandable-grid tr.expansor.expanded{border-bottom:0}table.expandable-grid tr.expandable{border-bottom:0 solid #797979}table.expandable-grid{margin-top:5px;float:left;width:100%;border:0 solid #797979;border-collapse:collapse}table.expandable-grid tr{width:100%;border-collapse:collapse}table.version-grid{width:100%;margin:5px 0 10px 0}table.version-grid tr{border:1px #29abe2 solid}table.version-grid thead .store-version{width:80px}table.expandable-grid tr.expansor td{height:20px;cursor:pointer}table.expandable-grid tr.expansor td span{font-size:13px}table.expandable-grid tr.expansor.expanded td span div.arrow{background:url(../images/icons/expand-collapse-sprite.png) no-repeat top right}table.expandable-grid tr.expansor td span div.arrow{background:url(../images/icons/expand-collapse-sprite.png) no-repeat top left;margin:0 5px 0 5px;width:13px;height:13px;display:inline-block}#wizard-app-categories #app-families,#wizard-app-categories #store-list{margin:8px 0 8px}#wizard-app-categories #store-list{width:755px}#wizard-app-categories #store-list .store-title{width:200px}#wizard-app-categories .families-products .store-title.disabled{color:#b1b1b1}#publish-step2-categories .families-products td.label{color:black;background:transparent;text-shadow:none}#publish-step2-categories table.version-grid{margin-top:2px}#wizard-app-categories #store-list .store-version{width:100px}#wizard-app-categories #store-list tbody tr:nth-child(even){background-color:#e8e8e8}#wizard-app-categories #recommend{margin-top:10px;background-color:#e8e8e8;padding:5px}#wizard-app-categories .othercategory-container{display:inline-block;margin-top:20px}#wizard-help-documentation #app-commands{width:100%}#wizard-help-documentation #app-commands .command{margin-top:10px;padding:5px;position:relative}#wizard-help-documentation #app-commands .command h3{margin:0;font-weight:normal}#wizard-help-documentation #app-commands .command .file{width:717px}#wizard-help-documentation #app-commands .command .save-command{right:7px;bottom:7px}#wizard-help-documentation .new-command{width:150px;margin-top:5px;cursor:pointer;height:25px;text-align:center;line-height:25px;font-size:12px;display:block}#wizard-help-documentation .mceEditor{margin-top:5px;display:block}#wizard-app-summary .info{min-height:20px;padding:2px 5px;line-height:20px}#wizard-app-summary .info:nth-child(even){background-color:#e8e8e8}#wizard-app-summary .info .description{float:left;width:210px;font-weight:normal;color:#666}#wizard-app-summary .info>*{display:inline-block;margin-left:10px;color:black}#wizard-app-summary .info .value p{margin:0}#wizard-app-summary .summary-icon{width:80px;height:80px}#wizard-app-summary .summary-screenshot{border:1px #29abe2 solid;width:200px;height:120px}#wizard-app-summary .summary-screenshot img{height:120px}.developer-submit-complete #content{width:940px}.developer-submit-complete #content h1,.developer-submit-complete #content h2{color:#4d4d4d}#footer{border-top:1px solid #c4c4c4;height:38px;line-height:38px;background-color:#f3f3f3;font-size:11px;color:#999}.footer_wrap{margin:0 auto;height:38px;line-height:38px;background:url(../images/icons/adsk_footer_logo.png) no-repeat right center}.footer_wrap .copy{line-height:38px;height:38px;float:left;color:#949494}.copy p{margin:0;padding:0}.footer_wrap .legalese{float:left;list-style-type:none;margin:0;padding:0;height:38px;line-height:38px;padding:0}.footer_wrap .btn-group button{font-size:12px}.footer_wrap .btn-group .dropdown-menu{top:auto;bottom:100%;min-width:80px}.footer_wrap .btn-group .dropdown-menu li{font-size:12px;padding-left:6px}.footer_wrap .btn-group .dropdown-menu li:hover{color:white;background-color:#0081c2}.legalese li{list-style-type:none;margin-left:12px;float:left;cursor:pointer;line-height:38px}.legalese li a{color:#999}.legalese li a:hover,.legalese li:hover{color:#666}.contact_us{font-size:104%;font-weight:bold!important;color:#666}.paynow_button form input[type="submit"]{background:none repeat scroll 0 0 transparent;border:0 none;color:#fff;margin:0;padding:0}#supported_languages{width:400px}#supported_languages ul{padding:0;margin:0}#supported_languages ul li{color:#000;padding-left:25px;line-height:23px;cursor:pointer}.odd{background-color:#fff}.even{background-color:#f2f2f2}#supported_languages ul li:hover{background-color:#dae2ef}#supported_languages ul li.selected{background-color:#8899b4;color:#fff}#accept_terms_section{font-size:12px;width:780px}#accept_terms_section label{display:inline}#accept_terms_section .group_body_container{margin:20px}#accept_terms_section .group_body_container input[type="checkbox"]{margin-right:10px}#accept_terms_section .group_body_container>div{margin-bottom:20px}#accept_terms_section .group_body_container a{color:#039}#accept_terms_section .group_body_container p.legal{font-size:10px;font-style:italic;margin-left:27px}#accept_terms_section .group_body_container .receiveEmail label{display:inline-block;margin-left:23px}#accept_terms_section .group_body_container .receiveEmail input{position:absolute}.input_text_readonly{background-color:#f4f4f4;color:#555}#accept_terms_section .alert{color:red;margin-left:13px}#confirmationPopup button[data-type="Cancel"]{margin-right:6px}#confirmationPopup button{min-width:35px}#wizard-app-categories .families-products td.categorycheck input[type=checkbox]{margin-left:0}#wizard-app-categories .families-products td.label{width:210px}#wizard-app-products .selectAll{font-size:10px}#wizard-app-products .version-grid td label{font-size:12px;white-space:normal;display:inline-block}.faq-page h1{font-size:15pt;margin:15px 0;text-align:center}.faq-page .leftalig-headline{text-align:left}.faq-page h3{font-size:11pt}.faq-page p{margin:0 0 15px}.faq-page ul{margin:0 0 15px;padding:0;list-style:square inside none}.faq-page ul li{list-style:square inside none;margin-top:10px;margin-bottom:3px;margin-left:20px}.faq-page .numbered-ul li{list-style-type:decimal}.faq-page .circled-ul li{list-style-type:disc}.faq-page .empty-circled-ul li{list-style-type:circle}.faq-page ul li img{margin-top:5px}.faq-page .faq_notediv{margin-top:5px;margin-bottom:5px;border-bottom:1px solid #5b9bd5;border-top:1px solid #5b9bd5;color:#5b9bd5;padding:5px}.faq-page .cancel_subscription ol,.faq-page .cancel_subscription ol li{list-style:decimal!important}.faq-page .cancel_subscription ul,.faq-page .cancel_subscription ul li{list-style:disc!important}.faq-page .cancel_subscription ul{padding-left:40px!important}#back-to-top,#back-to-top:visited{margin:7px 0 7px 0;text-align:center;float:left;color:#369}.strikeout-price{text-decoration:line-through;vertical-align:middle;font-size:10px;color:#808080;padding:0;margin-right:15px;display:inline;clear:both}.product-badge-div-placeholder{margin:1px 0 1px 0;height:16px}#detail-info span.subscriptionDes{vertical-align:middle;font-size:12px;float:right}.subscriptionBadge{float:none;position:relative;width:16px;height:16px;margin:0}.big-subscriptionbadge{width:24px;height:24px}.badge-popup-div{position:absolute;display:none;left:-82px;width:180px;font-size:10px;overflow:hidden;z-index:9999;text-align:center}.subscriber-pop-up{left:0;top:10px}.big-badge-popup-offset{left:-78px}.badge-popup-content-div{border-style:solid;border-width:0 1px 1px 1px;border-color:#6d6e70;background-color:white;margin:0;padding:10px}.badge-popup-content-div p{margin:0;padding:0;color:#000}.badge-popup-content-div a{color:blue}.badge-popup-header-div{height:0;margin:0;padding:0}.badge-popup-div img.badge-popup-header-img{float:none;height:10px;width:180px;margin:0}.badge-hover-stub:hover .badge-popup-div{display:block}.subscriber-hover-stub,.badge-hover-stub{position:relative}.product-rating-small-bestseller .star-rating{width:13px;height:12px;cursor:default;display:inline-block;background:url(../images/icons/star_small.png) no-repeat 0 0;overflow:hidden;vertical-align:middle;margin:0 0 4px 2px}.product-rating-small-bestseller .star-on{background-position:0 -12px!important}.product-rating-small-bestseller .star-off{background-position:0 0!important}.ellipsis{width:120px;overflow:hidden;text-overflow:ellipsis;-o-text-overflow:ellipsis;-ms-text-overflow:ellipsis;white-space:nowrap;display:inline-block}#restrict_access_wrapper h2{color:#000;font-size:20px;font-weight:normal}#restrict_access_wrapper h3{font-weight:normal;color:#666;font-size:14px;margin:0 0 15px 0}#restrict_access_wrapper label{font-weight:bold}#restrict_access_wrapper #no_passcode_label li{padding-bottom:20px}#restrict_access_wrapper #no_passcode_controls li{padding-bottom:10px}#restrict_access_wrapper .ui-button{width:70px}#restrict_access_wrapper .text-box{width:200px}#restrict_access_wrapper .multi-line{width:400px;height:100px}#restrict_access_wrapper{margin:10px auto;width:900px;padding:10px}#restrict_access_wrapper #left_panel{float:left;width:80px;margin:10px;padding:10px}#restrict_access_wrapper #right_panel{float:left;width:650px;margin:10px;padding:10px}#restrict_access_wrapper #passcode_label{float:left;width:100px;padding:5px;text-align:right;margin-top:5px}#restrict_access_wrapper #passcode_controls{float:left;width:200px;padding:5px}#restrict_access_wrapper #passcode_submit{position:relative;left:115px;top:5px;clear:both}#restrict_access_wrapper #divider{border-top:1px solid #666;margin:20px 0}#restrict_access_wrapper #no_passcode_label{float:left;width:100px;padding:5px;text-align:right;margin-top:5px}#restrict_access_wrapper #no_passcode_controls{float:left;width:200px;padding:5px}#restrict_access_wrapper #no_passcode_submit{position:relative;left:115px;top:5px;clear:both}#restrict_access_wrapper .validation-summary-errors{position:relative;clear:both;left:115px}#restrict_access_wrapper #passcode_description{margin-bottom:0}#restrict_access_wrapper a:link,#restrict_access_wrapper a:visited,#restrict_access_wrapper a:hover{color:#1a52ad}#HealthStatus table{margin:10px 0 20px 0;text-align:left;font-size:11px;width:700px}#HealthStatus table td,#HealthStatus table thead th{padding:5px;vertical-align:middle;text-align:left}div.developer-submit-product span.profile-notice{float:left;color:#666}#app-detail-for-publisher #icon{float:left}#app-detail-for-publisher #detail-info div.title-rating span{float:right;padding-top:2px}#app-detail-for-publisher #detail-info div.description{margin-top:10px}option.disabled{background-color:lightgray}#language-selector-title{color:#29abe2;font-weight:normal;font-family:Arial;font-size:18px;margin-top:20px}#language-os-selector-info{float:left;border:1px #a8a8a8 solid;border-radius:4px;padding:20px 20px 10px 20px;margin:5px 10px 30px 0;background:white}#os-selector-info{float:none}#language-os-selector-desc{clear:both;padding-top:15px;font-size:11px;color:#999;font-family:Arial}#detail .language-os-select,#language-os-selector-info .language-os-select{width:130px;height:28px;padding-left:8px;border:1px solid #666;border-radius:2px;margin-right:10px}#language-os-selector-info .language-selector-group .language-selector-title,#os-selector-info .os-selector-title{margin-right:10px;color:#29abe2;font-family:Arial;font-size:20px}#language-os-selector-info .language-selector-group{float:left}#detail .language-os-select option,#language-os-selector-info .language-os-select option{line-height:20px;color:#000;font-family:Arial!important;font-size:12px!important}#language-os-selector-info separator span{color:#666;font-weight:normal;font-family:Arial;font-size:11px}.language-selector-cancelButton{height:31px;width:100px;float:left;font-weight:normal;font-family:Arial;font-size:14px}.language-selector-continueButton{height:31px;width:100px;float:right;margin-right:10px;color:#fff;font-weight:normal;font-family:Arial;font-size:14px}#action-wrapper .flat-button,#app-detail-for-publisher{width:230px;float:left;margin-bottom:13px}#action-wrapper span#action-link{margin-left:10px}#my-published .product-info{width:150px;float:left}#my-published .info-cell>div{display:inline-block}#my-published .image-info{width:58px;height:58px;float:left;margin-right:6px}#my-published .product-info a.details_link{width:150px}#my-published .product-info div.details_div{height:16px}#my-published a.publish-link{display:block;width:160px;height:31px}#apps-description{margin:2px 0 2px 0}.product-info .details_dropdownul{margin-top:0;padding:0}.product-info .details_dropdownul .drop_down{padding-top:5px}.product-info .details_dropdownul .live_version_info,.product-info .details_dropdownul .preview_version_info{cursor:default;padding-right:10px;background:url(../images/buttons/btn_popup_sort.png) no-repeat right 7px}#my-published #published-products td.language-cell div.live_version_info,#my-published #published-products td.language-cell div.preview_version_info{height:40px;overflow:hidden}#my-published .has_preview_version .live_version_info{display:none}.keyword-font{font-weight:bold;font-size:13px;color:#000}.normal-font{font-size:13px;color:#595959;word-wrap:break-word}.link-font{font-family:Arial;font-size:12px;color:#4675a8}.cash-font{font-family:Arial;font-size:16px;color:#000}.submit-font{font-family:Arial;font-size:12px;color:#fff}.description-font{font-family:Arial;font-size:11px;color:#666}.learn-more-font{font-family:Arial;font-size:11px;color:#4675a8;margin-bottom:7px}.detail-page #detail .gotoUrl,.detail-page #detail #detailosselector{height:28px;width:130px;border-color:#a8a8a8;border-radius:2px;background:linear-gradient(#f9f9f9,#d5d5d5);color:#000;font-weight:normal;font-family:Arial;font-size:12px}#store-management{width:900px;margin:0 auto;min-height:1200px}#store-management h3,#store-management .show-top-title{float:left}#store-management h1{margin:33px 0 25px}#store-management h3,#store-management .show-top-title{display:inline;line-height:30px}@media only screen and (max-width:780px){#store-management{margin:5%;width:90%}}#store-management .section{margin:20px 0}#store-management #selection.section{height:50px}#store-management .section .resp-content-div ul.sortable{margin-top:40px}#horizontalTab .resp-tabs-container{margin:0 7px 15px 0}#horizontalTab .settings-button{float:right;margin:5px 10px 5px 10px}#storeActions input{margin:5px}#store-management .special-group-widget-img{float:left;margin-right:7px}.selection-div{display:inline;margin-right:10px}.selection-div *{font-size:12px}.selection-div select{width:130px}#languageSelection{margin-left:10px}#store-management ul{list-style-type:none;margin:0;padding:0;margin-bottom:10px}#store-management .sortable li{float:left;width:180px;height:100px;margin:10px 10px;background:#ddd;border:1px solid lightgray;padding:1px;border-radius:5px}#store-management .sortable li:hover{border:1px solid #2a6496}#store-management li#draggable{float:left}#store-management .store-apps-container .sortable{width:650px;min-height:900px}#store-management .store-apps-container .sortable img{width:80px;height:80px;float:left}#store-management div.product-info{float:left;width:98px;position:relative;top:-20px;padding-left:2px}#store-management .publisher-name{display:block;overflow:hidden;width:98px;height:15px;font-weight:bold}#store-management #visible-settings{display:inline;font-weight:bold;font-size:14px;margin-left:10px}#store-management #select-app{display:inline;font-weight:bold;font-size:14px}#store-management #select-app{float:right;margin-right:80px}#store-management #select-app input{display:block;float:right}#store-management #select-app span{display:block}#store-management .button{width:auto;border:0;font-size:14px;cursor:pointer;height:24px;text-align:center;color:white}#store-management .store-action-input{width:70px}#store-management #store-reset-input{width:auto}#store-management span.add-app-hint-hidden{visibility:hidden;text-align:center}#store-management span.add-app-hint-visible{visibility:visible;text-align:center}#store-management .app-name{overflow:hidden;width:98px;height:62px;line-height:16px;word-wrap:break-word}.resp-vtabs .resp-tabs-list li span,.resp-vtabs .resp-tabs-list .input_widget_title{float:left;max-width:172px;width:172px}.resp-vtabs .resp-tabs-list .input_widget_title{display:none}#store-images .file{background:lightgray;margin-bottom:10px;height:205px;width:900px}#store-images .thumbnail,#store-images .thumbnail img{max-width:400px;max-height:165px}#store-images .storeimage_tools{position:absolute;top:5px;left:415px}#store-images .storeimage_tools label{margin-bottom:0}#store-images .storeimage_tools input{margin-bottom:2px;width:450px}#store-images .storeimage_tools textarea{margin-bottom:2px;width:450px}.fancy-chosen-tr,.fancy-chosen-tr span{color:red!important}.fancy-remove-app{visibility:hidden;position:relative;top:-10px;left:-10px;width:24px;height:24px;z-index:1;background-image:url(../images/buttons/close_24.png);cursor:pointer}.remove-widget{float:left;width:15px;height:15px;background:url(../images/buttons/widgetgroup_buttons.png) no-repeat -15px 0;cursor:pointer}.wg_edit-hidden,.wg_edit-widget,.eg-edit-widget{visibility:hidden;float:left;width:15px;height:15px;background:url(../images/buttons/widgetgroup_buttons.png) no-repeat 0 0;cursor:pointer;margin-right:5px;margin-left:5px}.wg_edit-accept,.eg-edit-accept{display:none;float:left;width:15px;height:15px;background:url(../images/buttons/widgetgroup_buttons.png) no-repeat -30px 0;cursor:pointer;margin-right:5px;margin-left:5px}.eg-edit-widget,.eg-edit-accept{float:right}.eg-name-input{width:140px;float:left;margin-bottom:0}#search-fancy-iframe{width:1300px;height:800px}#search-fancy-iframe thead{text-align:left;font-size:13px;border:1px solid #797979;background:gray;color:white}#search-fancy-iframe table td{border:1px solid #797979;padding:8px;vertical-align:middle}.fancy-search-main{height:760px;overflow-y:scroll}#result-list-div thead{text-align:left;font-size:13px;color:white;background:#999}#result-list-div th{height:25px;border:1px gray solid}#result-list-div td{border:1px gray solid;height:45px;vertical-align:middle}#result-list-div th:hover{background:#575757}#result-list-div .row-odd{background:#ededed}#result-list-div{width:100%}.fancy-compatibility{float:left;width:190px}.fancy-compatibility-visible{display:inline}.fancy-compatibility-hidden{display:none}.fancy-show-option,span.fancy-show-option{width:180px;float:left;cursor:pointer;color:#4675a8!important}.copy-settings{margin:10px 0}#copy-settings-info{color:red}#copy-settings-title{font-weight:bold}.fancy-copy-tabs{margin-right:5px}#copy-settings-tabs-title{font-weight:bold}.container-with-fixed-footer{margin-bottom:39px}#analytics-report{width:1370px;position:relative}#analytics-report #myTab>li>a{color:black}#analytics-report #selection .selection-div>h3{line-height:38px;color:#333;font-size:14px;font-weight:bold;margin-right:10px}#analytics-report #selection #languageSelection .dropdown{width:100px}#analytics-report #selection .selection-div>h3,#analytics-report #selection .selection-div>div{float:left}#analytics-report #selection .radio-wrapper{float:right}#analytics-report #selection #go{float:right;margin-left:20px;height:38px}#analytics-report #selection .recent-wrapper{float:left}#analytics-report #selection .radio-wrapper input[type="radio"]{float:left;margin-top:14px;margin-right:5px}#analytics-report #selection .radio-wrapper>span,#analytics-report #selection .radio-wrapper .recent-wrapper>span{line-height:40px;font-size:14px;color:#333;float:left;margin-right:5px}#analytics-report #selection .or{float:right;font-size:14px;font-weight:bold;line-height:40px;margin:0 10px}#analytics-report #selection .recent-wrapper .dropdown,#analytics-report #selection .recent-wrapper h3{float:left}#analytics-report #selection .recent-wrapper h3{line-height:38px;font-size:14px;color:#333;font-weight:normal}#analytics-report #selection .selection-div{float:left}#analytics-report #selection .input-daterange{float:left}#analytics-report #selection .input-daterange .input-sm{height:30px;margin-bottom:0;width:100px}#analytics-report #selection .input-daterange .input-group-addon{padding:11px 5px;margin-left:-4px}#analytics-report .nav-tabs>li{width:25%;text-align:center}#analytics-report .nav-tabs{padding:0}#analytics-report #info-box{position:absolute;right:0;top:-50px;background-color:#d9edf7;font-size:14px;line-height:30px;width:500px;text-align:center;display:none}#analytics-report .chart_act{cursor:pointer}#analytics-report #Statistics{min-height:1000px}#analytics-report .statistics-chart-div{float:left;margin-right:12px;margin-top:12px;display:flex;display:-moz-flex;display:-ms-flex;display:-webkit-flex}#analytics-report .statistics-detail{margin-top:50px;min-height:500px}#analytics-report .statistics-detail-header .detail-header-wrapper{float:left}#analytics-report .statistics-detail-header #goLineChart{margin-left:30px}#analytics-report .statistics-detail-header #granularity-span{margin-left:30px}#analytics-report .statistics-detail-body{padding:10px}#analytics-report .statistics-detail-body .pie-chart{display:block;height:400px;width:650px;float:left;margin:0 5px}#analytics-report .statistics-detail-body .pie-chart-content{position:relative;padding:0;width:100%;height:100%}#analytics-report .statistics-detail-body #line-chart-placeholder{height:400px}#analytics-report .nav-tabs{margin-top:25px}#analytics-report .nav-tabs li{text-align:center;width:200px}#analytics-report .nav-tabs .active{font-weight:bold}#analytics-report .nav-tabs li a,#analytics-report .nav-tabs li a:visited{color:Black}.chart_title{display:-moz-box;display:-webkit-box;display:box;box-pack:center;box-align:center}.chart-title-left .dropdown{height:25px;border:0;background:transparent;width:initial;font-size:13px;font-weight:bold}.chart-title-left .dropdown.focus,.chart-title-left .dropdown:hover{box-shadow:none;border:0}.chart-title-left .dropdown.open>div:last-child{min-width:100px}.chart-title-left .dropdown .selected{margin-left:0}.chart-title-left .dropdown .selected::after{box-shadow:none}.statistics-chart-div .chart_title .chart-title-left{margin-left:0}.chart-title-left .dropdown .carat{right:-12px;top:16px}.title-bar-action{right:0;top:0;position:absolute;margin-right:10px}.title-bar-action a{font-size:12px;font-weight:lighter;color:#468eb2}.analytic_chart_FullWidth,.analytic_chart_FullWidth .chart_title{width:100%}.analytic_chart_Middle,.analytic_chart_Middle .chart_title,.analytic_chart_Large,.analytic_chart_Large .chart_title{width:440px}.analytic_chart_Small,.analytic_chart_Small .chart_title{width:213px}.analytic_chart .chart_act{float:right}.analytic_chart .chart_str{font-size:18px;font-weight:bold}.analytic_chart_Middle .chart_contdiv,.analytic_chart_Small .chart_contdiv{height:109px;padding-top:20px;padding-left:10px;padding-right:10px}.analytic_chart_Large .chart_contdiv{height:281px;padding-top:20px;padding-left:10px;padding-right:10px}.analytic_chart_FullWidth .chart_contdiv{height:290px;padding-top:20px;padding-left:10px;padding-right:10px;background:white}.chart_contdiv>a,.chart_contdiv>a:hover,.chart_contdiv>a:visited{color:#468eb2}.analytic_chart_Middle .chart_cont,.analytic_chart_Small .chart_cont{height:62px;margin-bottom:5px}.analytic_chart_Large .chart_cont,.analytic_chart_FullWidth .chart_cont{height:230px;margin-bottom:5px;margin-left:12px}.analytic_chart .chart_title,.top-50-quickview h2{border-bottom:1px solid #29abe2;height:28px;background:#e6e6e6;color:#468eb2;font-weight:bold;font-size:15px;line-height:28px}.analytic_chart .chart_title span{margin-left:10px}.admin-tool-footer{bottom:0;width:100%}#admin_home_title{margin:50px;font-size:18px;text-align:center}.admin_home_element{margin-bottom:10px}#admin_home_content h2{margin-bottom:20px}#comment-management{width:1600px}#comment-management #selection{float:left}#comment-management #searchBar{float:right}#comment-management .section{width:100%;margin:0 10px}#comment-management{margin-bottom:540px}#comment-management a{color:#1a52ad;text-decoration:none}#comment-management select,#comment-management #query-term{margin-top:10px}#comment-management #checkbox-th{text-align:center}#comment-management .title-comment{float:left;width:400px;height:auto;text-overflow:ellipsis;text-align:left;overflow-y:hidden}#comment-management .title-area{width:400px;height:18px;margin:0;font-weight:bold;text-overflow:ellipsis;overflow:hidden;white-space:nowrap}#comment-management .comment-area{width:400px;word-wrap:break-word}#comment-management .comment-area-more{height:auto}#comment-management .comment-area-hide{overflow:hidden;max-height:40px}#comment-management .appname-area{text-align:left;width:200px;word-wrap:break-word}#comment-management .review-author-area{width:130px;word-wrap:break-word}#comment-management .publisher-area{width:130px;word-wrap:break-word}#comment-management .title-comment-td{height:auto;width:400px;padding:5px;text-align:left}#comment-management #actions{margin-bottom:10px}#comment-management td{text-align:center}#comment-management .description{color:Gray;font-size:12px}#comment-management #number-area{margin-bottom:5px}.hidden-element{visibility:hidden}#comment-management .my-modal-note{width:500px;height:300px}#comment-management .action-td{text-align:left}#comment-management .comments-table{font-size:12px}.comment-mangement-hightlight{background-color:lightcoral}#comment-management .tooltip{border:0;background-color:transparent;background:0;box-shadow:none;-moz-box-shadow:none;-webkit-box-shadow:none}#comment-management .note-textarea{height:40px;width:130px;word-wrap:break-word;text-align:left;overflow:hidden;resize:none;margin-bottom:0;border:0;background-color:transparent;box-shadow:none;cursor:default}#comment-management .note{overflow:hidden;height:40px;line-height:20px}#comment-management .note:before{content:"";float:left;width:5px;height:40px}#comment-management .note>*:first-child{float:right;width:100%;margin-left:-5px}#comment-management .note:after{content:"\02026";float:right;position:relative;top:-25px;left:100%;width:3em;margin-left:-3em;padding-right:5px;text-align:right}#comment-management .note-area{text-align:left}#download-entitlement-management{width:1205px;min-height:800px;margin:0 auto}#download-entitlement-management #base h1{font-size:18px;margin:10px 0}#download-entitlement-management #app-name{margin-bottom:20px}#download-entitlement-management #add-new-entitlement{float:left}#download-entitlement-management #add-new-entitlement input{width:100px}#download-entitlement-management #search-form{float:right}#download-entitlement-management #action-search-wrapper{margin-bottom:20px}#add-download-entitlement-input{width:424px;margin:20px 0 10px 0}#add-download-entitlement-form .error-email{color:red}.entitlement-table .notes .display-block{display:block}.entitlement-table .notes .display-none{display:none}.entitlement-table .notes .notes-edit-button,.entitlement-table .notes .notes-cancel,.entitlement-table .notes .notes-save{float:right}#footerloglink{width:120px;height:38px;float:right}.dropdown{font-size:12px;border-radius:0}.search-brief-component .dropdown{width:65px;float:right}#store-management .dropdown{float:left}.detail-page .dropdown{float:left;width:150px;margin-right:5px;padding:0}.dropdown ul{margin:0;padding:0}.dropdown li.focus{background:#29abe1;color:#fff}.dropdown .carat,.dropdown.open .carat{border-width:5px}.btn-group>.btn:last-child:not(:first-child),.btn-group>.dropdown-toggle:not(:first-child){border-bottom-left-radius:0;border-top-left-radius:0}.btn-group>.btn:first-child:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:2px}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}.drawer{background:#f2f2f2;overflow:hidden}.drawer .drawercontent{border:1px solid #ccc;padding:15px;display:none}.drawer.open .drawercontent{display:block}.drawer .normal-text{font:12px/24px arial,sans-serif;color:#000}.drawer .bold-text{font:bold 15px/24px arial,sans-serif;color:#000}.drawer .description-text{font:11px arial,sans-serif;color:#666}.qty-purchased-limit>.qty-limit,.qty-purchased-limit>.qty-purchased{float:left;line-height:15px}.qty-purchased-limit>.qty-limit{padding-top:1px;margin-left:15px}.qty-purchased-limit>.qty-limit-roof{color:red}.purchase-roof{display:none}.drawer .purchase-grid:not(:first-child){margin-left:30px}.drawer.open .drawercontent .subscrib-list{font-style:italic}.waiting-layer{width:398px;height:113px;background:#fff;border:1px solid #4675a8;-moz-box-shadow:rgba(0,0,0,0.25) 1px 1px 8px 3px;-ms-box-shadow:rgba(0,0,0,0.25) 1px 1px 8px 3px;-webkit-box-shadow:rgba(0,0,0,0.25) 1px 1px 8px 3px;box-shadow:rgba(0,0,0,0.25) 1px 1px 8px 3px}.waiting-layer #wrapper{width:370px;margin:auto}.waiting-layer #wrapper p{font-size:14px;color:#666;text-align:left;margin-top:25px}.waiting-layer #loader-wrapper{text-align:center;margin-top:15px}.waiting-layer #loader{width:24px;height:24px}#error-board{width:604px;margin:0 auto 0 auto;min-height:230px;background-color:white;padding:20px;background-image:url("../images/layout/error_board_bg.png");background-repeat:no-repeat;background-position:right top;-moz-box-shadow:1px 1px 3px rgba(0,0,0,0.25);-ms-box-shadow:1px 1px 3px rgba(0,0,0,0.25);-webkit-box-shadow:1px 1px 3px rgba(0,0,0,0.25);box-shadow:1px 1px 3px rgba(0,0,0,0.25)}#error-board-title,#main .opening-soon span{margin-bottom:30px;font-size:48px;color:#033333;line-height:100%}#main .opening-soon span{font-size:42px}#error-board-desc,#main .opening-soon p{font-size:16px;color:#666;line-height:180%}.whats-verified-download-main .headline{font-size:20px;color:#f90}#bluesnap-promotion-landing{display:none;text-align:center}#bluesnap-promotion-landing-text{font-family:'Myriad Pro';font-weight:400;font-size:24px}#bluesnap-promotion-landing-text2{font-family:'Arial Italic','Arial';font-weight:400;font-style:italic;font-size:18px;color:#666}#bluesnap-promotion-landing-banner{width:660px;padding:10px 10px 10px 10px}#bluesnap-promotion-detail{display:inline-block}#bluesnap-promotion-detail-logo-container{height:15px;vertical-align:middle}#bluesnap-promotion-detail-logo-container img{margin-top:15px}#bluesnap-promotion-detail img{height:inherit}#bluesnap-promotion-detail-text{font-family:'Arial Italic','Arial';font-weight:400;font-style:italic;font-size:10px;color:#369;float:right;height:24px}#process-payment-dialog{text-align:center;width:400px;padding:10px 10px 10px 10px}#process-payment-dialog div{margin-top:15px}#process-payment-dialog button{width:180px;height:28px;vertical-align:middle;margin-top:15px;margin-bottom:10px}.top-50-container{width:1200px}.top-50-container>*{width:100%;width:inherit;padding:10px}.horizontal-container{width:100%;display:-ms-flexbox;-ms-flex-pack:center;display:-moz-box;-moz-box-pack:center;-moz-box-align:center;display:-webkit-box;-webkit-box-pack:center;-webkit-box-align:center;display:box;box-pack:center;box-align:center}.top-50-quickview{margin:10px;width:33%}.top-50-quickview h2{padding-left:10px}.top-50-quickview ul{margin:0;padding:0}.top-50-quickview li:first-of-type{font-size:18px}.top-50-quickview li{background:white;padding:5px}.analytic-report-table-container>*{padding:8px}.analytic-report-table-container h1{font-size:18px}.analytic-report-table-container table{margin:10px}.analytic-report-table-container col{width:10%}.analytic-report-table-container td{text-align:left;vertical-align:middle}.analytic-report-table-container th{text-align:left}.analytic-report-table-container tr:nth-child(even){background:#f2f2f2}.analytic-report-table-container table *{padding:5px}.analytic-report-table-container thead{background:#f0f0f0}.statistics-chart-div.full-width{width:100%;position:relative}.file-list td{vertical-align:middle}.file-list label{margin:3px 3px}#featured-apps #result-list li{padding:10px;height:80px;overflow:visible}#featured-apps #result-list li:nth-child(odd){background:#ededed}#result-list{margin:0;padding:0;background:white;border:1px solid #CCC;border-top:0;width:100%}.admin-table table td,.master-table table td{border:1px solid #e6e6e6;height:40px;vertical-align:middle}#analytics-report a.admin-favorite{display:inline-block;height:7px;width:8px;background:url(../images/icons/star_big.png) no-repeat 2px 1px}#analytics-report a.admin-favorite.added{background:url(../images/icons/star_big.png) no-repeat 2px -16px}.search-type-area{height:25px;background:#fff;margin-right:6px;position:relative;display:none}.search-type{font:12px arial;text-align:center;height:25px;line-height:25px;padding-left:15px;padding-right:15px;margin-right:-4px;display:-moz-inline-box;display:inline-block}.search-type:hover{color:#29abe2!important;background:#e6e6e6!important;cursor:pointer}.search-type-unhightlighted{color:#29abe2!important;background:white}.search-type-hightlighted{color:white!important;background:#29abe2!important}.publisher-result-list{margin-left:-20px}.publisher-result-list li{height:130px;background-color:white;margin-right:6px;margin-bottom:6px}.pubsearch-result-row{height:100%;float:left;position:relative}.pubsearch-result-row-left{width:15%}.pubsearch-result-row-middle{margin-left:5px;width:70%}.pubsearch-result-row-right{width:13.5%}.pubsearch-result-image-link{height:98%;width:98%;background-color:white;display:inline-block;text-align:center;margin-right:2px}.pubsearch-result-image-helper{display:inline-block;height:100%;vertical-align:middle}.pubsearch-result-image{vertical-align:middle;display:inline-block;max-height:96%;max-width:96%;overflow:hidden}.pubsearch-result-name{margin-top:3px;font-size:14px;color:#29abe2;width:100%;overflow:hidden}.pubsearch-result-desc{margin-top:3px;font-size:12px;height:56px;width:100%;overflow:hidden}.publisher-consulting-services-region{position:absolute;bottom:-5px}.publisher-consulting-services-label{margin-bottom:3px;font-size:12px;width:100%}.pubsearch-consulting-service{margin-right:2px;float:left;width:auto;font-size:12px;vertical-align:bottom;margin-bottom:5px}.pubsearch-consulting-service-text{background-color:white;color:#29abe2}.pubsearch-result-row-right button{position:absolute!important;color:white;bottom:0;right:0;margin-bottom:6px;padding:5px}.pubsearch-apps-count{font-size:14px;color:#29abe2;font-weight:bold;position:relative;float:right;margin-top:5px;margin-right:2px}.pubsearch-apps-count-label{margin-top:5px;margin-right:5px;font-size:14px;position:relative;float:right}.ad-hide{display:none}.box-ad-hide{margin-left:189px}
\ No newline at end of file
diff --git a/2023/scripts/rigging_tools/ngskintools2/docs/Resources/linux64.png b/2023/scripts/rigging_tools/ngskintools2/docs/Resources/linux64.png
deleted file mode 100644
index 9e7f5bf..0000000
Binary files a/2023/scripts/rigging_tools/ngskintools2/docs/Resources/linux64.png and /dev/null differ
diff --git a/2023/scripts/rigging_tools/ngskintools2/docs/Resources/macos64.png b/2023/scripts/rigging_tools/ngskintools2/docs/Resources/macos64.png
deleted file mode 100644
index 8053b36..0000000
Binary files a/2023/scripts/rigging_tools/ngskintools2/docs/Resources/macos64.png and /dev/null differ
diff --git a/2023/scripts/rigging_tools/ngskintools2/docs/Resources/original_89910fa8-2c30-4376-a905-12c8a003d16b_.png b/2023/scripts/rigging_tools/ngskintools2/docs/Resources/original_89910fa8-2c30-4376-a905-12c8a003d16b_.png
deleted file mode 100644
index 65887c5..0000000
Binary files a/2023/scripts/rigging_tools/ngskintools2/docs/Resources/original_89910fa8-2c30-4376-a905-12c8a003d16b_.png and /dev/null differ
diff --git a/2023/scripts/rigging_tools/ngskintools2/docs/Resources/resized_5ca803cc-8cd1-4cbe-8825-98efaeef156e_.png b/2023/scripts/rigging_tools/ngskintools2/docs/Resources/resized_5ca803cc-8cd1-4cbe-8825-98efaeef156e_.png
deleted file mode 100644
index 412ca74..0000000
Binary files a/2023/scripts/rigging_tools/ngskintools2/docs/Resources/resized_5ca803cc-8cd1-4cbe-8825-98efaeef156e_.png and /dev/null differ
diff --git a/2023/scripts/rigging_tools/ngskintools2/docs/Resources/win64.png b/2023/scripts/rigging_tools/ngskintools2/docs/Resources/win64.png
deleted file mode 100644
index 3f3ee90..0000000
Binary files a/2023/scripts/rigging_tools/ngskintools2/docs/Resources/win64.png and /dev/null differ
diff --git a/2023/scripts/rigging_tools/ngskintools2/docs/index.html b/2023/scripts/rigging_tools/ngskintools2/docs/index.html
deleted file mode 100644
index a89a39a..0000000
--- a/2023/scripts/rigging_tools/ngskintools2/docs/index.html
+++ /dev/null
@@ -1,353 +0,0 @@
-
-
-
-
-
-
- Autodesk App Store - help file
-
-
-
-
-
-
-
ngSkinTools 2
-
-
-
-
Viktoras Makauskas
-
ngSkinTools is a skinning plugin for Autodesk® Maya®, introducing new concepts to character skinning such as layers, any-pose-mirroring, enhanced paint brushes, true smoothing, and more.
Skinning
-layers are a central feature of ngSkinTools. With them, you break your rig down
-into easier manageable parts and edit them separately, then blend everything
-together through layer transparency.
-
They’re
-not just a simple way to make your work more organized - they also physically
-isolate groups of influences from the rest of the rig, so paint and edit
-operations won’t mix-in influences you were not expecting. This also allows you
-to do things that were impossible before: per-layer mirroring, adjusting
-influence weight up/down through layer transparency, blend transferred weights
-with previous weights, to name a few.
-
-
Viewport
-tools
-
Just
-like in the previous version, ngSkinTools brings its own weight painting tools.
-Improving viewport experience is the main focus of V2, and it's complete revamp
-over the previous implementation.
-
-
Selecting
- influences on screen, a #1 requested feature from users, is nowhere. Just hold
- “S” and drag over the surface to select dominant influence from that part of
- the mesh, or hover over a joint pivot to select precisely the joints you
- want;
-
In
- addition to the usual surface projection mode for the brush, the new “screen”
- brush projection mode is useful when you want to quickly set weights for both
- sides of the mesh;
-
Custom
- shortcuts while in paint mode allow for quick access to intensity
-presets;
-
Color
- feedback is now provided through VP2 APIs, greatly improving the performance
- of displayed meshes.
-
-
Smoothing
-
Keeping
-weights in harmony with each other is not easy. ngSkinTools help you smooth
-weights with the control you need, allowing you to control the intensity, number
-of iterations and effective radius. For very dense meshes, added “iterations”
-argument now allows for the quicker spread of smoothness over larger areas of
-the mesh.
-
The
-“relax” tool from V1 is gone. With major performance rework, you’ll notice that
-simple flood-smoothing is now much faster and should be a near-instant operation
-even with large meshes.
-
The
-opposite “brother” of smooth brush, “sharpen”, is also there - for cases where
-you want to just bring out the dominant influences
-
-
Mirroring
-
Mirroring
-is one of the most frequent automated tasks you might want from your skinning
-tool. With ngSkinTools, you’ll be able to:
-
-
Mirror
- rigs in any pose; no need to switch to T-pose;
-
Have
- granular control over left/right/center influences mapping, matching
- left/right joints by naming convention, joint labels, etc;
-
Easily
- mirror parts of your rig by leveraging layers;
-
Automatic
- mirroring of weights to the opposite side as you paint so that you don’t need
- to get distracted from painting while working on symmetrical layers.
-
-
Layer
-effects
-
With
-the “mirror as a layer effect” feature, ngSkinTools introduce a new concept to
-ngSkinTools - layer effects. This differs from automatic mirroring of weights as
-it’s not directly modifying your layer weights; instead, it’s a post-effect that
-happens in the background buffer. This has multiple benefits, like a much
-cleaner seamline of left/right sides, the ability to tweak mirroring settings
-AFTER weights are painted, etc.
-
-
Compatibility
-
As
-it's predecessor, ngSkinTools2 operates on standard Maya skinCluster (also known
-as “smooth skin”), so no custom nodes will be required to use your rig. The
-plugin has a couple of custom nodes, but they’re only required while you work on
-setting up your skin weights and can be deleted after, so your work should stay
-compatible with most pipelines out there.
-
-
Performance
-
A
-lot of speed improvements have been made since V2, like improving the
-utilization of modern multi-core processors, or eliminating bottlenecks through
-much heavier use of performance profiling. Having a responsive, snappy tool is
-always a pleasure to work with.
-
-
-
-
-
General Usage Instructions
-
The installer from Autodesk App Store loads the application under the Custom shelf.
The installer that ran when you downloaded this plug-in from Autodesk App Store has already installed the plug-in. Windows only: To uninstall this plug-in, simply rerun the installer downloaded, and select the 'Uninstall' button, or you can uninstall it from 'Control Panel\Programs\Programs and Features', just as you would uninstall any other application from your system. The panel on the Plug-ins tab will not be removed until Maya is restarted.
-
-
-
Linux and OSX: To uninstall this plug-in, simply delete the module directory from your system. The panel on the Plug-ins tab will not be removed until Maya is restarted.
-
-
-
Download .msi and run it on your computer. The installation will place files in C:\ProgramData\Autodesk\ApplicationPlugins\ngskintools2 (unless your %ProgramData% the environment variable is different).
-
-
-
Using an autoloader system, nothing needs to be configured additionally. Maya scans autoloader locations for plugins at startup and configures each discovered plugin automatically. The autoloader will create a “ngSkinTools2” shelf with a button to open UI.
-
Now, restart Maya and a new tab ngSkinTools2 should appear on your shelf.
2.0.23 (2021-Mar-12)
-* Fixed: stylus pressure is not updated during the stroke;
-* Fixed: Maya crashes when smoothing an empty layer with "adjust existing influences only";
-* Fixed: (regression) UI is not opening on macOS;
-
-
-
-
-
- 2.0.23
-
-
-
2.0.23 (2021-Mar-10)
-* Added: adjustable brush size: don't reset to zero when changing brush size in the viewport.
-* Added: randomize influence colors in paint/display settings;
-* Added: layers on/off "eye" button in layers tree UI;
-* Fixed: ngSkinTools will not modify skinCluster's `normalizeWeights` value anymore; for performance boost, you still
- can disable skinCluster's normalization by setting `normalizeWeights=None`. In "normalizeWeights:interactive"
- skinCluster mode, Maya will no longer complain that "The weight total would have exceeded 1.0". ngSkinTools will try
- extra hard to normalize each vertex to a perfect 1.0;
-* Fixed: UI is not displayed correctly on high DPI displays when UI scaling is enabled in Maya;
-
-
-
-
-
- 2.0.22
-
-
-
2.0.22 (2021-Feb-06)
- Added: convenience tool for adding influences to existing skin clusters. Select influences, target mesh and select “Tools | Add Influence”;
- Fixed: weights will now display properly when viewport option “use default material” is turned on;
- Added: (v1 feature) Limit max influences per vertex before writing to skin cluster;
- Added: (v1 feature) Prune small weights before writing to skin cluster.
-
-2.0.21 (2021-Jan-11)
- Added: copy/paste vertex weights between different selections (tab “tools” - “copy component weights/paste average component weights”);
- Added: tool “fill transparency” - for all empty vertices in a layer, assign weights from closest non-empty vertex;
- Added: “duplicate layer” operation;
- Added: “Merge layers” operation: combine selected layers into one.
-
-2.0.20 (2020-Dec-02)
- Fixed: Linux: crashing on startup
-
-2.0.19 (2020-Nov-28)
- Added: influences mapping in mirror screen will now allow matching joints by DG connections; if symmetrical joints are linked between themselves with message connections, ngSkinTools will be able to leverage that information when mirroring weights;
- Added: symmetry mesh: an option to provide an alternative mesh for calculating vertex mapping for mirroring;
- Fixed: deleting visibility node can crash Maya sometimes, e.g. switching to component mode (F8) while paint tool is active
-
-2.0.18 (2020-Nov-20)
- Added: “use all joints” option for “weights from closest joint” tool; few internal optimizations to speedup operation;
- Added: “weights from closest joint” option: create a new layer
- Fixed: “weights from closest joint”: the tool is only using joints as spots, but not as segments;
- Fixed: after “weights from closest joint” operation influences list is not refreshed;
- Fixed: “weights from closest joint”: “assign” button sometimes disabled;
-
-2.0.17 (2020-Nov-19)
- Fixed: “resume in workspace” error while opening UI
-
-2.0.16 (2020-Nov-15)
- Added: skin data will be compressed for ngSkinTools data nodes, which should substantially reduce file size for scenes with lots of skinning layers;
- Added: paint mode intensity sliders are now exponential: “smooth”, “add” and “sharpen” sliders will now be more precise for lower values, and “scale” mode will allow for more precision when setting high values.
-
-2.0.15 (2020-Nov-10)
- Added: new “Set Weights” tab contains tools to apply weights to vertex/edge/polygon selection instead of painting.
- Added: a new option for smooth tool - “only adjust existing vertex influences”; when this is turned on, the smooth tool will prevent influences weights spreading across the surface
- Fixed: layer mirror effects correctly saved/loaded in files;
- Fixed: mask mirror effect was not correctly used by layer blending engine
-
-2.0.14 (2020-Oct-04)
- Fixed: occasional crashes when using mirror effect on layers;
- Additional stability fixes.
-
-2.0.13 (2020-Oct-04)
- Fixed: minor bug in 2.0.12 blocks UI from opening;
-
-2.0.12 (2020-Oct-03)
- Added: option to view used influences in influences list;
- Added: hide “DQ weights” channel in influences list if skin cluster skinning method is not set to “Weight Blended”;
-
-2.0.11 (2020-Oct-01)
- Fixed: broken Linux builds
-
-2.0.10 (2020-Sep-26)
- Added: pressing “f” while painting focuses viewport camera to current paint target; for joints and other influences, the current joint pivot is used as camera interest point; when current paint target is a mask, viewport centers around painted values;
- Fixed: influence mapping UI error if some influences are no joints;
-
-2.0.9 (2020-Sep-11)
- Fixed: undo paint crashing Maya;
- Fixed: incorrect brush behavior with multiple viewports open;
- Fixed: incorrect mesh display / VP2 transparency setting sensitive;
- Fixed: clearing selection while painting does not update the display of current mesh;
-
-
-
-
-
-
-
-
diff --git a/2023/scripts/rigging_tools/ngskintools2/launcher.py b/2023/scripts/rigging_tools/ngskintools2/launcher.py
index 06ddd41..7e5e5a1 100644
--- a/2023/scripts/rigging_tools/ngskintools2/launcher.py
+++ b/2023/scripts/rigging_tools/ngskintools2/launcher.py
@@ -1,158 +1,43 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
-
"""
-ngSkinTools2 启动器
-用于从工具架快速启动 ngSkinTools2
+ngSkinTools2 Launcher
+Provides a simple interface to launch ngSkinTools2 from Maya shelf buttons
"""
import sys
-import os
-
-def get_maya_version():
- """
- 获取当前 Maya 版本号
- 返回格式: '2023', '2024' 等
- """
- try:
- from maya import cmds
- maya_version = cmds.about(version=True)
- # Maya 版本格式可能是 "2023" 或 "2023.1" 等,取主版本号
- return maya_version.split('.')[0]
- except Exception as e:
- print(f"Failed to get Maya version: {e}")
- return None
-
-
-def find_compatible_plugin_dir(base_dir, maya_version):
- """
- 查找兼容的插件目录
- 优先使用完全匹配的版本,如果没有则向下查找最接近的版本
-
- Args:
- base_dir: 插件基础目录 (plug-ins/)
- maya_version: Maya 版本号字符串,如 '2023'
-
- Returns:
- 插件目录路径,如果找不到则返回 None
- """
- if not maya_version:
- return None
-
- try:
- maya_ver_int = int(maya_version)
- except ValueError:
- print(f"Invalid Maya version format: {maya_version}")
- return None
-
- # 列出所有可用的插件版本目录
- available_versions = []
- if os.path.exists(base_dir):
- for item in os.listdir(base_dir):
- item_path = os.path.join(base_dir, item)
- if os.path.isdir(item_path):
- try:
- ver_int = int(item)
- available_versions.append((ver_int, item_path))
- except ValueError:
- continue
-
- if not available_versions:
- return None
-
- # 按版本号排序
- available_versions.sort(reverse=True)
-
- # 首先尝试完全匹配
- for ver, path in available_versions:
- if ver == maya_ver_int:
- print(f"Found exact match plugin for Maya {maya_version}: {path}")
- return path
-
- # 如果没有完全匹配,使用小于等于当前版本的最高版本
- for ver, path in available_versions:
- if ver <= maya_ver_int:
- print(f"Using compatible plugin for Maya {maya_version}: {path} (version {ver})")
- return path
-
- # 如果当前版本比所有可用版本都旧,使用最旧的版本
- oldest_ver, oldest_path = available_versions[-1]
- print(f"Warning: Maya {maya_version} is older than available plugins. Using oldest: {oldest_path} (version {oldest_ver})")
- return oldest_path
def LaunchNgSkinTools():
"""
- 启动 ngSkinTools2 主界面
- 自动检测 Maya 版本并加载对应的插件
+ Launch ngSkinTools2 main UI window
+
+ This function handles two scenarios:
+ 1. If module alias exists (ngSkinTools2 -> rigging_tools.ngskintools2), use it
+ 2. If not, create the alias on-the-fly and then launch
"""
try:
- from maya import cmds, mel
-
- # 获取当前 Maya 版本
- maya_version = get_maya_version()
- if not maya_version:
- print("Warning: Could not determine Maya version, will try to continue anyway")
- else:
- print(f"Detected Maya version: {maya_version}")
-
- # 将当前目录添加到 Python 路径,并使用别名
- # 这样 ngSkinTools2 内部的 "from ngSkinTools2.ui" 就能找到模块
- current_dir = os.path.dirname(os.path.abspath(__file__))
- parent_dir = os.path.dirname(current_dir)
-
- # 添加父目录到路径
- if parent_dir not in sys.path:
- sys.path.insert(0, parent_dir)
-
- # 添加当前目录到路径,作为 ngSkinTools2 模块
- if current_dir not in sys.path:
- sys.path.insert(0, current_dir)
-
- # 在 sys.modules 中创建别名,让 ngSkinTools2 指向 ngskintools2
- import rigging_tools.ngskintools2 as ngskintools2_module
- sys.modules['ngSkinTools2'] = ngskintools2_module
-
- # 查找并添加插件路径
- # 根据 Maya 版本自动选择对应的插件目录
- plugin_base_dir = os.path.join(current_dir, 'plug-ins')
- plugin_dir = find_compatible_plugin_dir(plugin_base_dir, maya_version)
-
- if plugin_dir and os.path.exists(plugin_dir):
- # 添加插件路径
- current_plugin_path = os.environ.get('MAYA_PLUG_IN_PATH', '')
- if plugin_dir not in current_plugin_path:
- os.environ['MAYA_PLUG_IN_PATH'] = plugin_dir + os.pathsep + current_plugin_path
-
- # 加载插件
+ # Check if module alias already exists
+ if 'ngSkinTools2' not in sys.modules:
+ # Create the alias on-the-fly
try:
- # 检查插件是否已加载
- if not cmds.pluginInfo('ngSkinTools2', query=True, loaded=True):
- cmds.loadPlugin(os.path.join(plugin_dir, 'ngSkinTools2.mll'))
- print(f"ngSkinTools2 plugin loaded successfully from {plugin_dir}")
- else:
- print(f"ngSkinTools2 plugin already loaded")
- except RuntimeError:
- # 插件不存在,尝试加载
- try:
- cmds.loadPlugin(os.path.join(plugin_dir, 'ngSkinTools2.mll'))
- print(f"ngSkinTools2 plugin loaded successfully from {plugin_dir}")
- except Exception as plugin_error:
- print(f"Warning: Could not load ngSkinTools2 plugin: {plugin_error}")
- except Exception as plugin_error:
- print(f"Warning: Could not load ngSkinTools2 plugin: {plugin_error}")
- else:
- print(f"Warning: Plugin directory not found: {plugin_dir}")
+ import rigging_tools.ngskintools2
+ sys.modules['ngSkinTools2'] = rigging_tools.ngskintools2
+ print("Created ngSkinTools2 module alias")
+ except ImportError as import_err:
+ print(f"Error: Failed to import rigging_tools.ngskintools2 - {import_err}")
+ print("Please ensure the ngskintools2 directory is in the correct location")
+ return
- # 现在可以导入并打开 UI
- from rigging_tools.ngskintools2 import open_ui
+ # Now import and launch
+ from ngSkinTools2 import open_ui
open_ui()
- print("ngSkinTools2 UI opened successfully")
+ print("ngSkinTools2 launched successfully")
+
+ except ImportError as e:
+ print(f"Error: Failed to import ngSkinTools2 - {e}")
+ print("Please ensure ngSkinTools2 is properly installed")
except Exception as e:
- print(f"Failed to open ngSkinTools2: {e}")
+ print(f"Error: Failed to launch ngSkinTools2 - {e}")
import traceback
traceback.print_exc()
-
-
-if __name__ == "__main__":
- LaunchNgSkinTools()
diff --git a/2023/scripts/rigging_tools/ngskintools2/license.txt b/2023/scripts/rigging_tools/ngskintools2/license.txt
deleted file mode 100644
index 69c070d..0000000
--- a/2023/scripts/rigging_tools/ngskintools2/license.txt
+++ /dev/null
@@ -1,32 +0,0 @@
-ngSkinTools Software License Agreement.
-
-
-This is a legal agreement between you and ngSkinTools author (Viktoras Makauskas) covering your use of
-ngSkinTools (the "Software").
-
-1) ngSkinTools is provided as freeware.
-
-2) ngSkinTools Software is owned by Viktoras Makauskas and is protected by copyright laws and international
-treaty provisions. Therefore, you must treat the Software like any other copyrighted material.
-
-3) You may not distribute, rent, sub-license or otherwise make available to others the Software or
-documentation or copies thereof, except as expressly permitted in this License without prior written consent
-from ngSkinTools author (Viktoras Makauskas). In the case of an authorized transfer, the transferee must agree
-to be bound by the terms and conditions of this License Agreement.
-
-4) You may not remove any proprietary notices, labels, trademarks on the Software or documentation. You may not
-modify, de-compile, disassemble or reverse engineer the Software.
-
-5) Limited warranty: ngSkinTools software and documentation are "as is" without any warranty as to their
-performance, merchantability or fitness for any particular purpose. The licensee assumes the entire risk as to
-the quality and performance of the software. In no event shall ngSkinTools author or anyone else who has been
-involved in the creation, development, production, or delivery of this software be liable for any direct,
-incidental or consequential damages, such as, but not limited to, loss of anticipated profits, benefits, use,
-or data resulting from the use of this software, or arising out of any breach of warranty.
-
-Copyright (C) 2009-2020 Viktoras Makauskas
-
-http://www.ngskintools.com
-support@ngskintools.com
-
-All rights reserved.
diff --git a/2023/scripts/rigging_tools/ngskintools2/observableValue.py b/2023/scripts/rigging_tools/ngskintools2/observableValue.py
index f01c198..3410295 100644
--- a/2023/scripts/rigging_tools/ngskintools2/observableValue.py
+++ b/2023/scripts/rigging_tools/ngskintools2/observableValue.py
@@ -22,4 +22,4 @@ class ObservableValue(Object):
if default != Undefined:
return default
- raise Exception("using observable value before setting it")
+ raise Exception("在设置之前使用可观察值")
diff --git a/2023/scripts/rigging_tools/ngskintools2/operations/copy_paste_actions.py b/2023/scripts/rigging_tools/ngskintools2/operations/copy_paste_actions.py
index 916b25b..f362bc0 100644
--- a/2023/scripts/rigging_tools/ngskintools2/operations/copy_paste_actions.py
+++ b/2023/scripts/rigging_tools/ngskintools2/operations/copy_paste_actions.py
@@ -24,7 +24,7 @@ def action_copy_cut(session, parent, cut):
operation(session.state.currentLayer.layer, influences)
operation_name = "Cut" if cut else "Copy"
- result = actions.define_action(parent, operation_name + " weights to clipboard", callback=cut_copy_callback)
+ result = actions.define_action(parent, operation_name + " 将权重复制到剪贴板", callback=cut_copy_callback) # 将权重复制到剪贴板 weights to clipboard
@signal.on(session.events.currentLayerChanged, session.events.currentInfluenceChanged, qtParent=parent)
def on_selection_changed():
@@ -49,13 +49,13 @@ def action_paste(session, parent, operation):
api.paste_weights(session.state.currentLayer.layer, operation, influences=influences)
labels = {
- PasteOperation.add: 'Paste weights (add to existing)',
- PasteOperation.subtract: 'Paste weight (subtract from existing)',
- PasteOperation.replace: 'Paste weights (replace existing)',
+ PasteOperation.add: '粘贴权重(添加到现有)',
+ PasteOperation.subtract: '粘贴权重(从现有值中减去)',
+ PasteOperation.replace: '粘贴权重(替换现有)',
}
result = actions.define_action(parent, labels[operation], callback=paste_callback)
- result.setToolTip("Paste previously copied weights from clipboard")
+ result.setToolTip("从剪贴板粘贴先前复制的权重")
@signal.on(session.events.currentLayerChanged)
def on_selection_changed():
diff --git a/2023/scripts/rigging_tools/ngskintools2/operations/import_export_actions.py b/2023/scripts/rigging_tools/ngskintools2/operations/import_export_actions.py
index 2a64020..17f7d6d 100644
--- a/2023/scripts/rigging_tools/ngskintools2/operations/import_export_actions.py
+++ b/2023/scripts/rigging_tools/ngskintools2/operations/import_export_actions.py
@@ -31,7 +31,7 @@ def buildAction_export(session, parent):
result = actions.define_action(
parent,
- "Export Layers to Json...",
+ "导出图层...",
callback=export_callback,
tooltip="Save layer info to external file, suitable for importing weights to different scene/mesh",
)
@@ -79,7 +79,7 @@ def buildAction_import(session, parent, file_dialog_func=None):
t.customize_callback = transfer_dialog
t.execute()
- result = actions.define_action(parent, "Import Layers from Json...", callback=import_callback, tooltip="Load previously exported weights")
+ result = actions.define_action(parent, "导入图层...", callback=import_callback, tooltip="Load previously exported weights")
@signal.on(session.events.targetChanged, qtParent=parent)
def update():
diff --git a/2023/scripts/rigging_tools/ngskintools2/operations/import_v1_actions.py b/2023/scripts/rigging_tools/ngskintools2/operations/import_v1_actions.py
index 2b19f45..9a74704 100644
--- a/2023/scripts/rigging_tools/ngskintools2/operations/import_v1_actions.py
+++ b/2023/scripts/rigging_tools/ngskintools2/operations/import_v1_actions.py
@@ -28,8 +28,8 @@ def build_action_import_v1(session, parent):
update_state()
session.events.targetChanged.emitIfChanged()
- result = actions.define_action(parent, "Convert From v1.0 Layers", callback=do_convert)
- result.setToolTip("Convert skinning layers from previous version of ngSkinTools; after completing this action, v1 nodes will be deleted.")
+ result = actions.define_action(parent, "从v1.0图层转换", callback=do_convert)
+ result.setToolTip("“转化旧版ngSkinTools的图层;完成此操作后,v1节点将被删除。")
@signal.on(session.events.targetChanged)
def update_state():
diff --git a/2023/scripts/rigging_tools/ngskintools2/operations/layers.py b/2023/scripts/rigging_tools/ngskintools2/operations/layers.py
index 028eb96..b3004ce 100644
--- a/2023/scripts/rigging_tools/ngskintools2/operations/layers.py
+++ b/2023/scripts/rigging_tools/ngskintools2/operations/layers.py
@@ -28,7 +28,7 @@ def initializeLayers(createFirstLayer=True):
layers = ngSkinTools2.api.init_layers(target)
with ngSkinTools2.api.suspend_updates(target):
if createFirstLayer:
- layer = layers.add("Base weights")
+ layer = layers.add("基础权重") #Base weights
layer.set_current()
Mirror(target).set_mirror_config(config.mirrorInfluencesDefaults)
@@ -36,7 +36,7 @@ def initializeLayers(createFirstLayer=True):
if ngSkinTools2.api.is_slow_mode_skin_cluster(target):
dialogs.info(
- "ngSkinTools switched to slow maya API for setting skin cluster weights for this skinCluster, to workaround a Maya bug when skinCluster uses dg nodes as inputs"
+ "切换为设置皮肤集群权重,以解决 Maya皮肤集群使用装点作为输入时的错误。"
)
@@ -73,15 +73,15 @@ def build_action_initialize_layers(session, parent):
def do_initialize():
if import_v1_actions.can_import(session):
q = (
- "Skinning layers from previous version of ngSkinTools are present on this mesh. This operation will initialize "
- "skinning layers from scratch, discarding previous layers information. Do you want to continue?"
+ "来自旧版 ngSkinTools的皮肤层存在于此网格上。此操作将初始化"
+ "从头开始剥离图层,丢弃之前的图层信息。您要继续吗?"
)
if not dialogs.yesNo(q):
return
initializeLayers()
- result = actions.define_action(parent, "Initialize Skinning Layers", callback=do_initialize)
+ result = actions.define_action(parent, "初始化蒙皮层", callback=do_initialize)
@signal.on(session.events.nodeSelectionChanged)
def update():
@@ -95,7 +95,7 @@ def build_action_initialize_layers(session, parent):
def buildAction_createLayer(session, parent):
from ngSkinTools2.ui import actions
- result = actions.define_action(parent, "Create Layer", callback=addLayer, icon=":/newLayerEmpty.png", shortcut=QtCore.Qt.Key_Insert)
+ result = actions.define_action(parent, "创建图层", callback=addLayer, icon=":/newLayerEmpty.png", shortcut=QtCore.Qt.Key_Insert)
@signal.on(session.events.targetChanged)
def update_to_target():
@@ -109,7 +109,7 @@ def buildAction_createLayer(session, parent):
def buildAction_deleteLayer(session, parent):
from ngSkinTools2.ui import actions
- result = actions.define_action(parent, "Delete Layer", callback=deleteSelectedLayers, shortcut=QtCore.Qt.Key_Delete)
+ result = actions.define_action(parent, "删除图层", callback=deleteSelectedLayers, shortcut=QtCore.Qt.Key_Delete)
@signal.on(session.context.selected_layers.changed, session.events.targetChanged, qtParent=parent)
def update_to_target():
@@ -126,12 +126,12 @@ def setCurrentLayer(layer):
:type layer: ngSkinTools2.api.layers.Layer
"""
if not session.active():
- logger.info("didn't set current layer: no session")
+ logger.info("未设置当前图层:没有会话")
if not session.state.layersAvailable:
- logger.info("didn't set current layer: layers not enabled")
+ logger.info("未设置当前图层:图层未启用")
- logger.info("setting current layer to %r on %r", layer, session.state.selectedSkinCluster)
+ logger.info("将当前图层设置为 %r on %r", layer, session.state.selectedSkinCluster)
layer.set_current()
session.events.currentLayerChanged.emitIfChanged()
@@ -158,7 +158,7 @@ def deleteSelectedLayers():
class ToggleEnabledAction(Action):
- name = "Enabled"
+ name = "启用图层" #Enabled
checkable = True
def __init__(self, session):
@@ -192,7 +192,7 @@ class ToggleEnabledAction(Action):
for i in selected_layers:
i.enabled = enabled
- logger.info("layers toggled: %r", selected_layers)
+ logger.info("图层已切换: %r", selected_layers)
session.events.layerListChanged.emitIfChanged()
@@ -209,8 +209,8 @@ def build_action_randomize_influences_colors(session, parent):
:type session: ngSkinTools2.api.session.Session
"""
- result = QAction("Randomize colors", parent)
- result.setToolTip("Choose random colors for each influence, selecting from Maya's pallete of indexed colors")
+ result = QAction("随机颜色", parent)
+ result.setToolTip("为每个影响选择随机颜色,从Maya的索引色板中选择。")
def color_filter(c):
brightness = c[0] * c[0] + c[1] * c[1] + c[2] * c[2]
diff --git a/2023/scripts/rigging_tools/ngskintools2/operations/paint.py b/2023/scripts/rigging_tools/ngskintools2/operations/paint.py
index 41d46d3..f9ec0ea 100644
--- a/2023/scripts/rigging_tools/ngskintools2/operations/paint.py
+++ b/2023/scripts/rigging_tools/ngskintools2/operations/paint.py
@@ -9,8 +9,8 @@ log = getLogger("operations/paint")
class FloodAction(Action):
- name = "Flood"
- tooltip = "Apply current brush to whole selection"
+ name = "填充" # Flood
+ tooltip = "将当前画笔应用于整个选择区域"
def run(self):
session.paint_tool.flood(self.session.state.currentLayer.layer, influences=self.session.state.currentLayer.layer.paint_targets)
@@ -28,8 +28,8 @@ class FloodAction(Action):
class PaintAction(Action):
- name = "Paint"
- tooltip = "Toggle paint tool"
+ name = "绘制" # Paint
+ tooltip = "切换绘制工具"
checkable = True
def run(self):
diff --git a/2023/scripts/rigging_tools/ngskintools2/operations/removeLayerData.py b/2023/scripts/rigging_tools/ngskintools2/operations/removeLayerData.py
index d8e91b7..f8cf0f2 100644
--- a/2023/scripts/rigging_tools/ngskintools2/operations/removeLayerData.py
+++ b/2023/scripts/rigging_tools/ngskintools2/operations/removeLayerData.py
@@ -43,14 +43,14 @@ def list_custom_nodes_for_meshes(meshes):
return list(itertools.chain.from_iterable([list_custom_nodes_for_mesh(i) for i in meshes]))
-message_scene_noCustomNodes = 'Scene does not contain any custom ngSkinTools nodes.'
-message_selection_noCustomNodes = 'Selection does not contain any custom ngSkinTools nodes.'
+message_scene_noCustomNodes = '场景中不包含任何自定义的ngSkinTools节点。'
+message_selection_noCustomNodes = '选择不包含任何自定义ngskinTools节点。'
message_scene_warning = (
- 'This command deletes all custom ngSkinTools nodes. Skin weights ' 'will be preserved, but all layer data will be lost. Do you want to continue?'
+ '此命令删除所有自定义ngSkinTools节点。蒙皮权重“”将被保留,但所有图层数据都将丢失。您想继续吗?'
)
message_selection_warning = (
- 'This command deletes custom ngSkinTools nodes for selection. Skin weights '
- 'will be preserved, but all layer data will be lost. Do you want to continue?'
+ '此命令删除要选择的自定义ngSkinTools节点。皮肤重量'
+ '将被保留,但所有图层数据都将丢失。您想继续吗?'
)
@@ -89,7 +89,7 @@ def remove_custom_nodes(interactive=False, session=None, meshes=None):
if PaintTool.is_painting():
# make sure that painting is canceled to restore mesh display etc
- cmds.setToolTo("Move")
+ cmds.setToolTo("移除") # Move
if session is not None:
session.events.targetChanged.emitIfChanged()
diff --git a/2023/scripts/rigging_tools/ngskintools2/operations/tools.py b/2023/scripts/rigging_tools/ngskintools2/operations/tools.py
index 27e8169..4aee804 100644
--- a/2023/scripts/rigging_tools/ngskintools2/operations/tools.py
+++ b/2023/scripts/rigging_tools/ngskintools2/operations/tools.py
@@ -54,7 +54,7 @@ def create_action__from_closest_joint(parent, session):
if not options.all_influences():
influences = layer.paint_targets
if not influences:
- dialogs.info("Select one or more influences in Influences list")
+ dialogs.info("在影响列表中选择一个或多个影响")
return
if options.create_new_layer():
@@ -77,8 +77,8 @@ def create_action__from_closest_joint(parent, session):
__create_tool_action__(
parent,
session,
- action_name=u"Assign From Closest Joint",
- action_tooltip="Assign 1.0 weight for closest influence per each vertex in selected layer",
+ action_name=u"从最近的关节分配",
+ action_tooltip="为选定层中每个顶点的最近影响分配权重1.0",
exec_handler=exec_handler,
),
options,
@@ -105,8 +105,8 @@ def create_action__unify_weights(parent, session):
__create_tool_action__(
parent,
session,
- action_name=u"Unify Weights",
- action_tooltip="For selected vertices, make verts the same for all verts",
+ action_name=u"统一权重", # Unify Weights
+ action_tooltip="对于选定的顶点,使所有顶点相同。", #对于选定的顶点,使所有顶点相同。
exec_handler=exec_handler,
),
options,
@@ -130,8 +130,8 @@ def create_action__merge_layers(parent, session):
return __create_tool_action__(
parent,
session,
- action_name=u"Merge",
- action_tooltip="Merge contents of this layer into underlying layer. Pre-effects weights will be used for this",
+ action_name=u"合并", # Merge
+ action_tooltip="将本层的元素合并到底层。预效果权重将用于此。",
exec_handler=exec_handler,
enabled_handler=enabled_handler,
)
@@ -155,8 +155,8 @@ def create_action__duplicate_layer(parent, session):
return __create_tool_action__(
parent,
session,
- action_name=u"Duplicate",
- action_tooltip="Duplicate selected layer(s)",
+ action_name=u"复制",
+ action_tooltip="复制选择的图层(多选)",
exec_handler=exec_handler,
)
@@ -176,8 +176,8 @@ def create_action__fill_transparency(parent, session):
return __create_tool_action__(
parent,
session,
- action_name=u"Fill Transparency",
- action_tooltip="All transparent vertices in the selected layer(s) receive weights from their closest non-empty neighbour vertex",
+ action_name=u"填充透明度",
+ action_tooltip="所选图层中的所有透明顶点接收其最近非空邻接顶点的权重,",
exec_handler=exec_handler,
)
@@ -195,8 +195,8 @@ def create_action__copy_component_weights(parent, session):
return __create_tool_action__(
parent,
session,
- action_name=u"Copy Component Weights",
- action_tooltip="Store components weights in memory for further component-based paste actions",
+ action_name=u"复制组件权重",
+ action_tooltip="将组件权重存储在内存中,以便进行进一步的基于组件的粘贴操作",
exec_handler=exec_handler,
)
@@ -214,8 +214,8 @@ def create_action__paste_average_component_weight(parent, session):
return __create_tool_action__(
parent,
session,
- action_name=u"Paste Average Component Weight",
- action_tooltip="Compute average of copied component weights and set that value to currently selected components",
+ action_name=u"粘贴平均组件权重",
+ action_tooltip="计算复制的组件重量的平均值,并将该值设置为当前选定的组件",
exec_handler=exec_handler,
)
@@ -229,7 +229,7 @@ def create_action__add_influences(parent, session):
def exec_handler():
selection = cmds.ls(sl=True, l=True)
if len(selection) < 2:
- logger.info("invalid selection: %s", selection)
+ logger.info("无效选择: %s", selection)
return
api.add_influences(selection[:-1], selection[-1])
cmds.select(selection[-1])
@@ -238,8 +238,8 @@ def create_action__add_influences(parent, session):
return __create_tool_action__(
parent,
session,
- action_name=u"Add Influences",
- action_tooltip="Add selected influences to current skin cluster.",
+ action_name=u"增加影响",
+ action_tooltip="将选定的影响添加到当前皮肤集群。",
exec_handler=exec_handler,
)
@@ -289,7 +289,7 @@ def create_action__select_affected_vertices(parent, session):
return __create_tool_action__(
parent,
session,
- action_name=u"Select Affected Vertices",
- action_tooltip="Select vertices that have non-zero weight for current influence.",
+ action_name=u"选择受影响的顶点",
+ action_tooltip="选择当前影响中权重不为要的顶点。",
exec_handler=exec_handler,
)
diff --git a/2023/scripts/rigging_tools/ngskintools2/operations/website_links.py b/2023/scripts/rigging_tools/ngskintools2/operations/website_links.py
index 3a36476..453e8e5 100644
--- a/2023/scripts/rigging_tools/ngskintools2/operations/website_links.py
+++ b/2023/scripts/rigging_tools/ngskintools2/operations/website_links.py
@@ -12,10 +12,10 @@ def website_base_url():
class WebsiteLinksActions(Object):
def __init__(self, parent):
- self.api_root = make_documentation_action(parent, "API Documentation", "/v2/api")
- self.user_guide = make_documentation_action(parent, "User Guide", "/v2/")
- self.changelog = make_documentation_action(parent, "Change Log", "/v2/changelog", icon=None)
- self.contact = make_documentation_action(parent, "Contact", "/contact/", icon=None)
+ self.api_root = make_documentation_action(parent, "API 文档", "/v2/api")
+ self.user_guide = make_documentation_action(parent, "用户指南", "/v2/")
+ self.changelog = make_documentation_action(parent, "更新日志", "/v2/changelog", icon=None)
+ self.contact = make_documentation_action(parent, "联系", "/contact/", icon=None)
def make_documentation_action(parent, title, url, icon=":/help.png"):
diff --git a/2023/scripts/rigging_tools/ngskintools2/signal.py b/2023/scripts/rigging_tools/ngskintools2/signal.py
index 7961484..ceecb38 100644
--- a/2023/scripts/rigging_tools/ngskintools2/signal.py
+++ b/2023/scripts/rigging_tools/ngskintools2/signal.py
@@ -24,8 +24,8 @@ class SignalQueue(Object):
def emit(self, handler):
if len(self.queue) > self.max_length:
- log.error("queue max length reached: emitting too many events?")
- raise Exception("queue max length reached: emitting too many events?")
+ log.error("队列最大长度已达到:发出的事件过多?")
+ raise Exception("队列最大长度已达到:正在发出太多事件?")
should_start = len(self.queue) == 0
@@ -53,7 +53,7 @@ class SignalQueue(Object):
current_handler += 1
if len(self.queue) > 50:
- log.info("handler queue finished with %d items", len(self.queue))
+ log.info("处理器队列完成,共 %d 项", len(self.queue))
self.queue = []
@@ -77,7 +77,7 @@ class Signal(Object):
def __init__(self, name):
if name is None:
- raise Exception("need name for debug purposes later")
+ raise Exception("需要稍后用于调试目的的名称")
self.name = name
self.handlers = []
self.executing = False
diff --git a/2023/scripts/rigging_tools/ngskintools2/ui/aboutwindow.py b/2023/scripts/rigging_tools/ngskintools2/ui/aboutwindow.py
index e96ffd2..cde00c6 100644
--- a/2023/scripts/rigging_tools/ngskintools2/ui/aboutwindow.py
+++ b/2023/scripts/rigging_tools/ngskintools2/ui/aboutwindow.py
@@ -19,7 +19,7 @@ def show(parent):
layout = QtWidgets.QVBoxLayout()
layout.addStretch()
layout.addWidget(QtWidgets.QLabel("
ngSkinTools
"))
- layout.addWidget(QtWidgets.QLabel("Version {0}".format(version.pluginVersion())))
+ layout.addWidget(QtWidgets.QLabel("当前版本 {0}".format(version.pluginVersion())))
layout.addWidget(QtWidgets.QLabel(version.COPYRIGHT))
url = QtWidgets.QLabel('{0}'.format(version.PRODUCT_URL))
@@ -65,7 +65,7 @@ def show(parent):
def buttonsRow(window):
layout = QtWidgets.QHBoxLayout()
layout.addStretch()
- btnClose = QtWidgets.QPushButton("Close")
+ btnClose = QtWidgets.QPushButton("退出")
btnClose.setMinimumWidth(100 * scale_multiplier)
layout.addWidget(btnClose)
layout.setContentsMargins(20 * scale_multiplier, 15 * scale_multiplier, 20 * scale_multiplier, 15 * scale_multiplier)
@@ -76,7 +76,7 @@ def show(parent):
window = QtWidgets.QWidget(parent, Qt.Window | Qt.WindowTitleHint | Qt.CustomizeWindowHint)
window.resize(600 * scale_multiplier, 500 * scale_multiplier)
window.setAttribute(Qt.WA_DeleteOnClose)
- window.setWindowTitle("About ngSkinTools")
+ window.setWindowTitle("关于 ngSkinTools")
layout = QtWidgets.QVBoxLayout()
window.setLayout(layout)
layout.setContentsMargins(0, 0, 0, 0)
diff --git a/2023/scripts/rigging_tools/ngskintools2/ui/actions.py b/2023/scripts/rigging_tools/ngskintools2/ui/actions.py
index 28b66af..45fac41 100644
--- a/2023/scripts/rigging_tools/ngskintools2/ui/actions.py
+++ b/2023/scripts/rigging_tools/ngskintools2/ui/actions.py
@@ -35,7 +35,7 @@ def build_action_delete_custom_nodes_for_selection(parent, session):
result = define_action(
parent,
- "Delete Custom Nodes For Selection",
+ "删除选中网格的Ng节点",
callback=lambda: removeLayerData.remove_custom_nodes_from_selection(interactive=True, session=session),
)
@@ -86,7 +86,7 @@ class Actions(Object):
self.toolsUnifyWeights, self.toolsUnifyWeightsOptions = tools.create_action__unify_weights(parent, session)
self.toolsDeleteCustomNodes = define_action(
- parent, "Delete All Custom Nodes", callback=lambda: removeLayerData.remove_custom_nodes(interactive=True, session=session)
+ parent, "删除所有网格的Ng节点", callback=lambda: removeLayerData.remove_custom_nodes(interactive=True, session=session)
)
self.toolsDeleteCustomNodesOnSelection = build_action_delete_custom_nodes_for_selection(parent, session)
@@ -135,10 +135,10 @@ class Actions(Object):
context.addAction(self.toggle_layer_enabled)
def addInfluencesActions(self, context):
- context.addAction(self.separator(context, "Actions"))
+ context.addAction(self.separator(context, "动作"))
context.addAction(self.toolsAssignFromClosestJointSelectedInfluences)
context.addAction(self.select_affected_vertices)
- context.addAction(self.separator(context, "Clipboard"))
+ context.addAction(self.separator(context, "剪贴板"))
context.addAction(self.cut_influences)
context.addAction(self.copy_influences)
context.addAction(self.paste_weights)
diff --git a/2023/scripts/rigging_tools/ngskintools2/ui/influenceMappingUI.py b/2023/scripts/rigging_tools/ngskintools2/ui/influenceMappingUI.py
index a77deef..b3991e8 100644
--- a/2023/scripts/rigging_tools/ngskintools2/ui/influenceMappingUI.py
+++ b/2023/scripts/rigging_tools/ngskintools2/ui/influenceMappingUI.py
@@ -36,7 +36,7 @@ def open_as_dialog(parent, matcher, result_callback):
window.close()
def save_defaults():
- if not yesNo("Save current settings as default?"):
+ if not yesNo("将当前设置保存为默认设置?"):
return
config.mirrorInfluencesDefaults = matcher.config.as_json()
@@ -47,18 +47,18 @@ def open_as_dialog(parent, matcher, result_callback):
return widgets.button_row(
[
- ("Apply", apply),
- ("Cancel", window.close),
+ ("应用", apply),
+ ("取消", window.close),
],
side_menu=[
- ("Save As Default", save_defaults),
- ("Load Defaults", load_defaults),
+ ("储存为默认值", save_defaults),
+ ("加载默认值", load_defaults),
],
)
window = QtWidgets.QDialog(parent)
cleanup.registerCleanupHandler(window.close)
- window.setWindowTitle("Influence Mirror Mapping")
+ window.setWindowTitle("影响镜像映射")
window.setAttribute(QtCore.Qt.WA_DeleteOnClose)
window.resize(720 * scale_multiplier, 500 * scale_multiplier)
window.setLayout(QtWidgets.QVBoxLayout())
@@ -102,10 +102,10 @@ def build_ui(parent, matcher):
split_path = path.rsplit("|", 1)
parent_path, name = split_path if len(split_path) == 2 else ["", split_path[0]]
- item = QtWidgets.QTreeWidgetItem([name, '-', '(not in skin cluster)' if is_intermediate else '?'])
+ item = QtWidgets.QTreeWidgetItem([name, '-', '(不在皮肤簇中)' if is_intermediate else '?'])
tree_items[path] = item
- parent_item = None if parent_path == "" else find_item(parent_path, True)
+ parent_item = None if parent_path is "" else find_item(parent_path, True)
if parent_item is not None:
parent_item.addChild(item)
@@ -142,7 +142,7 @@ def build_ui(parent, matcher):
def pattern():
result = QtWidgets.QTableWidget()
result.setColumnCount(2)
- result.setHorizontalHeaderLabels(["Pattern", "Opposite"] if mirror_mode else ["Source", "Destination"])
+ result.setHorizontalHeaderLabels(["左", "右"] if mirror_mode else ["来源", "目标"])
result.setEditTriggers(QtWidgets.QTableWidget.AllEditTriggers)
result.verticalHeader().setVisible(False)
@@ -209,12 +209,12 @@ def build_ui(parent, matcher):
def automaticRules():
form = QtWidgets.QFormLayout()
- use_joint_names = QtWidgets.QCheckBox("Match by joint name")
+ use_joint_names = QtWidgets.QCheckBox("匹配骨骼名称")
naming_patterns = pattern()
- use_position = QtWidgets.QCheckBox("Match by position")
+ use_position = QtWidgets.QCheckBox("匹配位置")
tolerance_scroll = tolerance()
- use_joint_labels = QtWidgets.QCheckBox("Match by joint label")
- use_dg_links = QtWidgets.QCheckBox("Match by dependency graph links")
+ use_joint_labels = QtWidgets.QCheckBox("匹配骨骼标签")
+ use_dg_links = QtWidgets.QCheckBox("匹配依存关系图连接")
def update_enabled_disabled():
def enable_form_row(form_item, e):
@@ -260,27 +260,27 @@ def build_ui(parent, matcher):
use_dg_links.setChecked(matcher.config.use_dg_link_matching)
update_enabled_disabled()
- g = QtWidgets.QGroupBox("Rules")
+ g = QtWidgets.QGroupBox("规则")
g.setLayout(form)
form.addRow(use_dg_links)
- form.addRow("Attribute name:", dg_attribute)
+ form.addRow("属性名称:", dg_attribute)
form.addRow(use_joint_labels)
form.addRow(use_joint_names)
- form.addRow("Naming scheme:", naming_patterns)
+ form.addRow("命名方案:", naming_patterns)
form.addRow(use_position)
- form.addRow("Position tolerance:", tolerance_scroll.layout())
+ form.addRow("位置容差:", tolerance_scroll.layout())
update_values()
return g
def scriptedRules():
- g = QtWidgets.QGroupBox("Scripted rules")
+ g = QtWidgets.QGroupBox("脚本规则")
g.setLayout(QtWidgets.QVBoxLayout())
g.layout().addWidget(QtWidgets.QLabel("TODO"))
return g
def manualRules():
- g = QtWidgets.QGroupBox("Manual overrides")
+ g = QtWidgets.QGroupBox("手动覆盖")
g.setLayout(QtWidgets.QVBoxLayout())
g.layout().addWidget(QtWidgets.QLabel("TODO"))
return g
@@ -302,7 +302,7 @@ def build_ui(parent, matcher):
def createMappingView():
view = QtWidgets.QTreeWidget()
view.setColumnCount(3)
- view.setHeaderLabels(["Source", "Destination", "Matched by rule"])
+ view.setHeaderLabels(["来源", "目标", "按规则匹配"])
view.setIndentation(7)
view.setExpandsOnDoubleClick(False)
@@ -316,14 +316,14 @@ def build_ui(parent, matcher):
:type mapping: dict[InfluenceInfo, InfluenceInfo]
"""
for treeItem in list(usedItems.values()):
- treeItem.setText(1, "(not matched)")
+ treeItem.setText(1, "(不匹配)")
treeItem.setText(2, "")
for k, v in list(mapping.items()):
treeItem = usedItems.get(k.path_name(), None)
if treeItem is None:
continue
- treeItem.setText(1, "(self)" if k == v['infl'] else v["infl"].shortestPath)
+ treeItem.setText(1, "(自己)" if k == v['infl'] else v["infl"].shortestPath)
treeItem.setText(2, v["matchedRule"])
treeItem.setData(1, linkedItemRole, v["infl"].path)
@@ -343,7 +343,7 @@ def build_ui(parent, matcher):
matches = matcher.calculate()
mappingView_updateMatches(matches)
- g = QtWidgets.QGroupBox("Calculated mapping")
+ g = QtWidgets.QGroupBox("计算映射")
g.setLayout(QtWidgets.QVBoxLayout())
mappingView, mappingView_updateMatches = createMappingView()
g.layout().addWidget(mappingView)
diff --git a/2023/scripts/rigging_tools/ngskintools2/ui/influencesview.py b/2023/scripts/rigging_tools/ngskintools2/ui/influencesview.py
index 2f5307b..8c18b93 100644
--- a/2023/scripts/rigging_tools/ngskintools2/ui/influencesview.py
+++ b/2023/scripts/rigging_tools/ngskintools2/ui/influencesview.py
@@ -19,9 +19,9 @@ def build_used_influences_action(parent):
result = actions.define_action(
parent,
- "Used Influences Only",
+ "只显示有权重的影响物",
callback=toggle,
- tooltip="If enabled, influences view will only show influences that have weights on current layer",
+ tooltip="如果启用,影响视图将仅显示当前层上有权重的影响。",
)
@signal.on(config.influences_show_used_influences_only.changed, qtParent=parent)
@@ -46,7 +46,7 @@ def build_set_influences_sorted_action(parent):
parent,
"Show influences sorted",
callback=toggle,
- tooltip="Sort influences by name",
+ tooltip="按名称排序影响",
)
@signal.on(config.influences_show_used_influences_only.changed, qtParent=parent)
@@ -108,7 +108,7 @@ def build_view(parent, actions, session, filter):
targets = (item_id,)
layer.locked_influences = add_or_remove(layer.locked_influences, targets, lock)
- log.info("updated locked influences to %r", layer.locked_influences)
+ log.info("更新锁定的影响为 %r", layer.locked_influences)
session.events.influencesListUpdated.emit()
return handler
@@ -170,14 +170,14 @@ def build_view(parent, actions, session, filter):
view.setSelectionMode(QtWidgets.QAbstractItemView.ExtendedSelection)
view.setContextMenuPolicy(QtCore.Qt.ActionsContextMenu)
actions.addInfluencesActions(view)
- view.addAction(actions.separator(parent, "View Options"))
+ view.addAction(actions.separator(parent, "显示设置"))
view.addAction(actions.show_used_influences_only)
view.addAction(actions.set_influences_sorted)
view.setIndentation(10 * scale_multiplier)
view.header().setStretchLastSection(False)
view.header().setSectionResizeMode(0, QtWidgets.QHeaderView.Stretch)
- view.setHeaderLabels(["Influences", ""])
+ view.setHeaderLabels(["影响物", ""])
view.header().setSectionResizeMode(1, QtWidgets.QHeaderView.Fixed)
view.setColumnWidth(1, 25 * scale_multiplier)
@@ -208,7 +208,7 @@ def build_view(parent, actions, session, filter):
if not session.state.currentLayer.layer:
build_items(view, [], None)
else:
- log.info("current layer changed to %s", session.state.currentLayer.layer)
+ log.info("当前图层更改为 %s", session.state.currentLayer.layer)
refresh_items()
current_influence_changed()
@@ -217,7 +217,7 @@ def build_view(parent, actions, session, filter):
if session.state.currentLayer.layer is None:
return
- log.info("current influence changed - updating item selection")
+ log.info("当前影响已更改-更新项目选择")
with qt.signals_blocked(view):
targets = session.state.currentLayer.layer.paint_targets
first = True
@@ -239,12 +239,12 @@ def build_view(parent, actions, session, filter):
if not session.state.currentLayer.layer:
return
- log.info("focused item changed: %r", get_item_id(curr))
+ log.info("焦点项已更改: %r", get_item_id(curr))
sync_paint_targets_to_selection()
@qt.on(view.itemSelectionChanged)
def sync_paint_targets_to_selection():
- log.info("syncing paint targets")
+ log.info("同步绘画目标")
selected_ids = [get_item_id(item) for item in view.selectedItems()]
selected_ids = [i for i in selected_ids if i is not None]
diff --git a/2023/scripts/rigging_tools/ngskintools2/ui/layersview.py b/2023/scripts/rigging_tools/ngskintools2/ui/layersview.py
index 708450c..a959849 100644
--- a/2023/scripts/rigging_tools/ngskintools2/ui/layersview.py
+++ b/2023/scripts/rigging_tools/ngskintools2/ui/layersview.py
@@ -48,12 +48,12 @@ def build_view(parent, actions):
child_layer = item_to_layer(child)
if child_layer.parent_id != parent_layer_id:
- log.info("changing layer parent: %r->%r (was %r)", parent_layer_id, child_layer, child_layer.parent_id)
+ log.info("更改图层父级: %r->%r (was %r)", parent_layer_id, child_layer, child_layer.parent_id)
child_layer.parent = parent_layer_id
new_index = tree_item.childCount() - i - 1
if child_layer.index != new_index:
- log.info("changing layer index: %r->%r (was %r)", child_layer, new_index, child_layer.index)
+ log.info("更改图层索引: %r->%r (was %r)", child_layer, new_index, child_layer.index)
child_layer.index = new_index
sync_item(child, child_layer.id)
@@ -82,7 +82,7 @@ def build_view(parent, actions):
view.setContextMenuPolicy(QtCore.Qt.ActionsContextMenu)
actions.addLayersActions(view)
- view.setHeaderLabels(["Layers", ""])
+ view.setHeaderLabels(["图层", ""])
# view.setHeaderHidden(True)
view.header().setMinimumSectionSize(1)
view.header().setStretchLastSection(False)
@@ -100,7 +100,7 @@ def build_view(parent, actions):
bar = QtWidgets.QToolBar(parent=parent)
bar.setMovable(False)
bar.setIconSize(QtCore.QSize(visibility_icon_size * scale_multiplier, visibility_icon_size * scale_multiplier))
- a = bar.addAction(icon_visible if layer is None or layer.enabled else icon_hidden, "Toggle enabled/disabled")
+ a = bar.addAction(icon_visible if layer is None or layer.enabled else icon_hidden, "切换 启用/禁用")
@qt.on(a.triggered)
def handler():
@@ -117,11 +117,11 @@ def build_view(parent, actions):
# build map "parent id->list of children "
- log.info("syncing items...")
+ log.info("同步项目q...")
# save selected layers IDs to restore item selection later
selected_layer_ids = {item_to_layer(item).id for item in view.selectedItems()}
- log.info("selected layer IDs: %r", selected_layer_ids)
+ log.info("选择层 IDs: %r", selected_layer_ids)
current_item_id = None if view.currentItem() is None else item_to_layer(view.currentItem()).id
hierarchy = {}
@@ -167,7 +167,7 @@ def build_view(parent, actions):
@signal.on(session.events.layerListChanged, qtParent=view)
def refresh_layer_list():
- log.info("event handler for layer list changed")
+ log.info("图层列表更改的事件处理程序")
if not session.state.layersAvailable:
build_items([])
else:
@@ -177,7 +177,7 @@ def build_view(parent, actions):
@signal.on(session.events.currentLayerChanged, qtParent=view)
def current_layer_changed():
- log.info("event handler for currentLayerChanged")
+ log.info("当前图层更改的事件处理程序")
layer = session.state.currentLayer.layer
current_item = view.currentItem()
if layer is None:
@@ -189,14 +189,14 @@ def build_view(parent, actions):
if prev_layer is None or prev_layer.id != layer.id:
item = tree_items.get(layer.id, None)
if item is not None:
- log.info("setting current item to " + item.text(0))
+ log.info("将当前项目设置为 " + item.text(0))
view.setCurrentItem(item, 0, QtCore.QItemSelectionModel.SelectCurrent | QtCore.QItemSelectionModel.ClearAndSelect)
item.setSelected(True)
@qt.on(view.currentItemChanged)
def current_item_changed(curr, _):
- log.info("current item changed")
+ log.info("当前项目已更改")
if curr is None:
return
@@ -209,7 +209,7 @@ def build_view(parent, actions):
@qt.on(view.itemChanged)
def item_changed(item, column):
- log.info("item changed")
+ log.info("项目已更改")
layers.renameLayer(item_to_layer(item), item.text(column))
@qt.on(view.itemSelectionChanged)
@@ -217,7 +217,7 @@ def build_view(parent, actions):
selection = [item_to_layer(item) for item in view.selectedItems()]
if selection != session.context.selected_layers(default=[]):
- log.info("new selected layers: %r", selection)
+ log.info("新选择图层: %r", selection)
session.context.selected_layers.set(selection)
refresh_layer_list()
diff --git a/2023/scripts/rigging_tools/ngskintools2/ui/mainwindow.py b/2023/scripts/rigging_tools/ngskintools2/ui/mainwindow.py
index e5b2e87..8b12a4f 100644
--- a/2023/scripts/rigging_tools/ngskintools2/ui/mainwindow.py
+++ b/2023/scripts/rigging_tools/ngskintools2/ui/mainwindow.py
@@ -46,20 +46,20 @@ def build_menu(parent, actions):
sub_item.setTearOffEnabled(True)
return sub_item
- sub = top_level_menu("File")
- sub.addSeparator().setText("Import/Export")
+ sub = top_level_menu("文件")
+ sub.addSeparator().setText("导入/导出")
sub.addAction(actions.importFile)
sub.addAction(actions.exportFile)
- sub = top_level_menu("Layers")
- sub.addSeparator().setText("Layer actions")
+ sub = top_level_menu("图层")
+ sub.addSeparator().setText("图层操作")
sub.addAction(actions.initialize)
sub.addAction(actions.import_v1)
actions.addLayersActions(sub)
- sub.addSeparator().setText("Copy")
+ sub.addSeparator().setText("复制")
sub.addAction(actions.transfer)
- sub = top_level_menu("Tools")
+ sub = top_level_menu("工具")
sub.addAction(actions.add_influences)
sub.addAction(actions.toolsAssignFromClosestJoint)
sub.addSeparator()
@@ -68,17 +68,17 @@ def build_menu(parent, actions):
sub.addAction(actions.toolsDeleteCustomNodesOnSelection)
sub.addAction(actions.toolsDeleteCustomNodes)
- sub = top_level_menu("View")
+ sub = top_level_menu("查看")
sub.addAction(actions.show_used_influences_only)
- sub = top_level_menu("Help")
+ sub = top_level_menu("帮助")
sub.addAction(actions.documentation.user_guide)
sub.addAction(actions.documentation.api_root)
sub.addAction(actions.documentation.changelog)
sub.addAction(actions.documentation.contact)
sub.addSeparator()
sub.addAction(actions.check_for_updates)
- sub.addAction("About...").triggered.connect(lambda: aboutwindow.show(parent))
+ sub.addAction("关于...").triggered.connect(lambda: aboutwindow.show(parent))
return menu
@@ -107,11 +107,11 @@ def build_ui(parent):
tabs = QtWidgets.QTabWidget(window)
- tabs.addTab(tabPaint.build_ui(tabs, actions), "Paint")
- tabs.addTab(tabSetWeights.build_ui(tabs), "Set Weights")
- tabs.addTab(tabMirror.build_ui(tabs), "Mirror")
- tabs.addTab(tabLayerEffects.build_ui(), "Effects")
- tabs.addTab(tabTools.build_ui(actions, session), "Tools")
+ tabs.addTab(tabPaint.build_ui(tabs, actions), "绘制")
+ tabs.addTab(tabSetWeights.build_ui(tabs), "设置权重")
+ tabs.addTab(tabMirror.build_ui(tabs), "镜像")
+ tabs.addTab(tabLayerEffects.build_ui(), "样式")
+ tabs.addTab(tabTools.build_ui(actions, session), "工具")
@signal.on(options.current_tab.changed)
def set_current_tab():
diff --git a/2023/scripts/rigging_tools/ngskintools2/ui/model_binds.py b/2023/scripts/rigging_tools/ngskintools2/ui/model_binds.py
index 314313c..da06573 100644
--- a/2023/scripts/rigging_tools/ngskintools2/ui/model_binds.py
+++ b/2023/scripts/rigging_tools/ngskintools2/ui/model_binds.py
@@ -19,4 +19,4 @@ def bind(ui, model):
model.set(ui.value())
else:
- raise Exception("could not bind control to model")
+ raise Exception("无法将控件绑定到模型")
diff --git a/2023/scripts/rigging_tools/ngskintools2/ui/options.py b/2023/scripts/rigging_tools/ngskintools2/ui/options.py
index df7ddca..076510b 100644
--- a/2023/scripts/rigging_tools/ngskintools2/ui/options.py
+++ b/2023/scripts/rigging_tools/ngskintools2/ui/options.py
@@ -99,10 +99,10 @@ def save_option(varName, value):
elif is_string(value):
key = 'sv'
else:
- raise ValueError("could not save option %s: invalid value %r" % (varName, value))
+ raise ValueError("无法保存选项 %s: 无效值 %r" % (varName, value))
kvargs = {key: (varName, value)}
- log.info("saving optionvar: %r", kvargs)
+ log.info("保存选项变量: %r", kvargs)
cmds.optionVar(**kvargs)
@@ -153,11 +153,11 @@ class Config(Object):
def __get_value__(self, name, default_value):
result = self.__state__.get(name, default_value)
- log.info("config: return %s=%r", name, result)
+ log.info("配置: return %s=%r", name, result)
return result
def __set_value__(self, name, value):
- log.info("config: save %s=%r", name, value)
+ log.info("配置: save %s=%r", name, value)
self.__state__[name] = value
self.save()
diff --git a/2023/scripts/rigging_tools/ngskintools2/ui/tabLayerEffects.py b/2023/scripts/rigging_tools/ngskintools2/ui/tabLayerEffects.py
index 56c53f6..4da7beb 100644
--- a/2023/scripts/rigging_tools/ngskintools2/ui/tabLayerEffects.py
+++ b/2023/scripts/rigging_tools/ngskintools2/ui/tabLayerEffects.py
@@ -36,9 +36,9 @@ def build_ui():
def build_properties():
layout = QtWidgets.QVBoxLayout()
- opacity = widgets.NumberSliderGroup(tooltip="multiply layer mask to control overall transparency of the layer.")
+ opacity = widgets.NumberSliderGroup(tooltip="多层蒙版来控制图层的整体透明度.")
opacity.set_value(1.0)
- layout.addLayout(createTitledRow("Opacity:", opacity.layout()))
+ layout.addLayout(createTitledRow("不透明度:", opacity.layout()))
def default_selection_opacity(layers):
if len(layers) > 0:
@@ -65,7 +65,7 @@ def build_ui():
update_values()
- group = QtWidgets.QGroupBox("Layer properties")
+ group = QtWidgets.QGroupBox("图层属性")
group.setLayout(layout)
return group
@@ -76,18 +76,18 @@ def build_ui():
i.effects.configure_mirror(**{option: value})
mirror_direction = QtWidgets.QComboBox()
- mirror_direction.addItem("Positive to negative", MirrorOptions.directionPositiveToNegative)
- mirror_direction.addItem("Negative to positive", MirrorOptions.directionNegativeToPositive)
- mirror_direction.addItem("Flip", MirrorOptions.directionFlip)
+ mirror_direction.addItem("从正到负", MirrorOptions.directionPositiveToNegative)
+ mirror_direction.addItem("从负到正", MirrorOptions.directionNegativeToPositive)
+ mirror_direction.addItem("翻转", MirrorOptions.directionFlip)
mirror_direction.setMinimumWidth(1)
@qt.on(mirror_direction.currentIndexChanged)
def value_changed():
- configure_mirror_all_layers("mirror_direction", mirror_direction.currentData())
+ configure_mirror_all_layers("镜像方向", mirror_direction.currentData())
- influences = QtWidgets.QCheckBox("Influence weights")
- mask = QtWidgets.QCheckBox("Layer mask")
- dq = QtWidgets.QCheckBox("Dual quaternion weights")
+ influences = QtWidgets.QCheckBox("影响物权重")
+ mask = QtWidgets.QCheckBox("图层蒙板")
+ dq = QtWidgets.QCheckBox("双四元数权重")
def configure_checkbox(checkbox, option):
@qt.on(checkbox.stateChanged)
@@ -125,21 +125,21 @@ def build_ui():
return result
layout = QtWidgets.QVBoxLayout()
- layout.addLayout(createTitledRow("Mirror effect on:", elements()))
- layout.addLayout(createTitledRow("Mirror direction:", mirror_direction))
+ layout.addLayout(createTitledRow("镜像效果打开:", elements()))
+ layout.addLayout(createTitledRow("镜像方向:", mirror_direction))
- group = QtWidgets.QGroupBox("Mirror")
+ group = QtWidgets.QGroupBox("镜像")
group.setLayout(layout)
return group
def build_skin_properties():
- use_max_influences = QtWidgets.QCheckBox("Limit max influences per vertex")
+ use_max_influences = QtWidgets.QCheckBox("限制每个顶点的最大影响物")
max_influences = widgets.NumberSliderGroup(min_value=1, max_value=5, tooltip="", value_type=int)
- use_prune_weight = QtWidgets.QCheckBox("Prune small weights before writing to skin cluster")
+ use_prune_weight = QtWidgets.QCheckBox("在写入蒙皮簇之前修剪小权重")
prune_weight = widgets.NumberSliderGroup(decimals=6, min_value=0.000001, max_value=0.05, tooltip="")
prune_weight.set_value(prune_weight.min_value)
- prune_weight.set_expo("start", 3)
+ prune_weight.set_expo("开始", 3)
@signal.on(session.events.targetChanged)
def update_ui():
@@ -164,7 +164,7 @@ def build_ui():
@qt.on(use_max_influences.stateChanged, use_prune_weight.stateChanged)
@signal.on(max_influences.valueChanged, prune_weight.valueChanged)
def update_values():
- log.info("updating effects tab")
+ log.info("更新效果标签页")
if session.state.layersAvailable:
session.state.layers.influence_limit_per_vertex = max_influences.value() if use_max_influences.isChecked() else 0
@@ -174,11 +174,11 @@ def build_ui():
layout = QtWidgets.QVBoxLayout()
layout.addWidget(use_max_influences)
- layout.addLayout(createTitledRow("Max influences:", max_influences.layout()))
+ layout.addLayout(createTitledRow("最大影响物:", max_influences.layout()))
layout.addWidget(use_prune_weight)
- layout.addLayout(createTitledRow("Prune below:", prune_weight.layout()))
+ layout.addLayout(createTitledRow("修剪以下:", prune_weight.layout()))
- group = QtWidgets.QGroupBox("Skin Properties")
+ group = QtWidgets.QGroupBox("蒙皮属性")
group.setLayout(layout)
update_ui()
diff --git a/2023/scripts/rigging_tools/ngskintools2/ui/tabMirror.py b/2023/scripts/rigging_tools/ngskintools2/ui/tabMirror.py
index c8873f8..bae7ec9 100644
--- a/2023/scripts/rigging_tools/ngskintools2/ui/tabMirror.py
+++ b/2023/scripts/rigging_tools/ngskintools2/ui/tabMirror.py
@@ -16,10 +16,10 @@ def build_ui(parent_window):
def build_mirroring_options_group():
def get_mirror_direction():
mirror_direction = QtWidgets.QComboBox()
- mirror_direction.addItem("Guess from stroke", MirrorOptions.directionGuess)
- mirror_direction.addItem("Positive to negative", MirrorOptions.directionPositiveToNegative)
- mirror_direction.addItem("Negative to positive", MirrorOptions.directionNegativeToPositive)
- mirror_direction.addItem("Flip", MirrorOptions.directionFlip)
+ mirror_direction.addItem("从笔划猜测", MirrorOptions.directionGuess)
+ mirror_direction.addItem("从正到负", MirrorOptions.directionPositiveToNegative)
+ mirror_direction.addItem("从负到正", MirrorOptions.directionNegativeToPositive)
+ mirror_direction.addItem("翻转", MirrorOptions.directionFlip)
mirror_direction.setMinimumWidth(1)
qt.select_data(mirror_direction, config.mirror_direction())
@@ -65,19 +65,19 @@ def build_ui(parent_window):
return seam_width_ctrl.layout()
def elements():
- influences = bind_checkbox(QtWidgets.QCheckBox("Influence weights"), config.mirror_weights)
- mask = bind_checkbox(QtWidgets.QCheckBox("Layer mask"), config.mirror_mask)
- dq = bind_checkbox(QtWidgets.QCheckBox("Dual quaternion weights"), config.mirror_dq)
+ influences = bind_checkbox(QtWidgets.QCheckBox("影响物权重"), config.mirror_weights)
+ mask = bind_checkbox(QtWidgets.QCheckBox("图层遮罩"), config.mirror_mask)
+ dq = bind_checkbox(QtWidgets.QCheckBox("双四元权重"), config.mirror_dq)
return influences, mask, dq
- result = QtWidgets.QGroupBox("Mirroring options")
+ result = QtWidgets.QGroupBox("镜像选项")
layout = QtWidgets.QVBoxLayout()
result.setLayout(layout)
- layout.addLayout(createTitledRow("Axis:", axis()))
- layout.addLayout(createTitledRow("Direction:", get_mirror_direction()))
- layout.addLayout(createTitledRow("Seam width:", mirror_seam_width()))
- layout.addLayout(createTitledRow("Elements to mirror:", *elements()))
+ layout.addLayout(createTitledRow("镜像轴:", axis()))
+ layout.addLayout(createTitledRow("方向:", get_mirror_direction()))
+ layout.addLayout(createTitledRow("接缝宽度:", mirror_seam_width()))
+ layout.addLayout(createTitledRow("镜像要素:", *elements()))
return result
@@ -86,10 +86,10 @@ def build_ui(parent_window):
def mirror_mesh_group():
mesh_name_edit = QtWidgets.QLineEdit("mesh1")
mesh_name_edit.setReadOnly(True)
- select_button = QtWidgets.QPushButton("Select")
- create_button = QtWidgets.QPushButton("Create")
+ select_button = QtWidgets.QPushButton("选择")
+ create_button = QtWidgets.QPushButton("创建")
set_button = QtWidgets.QPushButton("Set")
- set_button.setToolTip("Select symmetry mesh and a skinned target first")
+ set_button.setToolTip("首先选择对称网格和蒙皮目标")
layout = QtWidgets.QHBoxLayout()
layout.addWidget(mesh_name_edit)
@@ -144,13 +144,13 @@ def build_ui(parent_window):
return layout
vertex_mapping_mode = QtWidgets.QComboBox()
- vertex_mapping_mode.addItem("Closest point on surface", VertexTransferMode.closestPoint)
- vertex_mapping_mode.addItem("UV space", VertexTransferMode.uvSpace)
+ vertex_mapping_mode.addItem("曲面上最近的点", VertexTransferMode.closestPoint)
+ vertex_mapping_mode.addItem("UV空间", VertexTransferMode.uvSpace)
- result = QtWidgets.QGroupBox("Vertex Mapping")
+ result = QtWidgets.QGroupBox("顶点映射")
layout = QtWidgets.QVBoxLayout()
- layout.addLayout(createTitledRow("Mapping mode:", vertex_mapping_mode))
- layout.addLayout(createTitledRow("Symmetry mesh:", mirror_mesh_group()))
+ layout.addLayout(createTitledRow("映射模式:", vertex_mapping_mode))
+ layout.addLayout(createTitledRow("对称网格:", mirror_mesh_group()))
result.setLayout(layout)
@qt.on(vertex_mapping_mode.currentIndexChanged)
@@ -166,7 +166,7 @@ def build_ui(parent_window):
def influence_mapping_group():
def edit_mapping():
- mapping = QtWidgets.QPushButton("Preview and edit mapping")
+ mapping = QtWidgets.QPushButton("预览和编辑映射")
single_window_policy = qt.SingleWindowPolicy()
@@ -182,7 +182,7 @@ def build_ui(parent_window):
layout = QtWidgets.QVBoxLayout()
layout.addWidget(edit_mapping())
- result = QtWidgets.QGroupBox("Influences mapping")
+ result = QtWidgets.QGroupBox("影响物映射")
result.setLayout(layout)
return result
@@ -192,7 +192,7 @@ def build_ui(parent_window):
tab.innerLayout.addWidget(influence_mapping_group())
tab.innerLayout.addStretch()
- btn_mirror = QtWidgets.QPushButton("Mirror")
+ btn_mirror = QtWidgets.QPushButton("镜像")
tab.lowerButtonsRow.addWidget(btn_mirror)
@qt.on(btn_mirror.clicked)
diff --git a/2023/scripts/rigging_tools/ngskintools2/ui/tabPaint.py b/2023/scripts/rigging_tools/ngskintools2/ui/tabPaint.py
index 9ee6d56..f265d6e 100644
--- a/2023/scripts/rigging_tools/ngskintools2/ui/tabPaint.py
+++ b/2023/scripts/rigging_tools/ngskintools2/ui/tabPaint.py
@@ -50,14 +50,14 @@ def build_ui(parent, global_actions):
t.addAction(a)
t = QtWidgets.QToolBar()
- create_brush_mode_button(t, PaintMode.replace, "Replace", "Whatever")
- create_brush_mode_button(t, PaintMode.add, "Add", "")
- create_brush_mode_button(t, PaintMode.scale, "Scale", "")
+ create_brush_mode_button(t, PaintMode.replace, "替换", "替换")
+ create_brush_mode_button(t, PaintMode.add, "添加", "")
+ create_brush_mode_button(t, PaintMode.scale, "减少", "")
row.addWidget(t)
t = QtWidgets.QToolBar()
- create_brush_mode_button(t, PaintMode.smooth, "Smooth", "")
- create_brush_mode_button(t, PaintMode.sharpen, "Sharpen", "")
+ create_brush_mode_button(t, PaintMode.smooth, "平滑", "")
+ create_brush_mode_button(t, PaintMode.sharpen, "锐化", "")
row.addWidget(t)
@on_signal(et.tool_settings_changed, scope=row)
@@ -96,9 +96,9 @@ def build_ui(parent, global_actions):
update_to_tool()
qt.on(a.toggled)(toggled)
- add_brush_shape_action(':/circleSolid.png', 'Solid', BrushShape.solid, checked=True)
- add_brush_shape_action(':/circlePoly.png', 'Smooth', BrushShape.smooth)
- add_brush_shape_action(':/circleGaus.png', 'Gaus', BrushShape.gaus)
+ add_brush_shape_action(':/circleSolid.png', '硬边圆', BrushShape.solid, checked=True)
+ add_brush_shape_action(':/circlePoly.png', '软边圆', BrushShape.smooth)
+ add_brush_shape_action(':/circleGaus.png', '喷枪', BrushShape.gaus)
return result
@@ -136,23 +136,23 @@ def build_ui(parent, global_actions):
update_to_tool()
add(
- 'Surface',
- 'Using first surface hit under the mouse, update all nearby vertices that are connected by surface to the hit location. '
- + 'Only current shell will be updated.',
+ '表面',
+ '绘制由与曲面相连的模型顶点.'
+ + '仅更新当前shell.',
BrushProjectionMode.surface,
use_volume=False,
checked=True,
)
add(
- 'Volume',
- 'Using first surface hit under the mouse, update all nearby vertices, including those from other shells.',
+ '体积',
+ '绘制附近所有模型顶点,包括没有连接的顶点.',
BrushProjectionMode.surface,
use_volume=True,
checked=False,
)
add(
- 'Screen',
- 'Use screen projection of a brush, updating all vertices on all surfaces that are within the brush radius.',
+ '屏幕',
+ '从屏幕方向投影到笔刷半径内所有曲面上的顶点.',
BrushProjectionMode.screen,
use_volume=False,
checked=False,
@@ -163,53 +163,53 @@ def build_ui(parent, global_actions):
def stylus_pressure_selection():
# noinspection PyShadowingNames
result = QtWidgets.QComboBox()
- result.addItem("Unused")
- result.addItem("Multiply intensity")
- result.addItem("Multiply opacity")
- result.addItem("Multiply radius")
+ result.addItem("未使用")
+ result.addItem("倍增强度")
+ result.addItem("倍增不透明度")
+ result.addItem("倍增半径")
return result
layout = QtWidgets.QVBoxLayout()
- layout.addLayout(createTitledRow("Brush projection:", brush_projection_mode_row()))
- layout.addLayout(createTitledRow("Brush mode:", brush_mode_row3()))
- layout.addLayout(createTitledRow("Brush shape:", brush_shape_row()))
+ layout.addLayout(createTitledRow("笔刷投影:", brush_projection_mode_row()))
+ layout.addLayout(createTitledRow("笔刷模式:", brush_mode_row3()))
+ layout.addLayout(createTitledRow("笔刷形状:", brush_shape_row()))
intensity = widgets.NumberSliderGroup()
radius = widgets.NumberSliderGroup(
- max_value=100, tooltip="You can also set brush radius by just holding B " "and mouse-dragging in the viewport"
+ max_value=100, tooltip="可以通过在视口中按住 B " "并鼠标左键按住拖动来设置笔刷半径"
)
iterations = widgets.NumberSliderGroup(value_type=int, min_value=1, max_value=100)
- layout.addLayout(createTitledRow("Intensity:", intensity.layout()))
- layout.addLayout(createTitledRow("Brush radius:", radius.layout()))
- layout.addLayout(createTitledRow("Brush iterations:", iterations.layout()))
+ layout.addLayout(createTitledRow("强度:", intensity.layout()))
+ layout.addLayout(createTitledRow("笔刷半径:", radius.layout()))
+ layout.addLayout(createTitledRow("笔刷迭代次数:", iterations.layout()))
influences_limit = widgets.NumberSliderGroup(value_type=int, min_value=0, max_value=10)
- layout.addLayout(createTitledRow("Influences limit:", influences_limit.layout()))
+ layout.addLayout(createTitledRow("影响物限制:", influences_limit.layout()))
@signal.on(influences_limit.valueChanged)
def influences_limit_changed():
paint.influences_limit = influences_limit.value()
update_ui()
- fixed_influences = QtWidgets.QCheckBox("Only adjust existing vertex influences")
+ fixed_influences = QtWidgets.QCheckBox("仅调整顶点现有影响物,防止周围权重扩散")
fixed_influences.setToolTip(
- "When this option is enabled, smooth will only adjust existing influences per vertex, "
- "and won't include other influences from nearby vertices"
+ "启用此选项后,平滑-将仅调整每个顶点的现有影响物, "
+ "而不会包含来自附近顶点的影响物,防止周围权重扩散"
)
- layout.addLayout(createTitledRow("Weight bleeding:", fixed_influences))
+ layout.addLayout(createTitledRow("平滑辅助:", fixed_influences))
@qt.on(fixed_influences.stateChanged)
def fixed_influences_changed():
paint.fixed_influences_per_vertex = fixed_influences.isChecked()
- limit_to_component_selection = QtWidgets.QCheckBox("Limit to component selection")
- limit_to_component_selection.setToolTip("When this option is enabled, smoothing will only happen between selected components")
- layout.addLayout(createTitledRow("Isolation:", limit_to_component_selection))
+ limit_to_component_selection = QtWidgets.QCheckBox("限制在选中组件中平滑")
+ limit_to_component_selection.setToolTip("启用此选项后,仅在选定组件之间进行平滑")
+ layout.addLayout(createTitledRow("隔离选中组件:", limit_to_component_selection))
@qt.on(limit_to_component_selection.stateChanged)
def limit_to_component_selection_changed():
paint.limit_to_component_selection = limit_to_component_selection.isChecked()
- interactive_mirror = QtWidgets.QCheckBox("Interactive mirror")
+ interactive_mirror = QtWidgets.QCheckBox("交互式镜像")
layout.addLayout(createTitledRow("", interactive_mirror))
@qt.on(interactive_mirror.stateChanged)
@@ -217,7 +217,7 @@ def build_ui(parent, global_actions):
paint.mirror = interactive_mirror.isChecked()
update_ui()
- sample_joint_on_stroke_start = QtWidgets.QCheckBox("Sample current joint on stroke start")
+ sample_joint_on_stroke_start = QtWidgets.QCheckBox("在笔画开始时取样当前骨骼")
layout.addLayout(createTitledRow("", sample_joint_on_stroke_start))
@qt.on(sample_joint_on_stroke_start.stateChanged)
@@ -225,8 +225,8 @@ def build_ui(parent, global_actions):
paint.sample_joint_on_stroke_start = sample_joint_on_stroke_start.isChecked()
update_ui()
- redistribute_removed_weight = QtWidgets.QCheckBox("Distribute to other influences")
- layout.addLayout(createTitledRow("Removed weight:", redistribute_removed_weight))
+ redistribute_removed_weight = QtWidgets.QCheckBox("分配给其它影响物")
+ layout.addLayout(createTitledRow("移除的权重:", redistribute_removed_weight))
@qt.on(redistribute_removed_weight.stateChanged)
def redistribute_removed_weight_changed():
@@ -234,12 +234,12 @@ def build_ui(parent, global_actions):
update_ui()
stylus = stylus_pressure_selection()
- layout.addLayout(createTitledRow("Stylus pressure:", stylus))
+ layout.addLayout(createTitledRow("手绘板压力:", stylus))
@on_signal(et.tool_settings_changed, scope=layout)
def update_ui():
- log.info("updating paint settings ui")
- log.info("brush mode:%s, brush shape: %s", paint.mode, paint.brush_shape)
+ log.info("更新的绘制设置的ui")
+ log.info("画笔模式:%s, 画笔形状: %s", paint.mode, paint.brush_shape)
paint.update_plugin_brush_radius()
paint.update_plugin_brush_intensity()
@@ -280,7 +280,7 @@ def build_ui(parent, global_actions):
@signal.on(radius.valueChanged, qtParent=layout)
def radius_edited():
- log.info("updated brush radius")
+ log.info("更新笔刷半径")
paint.brush_radius = radius.value()
update_ui()
@@ -301,18 +301,18 @@ def build_ui(parent, global_actions):
update_ui()
- result = QtWidgets.QGroupBox("Brush behavior")
+ result = QtWidgets.QGroupBox("笔刷行为")
result.setLayout(layout)
return result
def build_display_settings():
- result = QtWidgets.QGroupBox("Display settings")
+ result = QtWidgets.QGroupBox("显示设置")
layout = QtWidgets.QVBoxLayout()
influences_display = QtWidgets.QComboBox()
- influences_display.addItem("All influences, multiple colors", WeightsDisplayMode.allInfluences)
- influences_display.addItem("Current influence, grayscale", WeightsDisplayMode.currentInfluence)
- influences_display.addItem("Current influence, colored", WeightsDisplayMode.currentInfluenceColored)
+ influences_display.addItem("所有权重,多种颜色", WeightsDisplayMode.allInfluences)
+ influences_display.addItem("当前权重,灰度", WeightsDisplayMode.currentInfluence)
+ influences_display.addItem("当前权重,彩色", WeightsDisplayMode.currentInfluenceColored)
influences_display.setMinimumWidth(1)
influences_display.setCurrentIndex(paint.display_settings.weights_display_mode)
@@ -327,11 +327,11 @@ def build_ui(parent, global_actions):
display_layout = QtWidgets.QVBoxLayout()
display_layout.addWidget(influences_display)
display_layout.addWidget(display_toolbar)
- layout.addLayout(createTitledRow("Influences display:", display_layout))
+ layout.addLayout(createTitledRow("权重显示:", display_layout))
mask_display = QtWidgets.QComboBox()
- mask_display.addItem("Default", MaskDisplayMode.default_)
- mask_display.addItem("Color ramp", MaskDisplayMode.color_ramp)
+ mask_display.addItem("默认", MaskDisplayMode.default_)
+ mask_display.addItem("彩色渐变", MaskDisplayMode.color_ramp)
mask_display.setMinimumWidth(1)
mask_display.setCurrentIndex(paint.display_settings.weights_display_mode)
@@ -340,14 +340,14 @@ def build_ui(parent, global_actions):
paint.display_settings.mask_display_mode = mask_display.currentData()
update_ui_to_tool()
- layout.addLayout(createTitledRow("Mask display:", mask_display))
+ layout.addLayout(createTitledRow("表面显示:", mask_display))
- show_effects = QtWidgets.QCheckBox("Show layer effects")
+ show_effects = QtWidgets.QCheckBox("显示图层效果")
layout.addLayout(createTitledRow("", show_effects))
- show_masked = QtWidgets.QCheckBox("Show masked weights")
+ show_masked = QtWidgets.QCheckBox("显示蒙皮权重")
layout.addLayout(createTitledRow("", show_masked))
- show_selected_verts_only = QtWidgets.QCheckBox("Hide unselected vertices")
+ show_selected_verts_only = QtWidgets.QCheckBox("隐藏未选择的顶点")
layout.addLayout(createTitledRow("", show_selected_verts_only))
@qt.on(show_effects.stateChanged)
@@ -363,7 +363,7 @@ def build_ui(parent, global_actions):
paint.display_settings.show_selected_verts_only = show_selected_verts_only.isChecked()
mesh_toolbar = QtWidgets.QToolBar()
- toggle_original_mesh = QAction("Show Original Mesh", mesh_toolbar)
+ toggle_original_mesh = QAction("显示原本模型", mesh_toolbar)
toggle_original_mesh.setCheckable(True)
mesh_toolbar.addAction(toggle_original_mesh)
layout.addLayout(createTitledRow("", mesh_toolbar))
@@ -374,7 +374,7 @@ def build_ui(parent, global_actions):
update_ui_to_tool()
wireframe_color_button = widgets.ColorButton()
- layout.addLayout(createTitledRow("Wireframe color:", wireframe_color_button))
+ layout.addLayout(createTitledRow("线框颜色:", wireframe_color_button))
@signal.on(wireframe_color_button.color_changed)
def update_wireframe_color():
diff --git a/2023/scripts/rigging_tools/ngskintools2/ui/tabSetWeights.py b/2023/scripts/rigging_tools/ngskintools2/ui/tabSetWeights.py
index 0e0e67d..34cd91c 100644
--- a/2023/scripts/rigging_tools/ngskintools2/ui/tabSetWeights.py
+++ b/2023/scripts/rigging_tools/ngskintools2/ui/tabSetWeights.py
@@ -1,3 +1,4 @@
+# -*- coding: UTF-8 -*-
from ngSkinTools2 import signal
from ngSkinTools2.api import PaintMode, PaintModeSettings, flood_weights
from ngSkinTools2.api.log import getLogger
@@ -70,14 +71,14 @@ def build_ui(parent):
toolbar.addAction(a)
t = QtWidgets.QToolBar()
- create_mode_button(t, PaintMode.replace, "Replace", "")
- create_mode_button(t, PaintMode.add, "Add", "")
- create_mode_button(t, PaintMode.scale, "Scale", "")
+ create_mode_button(t, PaintMode.replace, "替换", "")
+ create_mode_button(t, PaintMode.add, "添加", "")
+ create_mode_button(t, PaintMode.scale, "减少", "")
row.addWidget(t)
t = QtWidgets.QToolBar()
- create_mode_button(t, PaintMode.smooth, "Smooth", "")
- create_mode_button(t, PaintMode.sharpen, "Sharpen", "")
+ create_mode_button(t, PaintMode.smooth, "平滑", "")
+ create_mode_button(t, PaintMode.sharpen, "锐化", "")
row.addWidget(t)
actions[model.current_settings.mode].setChecked(True)
@@ -109,20 +110,20 @@ def build_ui(parent):
model.current_settings.iterations = iterations.value()
update_ui()
- fixed_influences = QtWidgets.QCheckBox("Only adjust existing vertex influences")
+ fixed_influences = QtWidgets.QCheckBox("仅调整顶点现有影响物,防止周围权重扩散")
fixed_influences.setToolTip(
- "When this option is enabled, smooth will only adjust existing influences per vertex, "
- "and won't include other influences from nearby vertices"
+ "启用此选项后,平滑-将仅调整每个顶点的现有影响物, "
+ "而不会包含来自附近顶点的影响物,防止周围权重扩散"
)
- volume_neighbours = QtWidgets.QCheckBox("Smooth across gaps and thin surfaces")
+ volume_neighbours = QtWidgets.QCheckBox("平滑间隙和薄表面")
volume_neighbours.setToolTip(
- "Use all nearby neighbours, regardless if they belong to same surface. "
- "This will allow for smoothing to happen across gaps and thin surfaces."
+ "使用所有附近相邻的面,无论它们是否属于同一个曲面."
+ "这将允许在间隙和薄曲面之间进行平滑."
)
- limit_to_component_selection = QtWidgets.QCheckBox("Limit to component selection")
- limit_to_component_selection.setToolTip("When this option is enabled, smoothing will only happen between selected components")
+ limit_to_component_selection = QtWidgets.QCheckBox("在选择的组件中平滑")
+ limit_to_component_selection.setToolTip("启用此选项后,仅在选定组件之间进行平滑")
@qt.on(fixed_influences.stateChanged)
@ui_lock.skip_if_updating
@@ -154,16 +155,16 @@ def build_ui(parent):
volume_neighbours.setChecked(model.current_settings.use_volume_neighbours)
volume_neighbours.setEnabled(model.current_settings.mode == PaintMode.smooth)
- settings_group = QtWidgets.QGroupBox("Mode Settings")
+ settings_group = QtWidgets.QGroupBox("模式设置")
layout = QtWidgets.QVBoxLayout()
- layout.addLayout(createTitledRow("Mode:", mode_row()))
- layout.addLayout(createTitledRow("Intensity:", intensity.layout()))
- layout.addLayout(createTitledRow("Iterations:", iterations.layout()))
- layout.addLayout(createTitledRow("Influences limit:", influences_limit.layout()))
- layout.addLayout(createTitledRow("Weight bleeding:", fixed_influences))
- layout.addLayout(createTitledRow("Volume smoothing:", volume_neighbours))
- layout.addLayout(createTitledRow("Isolation:", limit_to_component_selection))
+ layout.addLayout(createTitledRow("模式:", mode_row()))
+ layout.addLayout(createTitledRow("强度:", intensity.layout()))
+ layout.addLayout(createTitledRow("迭代次数:", iterations.layout()))
+ layout.addLayout(createTitledRow("影响物限制:", influences_limit.layout()))
+ layout.addLayout(createTitledRow("平滑辅助:", fixed_influences))
+ layout.addLayout(createTitledRow("体积平滑:", volume_neighbours))
+ layout.addLayout(createTitledRow("隔离选中组件:", limit_to_component_selection))
settings_group.setLayout(layout)
update_ui()
@@ -173,7 +174,7 @@ def build_ui(parent):
def common_settings():
layout = QtWidgets.QVBoxLayout()
- mirror = QtWidgets.QCheckBox("Mirror")
+ mirror = QtWidgets.QCheckBox("镜像")
layout.addLayout(createTitledRow("", mirror))
@qt.on(mirror.stateChanged)
@@ -182,8 +183,8 @@ def build_ui(parent):
for _, v in model.presets.items():
v.mirror = mirror.isChecked()
- redistribute_removed_weight = QtWidgets.QCheckBox("Distribute to other influences")
- layout.addLayout(createTitledRow("Removed weight:", redistribute_removed_weight))
+ redistribute_removed_weight = QtWidgets.QCheckBox("分配给其它影响物")
+ layout.addLayout(createTitledRow("移除的权重:", redistribute_removed_weight))
@qt.on(redistribute_removed_weight.stateChanged)
def redistribute_removed_weight_changed():
@@ -195,7 +196,7 @@ def build_ui(parent):
mirror.setChecked(model.current_settings.mirror)
redistribute_removed_weight.setChecked(model.current_settings.distribute_to_other_influences)
- group = QtWidgets.QGroupBox("Common Settings")
+ group = QtWidgets.QGroupBox("常用设置")
group.setLayout(layout)
update_ui()
@@ -203,8 +204,8 @@ def build_ui(parent):
return group
def apply_button():
- btn = QtWidgets.QPushButton("Apply")
- btn.setToolTip("Apply selected operation to vertex")
+ btn = QtWidgets.QPushButton("应用")
+ btn.setToolTip("将设定操作应用于选中顶点")
@qt.on(btn.clicked)
def clicked():
diff --git a/2023/scripts/rigging_tools/ngskintools2/ui/tabTools.py b/2023/scripts/rigging_tools/ngskintools2/ui/tabTools.py
index 08e6c5c..0b930a7 100644
--- a/2023/scripts/rigging_tools/ngskintools2/ui/tabTools.py
+++ b/2023/scripts/rigging_tools/ngskintools2/ui/tabTools.py
@@ -1,3 +1,4 @@
+# -*- coding: UTF-8 -*-
from ngSkinTools2 import signal
from ngSkinTools2.api.pyside import QtWidgets
from ngSkinTools2.api.session import Session
@@ -20,7 +21,7 @@ def build_ui(actions, session):
def influences_options():
result = QtWidgets.QVBoxLayout()
button_group = QtWidgets.QButtonGroup()
- for index, i in enumerate(["Use all available influences", "Use selected influences"]):
+ for index, i in enumerate(["使用所有可用的影响物", "使用选定的影响物"]):
radio = QtWidgets.QRadioButton(i)
button_group.addButton(radio, index)
result.addWidget(radio)
@@ -38,7 +39,7 @@ def build_ui(actions, session):
return result
- new_layer = QtWidgets.QCheckBox("Create new layer")
+ new_layer = QtWidgets.QCheckBox("创建新图层")
@qt.on(new_layer.toggled)
def update_new_layer():
@@ -53,11 +54,11 @@ def build_ui(actions, session):
update_ui()
- result = QtWidgets.QGroupBox("Assign weights from closest joint")
+ result = QtWidgets.QGroupBox("从最近的关节指定权重")
layout = QtWidgets.QVBoxLayout()
result.setLayout(layout)
- layout.addLayout(createTitledRow("Target layer", new_layer))
- layout.addLayout(createTitledRow("Influences", influences_options()))
+ layout.addLayout(createTitledRow("目标层", new_layer))
+ layout.addLayout(createTitledRow("影响物", influences_options()))
layout.addWidget(btn)
return result
@@ -69,25 +70,25 @@ def build_ui(actions, session):
model_binds.bind(intensity, options.overall_effect)
single_cluster_mode = QtWidgets.QCheckBox(
- "Single group mode",
+ "单组模式",
)
- single_cluster_mode.setToolTip("average weights across whole selection, ignoring separate shells or selection gaps")
+ single_cluster_mode.setToolTip("整个选择的平均权重,忽略单独的壳或选择间隙")
model_binds.bind(single_cluster_mode, options.single_cluster_mode)
btn = QtWidgets.QPushButton()
qt.bind_action_to_button(actions.toolsUnifyWeights, btn)
- result = QtWidgets.QGroupBox("Unify weights")
+ result = QtWidgets.QGroupBox("统一权重")
layout = QtWidgets.QVBoxLayout()
result.setLayout(layout)
- layout.addLayout(createTitledRow("Intensity:", intensity.layout()))
- layout.addLayout(createTitledRow("Clustering:", single_cluster_mode))
+ layout.addLayout(createTitledRow("强度:", intensity.layout()))
+ layout.addLayout(createTitledRow("集群:", single_cluster_mode))
layout.addWidget(btn)
return result
def other_tools_group():
- result = QtWidgets.QGroupBox("Other")
+ result = QtWidgets.QGroupBox("其它")
layout = QtWidgets.QVBoxLayout()
result.setLayout(layout)
layout.addWidget(to_button(actions.fill_layer_transparency))
diff --git a/2023/scripts/rigging_tools/ngskintools2/ui/targetui.py b/2023/scripts/rigging_tools/ngskintools2/ui/targetui.py
index 7b3f975..70ababc 100644
--- a/2023/scripts/rigging_tools/ngskintools2/ui/targetui.py
+++ b/2023/scripts/rigging_tools/ngskintools2/ui/targetui.py
@@ -25,7 +25,7 @@ def build_layers_ui(parent, actions, session):
filter = QtWidgets.QComboBox()
filter.setMinimumHeight(22 * scale_multiplier)
filter.setEditable(True)
- filter.lineEdit().setPlaceholderText("Search...")
+ filter.lineEdit().setPlaceholderText("搜索...")
result.addWidget(filter)
# noinspection PyShadowingNames
clear = QAction(result)
@@ -83,7 +83,7 @@ def build_no_layers_ui(parent, actions, session):
selection_display = QtWidgets.QLabel("pPlane1")
selection_display.setStyleSheet("font-weight: bold")
- selection_note = QtWidgets.QLabel("Skinning Layers cannot be attached to this object")
+ selection_note = QtWidgets.QLabel("蒙皮层无法附加到此对象")
selection_note.setWordWrap(True)
layout.addStretch(1)
@@ -104,11 +104,11 @@ def build_no_layers_ui(parent, actions, session):
selection_display.setText(session.state.selectedSkinCluster)
selection_display.setVisible(is_skinned)
- note = "Select a mesh with a skin cluster attached."
+ note = "选择附着蒙皮节点的网格."
if is_skinned:
- note = "Skinning layers are not yet initialized for this mesh."
+ note = "尚未为此网格初始化蒙皮层."
if import_v1_actions.can_import(session):
- note = "Skinning layers from previous ngSkinTools version are initialized on this mesh."
+ note = "ngSkinTools的旧版本的蒙皮层在此网格上初始化."
selection_note.setText(note)
diff --git a/2023/scripts/rigging_tools/ngskintools2/ui/transferDialog.py b/2023/scripts/rigging_tools/ngskintools2/ui/transferDialog.py
index 7b5d13e..9270010 100644
--- a/2023/scripts/rigging_tools/ngskintools2/ui/transferDialog.py
+++ b/2023/scripts/rigging_tools/ngskintools2/ui/transferDialog.py
@@ -1,3 +1,4 @@
+# -*- coding: UTF-8 -*-
from ngSkinTools2 import api, cleanup, signal
from ngSkinTools2.api import VertexTransferMode
from ngSkinTools2.api.pyside import QtCore, QtWidgets
@@ -43,8 +44,8 @@ def open(parent, model):
return widgets.button_row(
[
- ("Transfer", apply),
- ("Cancel", window.close),
+ ("传递", apply),
+ ("取消", window.close),
]
)
@@ -55,32 +56,32 @@ def open(parent, model):
result = QtWidgets.QVBoxLayout()
vertexMappingMode = QtWidgets.QComboBox()
- vertexMappingMode.addItem("Closest point on surface", VertexTransferMode.closestPoint)
- vertexMappingMode.addItem("UV space", VertexTransferMode.uvSpace)
- vertexMappingMode.addItem("By vertex ID (source and destination vert count must match)", VertexTransferMode.vertexId)
+ vertexMappingMode.addItem("表面上最近的点", VertexTransferMode.closestPoint)
+ vertexMappingMode.addItem("UV空间", VertexTransferMode.uvSpace)
+ vertexMappingMode.addItem("按顶点ID(源和目标顶点数必须匹配)", VertexTransferMode.vertexId)
- g = QtWidgets.QGroupBox("Selection")
+ g = QtWidgets.QGroupBox("选择")
layout = QtWidgets.QVBoxLayout()
g.setLayout(layout)
sourceLabel = QtWidgets.QLabel()
- layout.addLayout(createTitledRow("Source:", sourceLabel))
+ layout.addLayout(createTitledRow("来源:", sourceLabel))
destinationLabel = QtWidgets.QLabel()
- layout.addLayout(createTitledRow("Destination:", destinationLabel))
+ layout.addLayout(createTitledRow("目标:", destinationLabel))
result.addWidget(g)
- g = QtWidgets.QGroupBox("Vertex mapping")
+ g = QtWidgets.QGroupBox("顶点映射")
layout = QtWidgets.QVBoxLayout()
- layout.addLayout(createTitledRow("Mapping mode:", vertexMappingMode))
+ layout.addLayout(createTitledRow("映射模式:", vertexMappingMode))
g.setLayout(layout)
result.addWidget(g)
- g = QtWidgets.QGroupBox("Influences mapping")
+ g = QtWidgets.QGroupBox("影响物映射")
layout = QtWidgets.QVBoxLayout()
g.setLayout(layout)
- edit = QtWidgets.QPushButton("Configure")
+ edit = QtWidgets.QPushButton("配置")
qt.on(edit.clicked)(view_influences_settings)
button_row = QtWidgets.QHBoxLayout()
@@ -90,12 +91,12 @@ def open(parent, model):
result.addWidget(g)
- g = QtWidgets.QGroupBox("Other options")
+ g = QtWidgets.QGroupBox("其他选项")
layout = QtWidgets.QVBoxLayout()
g.setLayout(layout)
- keep_layers = QtWidgets.QCheckBox("Keep existing layers on destination")
- keep_layers_row = qt.wrap_layout_into_widget(createTitledRow("Destination layers:", keep_layers))
+ keep_layers = QtWidgets.QCheckBox("保留目标网格的已有图层")
+ keep_layers_row = qt.wrap_layout_into_widget(createTitledRow("目标图层:", keep_layers))
layout.addWidget(keep_layers_row)
@qt.on(keep_layers.stateChanged)
@@ -137,12 +138,12 @@ def open(parent, model):
tabs = QtWidgets.QTabWidget()
- tabs.addTab(qt.wrap_layout_into_widget(build_settings()), "Settings")
- tabs.addTab(qt.wrap_layout_into_widget(build_influenes_tab()), "Influences mapping")
+ tabs.addTab(qt.wrap_layout_into_widget(build_settings()), "设置")
+ tabs.addTab(qt.wrap_layout_into_widget(build_influenes_tab()), "影响物映射")
window = QtWidgets.QDialog(parent)
cleanup.registerCleanupHandler(window.close)
- window.setWindowTitle("Transfer")
+ window.setWindowTitle("传递")
window.setAttribute(QtCore.Qt.WA_DeleteOnClose)
window.resize(720 * scale_multiplier, 500 * scale_multiplier)
window.setLayout(QtWidgets.QVBoxLayout())
@@ -196,7 +197,7 @@ def build_transfer_action(session, parent):
t.customize_callback = transfer_dialog
t.execute()
- result = define_action(parent, "Transfer layers...", callback=handler)
+ result = define_action(parent, "传递图层...", callback=handler)
@signal.on(session.events.nodeSelectionChanged)
def on_selection_changed():
diff --git a/2023/scripts/rigging_tools/ngskintools2/ui/updatewindow.py b/2023/scripts/rigging_tools/ngskintools2/ui/updatewindow.py
index dfdf7e3..5ac09e1 100644
--- a/2023/scripts/rigging_tools/ngskintools2/ui/updatewindow.py
+++ b/2023/scripts/rigging_tools/ngskintools2/ui/updatewindow.py
@@ -1,3 +1,4 @@
+# -*- coding: UTF-8 -*-
import webbrowser
from ngSkinTools2.api import versioncheck
@@ -27,10 +28,10 @@ def show(parent, silent_mode):
result.setLayout(layout)
layout.setContentsMargins(20, 30, 20, 20)
- header = QtWidgets.QLabel("Checking for update...")
- result1 = QtWidgets.QLabel("Current version: 2.0.0")
- result2 = QtWidgets.QLabel("Update available: 2.0.1")
- download = QtWidgets.QPushButton("Download ngSkinTools v2.0.1")
+ header = QtWidgets.QLabel(u"检查更新中...")
+ result1 = QtWidgets.QLabel(u"当前版本: 2.1.4")
+ result2 = QtWidgets.QLabel("最新版本: 2.1.4")
+ download = QtWidgets.QPushButton("下载 中文ngSkinTools v2.0.1")
# layout.addWidget(QtWidgets.QLabel("Checking for updates..."))
layout.addWidget(header)
layout.addWidget(result1)
@@ -52,16 +53,16 @@ def show(parent, silent_mode):
:type info: ngSkinTools2.api.versioncheck.
"""
- header.setText("{0}".format('Update available!' if info.update_available else 'ngSkinTools is up to date.'))
+ header.setText("{0}".format('更新可用!' if info.update_available else '中文ngSkinTools 已经是最新版.'))
result1.setVisible(True)
- result1.setText("Current version: {0}".format(version.pluginVersion()))
+ result1.setText(u"当前版本: {0}".format(version.pluginVersion()))
if info.update_available:
result2.setVisible(True)
result2.setText(
- "Update available: {0}, released on {1}".format(info.latest_version, info.update_date.strftime("%d %B, %Y"))
+ u"最新版本: {0}, 发布于 {1}".format(info.latest_version, info.update_date.strftime("%d %B, %Y"))
)
download.setVisible(True)
- download.setText("Download ngSkinTools v" + info.latest_version)
+ download.setText(u"下载 中文ngSkinTools v" + info.latest_version)
@qt.on(download.clicked)
def open_link():
@@ -71,10 +72,10 @@ def show(parent, silent_mode):
# noinspection PyShadowingNames
def buttonsRow(window):
- btn_close = QtWidgets.QPushButton("Close")
+ btn_close = QtWidgets.QPushButton("取消")
btn_close.setMinimumWidth(100 * scale_multiplier)
- check_do_on_startup = bind_checkbox(QtWidgets.QCheckBox("Check for updates at startup"), config.checkForUpdatesAtStartup)
+ check_do_on_startup = bind_checkbox(QtWidgets.QCheckBox("启动时检查更新"), config.checkForUpdatesAtStartup)
layout = QtWidgets.QHBoxLayout()
layout.addWidget(check_do_on_startup)
@@ -88,7 +89,7 @@ def show(parent, silent_mode):
window = QtWidgets.QWidget(parent, Qt.Window | Qt.WindowTitleHint | Qt.CustomizeWindowHint)
window.resize(400 * scale_multiplier, 200 * scale_multiplier)
window.setAttribute(Qt.WA_DeleteOnClose)
- window.setWindowTitle("ngSkinTools2 version update")
+ window.setWindowTitle("ngSkinTools2 (中文) 版本更新")
layout = QtWidgets.QVBoxLayout()
window.setLayout(layout)
layout.setContentsMargins(0, 0, 0, 0)
@@ -106,14 +107,14 @@ def show(parent, silent_mode):
if info.update_available:
window.show()
else:
- log.info("not showing the window")
+ log.info("未显示窗口")
window.close()
cleanup.registerCleanupHandler(window.close)
@qt.on(window.destroyed)
def closed():
- log.info("deleting update window")
+ log.info("删除更新窗口")
versioncheck.download_update_info(success_callback=success_signal.emit, failure_callback=error_signal.emit)
@@ -129,4 +130,4 @@ def show_and_start_update(parent):
def build_action_check_for_updates(parent):
from ngSkinTools2.ui import actions
- return actions.define_action(parent, "Check for Updates...", callback=lambda: show_and_start_update(parent))
+ return actions.define_action(parent, "检查更新...", callback=lambda: show_and_start_update(parent))
diff --git a/2023/scripts/rigging_tools/ngskintools2/version.py b/2023/scripts/rigging_tools/ngskintools2/version.py
index 29a258a..d279d88 100644
--- a/2023/scripts/rigging_tools/ngskintools2/version.py
+++ b/2023/scripts/rigging_tools/ngskintools2/version.py
@@ -66,7 +66,7 @@ class SemanticVersion(Object):
result = pattern.match(stringVersion)
if result is None:
- raise Exception("Invalid version string: '{0}'".format(stringVersion))
+ raise Exception("无效的版本字符串: '{0}'".format(stringVersion))
self.major = toInt(result.group(1))
self.minor = toInt(result.group(3))
diff --git a/2023/scripts/userSetup.py b/2023/scripts/userSetup.py
index ae107f0..cda9f83 100644
--- a/2023/scripts/userSetup.py
+++ b/2023/scripts/userSetup.py
@@ -13,37 +13,20 @@ Features:
- Maya 2018+ compatible
"""
-import maya.cmds as cmds
-import maya.mel as mel
-import maya.utils
+# Standard library imports
import atexit
import os
import sys
import re
-# Set MAYA_MODULE_PATH environment variable for external tools
+# Maya imports with error handling
try:
- _current_file = os.path.abspath(__file__)
- _script_dir = os.path.dirname(_current_file)
- _project_root = os.path.dirname(os.path.dirname(_script_dir))
- _modules_dir = os.path.join(_project_root, 'modules')
-
- if os.path.exists(_modules_dir):
- _modules_dir_normalized = os.path.normpath(_modules_dir)
- _current_module_path = os.environ.get('MAYA_MODULE_PATH', '')
-
- # Check if already in path
- _paths = [p.strip() for p in _current_module_path.split(os.pathsep) if p.strip()]
- _normalized_paths = [os.path.normpath(p) for p in _paths]
-
- if _modules_dir_normalized not in _normalized_paths:
- if _current_module_path:
- os.environ['MAYA_MODULE_PATH'] = f"{_modules_dir_normalized}{os.pathsep}{_current_module_path}"
- else:
- os.environ['MAYA_MODULE_PATH'] = _modules_dir_normalized
- print(f"[Tool] MAYA_MODULE_PATH set to: {_modules_dir_normalized}")
-except Exception as e:
- print(f"[Tool] Warning: Could not set MAYA_MODULE_PATH: {e}")
+ import maya.cmds as cmds
+ import maya.mel as mel
+ import maya.utils
+except ImportError as e:
+ print(f"[Tool] ERROR: Failed to import Maya modules: {e}")
+ raise
# Silently try to open default commandPort to avoid startup error if it's already in use
try:
@@ -51,6 +34,19 @@ try:
except Exception:
pass
+# =============================================================================
+# Constants
+# =============================================================================
+
+# Command port name
+COMMAND_PORT_NAME = "commandportDefault"
+
+# Log levels
+LOG_DEBUG = 0
+LOG_INFO = 1
+LOG_WARNING = 2
+LOG_ERROR = 3
+
# =============================================================================
# Configuration
# =============================================================================
@@ -58,6 +54,9 @@ except Exception:
# Shelves to load
SHELF_NAMES = ["Nexus_Manage", "Nexus_Modeling", "Nexus_Rigging", "Nexus_Animation", "Nexus_DevTools"]
+# User configuration file path (optional override)
+USER_CONFIG_FILE = os.path.join(os.path.expanduser("~"), ".nexus_maya_config.py")
+
# Tool packages configuration
TOOL_CONFIG = {
'scripts': [
@@ -67,12 +66,10 @@ TOOL_CONFIG = {
{'name': 'manage_tools', 'path': 'manage_tools'},
],
'plugins': [
- {'name': 'cv_manip.mll', 'path': 'modeling_tools/gs_curvetools/plugins/2023'},
{'name': 'ngskintools2.mll', 'path': 'rigging_tools/ngskintools2/plug-ins/2023'},
{'name': 'MGPicker_2023x64.mll', 'path': 'animation_tools/mgpicker/MGPicker_Program/Plug-ins'},
],
'icons': [
- {'name': 'gs_curvetools', 'path': 'modeling_tools/gs_curvetools/icons'},
{'name': 'gs_toolbox', 'path': 'modeling_tools/gs_toolbox/icons'},
{'name': 'modit', 'path': 'modeling_tools/ModIt/Icons/Theme_Classic'},
{'name': 'creaseplus', 'path': 'modeling_tools/creaseplus/icons'},
@@ -107,14 +104,41 @@ _ADDED_SCRIPT_PATHS = []
# Utility Functions
# =============================================================================
+def _log(msg, level=LOG_INFO):
+ """
+ Print log message with level control
+
+ Args:
+ msg: Message to print
+ level: LOG_DEBUG, LOG_INFO, LOG_WARNING, or LOG_ERROR
+ """
+ if level == LOG_DEBUG and not TOOL_DEBUG:
+ return
+
+ prefix_map = {
+ LOG_DEBUG: "[Tool:DEBUG]",
+ LOG_INFO: "[Tool]",
+ LOG_WARNING: "[Tool:WARNING]",
+ LOG_ERROR: "[Tool:ERROR]"
+ }
+ prefix = prefix_map.get(level, "[Tool]")
+ print(f"{prefix} {msg}")
+
def _tool_log(msg):
"""Print debug message if TOOL_DEBUG is enabled"""
- if TOOL_DEBUG:
- print(msg)
+ _log(msg, LOG_DEBUG)
def _tool_print(msg):
"""Print info message"""
- print(msg)
+ _log(msg, LOG_INFO)
+
+def _tool_warning(msg):
+ """Print warning message"""
+ _log(msg, LOG_WARNING)
+
+def _tool_error(msg):
+ """Print error message"""
+ _log(msg, LOG_ERROR)
def _get_script_dir():
"""Get the directory containing this script (with fallback)"""
@@ -157,16 +181,25 @@ def _check_maya_version():
try:
maya_version = int(cmds.about(version=True).split()[0])
if maya_version < MAYA_MIN_VERSION:
- _tool_print(f"[Tool] Warning: Maya {maya_version} detected. Minimum supported version is {MAYA_MIN_VERSION}")
+ _tool_warning(f"Maya {maya_version} detected. Minimum supported version is {MAYA_MIN_VERSION}")
return False
- _tool_log(f"[Tool] Maya version: {maya_version}")
+ _tool_log(f"Maya version: {maya_version}")
return True
except Exception as e:
- _tool_print(f"[Tool] Warning: Could not determine Maya version: {e}")
+ _tool_warning(f"Could not determine Maya version: {e}")
return True # Continue anyway
def _find_file_in_paths(filename, search_paths):
- """Find file in a list of search paths"""
+ """
+ Find file in a list of search paths
+
+ Args:
+ filename: Name of file to find
+ search_paths: List of directory paths to search
+
+ Returns:
+ Full path to file if found, None otherwise
+ """
for p in search_paths:
if not p:
continue
@@ -175,6 +208,45 @@ def _find_file_in_paths(filename, search_paths):
return candidate
return None
+def _validate_tool_config():
+ """
+ Validate TOOL_CONFIG structure
+
+ Returns:
+ True if valid, False otherwise
+ """
+ try:
+ required_keys = ['scripts', 'plugins', 'icons']
+ for key in required_keys:
+ if key not in TOOL_CONFIG:
+ _tool_error(f"Missing required key in TOOL_CONFIG: {key}")
+ return False
+
+ if not isinstance(TOOL_CONFIG[key], list):
+ _tool_error(f"TOOL_CONFIG['{key}'] must be a list")
+ return False
+
+ # Validate each item has required fields
+ for idx, item in enumerate(TOOL_CONFIG[key]):
+ if not isinstance(item, dict):
+ _tool_error(f"TOOL_CONFIG['{key}'][{idx}] must be a dict")
+ return False
+
+ if 'name' not in item:
+ _tool_error(f"TOOL_CONFIG['{key}'][{idx}] missing 'name' field")
+ return False
+
+ if 'path' not in item:
+ _tool_error(f"TOOL_CONFIG['{key}'][{idx}] missing 'path' field")
+ return False
+
+ _tool_log("TOOL_CONFIG validation passed")
+ return True
+
+ except Exception as e:
+ _tool_error(f"Error validating TOOL_CONFIG: {e}")
+ return False
+
def _verify_shelf_icon_references(search_paths):
"""Verify that shelf icon references can be resolved"""
if not TOOL_DEBUG:
@@ -198,9 +270,9 @@ def _verify_shelf_icon_references(search_paths):
for img in imgs:
found = any(os.path.exists(os.path.join(p, img).replace('\\', '/')) for p in search_paths)
if not found:
- _tool_log(f"[Tool] Warning: Icon '{img}' not found for shelf '{shelf_name}'")
+ _tool_warning(f"Icon '{img}' not found for shelf '{shelf_name}'")
except Exception as e:
- _tool_log(f"[Tool] Icon verification error: {e}")
+ _tool_log(f"Icon verification error: {e}")
def _remove_shelf_config(shelf_name):
"""Remove shelf config from Maya prefs to force reload"""
@@ -239,7 +311,7 @@ def setup_icon_paths():
if os.path.exists(full_path):
icon_paths[name] = full_path
else:
- _tool_print(f"[Tool] Warning: Icon path not found: {full_path}")
+ _tool_warning(f"Icon path not found: {full_path}")
# Check if already configured
global _ICONS_PATHS
@@ -273,7 +345,7 @@ def setup_icon_paths():
_verify_shelf_icon_references(paths)
except Exception as e:
- _tool_print(f"[Tool] Error setting up icon paths: {e}")
+ _tool_error(f"Error setting up icon paths: {e}")
def load_tool_shelves():
"""Load Nexus shelves into Maya"""
@@ -284,7 +356,7 @@ def load_tool_shelves():
script_dir = _get_script_dir()
shelf_paths = os.path.join(os.path.dirname(script_dir), "shelves")
if not os.path.exists(shelf_paths):
- _tool_print("[Tool] Shelf directory not found, skipping")
+ _tool_warning("Shelf directory not found, skipping")
return
shelf_path_list = [p.strip() for p in shelf_paths.split(os.pathsep) if p.strip()]
@@ -302,7 +374,7 @@ def load_tool_shelves():
break
if not shelf_file_found:
- _tool_print(f"[Tool] Shelf not found: shelf_{shelf_name}.mel")
+ _tool_warning(f"Shelf not found: shelf_{shelf_name}.mel")
continue
# Remove existing shelf
@@ -350,12 +422,12 @@ def load_tool_shelves():
_remove_shelf_config(shelf_name)
except Exception as e:
- _tool_print(f"[Tool] Error loading shelf {shelf_name}: {e}")
+ _tool_error(f"Error loading shelf {shelf_name}: {e}")
_tool_log(f"[Tool] ✓ Shelves: {loaded_count}/{len(SHELF_NAMES)} loaded")
except Exception as e:
- _tool_print(f"[Tool] Error loading shelves: {e}")
+ _tool_error(f"Error loading shelves: {e}")
def load_tool_plugins():
"""Load Nexus plugins"""
@@ -379,13 +451,13 @@ def load_tool_plugins():
# First check the configured path parameter
plugin_path = None
if plugin_rel_path:
- # Build the full path: script_dir/path/plugin_name
+ # Build full path: script_dir/path/plugin_name
full_path = _norm_path(os.path.join(script_dir, plugin_rel_path, plugin_name))
if os.path.exists(full_path):
plugin_path = full_path
_tool_log(f"[Tool] Found plugin at configured path: {plugin_path}")
- # If the configured path is not found, search the environment variable path.
+ # If the configuration path is not found, search the environment variable path.
if not plugin_path:
plugin_path = _find_file_in_paths(plugin_name, os.environ.get(env_var, '').split(os.pathsep))
@@ -398,7 +470,7 @@ def load_tool_plugins():
plugin_path = _find_file_in_paths(plugin_name, search_dirs)
if not plugin_path:
- _tool_print(f"[Tool] Plugin not found: {plugin_name}")
+ _tool_warning(f"Plugin not found: {plugin_name}")
continue
# Add plugin directory to environment
@@ -435,12 +507,12 @@ def load_tool_plugins():
loaded_count += 1
_LOADED_PLUGINS[plugin_basename] = plugin_path
except Exception as e:
- _tool_print(f"[Tool] Error loading plugin {plugin_basename}: {e}")
+ _tool_error(f"Error loading plugin {plugin_basename}: {e}")
_tool_log(f"[Tool] ✓ Plugins: {loaded_count}/{len(plugin_configs)} loaded")
except Exception as e:
- _tool_print(f"[Tool] Error loading plugins: {e}")
+ _tool_error(f"Error loading plugins: {e}")
def load_tool_scripts():
"""Add Nexus script paths to sys.path"""
@@ -451,7 +523,6 @@ def load_tool_scripts():
_tool_log("[Tool] No scripts configured")
return
- global _ADDED_SCRIPT_PATHS
loaded = 0
for cfg in script_configs:
name = cfg.get('name', '')
@@ -461,7 +532,7 @@ def load_tool_scripts():
full_path = os.path.normpath(os.path.join(script_dir, path))
if not os.path.exists(full_path):
- _tool_print(f"[Tool] Script path not found: {full_path}")
+ _tool_warning(f"Script path not found: {full_path}")
continue
if full_path not in sys.path:
@@ -473,10 +544,222 @@ def load_tool_scripts():
_tool_log(f"[Tool] ✓ Script paths: {loaded}/{len(script_configs)} added")
except Exception as e:
- _tool_print(f"[Tool] Error loading scripts: {e}")
+ _tool_error(f"Error loading scripts: {e}")
+
+def _parse_mod_file_line(line, maya_version, modules_dir, module_name):
+ """
+ Parse a single line from .mod file
+
+ Args:
+ line: Line to parse
+ maya_version: Current Maya version
+ modules_dir: Modules directory path
+ module_name: Name of the module
+
+ Returns:
+ Tuple of (in_correct_version, current_module_root) or None
+ """
+ parts = line.split()
+
+ if len(parts) < 4:
+ return None
+
+ # Detect current platform
+ current_platform = 'win64' if os.name == 'nt' else ('linux' if sys.platform.startswith('linux') else 'mac')
+
+ # Check for version and platform restrictions
+ has_version_requirement = False
+ version_matches = False
+ platform_matches = True # Assume match if no platform specified
+
+ for part in parts:
+ if part.startswith('MAYAVERSION:'):
+ has_version_requirement = True
+ required_version = int(part.split(':')[1])
+ version_matches = (required_version == maya_version)
+
+ if part.startswith('PLATFORM:'):
+ required_platform = part.split(':')[1].lower()
+ platform_matches = (required_platform == current_platform)
+
+ # Both version and platform must match (or not be specified)
+ if has_version_requirement:
+ if version_matches and platform_matches:
+ # Get the module root path (last parameter)
+ current_module_root = parts[-1]
+ if current_module_root.startswith('..'):
+ current_module_root = _norm_path(os.path.join(modules_dir, current_module_root))
+ _tool_print(f"{module_name}: Maya {maya_version} {current_platform} matched, root: {current_module_root}")
+ return (True, current_module_root)
+ else:
+ return (False, None)
+
+ # If there are no version restrictions, it works for all versions (but still check platform)
+ if platform_matches:
+ current_module_root = parts[-1]
+ if current_module_root.startswith('..'):
+ current_module_root = _norm_path(os.path.join(modules_dir, current_module_root))
+ _tool_print(f"{module_name}: No version restriction, root: {current_module_root}")
+ return (True, current_module_root)
+
+ return (False, None)
+
+def _load_plugins_from_directory(plugins_dir, mod_file):
+ """
+ Load all plugins from a directory
+
+ Args:
+ plugins_dir: Directory containing plugins
+ mod_file: Name of .mod file for logging
+
+ Returns:
+ Number of plugins loaded
+ """
+ plugins_loaded = 0
+
+ if not os.path.exists(plugins_dir):
+ _tool_log(f"Plugin dir not found: {plugins_dir}")
+ return 0
+
+ _tool_log(f"Checking plugin dir: {plugins_dir}")
+
+ for plugin_file in os.listdir(plugins_dir):
+ if not plugin_file.endswith(('.mll', '.so', '.bundle', '.py')):
+ continue
+
+ plugin_name = os.path.splitext(plugin_file)[0]
+ plugin_full_path = _norm_path(os.path.join(plugins_dir, plugin_file))
+
+ # Check if already tracked
+ if plugin_name in _LOADED_PLUGINS:
+ _tool_log(f"Plugin already tracked: {plugin_name}")
+ continue
+
+ # Check if already loaded
+ try:
+ is_loaded = cmds.pluginInfo(plugin_name, query=True, loaded=True)
+ except:
+ is_loaded = False
+
+ if not is_loaded:
+ try:
+ cmds.loadPlugin(plugin_full_path, quiet=False)
+ _tool_print(f"✓ Plugin loaded: {plugin_name} (from {mod_file})")
+ plugins_loaded += 1
+ _LOADED_PLUGINS[plugin_name] = plugin_full_path
+ except Exception as e:
+ _tool_error(f"Failed to load {plugin_name}: {e}")
+ else:
+ _tool_log(f"Plugin already loaded: {plugin_name}")
+ _LOADED_PLUGINS[plugin_name] = plugin_full_path
+
+ return plugins_loaded
+
+def _add_path_to_environment(env_var, path):
+ """
+ Add a path to an environment variable
+
+ Args:
+ env_var: Environment variable name (e.g., 'MAYA_SCRIPT_PATH')
+ path: Path to add
+
+ Returns:
+ True if added, False if already exists
+ """
+ if not os.path.exists(path):
+ _tool_warning(f"Path not found for {env_var}: {path}")
+ return False
+
+ # Get current paths
+ current_value = os.environ.get(env_var, '')
+ current_paths = [p.strip() for p in current_value.split(os.pathsep) if p.strip()]
+
+ # Normalize the new path
+ norm_path = _norm_path(path)
+
+ # Check if already in path
+ if norm_path in [_norm_path(p) for p in current_paths]:
+ _tool_log(f"{env_var} already contains: {norm_path}")
+ return False
+
+ # Add to front of path list
+ current_paths.insert(0, norm_path)
+ new_value = os.pathsep.join(current_paths)
+ os.environ[env_var] = new_value
+
+ # Update MEL environment if needed
+ if env_var in ['XBMLANGPATH', 'MAYA_SCRIPT_PATH', 'MAYA_PLUG_IN_PATH']:
+ try:
+ safe_value = new_value.replace('\\', '/').replace('"', '\\"')
+ mel.eval(f'putenv "{env_var}" "{safe_value}";')
+ except Exception as e:
+ _tool_warning(f"Could not update MEL environment for {env_var}: {e}")
+
+ # Also add PYTHONPATH to sys.path for Python imports
+ if env_var == 'PYTHONPATH':
+ if norm_path not in sys.path:
+ sys.path.insert(0, norm_path)
+ _tool_log(f"Added to sys.path: {norm_path}")
+
+ _tool_print(f"✓ Added to {env_var}: {os.path.basename(norm_path)}")
+ return True
+
+def _load_user_config():
+ """
+ Load user configuration from optional config file
+ Allows users to override default TOOL_CONFIG settings
+ """
+ global TOOL_CONFIG, SHELF_NAMES
+
+ if not os.path.exists(USER_CONFIG_FILE):
+ _tool_log(f"No user config file found at: {USER_CONFIG_FILE}")
+ return
+
+ try:
+ _tool_print(f"Loading user configuration from: {USER_CONFIG_FILE}")
+
+ # Create a namespace for user config
+ user_namespace = {}
+
+ # Execute user config file
+ with open(USER_CONFIG_FILE, 'r', encoding='utf-8') as f:
+ exec(f.read(), user_namespace)
+
+ # Override TOOL_CONFIG if provided
+ if 'TOOL_CONFIG' in user_namespace:
+ user_config = user_namespace['TOOL_CONFIG']
+
+ # Merge configurations
+ for key in ['scripts', 'plugins', 'icons']:
+ if key in user_config:
+ if key in TOOL_CONFIG:
+ # Extend existing config
+ TOOL_CONFIG[key].extend(user_config[key])
+ else:
+ # Add new key
+ TOOL_CONFIG[key] = user_config[key]
+
+ _tool_print("✓ User TOOL_CONFIG loaded and merged")
+
+ # Override SHELF_NAMES if provided
+ if 'SHELF_NAMES' in user_namespace:
+ user_shelves = user_namespace['SHELF_NAMES']
+ if isinstance(user_shelves, list):
+ # Extend shelf list
+ for shelf in user_shelves:
+ if shelf not in SHELF_NAMES:
+ SHELF_NAMES.append(shelf)
+ _tool_print(f"✓ User SHELF_NAMES loaded: {user_shelves}")
+
+ _tool_print("✓ User configuration applied successfully")
+
+ except Exception as e:
+ _tool_error(f"Error loading user config: {e}")
+ import traceback
+ traceback.print_exc()
def load_project_modules():
- """从 modules 目录加载 .mod 文件定义的插件"""
+ """Load plugins defined in .mod files from the modules directory."""
try:
# Get current Maya version
maya_version = int(cmds.about(version=True).split()[0])
@@ -487,114 +770,155 @@ def load_project_modules():
modules_dir = _norm_path(os.path.join(project_root, "modules"))
if not os.path.exists(modules_dir):
- _tool_log(f"[Tool] Modules directory not found: {modules_dir}")
+ _tool_log(f"Modules directory not found: {modules_dir}")
return
# Find all .mod files
mod_files = [f for f in os.listdir(modules_dir) if f.endswith('.mod')]
if not mod_files:
- _tool_log(f"[Tool] No .mod files found in: {modules_dir}")
+ _tool_log(f"No .mod files found in: {modules_dir}")
return
- _tool_print(f"[Tool] Found {len(mod_files)} module(s): {', '.join(mod_files)}")
+ _tool_print(f"Found {len(mod_files)} module(s): {', '.join(mod_files)}")
+
+ # TWO-PASS APPROACH: First configure all environment variables, then load plugins
+ # This ensures dependencies are available before plugins initialize
+
+ # PASS 1: Configure all environment variables (including MAYA_PLUG_IN_PATH paths)
+ # Track processed modules to avoid duplicates
+ processed_modules = set()
- # Parse .mod files and load plugins.
- plugins_loaded = 0
for mod_file in mod_files:
mod_path = os.path.join(modules_dir, mod_file)
- _tool_log(f"[Tool] Processing: {mod_file}")
+ module_name = os.path.splitext(mod_file)[0]
try:
current_module_root = None
in_correct_version = False
+ module_key = None
with open(mod_path, 'r', encoding='utf-8') as f:
for line in f:
line = line.strip()
-
+
# Skip comments and empty lines
if not line or line.startswith('#') or line.startswith('//'):
continue
-
+
# Parse module definition lines (starting with +)
if line.startswith('+'):
- parts = line.split()
- in_correct_version = False
- current_module_root = None
-
- if len(parts) >= 4:
- # Check for version restrictions.
- has_version_requirement = False
- for part in parts:
- if part.startswith('MAYAVERSION:'):
- has_version_requirement = True
- required_version = int(part.split(':')[1])
- if required_version == maya_version:
- in_correct_version = True
- # Get the module root path (last parameter)
- current_module_root = parts[-1]
- if current_module_root.startswith('..'):
- current_module_root = _norm_path(os.path.join(modules_dir, current_module_root))
- _tool_log(f"[Tool] Version matched for Maya {maya_version}: {current_module_root}")
- break
-
- # If there are no version restrictions, it works for all versions.
- if not has_version_requirement:
- in_correct_version = True
- current_module_root = parts[-1]
- if current_module_root.startswith('..'):
- current_module_root = _norm_path(os.path.join(modules_dir, current_module_root))
- _tool_log(f"[Tool] Module without version restriction loaded: {current_module_root}")
-
- # Only process MAYA_PLUG_IN_PATH that matches the version
+ result = _parse_mod_file_line(line, maya_version, modules_dir, module_name)
+ if result:
+ in_correct_version, current_module_root = result
+ # Create unique key for this module version
+ module_key = f"{module_name}:{maya_version}:{current_module_root}"
+
+ # Skip if already processed
+ if module_key in processed_modules:
+ _tool_log(f"Skipping duplicate module definition: {module_key}")
+ in_correct_version = False
+ current_module_root = None
+ continue
+
+ processed_modules.add(module_key)
+ else:
+ in_correct_version = False
+ current_module_root = None
+ module_key = None
+
+ # Process ALL environment variables in first pass (including MAYA_PLUG_IN_PATH to env, but don't load plugins)
+ elif in_correct_version and current_module_root and ('+:=' in line or '+=' in line):
+ if line.startswith('MAYA_PLUG_IN_PATH'):
+ # Add plugin directory to MAYA_PLUG_IN_PATH environment, but don't load plugins yet
+ plugin_path_relative = line.split('+:=')[-1].strip() if '+:=' in line else line.split('+=')[-1].strip()
+ plugins_dir = _norm_path(os.path.join(current_module_root, plugin_path_relative))
+ _add_path_to_environment('MAYA_PLUG_IN_PATH', plugins_dir)
+
+ elif line.startswith('MAYA_SCRIPT_PATH'):
+ script_path_relative = line.split('+:=')[-1].strip() if '+:=' in line else line.split('+=')[-1].strip()
+ script_path = _norm_path(os.path.join(current_module_root, script_path_relative))
+ _add_path_to_environment('MAYA_SCRIPT_PATH', script_path)
+ if script_path not in sys.path:
+ sys.path.insert(0, script_path)
+
+ elif line.startswith('XBMLANGPATH'):
+ icon_path_relative = line.split('+:=')[-1].strip() if '+:=' in line else line.split('+=')[-1].strip()
+ icon_path = _norm_path(os.path.join(current_module_root, icon_path_relative))
+ _add_path_to_environment('XBMLANGPATH', icon_path)
+
+ else:
+ # Handle PATH, PYTHONPATH, and other environment variables
+ try:
+ env_var = line.split('+')[0].strip()
+ rel_path = line.split('+:=')[-1].strip() if '+:=' in line else line.split('+=')[-1].strip()
+ full_path = _norm_path(os.path.join(current_module_root, rel_path))
+ _add_path_to_environment(env_var, full_path)
+ except Exception as e:
+ _tool_log(f"Could not process environment variable line: {line}, error: {e}")
+
+ except Exception as e:
+ _tool_error(f"Error processing environment variables in {mod_file}: {e}")
+
+ # PASS 2: Now load plugins with all dependencies configured
+ _tool_log("Environment variables configured, now loading plugins...")
+ plugins_loaded = 0
+ processed_modules.clear() # Reset for second pass
+
+ for mod_file in mod_files:
+ mod_path = os.path.join(modules_dir, mod_file)
+ module_name = os.path.splitext(mod_file)[0]
+
+ try:
+ current_module_root = None
+ in_correct_version = False
+ module_key = None
+
+ with open(mod_path, 'r', encoding='utf-8') as f:
+ for line in f:
+ line = line.strip()
+
+ if not line or line.startswith('#') or line.startswith('//'):
+ continue
+
+ if line.startswith('+'):
+ result = _parse_mod_file_line(line, maya_version, modules_dir, module_name)
+ if result:
+ in_correct_version, current_module_root = result
+ module_key = f"{module_name}:{maya_version}:{current_module_root}"
+
+ # Skip if already processed
+ if module_key in processed_modules:
+ _tool_log(f"Skipping duplicate module definition for plugin loading: {module_key}")
+ in_correct_version = False
+ current_module_root = None
+ continue
+
+ processed_modules.add(module_key)
+ else:
+ in_correct_version = False
+ current_module_root = None
+ module_key = None
+
+ # Now load plugins
elif line.startswith('MAYA_PLUG_IN_PATH') and in_correct_version and current_module_root:
if '+:=' in line or '+=' in line:
- plugin_path_relative = line.split('=')[-1].strip()
-
+ plugin_path_relative = line.split('+:=')[-1].strip() if '+:=' in line else line.split('+=')[-1].strip()
plugins_dir = _norm_path(os.path.join(current_module_root, plugin_path_relative))
-
-
- if os.path.exists(plugins_dir):
- _tool_log(f"[Tool] Checking plugin dir: {plugins_dir}")
-
- for plugin_file in os.listdir(plugins_dir):
- if plugin_file.endswith(('.mll', '.so', '.bundle', '.py')):
- plugin_name = os.path.splitext(plugin_file)[0]
- plugin_full_path = os.path.join(plugins_dir, plugin_file)
-
- # Check if it has been loaded
- if plugin_name in _LOADED_PLUGINS:
- continue
-
- try:
- is_loaded = cmds.pluginInfo(plugin_name, query=True, loaded=True)
- except:
- is_loaded = False
-
- if not is_loaded:
- try:
- cmds.loadPlugin(plugin_full_path, quiet=True)
- _tool_print(f"[Tool] ✓ Plugin loaded: {plugin_name} (from {mod_file})")
- plugins_loaded += 1
- _LOADED_PLUGINS[plugin_name] = plugin_full_path
- except Exception as e:
- _tool_print(f"[Tool] Failed to load {plugin_name}: {e}")
- else:
- _tool_log(f"[Tool] Plugin dir not found: {plugins_dir}")
+ plugins_loaded += _load_plugins_from_directory(plugins_dir, mod_file)
except Exception as e:
- _tool_print(f"[Tool] Error processing {mod_file}: {e}")
+ _tool_error(f"Error processing {mod_file}: {e}")
import traceback
traceback.print_exc()
if plugins_loaded > 0:
- _tool_print(f"[Tool] ✓ Total {plugins_loaded} module plugin(s) loaded")
+ _tool_print(f"✓ Total {plugins_loaded} module plugin(s) loaded")
else:
- _tool_print(f"[Tool] No module plugins loaded")
+ _tool_print("No module plugins loaded")
except Exception as e:
- _tool_print(f"[Tool] Error loading modules: {e}")
+ _tool_error(f"Error loading modules: {e}")
import traceback
traceback.print_exc()
@@ -604,18 +928,18 @@ def setup_command_port():
try:
# Check if already open
try:
- port_exists = bool(mel.eval('commandPort -q -name "commandportDefault"'))
+ port_exists = bool(mel.eval(f'commandPort -q -name "{COMMAND_PORT_NAME}"'))
except Exception:
port_exists = False
if port_exists:
- _tool_log("[Tool] Command port already open")
+ _tool_log("Command port already open")
_COMMAND_PORT_OPENED = True
return
# Open command port
- mel.eval('commandPort -securityWarning -name "commandportDefault";')
- _tool_log("[Tool] ✓ Command port opened")
+ mel.eval(f'commandPort -securityWarning -name "{COMMAND_PORT_NAME}";')
+ _tool_log("✓ Command port opened")
_COMMAND_PORT_OPENED = True
except Exception as e:
@@ -632,15 +956,19 @@ def initialize_tool():
print("[Tool] Nexus Plugin System - Initializing...")
print("=" * 80)
+ # Validate configuration
+ if not _validate_tool_config():
+ _tool_error("Configuration validation failed, continuing with caution...")
+
# Check Maya version compatibility
if not _check_maya_version():
- print("[Tool] Warning: Running on unsupported Maya version")
+ _tool_warning("Running on unsupported Maya version")
- # Set icon paths first, so shelves can find icons
+ # First, set the icon path so that the shelf can find the icon when it loads.
setup_icon_paths()
# Load project modules
- load_project_modules() # Automatic loading using Maya standard module system
+ load_project_modules() # Use Maya standard module systems for automatic loading.
# Setup command port
setup_command_port()
@@ -675,11 +1003,11 @@ def cleanup_on_exit():
global _COMMAND_PORT_OPENED
if _COMMAND_PORT_OPENED:
try:
- if mel.eval('commandPort -q -name "commandportDefault"'):
- mel.eval('commandPort -cl "commandportDefault"')
- _tool_log("[Tool] ✓ Command port closed")
+ if mel.eval(f'commandPort -q -name "{COMMAND_PORT_NAME}"'):
+ mel.eval(f'commandPort -cl "{COMMAND_PORT_NAME}"')
+ _tool_log("✓ Command port closed")
except Exception as e:
- _tool_log(f"[Tool] Could not close command port: {e}")
+ _tool_log(f"Could not close command port: {e}")
# Unload plugins
if _LOADED_PLUGINS:
@@ -727,4 +1055,4 @@ def cleanup_on_exit():
_tool_log(f"[Tool] Cleanup error: {e}")
# Register cleanup function
-atexit.register(cleanup_on_exit)
\ No newline at end of file
+atexit.register(cleanup_on_exit)
diff --git a/2023/shelves/shelf_Nexus_Modeling.mel b/2023/shelves/shelf_Nexus_Modeling.mel
index 51da4c7..f72fdf6 100644
--- a/2023/shelves/shelf_Nexus_Modeling.mel
+++ b/2023/shelves/shelf_Nexus_Modeling.mel
@@ -109,111 +109,6 @@ global proc shelf_Nexus_Modeling () {
-commandRepeatable 1
-flat 1
;
- shelfButton
- -enableCommandRepeat 1
- -flexibleWidthType 3
- -flexibleWidthValue 36
- -enable 1
- -width 39
- -height 34
- -manage 1
- -visible 1
- -preventOverride 0
- -annotation "GS Curvetools - Open UI"
- -enableBackground 0
- -backgroundColor 0 0 0
- -highlightColor 0.321569 0.521569 0.65098
- -align "center"
- -label "GSCurve"
- -labelOffset 0
- -rotation 0
- -flipX 0
- -flipY 0
- -useAlpha 1
- -font "plainLabelFont"
- -imageOverlayLabel "UI"
- -overlayLabelColor 0.8 0.8 0.8
- -overlayLabelBackColor 0 0 0 0.5
- -image "gsCurveToolsIcon_ui.png"
- -image1 "gsCurveToolsIcon_ui.png"
- -style "iconOnly"
- -marginWidth 0
- -marginHeight 1
- -command "import gs_curvetools.main as gs_curvetools_main; gs_curvetools_main.main();"
- -sourceType "python"
- -commandRepeatable 1
- -flat 1
- ;
- shelfButton
- -enableCommandRepeat 1
- -flexibleWidthType 3
- -flexibleWidthValue 36
- -enable 1
- -width 39
- -height 34
- -manage 1
- -visible 1
- -preventOverride 0
- -annotation "GS Curvetools - Reset"
- -enableBackground 0
- -backgroundColor 0 0 0
- -highlightColor 0.321569 0.521569 0.65098
- -align "center"
- -label "GSCReset"
- -labelOffset 0
- -rotation 0
- -flipX 0
- -flipY 0
- -useAlpha 1
- -font "plainLabelFont"
- -imageOverlayLabel "Reset"
- -overlayLabelColor 0.8 0.8 0.8
- -overlayLabelBackColor 0 0 0 0.5
- -image "gsCurveToolsIcon_reset.png"
- -image1 "gsCurveToolsIcon_reset.png"
- -style "iconOnly"
- -marginWidth 0
- -marginHeight 1
- -command "import gs_curvetools.core.utils as gs_curvetools_utils; gs_curvetools_utils.reset_ui(); del gs_curvetools_utils"
- -sourceType "python"
- -commandRepeatable 1
- -flat 1
- ;
- shelfButton
- -enableCommandRepeat 1
- -flexibleWidthType 3
- -flexibleWidthValue 36
- -enable 1
- -width 39
- -height 34
- -manage 1
- -visible 1
- -preventOverride 0
- -annotation "GS Curvetools - Stop/Close"
- -enableBackground 0
- -backgroundColor 0 0 0
- -highlightColor 0.321569 0.521569 0.65098
- -align "center"
- -label "GSCStop"
- -labelOffset 0
- -rotation 0
- -flipX 0
- -flipY 0
- -useAlpha 1
- -font "plainLabelFont"
- -imageOverlayLabel "Stop"
- -overlayLabelColor 0.8 0.8 0.8
- -overlayLabelBackColor 0 0 0 0.5
- -image "gsCurveToolsIcon_stop.png"
- -image1 "gsCurveToolsIcon_stop.png"
- -style "iconOnly"
- -marginWidth 0
- -marginHeight 1
- -command "import gs_curvetools.core.utils as gs_curvetools_utils; gs_curvetools_utils.stop_ui(); del gs_curvetools_utils"
- -sourceType "python"
- -commandRepeatable 1
- -flat 1
- ;
shelfButton
-enableCommandRepeat 1
-flexibleWidthType 3
diff --git a/2024/icons/EzRename.py b/2024/icons/EzRename.py
deleted file mode 100644
index ebe7c7f..0000000
Binary files a/2024/icons/EzRename.py and /dev/null differ
diff --git a/2024/scripts/animation_tools/mgpicker/MGPicker_Program/Plug-ins/MGPicker_2017x64.mll b/2024/scripts/animation_tools/mgpicker/MGPicker_Program/Plug-ins/MGPicker_2017x64.mll
deleted file mode 100644
index e7657f1..0000000
Binary files a/2024/scripts/animation_tools/mgpicker/MGPicker_Program/Plug-ins/MGPicker_2017x64.mll and /dev/null differ
diff --git a/2024/scripts/animation_tools/mgpicker/MGPicker_Program/Plug-ins/MGPicker_2018x64.mll b/2024/scripts/animation_tools/mgpicker/MGPicker_Program/Plug-ins/MGPicker_2018x64.mll
deleted file mode 100644
index af0b394..0000000
Binary files a/2024/scripts/animation_tools/mgpicker/MGPicker_Program/Plug-ins/MGPicker_2018x64.mll and /dev/null differ
diff --git a/2024/scripts/animation_tools/mgpicker/MGPicker_Program/Plug-ins/MGPicker_2019x64.mll b/2024/scripts/animation_tools/mgpicker/MGPicker_Program/Plug-ins/MGPicker_2019x64.mll
deleted file mode 100644
index 7243098..0000000
Binary files a/2024/scripts/animation_tools/mgpicker/MGPicker_Program/Plug-ins/MGPicker_2019x64.mll and /dev/null differ
diff --git a/2024/scripts/animation_tools/mgpicker/MGPicker_Program/Plug-ins/MGPicker_2020x64.mll b/2024/scripts/animation_tools/mgpicker/MGPicker_Program/Plug-ins/MGPicker_2020x64.mll
deleted file mode 100644
index 896efed..0000000
Binary files a/2024/scripts/animation_tools/mgpicker/MGPicker_Program/Plug-ins/MGPicker_2020x64.mll and /dev/null differ
diff --git a/2024/scripts/animation_tools/mgpicker/MGPicker_Program/Plug-ins/MGPicker_2022x64.mll b/2024/scripts/animation_tools/mgpicker/MGPicker_Program/Plug-ins/MGPicker_2022x64.mll
deleted file mode 100644
index f70eef9..0000000
Binary files a/2024/scripts/animation_tools/mgpicker/MGPicker_Program/Plug-ins/MGPicker_2022x64.mll and /dev/null differ
diff --git a/2024/scripts/animation_tools/mgpicker/MGPicker_Program/Plug-ins/MGPicker_2023x64.mll b/2024/scripts/animation_tools/mgpicker/MGPicker_Program/Plug-ins/MGPicker_2023x64.mll
deleted file mode 100644
index e324793..0000000
Binary files a/2024/scripts/animation_tools/mgpicker/MGPicker_Program/Plug-ins/MGPicker_2023x64.mll and /dev/null differ
diff --git a/2024/scripts/animation_tools/mgpicker/MGPicker_Program/Plug-ins/MGPicker_2025x64.mll b/2024/scripts/animation_tools/mgpicker/MGPicker_Program/Plug-ins/MGPicker_2025x64.mll
deleted file mode 100644
index fd01df6..0000000
Binary files a/2024/scripts/animation_tools/mgpicker/MGPicker_Program/Plug-ins/MGPicker_2025x64.mll and /dev/null differ
diff --git a/2024/scripts/animation_tools/mgpicker/MGPicker_Program/Plug-ins/MGPicker_2026x64.mll b/2024/scripts/animation_tools/mgpicker/MGPicker_Program/Plug-ins/MGPicker_2026x64.mll
deleted file mode 100644
index 95c8337..0000000
Binary files a/2024/scripts/animation_tools/mgpicker/MGPicker_Program/Plug-ins/MGPicker_2026x64.mll and /dev/null differ
diff --git a/2024/scripts/modeling_tools/gs_curvetools/LICENSE.txt b/2024/scripts/modeling_tools/gs_curvetools/LICENSE.txt
deleted file mode 100644
index e89f3e5..0000000
--- a/2024/scripts/modeling_tools/gs_curvetools/LICENSE.txt
+++ /dev/null
@@ -1,209 +0,0 @@
-"""
-GS CurveTools License:
-This collection of code named GS CurveTools is a property of George Sladkovsky (Yehor Sladkovskyi)
-and can not be copied or distributed without his written permission.
-
-GS CurveTools v1.3.11 Personal Edition
-Copyright 2025, George Sladkovsky (Yehor Sladkovskyi)
-All Rights Reserved
-
-UI font is Roboto that is licensed under the Apache 2.0 License:
-http://www.apache.org/licenses/LICENSE-2.0
-
-Autodesk Maya is a property of Autodesk, Inc:
-https://www.autodesk.com/
-
-Social Media and Contact Links:
-
-Discord Server: https://discord.gg/f4DH6HQ
-Online Store: https://sladkovsky3d.artstation.com/store
-Online Documentation: https://gs-curvetools.readthedocs.io/
-Twitch Channel: https://www.twitch.tv/videonomad
-YouTube Channel: https://www.youtube.com/c/GeorgeSladkovsky
-ArtStation Portfolio: https://www.artstation.com/sladkovsky3d
-Contact Email: george.sladkovsky@gmail.com
-"""
-
-https://www.artstation.com/marketplace-product-eula
-
-Marketplace Product & Services Agreement
-
-End User Agreement
-
-This Marketplace End User Agreement applies to all downloadable products and professional services (e.g. mentorships, personal training, portfolio reviews) sold via the ArtStation Marketplace, unless a custom agreement or license is provided by the seller.
-
-The EUA is an agreement between the buyer and the seller providing the goods or services.
-
-PLEASE READ THIS DOCUMENT CAREFULLY. IT SIGNIFICANTLY ALTERS YOUR LEGAL RIGHTS AND REMEDIES.
-
-BY CLICKING “I AGREE” OR DOWNLOADING OR USING THE DIGITAL PRODUCT OR RECEIVING THE PROFESSIONAL SERVICES TO WHICH THIS AGREEMENT RELATES YOU ACCEPT ALL OF THIS AGREEMENT’S TERMS, INCLUDING THE DISCLAIMERS OF WARRANTIES AND LIMITATIONS ON DAMAGES, USE AND TRANSFERABILITY. IF YOU DO NOT ACCEPT THIS AGREEMENT’S TERMS, DO NOT DOWNLOAD, INSTALL OR USE THE DIGITAL PRODUCT OR RECEIVE OR USE THE PROFESSIONAL SERVICES.
-
-This end-user agreement (“Agreement”) is a legally binding agreement between you, the licensee and customer (“you” or “your”), and the provider (“we” or “us” or “our”) of the digital products (“Products”) or instructional, training, mentorship or other professional service packages (“Professional Services”) that you purchase through the ArtStation Marketplace, regarding your rights and obligations regarding those Products and Professional Services.
-
-1. Your Status
-In this Agreement, “you” means the person or entity acquiring rights in the Products or purchasing Professional Services. That may be a natural person, or a corporate or business entity or organization.
-
-(a) If you are a natural person then you must be, and you confirm that you are, at least 13 years old. If you are between 13 years and the age of majority in your jurisdiction of residence, you confirm that your parent or legal guardian has reviewed and agrees to this Agreement and is happy for you to access and use the Product or receive the Professional Services.
-
-(b) If you are a corporate entity then: (i) the rights granted under this Agreement are granted to that entity; (ii) you represent and warrant that the individual completing and accepting this Agreement is an authorized your representative and has the authority to legally bind that you to the Agreement; and (iii) to the extent that one or more of your employees are granted any rights in the Product or to receive Professional Services under this Agreement, you will ensure that your employees comply with this Agreement and you will be responsible and liable for any breach of this Agreement by any employee.
-
-2. ArtStation
-ArtStation is a division of Epic Games, Inc., You acknowledge and agree that Epic is a third-party beneficiary of this Agreement and therefore will be entitled to directly enforce and rely upon any provision in this Agreement that confers a benefit on, or rights in favour of, Epic. In addition, you authorize Epic to act as your authorized representative to file a lawsuit or other formal action against a licensor in a court or with any other governmental authority if Epic knows or suspects that a licensor breached any representations or warranties under this Agreement. The foregoing authorization is nonexclusive, and Epic shall be under no obligation to pursue any claim. Epic will not initiate any such action on your behalf without first consulting with and obtaining your approval.
-
-Products
-The following sections 3 through 9 apply to any Products you acquire from us through the ArtStation Marketplace:
-
-3. Product Licence
-Subject to this Agreement’s terms and conditions, we hereby grant you a limited, non-exclusive, worldwide, non-transferable right and licence to (which will be perpetual unless the licence terminates as set out in this Agreement): (a) download the Product; and (b) copy and use the Product. We reserve all rights not expressly granted to you under this Agreement.
-
-4. Licence Scope and Restrictions
-(a) Tutorials
-You are purchasing ONE licence to create ONE copy of the Product for use by you only (or, if you are a corporate entity, for use by a single authorized employee).
-
-If this Product is bundled with a stock digital asset then you receive a limited personal use licence regarding that stock digital asset, and you may use that stock digital asset for your personal use only. You will not use that stock digital asset in any commercial manner unless you purchase a separate commercial licence.
-
-(b) Installable Tools
-You may purchase one or more licences for the Product. A single licence allows you to install the Product on a single computer at a time for use by a single authorized user. If you are a corporate entity and the authorized employee completing the transaction on your behalf purchases multiple licences, you may choose to store the Product on a single server or shared hard drive for use by a single authorized employee at a time for each licence purchased.
-
-Provided that you comply with the restrictions on users set out above, you may use the Product on an unlimited number of projects.
-
-(c) Stock Assets
-Subject to the restrictions set out in this Agreement, you may copy, use, modify, adapt, translate, distribute, publicly display, transmit, broadcast, and create derivative works from the Product in works you create (“Works”), which may include things like films, videos, multi-media projects, computer games, models, images, publications, broadcasts, documents, and presentations.
-
-If you are a corporate entity, you may make the Product available for use by your employees in accordance with this Agreement (for example, by storing the Product on a network server).
-
-You may only share the Product with external people or entities where:
-- You are collaborating with the external parties in the creation of your Work and you need to share the Product for that purpose, provided that any external party that receives the Product may only use it in your Work and must secure and limit access to the Product for that purpose;
-- You are working as a contractor for a client in the creation of a Work and need to share the Product with your client, or any external parties working with your client, provided that your client and any such external parties may use the Product only for your client’s Work, and all parties secure and limit access to the Product for that purpose.
-
-For any other use of the Product by any other party, that party must purchase a licence to the Product.
-
-In addition to any other restrictions in this Agreement, you will not:
-- publish, sell, license, offer or make available for sale or licensing, or otherwise distribute the Product except as part of a Work or through a form of sharing that is authorized in this Agreement; or
-- publish, distribute or make available the Product through any online clearinghouse platform.
-
-FURTHER SPECIFIC TERMS
-In addition to the restrictions set out above, the following terms and conditions apply to the following forms of commercial licences for the Product:
-
-Standard Commercial Licence
-If you have purchased a Standard Commercial licence then you may exercise your rights under that licence:
-- for personal use on an unlimited number of personal projects that are not used or distributed in any commercial manner; and
-- respect to one commercial Work, with up to a maximum of, as applicable, 2,000 sales of the Work or 20,000 monthly views of the Work.
-
-Extended Commercial Licence
-If you have purchased an Extended Commercial licence then you may exercise your rights under that licence:
-- for personal use on an unlimited number of personal projects that are not used or distributed in any commercial manner; and
-- with respect to any number of commercial Works, with no limit on sales or views.
-
-5. Additional Restrictions
-Except as expressly permitted under this Agreement, you will not:
-
-(a) make any copy of the Product except for archival or backup purposes;
-
-(b) circumvent or disable any access control technology, security device, procedure, protocol, or technological protection mechanism that may be included or established in or as part of the Product;
-
-(c) hack, reverse engineer, decompile, disassemble, modify or create derivative works of the Product or any part of the Product;
-
-(d) publish, sell distribute or otherwise make the Product available to others to use, download or copy;
-
-(e) transfer or sub-license the Product or any rights under this Agreement to any third party, whether voluntarily or by operation of law;
-
-(f) use the Product for any purpose that may be defamatory, threatening, abusive, harmful or invasive of anyone’s privacy, or that may otherwise violate any law or give rise to civil or other liability;
-
-(g) misrepresent yourself as the creator or owner of the Property;
-
-(h) remove or modify any proprietary notice, symbol or label in or on the Product;
-
-(i) directly or indirectly assist, facilitate or encourage any third party to carry on any activity prohibited by this Agreement.
-
-6. Proprietary Rights
-The Product is protected by copyright laws and international copyright treaties, as well as other intellectual property laws and treaties. You are licensing the Product and the right to access, install and use the Product in accordance with this Agreement, not buying the Product. As between you and us, we own all right, title and interest in and to the Product, and you are not acquiring any ownership of or rights in the Product except the limited rights granted under this Agreement.
-
-7. No Epic Support
-You acknowledge and agree that you are licensing the Product from us (the Provider), not from Epic, and that Epic has no obligation to support the Product.
-
-8. Interruptions and Errors
-Your use of the Product might be interrupted and might not be free of errors.
-
-9. Updates
-We have no obligation to update the Product.
-
-Professional Services
-The following sections 10 and 11 apply to any Professional Services you purchase from us through the ArtStation Marketplace:
-
-10. Provision of Professional Services
-We will provide the Professional Services directly to you and, subject to this Agreement, will assume all responsibility for all aspects of the Professional Services. We represent and warrant that we have the right to offer and provide the Professional Services and that we have appropriate qualifications and experience to provide the Professional Services.
-
-11. Epic is not Involved
-You acknowledge and agree that:
-
-(a) Epic is only a provider of the online ArtStation Marketplace where you purchased the Professional Services, and does not provide or exercise any control or oversight over us or the Professional Services, and is not responsible for us or the Professional Services or any shortcomings in them, including any damages, losses or legal issues caused by us or the Professional Services;
-
-(b) this Agreement (and any dispute under it) is an agreement between us and you only, and not with Epic, and Epic is not a party to this Agreement;
-
-(c) we are not Epic’s employee, agent or subcontractor;
-
-(d) Epic does not have any obligation to attempt to resolve any dispute between us and you; and
-
-(e) we will provide the Professional Services directly to you, and we (and not Epic) are solely responsible for the Professional Services, and Epic has no obligation or liability to you with respect to the Professional Services.
-
-Both Products and Services
-The following sections 12 through 25 apply to all Products or Services you purchase from us through the ArtStation Marketplace:
-
-12. Disclaimer
-ANY PRODUCTS OR PROFESSIONAL SERVICES ARE PROVIDED ON AN “AS IS” AND “AS AVAILABLE” BASIS, WITHOUT ANY REPRESENTATIONS, WARRANTIES OR CONDITIONS OF ANY KIND.
-
-TO THE FULLEST EXTENT PERMITTED BY APPLICABLE LAW WE DISCLAIM, AND YOU WAIVE (WITH REGARD TO US AND ALSO TO EPIC, ITS AFFILIATES, AND ITS AND THEIR LICENSORS AND SERVICE PROVIDERS (COLLECTIVELY, THE “EPIC PARTIES”), ALL TERMS, CONDITIONS, GUARANTEES, REPRESENTATIONS AND WARRANTIES (EXPRESS, IMPLIED, STATUTORY AND OTHERWISE), IN RESPECT OF THE PRODUCTS AND PROFESSIONAL SERVICES, INCLUDING THOSE OF MERCHANTABILITY, NON-INFRINGEMENT, TITLE, QUALITY AND FITNESS FOR A PARTICULAR PURPOSE.
-
-NEITHER WE NOR ANY OF THE EPIC PARTIES REPRESENT OR WARRANT THAT: (A) ANY PRODUCT OR PROFESSIONAL SERVICE IS ACCURATE, COMPLETE, RELIABLE, CURRENT OR ERROR-FREE; (B) ANY PRODUCT OR PROFESSIONAL SERVICE WILL MEET YOUR REQUIREMENTS OR EXPECTATIONS; (C) ANY PRODUCT OR PROFESSIONAL SERVICES IS FREE OF VIRUSES OR OTHER HARMFUL COMPONENTS; OR (D) ANY DEFECTS IN ANY PRODUCT OR PROFESSIONAL SERVICE WILL BE CORRECTED.
-
-13. Exclusion and Limitation of Liability
-(a) YOU DOWNLOAD, INSTALL AND OTHERWISE USE ALL PRODUCTS, AND RECEIVE AND USE ALL PROFESSIONAL SERVICES, AT YOUR OWN RISK. YOU AGREE TO, AND HEREBY DO:
-
-(i) WAIVE ANY CLAIMS THAT YOU MAY HAVE AGAINST US OR THE EPIC PARTIES OR OUR RESPECTIVE DIRECTORS, OFFICERS, EMPLOYEES, AGENTS, REPRESENTATIVES, LICENSORS, SUCCESSORS AND ASSIGNS (COLLECTIVELY THE “RELEASEES”) ARISING FROM OR RELATING TO ANY PRODUCTS OR PROFESSIONAL SERVICES, AND
-
-(ii) RELEASE THE RELEASEES FROM ANY LIABILITY FOR ANY LOSS, DAMAGE, EXPENSE OR INJURY ARISING FROM OR RELATING TO YOUR USE OF ANY PRODUCT OR PROFESSIONAL SERVICE, WHETHER ARISING IN TORT (INCLUDING NEGLIGENCE), CONTRACT OR OTHERWISE, EVEN IF THE RELEASEES ARE EXPRESSLY ADVISED OF THE POSSIBILITY OF SUCH LOSS, INJURY OR DAMAGE AND EVEN IF THAT LOSS, INJURY OR DAMAGE IS FORESEEABLE.
-
-(b) NEITHER WE NOR THE EPIC PARTIES WILL BE LIABLE FOR ANY LOSSES, DAMAGES, CLAIMS OR EXPENSES THAT CONSTITUTE: (I) LOSS OF INTEREST, PROFIT, BUSINESS, CUSTOMERS OR REVENUE; (II) BUSINESS INTERRUPTIONS; (III) COST OF REPLACEMENT PRODUCTS OR SERVICES; OR (IV) LOSS OF OR DAMAGE TO REPUTATION OR GOODWILL.
-
-(c) NEITHER WE NOR THE EPIC PARTIES WILL BE LIABLE FOR ANY LOSSES, DAMAGES, CLAIMS OR EXPENSES THAT CONSTITUTE INCIDENTAL, CONSEQUENTIAL, SPECIAL, PUNITIVE, EXEMPLARY, MULTIPLE OR INDIRECT DAMAGES, EVEN IF WE HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH LOSSES, DAMAGES, CLAIMS OR EXPENSES.
-
-(d) MAXIMUM LIABILITY: IF, DESPITE THE LIMITATIONS SET OUT ABOVE, WE OR ANY EPIC PARTY BECOME LIABLE TO YOU IN RESPECT OF ANY PRODUCT OR PROFESSIONAL SERVICE OR OTHERWISE UNDER THIS AGREEMENT, THE ENTIRE CUMULATIVE LIABILITY OF US AND THE EPIC PARTIES, AND YOUR EXCLUSIVE AND CUMULATIVE REMEDY, FOR ANY DAMAGES (REGARDLESS OF THE CAUSE OR FORM OR ACTION), WILL BE LIMITED TO CAD$10.
-
-14. Indemnity
-As a condition of your use of any Product or any Professional Services, you agree to hold harmless and indemnify the Releasees from any liability for any loss or damage to any third party resulting from your access to, installation or use of the Product or your receipt and use of the Professional Services.
-
-15. Term and Termination
-This Agreement is effective until terminated. Your rights under this Agreement will terminate automatically without notice if: (a) you breach any terms of this Agreement; or (b) you do not complete payment for the Product or Professional Services, or any payment you make is refunded, reversed or cancelled for any reason. Upon this Agreement’s termination, you will cease all use of the Product and destroy all copies, full or partial, of the Product in your possession. Sections 11 through 25 will survive the termination of this Agreement.
-
-16. Compliance with Laws
-You will comply with all applicable laws when using any Product or Professional Services (including intellectual property and export control laws).
-
-17. Entire Agreement
-This Agreement supersedes all prior agreements of the parties regarding the Product or Professional Services, and constitutes the whole agreement with respect to the Product or Professional Services.
-
-18. Disputes
-If you have any concerns about the Product or Professional Services, please contact us through our ArtStation Marketplace account and we will work with you to try to resolve the issue. You acknowledge and agree that any such dispute is between you and us, and that Epic will not be involved in the dispute and has no obligation to try to resolve the dispute.
-
-19. Persons Bound
-This Agreement will enure to the benefit of and be binding upon the parties and their heirs, executors, administrators, legal representatives, lawful successors and permitted assigns.
-
-20. Assignment
-We may assign this Agreement without notice to you. You may not assign this Agreement or any of your rights under it without our prior written consent, which we will not withhold unreasonably.
-
-21. Waiver
-No waiver, delay, or failure to act by us regarding any particular default or omission will prejudice or impair any of our rights or remedies regarding that or any subsequent default or omission that are not expressly waived in writing.
-
-22. Applicable Law and Jurisdiction
-You agree that this Agreement will be deemed to have been made and executed in the State of North Carolina, U.S.A., and any dispute will be resolved in accordance with the laws of North Carolina, excluding that body of law related to choice of laws, and of the United States of America. Any action or proceeding brought to enforce the terms of this Agreement or to adjudicate any dispute must be brought in the Superior Court of Wake County, State of North Carolina or the United States District Court for the Eastern District of North Carolina. You agree to the exclusive jurisdiction and venue of these courts. You waive any claim of inconvenient forum and any right to a jury trial. The Convention on Contracts for the International Sale of Goods will not apply. Any law or regulation which provides that the language of a contract shall be construed against the drafter will not apply to this Agreement.
-
-23. Legal Effect
-This Agreement describes certain legal rights. You may have other rights under the laws of your country. This Agreement does not change your rights under the laws of your country if the laws of your country do not permit it to do so.
-
-24. Interpretation
-In this Agreement, "we", "us", and "our" refer to the licensor of the Product alone and never refer to the combination of you and that licensor (that combination is referred to as "the parties"), or the combination of you or the licensor with Epic.
-
-25. Artificial Intelligence
-For purposes of this Agreement, “Generative AI Programs” means artificial intelligence, machine learning, deep learning, neural networks, or similar technologies designed to automate the generation of or aid in the creation of new content, including but not limited to audio, visual, or text-based content.
-
-We (the licensor of the Product) represent and warrant that where the Product was created using Generative AI Programs, we have applied the “CreatedWithAI” tag. Under this Agreement, a Product is considered to be created using Generative AI Programs where a material portion of a Product is generated with Generative AI Programs, whether characters, backgrounds, or other material elements. A Product is not considered to be created using Generative AI Programs merely for use of features that solely operate on a Product (e.g., AI-based upscaling or content-aware fill).
diff --git a/2024/scripts/modeling_tools/gs_curvetools/README.txt b/2024/scripts/modeling_tools/gs_curvetools/README.txt
deleted file mode 100644
index 95b782d..0000000
--- a/2024/scripts/modeling_tools/gs_curvetools/README.txt
+++ /dev/null
@@ -1,35 +0,0 @@
-GS CurveTools installation
-
-1. Copy gs_curvetools folder to {Path to Documents}\Documents\Maya\{Maya Version}\scripts\
-
- Example of the final folder structure:
-
- Documents\Maya\2022\scripts\gs_curvetools\fonts
- Documents\Maya\2022\scripts\gs_curvetools\icons
- Documents\Maya\2022\scripts\gs_curvetools\utils
- Documents\Maya\2022\scripts\gs_curvetools\__init__.py
- Documents\Maya\2022\scripts\gs_curvetools\core.py
- Documents\Maya\2022\scripts\gs_curvetools\init.py
- Documents\Maya\2022\scripts\gs_curvetools\LICENSE.txt
- Documents\Maya\2022\scripts\gs_curvetools\main.py
- Documents\Maya\2022\scripts\gs_curvetools\README.txt
-
-2. Run Maya
-
-3. Copy and paste this line to "Python" command box and press "Enter":
-
-import gs_curvetools.init as ct_init;from imp import reload;reload(ct_init);ct_init.Init();
-
-IMPORTANT: There should be no spaces or tabs before this command!
-
-4. Look for GS tab on your Shelf
-
-5. Click CT UI button to run the menu. Click again to hide the menu.
-
-NOTES:
->> To reset to factory defaults click CT with "refresh" arrow button.
->> To stop all scripts and close the menu press CT DEL button.
->> You can use middle-mouse button drag to move the buttons to any tab.
->> All the hotkeys are available in Hotkey Editor > Custom Scripts > GS > GS_CurveTools.
->> Always repeat initialization steps when updating the plug-in to a new version.
->> You can always repeat initialization steps if you lost control buttons or shelf.
diff --git a/2024/scripts/modeling_tools/gs_curvetools/fonts/Roboto-Bold.ttf b/2024/scripts/modeling_tools/gs_curvetools/fonts/Roboto-Bold.ttf
deleted file mode 100644
index 3742457..0000000
Binary files a/2024/scripts/modeling_tools/gs_curvetools/fonts/Roboto-Bold.ttf and /dev/null differ
diff --git a/2024/scripts/modeling_tools/gs_curvetools/fonts/Roboto-Italic.ttf b/2024/scripts/modeling_tools/gs_curvetools/fonts/Roboto-Italic.ttf
deleted file mode 100644
index c9df607..0000000
Binary files a/2024/scripts/modeling_tools/gs_curvetools/fonts/Roboto-Italic.ttf and /dev/null differ
diff --git a/2024/scripts/modeling_tools/gs_curvetools/fonts/Roboto-Regular.ttf b/2024/scripts/modeling_tools/gs_curvetools/fonts/Roboto-Regular.ttf
deleted file mode 100644
index 2b6392f..0000000
Binary files a/2024/scripts/modeling_tools/gs_curvetools/fonts/Roboto-Regular.ttf and /dev/null differ
diff --git a/2024/scripts/modeling_tools/gs_curvetools/icons/drop-down-arrow.png b/2024/scripts/modeling_tools/gs_curvetools/icons/drop-down-arrow.png
deleted file mode 100644
index 4452f34..0000000
Binary files a/2024/scripts/modeling_tools/gs_curvetools/icons/drop-down-arrow.png and /dev/null differ
diff --git a/2024/scripts/modeling_tools/gs_curvetools/icons/gsCurveToolsIcon_logo.png b/2024/scripts/modeling_tools/gs_curvetools/icons/gsCurveToolsIcon_logo.png
deleted file mode 100644
index 2dda8c9..0000000
Binary files a/2024/scripts/modeling_tools/gs_curvetools/icons/gsCurveToolsIcon_logo.png and /dev/null differ
diff --git a/2024/scripts/modeling_tools/gs_curvetools/icons/gsCurveToolsIcon_reset.png b/2024/scripts/modeling_tools/gs_curvetools/icons/gsCurveToolsIcon_reset.png
deleted file mode 100644
index a72f685..0000000
Binary files a/2024/scripts/modeling_tools/gs_curvetools/icons/gsCurveToolsIcon_reset.png and /dev/null differ
diff --git a/2024/scripts/modeling_tools/gs_curvetools/icons/gsCurveToolsIcon_reset_legacy.png b/2024/scripts/modeling_tools/gs_curvetools/icons/gsCurveToolsIcon_reset_legacy.png
deleted file mode 100644
index d40254d..0000000
Binary files a/2024/scripts/modeling_tools/gs_curvetools/icons/gsCurveToolsIcon_reset_legacy.png and /dev/null differ
diff --git a/2024/scripts/modeling_tools/gs_curvetools/icons/gsCurveToolsIcon_stop.png b/2024/scripts/modeling_tools/gs_curvetools/icons/gsCurveToolsIcon_stop.png
deleted file mode 100644
index 14be446..0000000
Binary files a/2024/scripts/modeling_tools/gs_curvetools/icons/gsCurveToolsIcon_stop.png and /dev/null differ
diff --git a/2024/scripts/modeling_tools/gs_curvetools/icons/gsCurveToolsIcon_stop_legacy.png b/2024/scripts/modeling_tools/gs_curvetools/icons/gsCurveToolsIcon_stop_legacy.png
deleted file mode 100644
index df5a67e..0000000
Binary files a/2024/scripts/modeling_tools/gs_curvetools/icons/gsCurveToolsIcon_stop_legacy.png and /dev/null differ
diff --git a/2024/scripts/modeling_tools/gs_curvetools/icons/gsCurveToolsIcon_ui.png b/2024/scripts/modeling_tools/gs_curvetools/icons/gsCurveToolsIcon_ui.png
deleted file mode 100644
index 5e0b410..0000000
Binary files a/2024/scripts/modeling_tools/gs_curvetools/icons/gsCurveToolsIcon_ui.png and /dev/null differ
diff --git a/2024/scripts/modeling_tools/gs_curvetools/icons/gsCurveToolsIcon_ui_legacy.png b/2024/scripts/modeling_tools/gs_curvetools/icons/gsCurveToolsIcon_ui_legacy.png
deleted file mode 100644
index e5bc3dc..0000000
Binary files a/2024/scripts/modeling_tools/gs_curvetools/icons/gsCurveToolsIcon_ui_legacy.png and /dev/null differ
diff --git a/2024/scripts/modeling_tools/gs_curvetools/icons/marking.png b/2024/scripts/modeling_tools/gs_curvetools/icons/marking.png
deleted file mode 100644
index 2835c8b..0000000
Binary files a/2024/scripts/modeling_tools/gs_curvetools/icons/marking.png and /dev/null differ
diff --git a/2024/scripts/modeling_tools/gs_curvetools/icons/mod.png b/2024/scripts/modeling_tools/gs_curvetools/icons/mod.png
deleted file mode 100644
index deb0c16..0000000
Binary files a/2024/scripts/modeling_tools/gs_curvetools/icons/mod.png and /dev/null differ
diff --git a/2024/scripts/modeling_tools/gs_curvetools/icons/reset.png b/2024/scripts/modeling_tools/gs_curvetools/icons/reset.png
deleted file mode 100644
index 4cba961..0000000
Binary files a/2024/scripts/modeling_tools/gs_curvetools/icons/reset.png and /dev/null differ
diff --git a/2024/scripts/modeling_tools/gs_curvetools/icons/sliderLock_en_reversed.png b/2024/scripts/modeling_tools/gs_curvetools/icons/sliderLock_en_reversed.png
deleted file mode 100644
index 8c2813c..0000000
Binary files a/2024/scripts/modeling_tools/gs_curvetools/icons/sliderLock_en_reversed.png and /dev/null differ
diff --git a/2024/scripts/modeling_tools/gs_curvetools/icons/sliderLock_reversed.png b/2024/scripts/modeling_tools/gs_curvetools/icons/sliderLock_reversed.png
deleted file mode 100644
index 638a116..0000000
Binary files a/2024/scripts/modeling_tools/gs_curvetools/icons/sliderLock_reversed.png and /dev/null differ
diff --git a/2024/scripts/modeling_tools/gs_curvetools/plugins/2018/cv_manip.mll b/2024/scripts/modeling_tools/gs_curvetools/plugins/2018/cv_manip.mll
deleted file mode 100644
index 0078219..0000000
Binary files a/2024/scripts/modeling_tools/gs_curvetools/plugins/2018/cv_manip.mll and /dev/null differ
diff --git a/2024/scripts/modeling_tools/gs_curvetools/plugins/2019/cv_manip.mll b/2024/scripts/modeling_tools/gs_curvetools/plugins/2019/cv_manip.mll
deleted file mode 100644
index 93736ce..0000000
Binary files a/2024/scripts/modeling_tools/gs_curvetools/plugins/2019/cv_manip.mll and /dev/null differ
diff --git a/2024/scripts/modeling_tools/gs_curvetools/plugins/2020/cv_manip.mll b/2024/scripts/modeling_tools/gs_curvetools/plugins/2020/cv_manip.mll
deleted file mode 100644
index 8e34d98..0000000
Binary files a/2024/scripts/modeling_tools/gs_curvetools/plugins/2020/cv_manip.mll and /dev/null differ
diff --git a/2024/scripts/modeling_tools/gs_curvetools/plugins/2022/cv_manip.mll b/2024/scripts/modeling_tools/gs_curvetools/plugins/2022/cv_manip.mll
deleted file mode 100644
index eff0140..0000000
Binary files a/2024/scripts/modeling_tools/gs_curvetools/plugins/2022/cv_manip.mll and /dev/null differ
diff --git a/2024/scripts/modeling_tools/gs_curvetools/plugins/2023/cv_manip.mll b/2024/scripts/modeling_tools/gs_curvetools/plugins/2023/cv_manip.mll
deleted file mode 100644
index 047dc3c..0000000
Binary files a/2024/scripts/modeling_tools/gs_curvetools/plugins/2023/cv_manip.mll and /dev/null differ
diff --git a/2024/scripts/modeling_tools/gs_curvetools/plugins/2024/cv_manip.mll b/2024/scripts/modeling_tools/gs_curvetools/plugins/2024/cv_manip.mll
deleted file mode 100644
index 2a1dd2a..0000000
Binary files a/2024/scripts/modeling_tools/gs_curvetools/plugins/2024/cv_manip.mll and /dev/null differ
diff --git a/2024/scripts/modeling_tools/gs_curvetools/plugins/2025/cv_manip.mll b/2024/scripts/modeling_tools/gs_curvetools/plugins/2025/cv_manip.mll
deleted file mode 100644
index dff851b..0000000
Binary files a/2024/scripts/modeling_tools/gs_curvetools/plugins/2025/cv_manip.mll and /dev/null differ
diff --git a/2024/scripts/modeling_tools/gs_curvetools/plugins/cv_manip.py b/2024/scripts/modeling_tools/gs_curvetools/plugins/cv_manip.py
deleted file mode 100644
index 8647705..0000000
--- a/2024/scripts/modeling_tools/gs_curvetools/plugins/cv_manip.py
+++ /dev/null
@@ -1,93 +0,0 @@
-"""
-CV Manipulator (highlighting) plug-in entry point for Mac
----
-GS CurveTools License:
-This collection of code named GS CurveTools is a property of George Sladkovsky (Yehor Sladkovskyi)
-and can not be copied or distributed without his written permission.
-
-GS CurveTools v1.3.11 Personal Edition
-Copyright 2025, George Sladkovsky (Yehor Sladkovskyi)
-All Rights Reserved
-
-UI font is Roboto that is licensed under the Apache 2.0 License:
-http://www.apache.org/licenses/LICENSE-2.0
-
-Autodesk Maya is a property of Autodesk, Inc:
-https://www.autodesk.com/
-
-Social Media and Contact Links:
-
-Discord Server: https://discord.gg/f4DH6HQ
-Online Store: https://sladkovsky3d.artstation.com/store
-Online Documentation: https://gs-curvetools.readthedocs.io/
-Twitch Channel: https://www.twitch.tv/videonomad
-YouTube Channel: https://www.youtube.com/c/GeorgeSladkovsky
-ArtStation Portfolio: https://www.artstation.com/sladkovsky3d
-Contact Email: george.sladkovsky@gmail.com
-"""
-
-# pylint: disable-all
-
-import sys
-
-try:
- from importlib import reload
-except ImportError:
- from imp import reload
-
-import maya.api.OpenMaya as om
-import maya.api.OpenMayaRender as omr
-
-from gs_curvetools.config.constants import NODES
-from gs_curvetools.plugins import cv_manip_src
-
-reload(cv_manip_src)
-
-# API parameters
-maya_useNewAPI = True
-
-
-# ------------ Init & UnInit Plugin ------------
-def initializePlugin(obj):
- plugin = om.MFnPlugin(obj, "GeorgeSladkovsky", "1.3", "Any")
- try:
- plugin.registerNode(
- NODES.DrawManager.node,
- cv_manip_src.DrawManagerNode.id,
- cv_manip_src.DrawManagerNode.creator,
- cv_manip_src.DrawManagerNode.initialize,
- om.MPxNode.kLocatorNode,
- cv_manip_src.DrawManagerNode.drawDbClassification,
- )
- except BaseException:
- sys.stderr.write("Failed to register node\n")
- raise
-
- try:
- omr.MDrawRegistry.registerDrawOverrideCreator(
- cv_manip_src.DrawManagerNode.drawDbClassification,
- cv_manip_src.DrawManagerNode.drawRegistrantId,
- cv_manip_src.DrawOverride.creator,
- )
- except BaseException:
- sys.stderr.write("Failed to register override\n")
- raise
-
-
-def uninitializePlugin(obj):
- om.MMessage.removeCallbacks(cv_manip_src.CALLBACK_IDS)
- cv_manip_src.CALLBACK_IDS = []
- plugin = om.MFnPlugin(obj)
- try:
- plugin.deregisterNode(cv_manip_src.DrawManagerNode.id)
- except BaseException:
- sys.stderr.write("Failed to deregister node\n")
- raise
-
- try:
- omr.MDrawRegistry.deregisterGeometryOverrideCreator(
- cv_manip_src.DrawManagerNode.drawDbClassification, cv_manip_src.DrawManagerNode.drawRegistrantId
- )
- except BaseException:
- sys.stderr.write("Failed to deregister override\n")
- raise
diff --git a/2024/scripts/modeling_tools/gs_curvetools/ui/components/curve_control.py b/2024/scripts/modeling_tools/gs_curvetools/ui/components/curve_control.py
deleted file mode 100644
index 5b04b8e..0000000
--- a/2024/scripts/modeling_tools/gs_curvetools/ui/components/curve_control.py
+++ /dev/null
@@ -1,949 +0,0 @@
-"""
-Curve control window
----
-GS CurveTools License:
-This collection of code named GS CurveTools is a property of George Sladkovsky (Yehor Sladkovskyi)
-and can not be copied or distributed without his written permission.
-
-GS CurveTools v1.3.10 Personal Edition
-Copyright 2025, George Sladkovsky (Yehor Sladkovskyi)
-All Rights Reserved
-
-UI font is Roboto that is licensed under the Apache 2.0 License:
-http://www.apache.org/licenses/LICENSE-2.0
-
-Autodesk Maya is a property of Autodesk, Inc:
-https://www.autodesk.com/
-
-Social Media and Contact Links:
-
-Discord Server: https://discord.gg/f4DH6HQ
-Online Store: https://sladkovsky3d.artstation.com/store
-Online Documentation: https://gs-curvetools.readthedocs.io/
-Twitch Channel: https://www.twitch.tv/videonomad
-YouTube Channel: https://www.youtube.com/c/GeorgeSladkovsky
-ArtStation Portfolio: https://www.artstation.com/sladkovsky3d
-Contact Email: george.sladkovsky@gmail.com
-"""
-from functools import partial
-import maya.cmds as mc
-from gs_curvetools.api.maya_tools import deferred, no_undo, undo
-from gs_curvetools.api.qt_compat import *
-from gs_curvetools.api.utils import open_link
-from gs_curvetools.config.constants import *
-from gs_curvetools.config.folders import GetFolder
-from gs_curvetools.core.core import Core
-from gs_curvetools.debug.logger import logger
-from gs_curvetools.managers.options_manager import OptionsManager
-from gs_curvetools.managers.script_jobs import ScriptJobs
-from gs_curvetools.managers.widget_manager import WidgetManager
-from gs_curvetools.ui import style
-from gs_curvetools.ui.tooltips import Tooltips
-from gs_curvetools.ui.utils import maya_dockable_window
-from gs_curvetools.ui.widgets import Button, ColorPicker, Column, ControlSlider, FallOffCurve, FloatField, Frame, IconCheckButton, Label, LayerSelector, LineEdit, PopOutWindow, Row, maya_slider, separator
-
-class CurveControlWindow(QWidget):
- """曲线控制用户界面"""
- update_curve_control_ui = Signal()
- update_main_ui = Signal()
-
- def __init__(self, parent):
- super(CurveControlWindow, self).__init__(parent)
- self.core = Core.singleton()
- self.widget_manager = WidgetManager()
- self.options_manager = OptionsManager()
- self.script_jobs = ScriptJobs.singleton()
- self.tooltips = Tooltips()
-
- def open_ui(self):
- """创建曲线控制工作区"""
- if mc.workspaceControl(WINDOWS.CurveControl.name, q=1, ex=1):
- if not mc.workspaceControl(WINDOWS.CurveControl.name, q=1, vis=1):
- mc.workspaceControl(WINDOWS.CurveControl.name, e=1, rs=1)
- deferred(self.update_main_ui.emit)()
- else:
- mc.workspaceControl(WINDOWS.CurveControl.name, e=1, vis=0)
- return
- else:
- dockable_window = maya_dockable_window(name=WINDOWS.CurveControl.name, label="曲线控制", i_w=350, i_h=750, width_property='free')
- layout = dockable_window.layout()
- assert layout is not None, '未找到布局'
- layout.addWidget(self)
- self.create_ui()
- self.update_curve_control_ui.emit()
- self.script_jobs.check_script_jobs(WINDOWS.CurveControl.name)
-
- def create_ui(self):
- """创建曲线控制用户界面"""
- main_layout = QtWidgets.QVBoxLayout(self)
- main_layout.setContentsMargins(*style.scale([2, 0, 2, 0]))
- scroll_widget = QtWidgets.QWidget()
- layout = QtWidgets.QVBoxLayout(scroll_widget)
- scroll_area = QtWidgets.QScrollArea()
- scroll_area.setWidget(scroll_widget)
- main_layout.addWidget(scroll_area)
- layout.setContentsMargins(0, 0, 0, 0)
- layout.setSpacing(style.scale(2))
- layout.setAlignment(QtCore.Qt.AlignmentFlag.AlignTop)
- scroll_area.setFrameShape(QtWidgets.QFrame.Shape.NoFrame)
- scroll_area.setWidgetResizable(True)
- layout.addWidget(separator())
- with Row(layout, 'gsCurveControlHeader') as row:
- row_layout = row.layout()
- if not row_layout:
- raise RuntimeError('未找到行布局')
- layer_selector = LayerSelector('gsLayerSelector', row_layout)
- layer_selector.setFixedWidth(style.scale(40))
- layer_selector.currentIndexChanged.connect(self.core.layer_manager.change_layer_via_option_menu)
- layer_color_picker = ColorPicker('gsColorPicker', row_layout)
- layer_color_picker.setContentsMargins(*style.scale([3, 3, 1, 3]))
- layer_color_picker.setFixedWidth(style.scale(20))
- layer_color_picker.connect_command(self.core.color_mode.change_layer_color_via_picker)
- curve_color_picker = ColorPicker('gsCurveColorPicker', row_layout)
- curve_color_picker.setContentsMargins(*style.scale([1, 3, 2, 3]))
- curve_color_picker.setFixedWidth(style.scale(20))
- curve_color_picker.connect_command(self.core.color_mode.change_curve_color_via_picker)
- selected_object_name = LineEdit('selectedObjectName', row_layout)
- selected_object_name.setPlaceholderText('选择曲线')
- selected_object_name.returnPressed.connect(undo(self.core.functions.rename_selected))
- line_thickness = FloatField('lineWidth', row_layout)
- line_thickness.setFixedWidth(style.scale(35))
- line_thickness.set_range(-1, 10)
- line_thickness.set_value(-1)
- line_thickness.set_drag_command(partial(self.core.sliders.curve_control_slider_drag, line_thickness))
- line_thickness.set_release_command(self.core.sliders.release)
- layout.addWidget(separator())
- label = Label(layout, 'selectCurvesPrompt')
- label.set_label('选择兼容的曲线')
- label.set_font_size(14)
- label.setVisible(False)
- with Column(layout, 'axisFrame') as column:
- column_layout = column.layout()
- if not column_layout:
- raise RuntimeError('未找到列布局')
- label = Label(column_layout)
- label.set_label('轴控制')
- label.set_font_size(14)
- with Row(column.layout()) as row:
- axis_button_grp = QtWidgets.QButtonGroup(row)
- self.widget_manager.add('Axis', axis_button_grp)
- axis_auto = Button(row.layout(), 'gsBindAxisAuto')
- axis_auto.set_label('自动', line_height=100)
- axis_auto.setCheckable(True)
- axis_auto.set_button_style('small')
- axis_auto.setChecked(True)
- axis_auto.clicked.connect(partial(undo(self.core.functions.apply_axis), 0))
- axis_x = Button(row.layout(), 'gsBindAxisX')
- axis_x.set_label('X', line_height=100)
- axis_x.setCheckable(True)
- axis_x.set_button_style('small')
- axis_x.clicked.connect(partial(undo(self.core.functions.apply_axis), 1))
- axis_y = Button(row.layout(), 'gsBindAxisY')
- axis_y.set_label('Y', line_height=100)
- axis_y.setCheckable(True)
- axis_y.set_button_style('small')
- axis_y.clicked.connect(partial(undo(self.core.functions.apply_axis), 2))
- axis_z = Button(row.layout(), 'gsBindAxisZ')
- axis_z.set_label('Z', line_height=100)
- axis_z.setCheckable(True)
- axis_z.set_button_style('small')
- axis_z.clicked.connect(partial(undo(self.core.functions.apply_axis), 3))
- axis_button_grp.addButton(axis_auto, 0)
- axis_button_grp.addButton(axis_x, 1)
- axis_button_grp.addButton(axis_y, 2)
- axis_button_grp.addButton(axis_z, 3)
- axis_flip = Button(row.layout(), 'AxisFlip')
- axis_flip.set_label('翻转', line_height=100)
- axis_flip.setCheckable(True)
- axis_flip.set_button_style('small')
- axis_flip.clicked.connect(partial(undo(self.core.functions.apply_axis), -1))
- column_layout.addWidget(separator())
- with Row(column.layout(), margins=style.scale([0, 0, 0, 0]), obj_name='originalCurvesRow') as original_curves_row:
- select_original_curves = Button(original_curves_row.layout(), 'selectOriginalCurves')
- select_original_curves.set_label('选择原始曲线', line_height=100)
- select_original_curves.set_button_style('small-filled')
- select_original_curves.clicked.connect(undo(self.core.curve_control.select_original_objects))
- edit_orig_obj = Button(original_curves_row.layout(), 'editOrigObj')
- edit_orig_obj.set_label('编辑原始对象', line_height=100)
- edit_orig_obj.setCheckable(True)
- edit_orig_obj.set_button_style('small')
- edit_orig_obj.clicked.connect(undo(self.core.curve_control.edit_original_objects))
- column_layout.addWidget(separator())
- with Row(layout, margins=style.scale([0, 0, 3, 0])) as length_divisions_row:
- length_division = ControlSlider(obj_name='lengthDivisions', typ='int')
- length_division.set_label('长度分段')
- length_division.set_min_max(2, 100)
- length_division.set_field_min_max(2, 10000)
- length_division.set_value(2)
- length_division.set_drag_command(partial(self.core.sliders.curve_control_slider_drag, length_division))
- length_division.set_release_command(self.core.sliders.release)
- dynamic_divisions_toggle = Button(obj_name='dynamicDivisions')
- dynamic_divisions_toggle.set_label('自动')
- dynamic_divisions_toggle.setFixedWidth(style.scale(35))
- dynamic_divisions_toggle.set_button_style('small')
- dynamic_divisions_toggle.setCheckable(True)
- dynamic_divisions_toggle.clicked.connect(undo(self.core.functions.toggle_dynamic_divisions))
- length_division_layout = length_divisions_row.layout()
- if not isinstance(length_division_layout, QHBoxLayout):
- raise RuntimeError('未找到长度分段布局')
- length_division_layout.addWidget(length_division, 4)
- length_division_layout.addWidget(dynamic_divisions_toggle, 1)
- width_division = ControlSlider(layout, 'widthDivisions', 'int')
- width_division.set_label('宽度分段')
- width_division.set_min_max(2, 31)
- width_division.set_field_min_max(2, 10000)
- width_division.set_value(2)
- width_division.set_drag_command(partial(self.core.sliders.curve_control_slider_drag, width_division))
- width_division.set_release_command(self.core.sliders.release)
- orientation = ControlSlider(layout, 'Orientation', 'float')
- orientation.set_label('方向')
- orientation.set_min_max(-180, 180)
- orientation.set_field_min_max(-36000, 36000)
- orientation.set_precision(1)
- orientation.set_step(0.5)
- orientation.set_drag_command(partial(self.core.sliders.curve_control_slider_drag, orientation))
- orientation.set_release_command(self.core.sliders.release)
- twist = ControlSlider(layout, 'Twist', 'float')
- twist.set_label('扭曲')
- twist.set_min_max(-180, 180)
- twist.set_field_min_max(-36000, 36000)
- twist.set_precision(1)
- twist.set_step(0.5)
- twist.set_drag_command(partial(self.core.sliders.curve_control_slider_drag, twist))
- twist.set_release_command(self.core.sliders.release)
- inv_twist = ControlSlider(layout, 'invTwist', 'float')
- inv_twist.set_label('反向扭曲')
- inv_twist.set_min_max(-180, 180)
- inv_twist.set_field_min_max(-36000, 36000)
- inv_twist.set_precision(1)
- inv_twist.set_step(0.5)
- inv_twist.set_drag_command(partial(self.core.sliders.curve_control_slider_drag, inv_twist))
- inv_twist.set_release_command(self.core.sliders.release)
- with Frame(layout, 'twistCurveFrame', margins=[0, 1, 0, 2]) as twist_curve_frame:
- twist_curve_frame.get_frame_button().set_label('扭曲曲线图表')
- twist_graph = FallOffCurve(twist_curve_frame.get_frame_layout(), 'twistCurve')
-
- def twist_graph_command(_):
- self.core.attributes.propagate_graphs(twist_graph)
- self.core.attributes.store_graphs(twist_graph)
- twist_graph.change_command(twist_graph_command)
- with Row(twist_curve_frame.get_frame_layout(), margins=style.scale([5, 0, 5, 2])) as row:
- row.setFixedHeight(int(style.BUTTON_HEIGHT))
- magnitude = FloatField('Magnitude', row.layout())
- magnitude.setFixedWidth(style.scale(45))
- magnitude.set_range(-99, 99)
- magnitude.set_step(0.01)
- magnitude.set_precision(2)
- magnitude.set_drag_command(partial(self.core.sliders.curve_control_slider_drag, magnitude))
- magnitude.set_release_command(self.core.sliders.release)
- reset_button = Button(row.layout(), 'gsTwistGraphResetButton')
- reset_button.set_label('重置曲线')
-
- def reset_twist_cmd():
- self.core.utils.reset_single_graph('twist')
- self.core.attributes.store_graphs(twist_graph)
- reset_button.clicked.connect(undo(reset_twist_cmd))
- pop_out_button = Button(row.layout(), 'gsTwistGraphPopOut')
- pop_out_button.setFixedWidth(style.scale(56))
- pop_out_button.set_label('^')
- pop_out_button.clicked.connect(self.twist_graph_pop_out)
- width = ControlSlider(layout, 'Width', 'float')
- width.set_label('宽度')
- width.set_min_max(0.001, 2)
- width.set_field_min_max(0.001, 1000)
- width.set_precision(3)
- width.set_step(0.001)
- width.set_value(1)
- width.set_drag_command(partial(self.core.sliders.curve_control_slider_drag, width))
- width.set_release_command(self.core.sliders.release)
- taper = ControlSlider(layout, 'Taper', 'float')
- taper.set_label('锥度')
- taper.set_min_max(0.001, 3)
- taper.set_field_min_max(0.001, 1000)
- taper.set_precision(3)
- taper.set_step(0.001)
- taper.set_value(1)
- taper.set_drag_command(partial(self.core.sliders.curve_control_slider_drag, taper))
- taper.set_release_command(self.core.sliders.release)
- with Row(layout, obj_name='widthComboSlider', spacing=0) as row:
- row_layout = row.layout()
- if not row_layout:
- raise RuntimeError('未找到行布局')
- with Column(row.layout()) as column:
- column_layout = column.layout()
- if not column_layout:
- raise RuntimeError('未找到列布局')
- width_x = ControlSlider(column_layout, 'WidthX', 'float')
- width_x.set_label('宽度 X')
- width_x.set_min_max(0.001, 2)
- width_x.set_field_min_max(0.001, 1000)
- width_x.set_precision(3)
- width_x.set_step(0.001)
- width_x.set_value(1)
- width_x.set_drag_command(partial(self.core.sliders.curve_control_slider_drag, width_x))
- width_x.set_release_command(self.core.sliders.release)
- width_z = ControlSlider(column.layout(), 'WidthZ', 'float')
- width_z.set_label('宽度 Z')
- width_z.set_min_max(0.001, 2)
- width_z.set_field_min_max(0.001, 1000)
- width_z.set_precision(3)
- width_z.set_step(0.001)
- width_z.set_value(1)
- width_z.set_drag_command(partial(self.core.sliders.curve_control_slider_drag, width_z))
- width_z.set_release_command(self.core.sliders.release)
- lock_button = IconCheckButton(row_layout, 'widthLockSwitch')
- lock_button.set_icons(GetFolder.icons() + 'sliderLock_en_reversed.png', GetFolder.icons() + 'sliderLock_reversed.png')
- lock_button.set_icon_width_height(10, 30)
- lock_button.setChecked(True)
- with Frame(layout, 'widthCurveFrame', margins=[0, 1, 0, 2]) as width_curve_frame:
- width_curve_frame.get_frame_button().set_label('宽度曲线图表')
- width_graph = FallOffCurve(width_curve_frame.get_frame_layout(), 'scaleCurve')
-
- def width_graph_command(_):
- self.core.attributes.propagate_graphs(width_graph)
- self.core.attributes.store_graphs(width_graph)
- width_graph.change_command(width_graph_command)
- with Row(width_curve_frame.get_frame_layout(), margins=style.scale([5, 0, 5, 2])) as row:
- row.setFixedHeight(int(style.BUTTON_HEIGHT))
- reset_button = Button(row.layout(), 'gsWidthGraphResetButton')
- reset_button.set_label('重置曲线')
-
- def reset_width_cmd():
- self.core.utils.reset_single_graph('scale')
- self.core.attributes.store_graphs(width_graph)
- reset_button.clicked.connect(undo(reset_width_cmd))
- pop_out_button = Button(row.layout(), 'gsWidthGraphPopOut')
- pop_out_button.setFixedWidth(style.scale(56))
- pop_out_button.set_label('^')
- pop_out_button.clicked.connect(self.width_graph_pop_out)
- length_unlock = Button(layout, 'LengthLock')
- length_unlock.set_label('长度解锁', line_height=100)
- length_unlock.setCheckable(True)
- length_unlock.set_button_style('small')
- length_unlock.setFixedWidth(style.scale(106))
- length_unlock.clicked.connect(partial(self.core.updates.curve_control_check_boxes, 2))
- length = ControlSlider(layout, 'Length', 'float')
- length.set_label('长度')
- length.set_min_max(0.001, 40)
- length.set_field_min_max(-1000, 1000)
- length.set_precision(3)
- length.set_step(0.001)
- length.set_value(20)
- length.set_drag_command(partial(self.core.sliders.curve_control_slider_drag, length))
- length.set_release_command(self.core.sliders.release)
- offset = ControlSlider(layout, 'Offset', 'float')
- offset.set_label('偏移')
- offset.set_min_max(-1, 1)
- offset.set_field_min_max(-30, 30)
- offset.set_step(0.001)
- offset.set_value(1)
- offset.set_drag_command(partial(self.core.sliders.curve_control_slider_drag, offset))
- offset.set_release_command(self.core.sliders.release)
- profile = ControlSlider(layout, 'Profile', 'float')
- profile.set_label('轮廓')
- profile.set_min_max(-2, 2)
- profile.set_field_min_max(-1000, 1000)
- profile.set_step(0.001)
- profile.set_drag_command(partial(self.core.sliders.curve_control_slider_drag, profile))
- profile.set_release_command(self.core.sliders.release)
- with Frame(layout, 'profileCurveGraph', margins=[0, 1, 0, 2]) as profile_curve_frame:
- profile_curve_frame.get_frame_button().set_label('轮廓曲线图表')
- profile_graph = FallOffCurve(profile_curve_frame.get_frame_layout(), 'profileCurve', attr=False)
-
- def change_command(value):
- self.core.attributes.update_lattice(value)
- self.core.attributes.equalize_profile_curve()
- self.core.attributes.store_graphs(profile_graph)
- profile_graph.change_command(change_command)
- profile_smoothing_slider = ControlSlider(profile_curve_frame.get_frame_layout(), 'profileSmoothing', 'int')
- profile_smoothing_slider.set_label('平滑度')
- profile_smoothing_slider.set_min_max(2, 30)
- profile_smoothing_slider.set_value(2)
- profile_smoothing_slider.set_drag_command(partial(self.core.sliders.curve_control_slider_drag, profile_smoothing_slider))
- profile_smoothing_slider.set_release_command(self.core.sliders.release)
- with Row(profile_curve_frame.get_frame_layout(), margins=style.scale([5, 0, 5, 2])) as row:
- row.setFixedHeight(int(style.BUTTON_HEIGHT))
- with Column(row.layout(), spacing=0) as eq_column:
- eq_column.setFixedHeight(style.scale(24))
- with Row(eq_column.layout(), spacing=0) as eq_row:
-
- def toggle_eq():
- self.widget_manager.get('equalizeCurveButton').setDisabled(self.widget_manager.get('autoEqualizeSwitchOn').isChecked())
- auto_equalize_group = QtWidgets.QButtonGroup(eq_row)
- auto_equalize_group.buttonClicked.connect(toggle_eq)
- auto_equalize_group.buttonClicked.connect(undo(self.core.attributes.equalize_profile_curve))
- auto_equalize = Button(eq_row.layout(), 'autoEqualizeSwitchOn')
- auto_equalize.set_label('自动', line_height=100)
- auto_equalize.set_label_style('small')
- auto_equalize.set_button_style('small-compound-top-left')
- auto_equalize.setCheckable(True)
- auto_equalize.setChecked(True)
- auto_equalize_off = Button(eq_row.layout(), 'autoEqualizeSwitchOff')
- auto_equalize_off.set_label('手动', line_height=100)
- auto_equalize_off.set_label_style('small')
- auto_equalize_off.set_button_style('small-compound-top-right')
- auto_equalize_off.setCheckable(True)
- auto_equalize_group.addButton(auto_equalize)
- auto_equalize_group.addButton(auto_equalize_off)
- equalize_profile_curve = Button(eq_column.layout(), 'equalizeCurveButton')
- equalize_profile_curve.set_label('均衡曲线', line_height=100)
- equalize_profile_curve.set_label_style('small')
- equalize_profile_curve.set_button_style('small-filled-compound-bottom')
- equalize_profile_curve.setDisabled(True)
- equalize_profile_curve.clicked.connect(partial(undo(self.core.attributes.equalize_profile_curve), True))
- reset_button = Button(obj_name='gsResetProfileGraphButton')
- reset_button.set_label('重置曲线')
-
- def reset_button_clicked(*_):
- self.core.attributes.reset_profile_curve()
- self.core.attributes.store_graphs(profile_graph)
- reset_button.clicked.connect(undo(reset_button_clicked))
- pop_out_button = Button(obj_name='gsProfileGraphPopOut')
- pop_out_button.set_label('^')
- pop_out_button.clicked.connect(self.profile_graph_pop_out)
- row_layout = row.layout()
- if not isinstance(row_layout, QHBoxLayout):
- raise RuntimeError('未找到行布局')
- row_layout.addWidget(eq_column, 2)
- row_layout.addWidget(reset_button, 3)
- row_layout.addWidget(pop_out_button, 1)
- normals = ControlSlider(layout, 'surfaceNormals', 'float')
- normals.set_label('法线')
- normals.set_min_max(0, 180)
- normals.set_precision(1)
- normals.set_value(180)
- normals.set_drag_command(partial(self.core.sliders.curve_control_slider_drag, normals))
- normals.set_release_command(self.core.sliders.release)
- reverse_normals = Button(layout, 'reverseNormals')
- reverse_normals.set_label('反转法线', line_height=100)
- reverse_normals.setCheckable(True)
- reverse_normals.set_button_style('small')
- reverse_normals.setFixedWidth(style.scale(106))
- reverse_normals.clicked.connect(partial(self.core.updates.curve_control_check_boxes, 0))
- with Frame(layout, 'otherFrame', label='其他', margins=[2, 2, 2, 2]) as refine_frame, Row(refine_frame.get_frame_layout(), margins=style.scale([0, 0, 3, 0])) as curve_sampling_row:
- sampling_accuracy = ControlSlider(layout, 'samplingAccuracy', 'float')
- sampling_accuracy.set_label('采样精度')
- sampling_accuracy.set_min_max(0.001, 2)
- sampling_accuracy.set_step(0.01)
- sampling_accuracy.set_value(0.33)
- sampling_accuracy.set_drag_command(partial(self.core.sliders.curve_control_slider_drag, sampling_accuracy))
- sampling_accuracy.set_release_command(self.core.sliders.release)
- auto_sampling = Button(obj_name='autoSampling')
- auto_sampling.set_label('自动')
- auto_sampling.setFixedWidth(style.scale(35))
- auto_sampling.set_button_style('small')
- auto_sampling.setCheckable(True)
- auto_sampling.clicked.connect(undo(self.core.functions.toggle_auto_sampling))
- curve_sampling_row_layout = curve_sampling_row.layout()
- if not isinstance(curve_sampling_row_layout, QHBoxLayout):
- raise RuntimeError('未找到曲线采样行布局')
- curve_sampling_row_layout.addWidget(sampling_accuracy, 4)
- curve_sampling_row_layout.addWidget(auto_sampling, 1)
- with Row(refine_frame.get_frame_layout(), margins=style.scale([0, 0, 3, 0])) as curve_refine_row:
- refine = ControlSlider(layout, 'curveRefine', 'int')
- refine.set_label('细化')
- refine.set_min_max(0, 100)
- refine.set_field_min_max(0, 10000)
- refine.set_value(20)
- refine.set_drag_command(partial(self.core.sliders.curve_control_slider_drag, refine))
- refine.set_release_command(self.core.sliders.release)
- auto_refine_toggle = Button(obj_name='autoRefine')
- auto_refine_toggle.set_label('自动')
- auto_refine_toggle.setFixedWidth(style.scale(35))
- auto_refine_toggle.set_button_style('small')
- auto_refine_toggle.setCheckable(True)
- auto_refine_toggle.clicked.connect(undo(self.core.functions.toggle_auto_refine))
- curve_refine_row_layout = curve_refine_row.layout()
- if not isinstance(curve_refine_row_layout, QHBoxLayout):
- raise RuntimeError('未找到曲线细化行布局')
- curve_refine_row_layout.addWidget(refine, 4)
- curve_refine_row_layout.addWidget(auto_refine_toggle, 1)
- smooth = ControlSlider(refine_frame.get_frame_layout(), 'curveSmooth', 'float')
- smooth.setVisible(False)
- smooth.set_label('平滑')
- smooth.set_min_max(0, 10)
- smooth.set_drag_command(partial(self.core.sliders.curve_control_slider_drag, smooth))
- smooth.set_release_command(self.core.sliders.release)
- with Frame(layout, 'orientToNormalsFrame', label='朝向法线', margins=[2, 2, 2, 2]) as orient_frame:
- orient_frame.setVisible(False)
-
- def select_mesh():
- sel = mc.filterExpand(mc.ls(sl=1, l=1), sm=12)
- if not sel:
- sel = mc.ls(hl=1, o=1, l=1)
- if not sel:
- logger.warning('选择兼容的网格。', in_view=True)
- else:
- self.mesh_name.setText(sel[0])
- with Row(orient_frame.get_frame_layout()) as row:
- select_mesh_btn = Button(row.layout(), 'gsOrientToNormalsSelectTarget')
- select_mesh_btn.setFixedWidth(style.scale(100))
- select_mesh_btn.set_label('选择目标')
- select_mesh_btn.clicked.connect(select_mesh)
- self.mesh_name = LineEdit('gsOrientMeshName', row.layout())
- self.mesh_name.setPlaceholderText('选择或输入目标网格')
- self.mesh_name.setClearButtonEnabled(True)
- orient_frame.get_frame_layout().addWidget(separator())
- with Row(orient_frame.get_frame_layout()) as row:
- iterations_slider = ControlSlider(row.layout(), 'gsIterationsSlider', 'int')
- iterations_slider.set_min_max(1, 100)
- iterations_slider.set_value(10)
- iterations_slider.set_label('迭代次数')
- auto_refresh_button = Button(row.layout(), 'orientRefreshViewport')
- auto_refresh_button.set_button_style('small')
- auto_refresh_button.setCheckable(True)
- auto_refresh_button.setChecked(True)
- auto_refresh_button.set_width_height(width=style.scale(60))
- auto_refresh_button.set_label('刷新视图', line_height=100)
- with Row(orient_frame.get_frame_layout()) as row:
- min_angle_slider = ControlSlider(row.layout(), 'gsMinimumAngle', 'float')
- min_angle_slider.set_min_max(0.1, 90)
- min_angle_slider.set_value(1)
- min_angle_slider.set_label('最小角度')
- orient_frame.get_frame_layout().addWidget(separator())
- with Row(orient_frame.get_frame_layout()) as row:
- orient = Button(row.layout(), 'gsOrientToNormals')
- orient.set_label('朝向')
- orient.clicked.connect(undo(self.core.functions.orient_to_face_normals))
- with Frame(layout, 'solidifyFrame', label='实体化控制', margins=[2, 2, 2, 2]) as solidify_frame:
- solidify = Button(solidify_frame.get_frame_layout(), 'solidify')
- solidify.set_label('实体化', line_height=100)
- solidify.setCheckable(True)
- solidify.set_button_style('small')
- solidify.setFixedWidth(style.scale(106))
- solidify.clicked.connect(partial(self.core.updates.curve_control_check_boxes, 1))
- thickness = ControlSlider(solidify_frame.get_frame_layout(), 'solidifyThickness', 'float')
- thickness.set_label('厚度')
- thickness.set_min_max(0.001, 5)
- thickness.set_field_min_max(-100, 100)
- thickness.set_value(0.25)
- thickness.set_step(0.001)
- thickness.set_drag_command(partial(self.core.sliders.curve_control_slider_drag, thickness))
- thickness.set_release_command(self.core.sliders.release)
- divisions = ControlSlider(solidify_frame.get_frame_layout(), 'solidifyDivisions', 'int')
- divisions.set_label('分段数')
- divisions.set_min_max(0, 10)
- divisions.set_field_min_max(0, 100)
- divisions.set_drag_command(partial(self.core.sliders.curve_control_slider_drag, divisions))
- divisions.set_release_command(self.core.sliders.release)
- solidify_scale_x = ControlSlider(solidify_frame.get_frame_layout(), 'solidifyScaleX', 'float')
- solidify_scale_x.set_label('缩放 X')
- solidify_scale_x.set_min_max(-10, 10)
- solidify_scale_x.set_field_min_max(-100, 100)
- solidify_scale_x.set_step(0.001)
- solidify_scale_x.set_drag_command(partial(self.core.sliders.curve_control_slider_drag, solidify_scale_x))
- solidify_scale_x.set_release_command(self.core.sliders.release)
- solidify_scale_y = ControlSlider(solidify_frame.get_frame_layout(), 'solidifyScaleY', 'float')
- solidify_scale_y.set_label('缩放 Y')
- solidify_scale_y.set_min_max(-10, 10)
- solidify_scale_y.set_field_min_max(-100, 100)
- solidify_scale_y.set_step(0.001)
- solidify_scale_y.set_drag_command(partial(self.core.sliders.curve_control_slider_drag, solidify_scale_y))
- solidify_scale_y.set_release_command(self.core.sliders.release)
- offset = ControlSlider(solidify_frame.get_frame_layout(), 'solidifyOffset', 'float')
- offset.set_label('偏移')
- offset.set_min_max(-1, 1)
- offset.set_field_min_max(-100, 100)
- offset.set_step(0.001)
- offset.set_drag_command(partial(self.core.sliders.curve_control_slider_drag, offset))
- offset.set_release_command(self.core.sliders.release)
- solidify_normals = ControlSlider(solidify_frame.get_frame_layout(), 'solidifyNormals', 'float')
- solidify_normals.set_label('实体化法线')
- solidify_normals.set_min_max(0, 180)
- solidify_normals.set_precision(1)
- solidify_normals.set_value(180)
- solidify_normals.set_drag_command(partial(self.core.sliders.curve_control_slider_drag, solidify_normals))
- solidify_normals.set_release_command(self.core.sliders.release)
- with Frame(layout, 'UVFrame', label='UV 控制', margins=[2, 2, 2, 2]) as uv_frame:
- flip_uv = Button(uv_frame.get_frame_layout(), 'flipUV')
- flip_uv.set_label('水平翻转 UV', line_height=100)
- flip_uv.setCheckable(True)
- flip_uv.set_button_style('small')
- flip_uv.setFixedWidth(style.scale(106))
- flip_uv.clicked.connect(partial(undo(self.core.updates.curve_control_check_boxes), 3))
- move_u = ControlSlider(uv_frame.get_frame_layout(), 'moveU', 'float')
- move_u.set_label('移动 U')
- move_u.set_min_max(-0.5, 0.5)
- move_u.set_step(0.001)
- move_u.set_field_min_max(-100, 100)
- move_u.set_drag_command(partial(self.core.sliders.curve_control_slider_drag, move_u))
- move_u.set_release_command(self.core.sliders.release)
- move_v = ControlSlider(uv_frame.get_frame_layout(), 'moveV', 'float')
- move_v.set_label('移动 V')
- move_v.set_min_max(-0.5, 0.5)
- move_v.set_step(0.001)
- move_v.set_field_min_max(-100, 100)
- move_v.set_drag_command(partial(self.core.sliders.curve_control_slider_drag, move_v))
- move_v.set_release_command(self.core.sliders.release)
- scale_u = ControlSlider(uv_frame.get_frame_layout(), 'scaleU', 'float')
- scale_u.set_label('缩放 U')
- scale_u.set_min_max(0.001, 1.999)
- scale_u.set_field_min_max(0, 100)
- scale_u.set_step(0.001)
- scale_u.set_value(1)
- scale_u.set_drag_command(partial(self.core.sliders.curve_control_slider_drag, scale_u))
- scale_u.set_release_command(self.core.sliders.release)
- scale_v = ControlSlider(uv_frame.get_frame_layout(), 'scaleV', 'float')
- scale_v.set_label('缩放 V')
- scale_v.set_min_max(0.001, 1.999)
- scale_v.set_field_min_max(0, 100)
- scale_v.set_step(0.001)
- scale_v.set_value(1)
- scale_v.set_drag_command(partial(self.core.sliders.curve_control_slider_drag, scale_v))
- scale_v.set_release_command(self.core.sliders.release)
- rotate_uv = ControlSlider(uv_frame.get_frame_layout(), 'rotateUV', 'float')
- rotate_uv.set_label('旋转 UV')
- rotate_uv.set_min_max(-180, 180)
- rotate_uv.set_field_min_max(-3600, 3600)
- rotate_uv.set_precision(2)
- rotate_uv.set_drag_command(partial(self.core.sliders.curve_control_slider_drag, rotate_uv))
- rotate_uv.set_release_command(self.core.sliders.release)
- rotate_uv_root = ControlSlider(uv_frame.get_frame_layout(), 'rotateRootUV', 'float')
- rotate_uv_root.set_label('旋转根部 UV')
- rotate_uv_root.set_min_max(-180, 180)
- rotate_uv_root.set_field_min_max(-3600, 3600)
- rotate_uv_root.set_precision(2)
- rotate_uv_root.set_drag_command(partial(self.core.sliders.curve_control_slider_drag, rotate_uv_root))
- rotate_uv_root.set_release_command(self.core.sliders.release)
- rotate_uv_root.setVisible(False)
- rotate_uv_tip = ControlSlider(uv_frame.get_frame_layout(), 'rotateTipUV', 'float')
- rotate_uv_tip.set_label('旋转尖端 UV')
- rotate_uv_tip.set_min_max(-180, 180)
- rotate_uv_tip.set_field_min_max(-3600, 3600)
- rotate_uv_tip.set_precision(2)
- rotate_uv_tip.set_drag_command(partial(self.core.sliders.curve_control_slider_drag, rotate_uv_tip))
- rotate_uv_tip.set_release_command(self.core.sliders.release)
- rotate_uv_tip.setVisible(False)
- if MAYA_VER in (2020, 2022) and (not self.options_manager.get('UVBugMessageDismissed')):
- with Row(uv_frame.get_frame_layout()) as row:
- label = Label(row.layout())
- label.set_label('
')
- link_button = Button(row.layout())
- link_button.set_label('打开修复方法')
- link_button.set_button_style('small-filled')
- link_button.clicked.connect(lambda: open_link('https://gs-curvetools.readthedocs.io/en/latest/faq.html#maya-2020-2022-and-broken-uvs'))
- dismiss_message = Button(row.layout())
- dismiss_message.set_label('忽略提示')
- dismiss_message.set_button_style('small-filled')
- dismiss_message.clicked.connect(lambda: row.setHidden(True))
- dismiss_message.clicked.connect(lambda: self.options_manager.set('UVBugMessageDismissed', 1))
-
- def update_colors(self, *_):
- """更新 UV 编辑器的颜色"""
- if self.editor:
- self.options_manager.save()
- try:
- self.editor.change_color(literal_eval(self.options_manager.get('UVEditorBGColor')), literal_eval(self.options_manager.get('UVEditorGridColor')), literal_eval(self.options_manager.get('UVEditorFrameColor')), literal_eval(self.options_manager.get('UVEditorUVCardFillColor')), literal_eval(self.options_manager.get('UVEditorUVFrameSelectedColor')))
- except BaseException as exc:
- self.editor.change_color()
- logger.exception(exc)
- self.editor.update()
-
- @no_undo
- def update_editor(self):
- """更新 UV 编辑器"""
- self.update_item_list()
- self.update_uvs()
- self.update_texture()
-
- def show_all(self):
- """显示所有 UV"""
- self.uv_list.expandAll()
- self.uv_list.selectAll()
- self.update_visibility()
- self.isolate_mode = False
-
- @no_undo
- def update_uvs(self, keep_selection=False):
- """更新 UV"""
- sel = mc.filterExpand(mc.ls(sl=1, fl=1, l=1), sm=9)
- old_uvs = self.editor.uv_dict
- self.editor.purge_uvs()
- if not sel:
- return
- sel = self.check_for_legacy_uvs(sel)
- assert sel is not None
- for item in sel:
- if mc.attributeQuery('Orientation', n=item, ex=1) and mc.connectionInfo(item + '.Orientation', isSource=1):
- if mc.attributeQuery('gsmessage', n=item, ex=1) and mc.listConnections(item + '.gsmessage'):
- curves = self.core.utils.get_all_connected_curves(item)
- else:
- curves = [item]
- for curve in curves:
- attrs = self.core.attributes.get_uvs(curve)
- checkbox = self.core.attributes.get_checkboxes(curve)
- if attrs:
- uv_item = self.editor.create_uv(curve)
- if 'flipUV' in checkbox:
- uv_item.flip = not checkbox['flipUV']
- uv_item.move_uv(x=attrs['moveU'], y=attrs['moveV'], rot=attrs['rotateUV'] * -1, s_x=attrs['scaleU'], s_y=attrs['scaleV'])
- if keep_selection:
- new_uvs = self.editor.uv_dict
- for key, val in new_uvs.items():
- if key in old_uvs:
- val.setSelected(True)
-
- def check_for_legacy_uvs(self, curves):
- """检查是否存在旧版 UV"""
- legacy_curves = []
- for curve in curves:
- root = mc.attributeQuery('rotateRootUV', n=curve, ex=1)
- tip = mc.attributeQuery('rotateTipUV', n=curve, ex=1)
- if root or tip:
- root_value = mc.getAttr(curve + '.rotateRootUV')
- tip_value = mc.getAttr(curve + '.rotateTipUV')
- if root_value or tip_value:
- legacy_curves.append(curve)
- if not legacy_curves:
- return curves
- logger.warning('检测到非零旧版 UV 属性', in_view=True)
- dialog = mc.confirmDialog(title='旧版 UV', message='检测到非零旧版 UV。\nUV 编辑器与此不兼容。\n是否将其归零以继续?', icon='warning', button=['是', '取消'], cancelButton='取消', dismissString='取消')
- if dialog == '是':
- for curve in legacy_curves:
- mc.setAttr(curve + '.rotateRootUV', 0)
- mc.setAttr(curve + '.rotateTipUV', 0)
- return curves
- elif dialog == '取消':
- dialog = mc.confirmDialog(title='旧版 UV', message='UV 编辑器与旧版 UV 不兼容。\n部分卡片将被忽略。', icon='信息', button='确定', cancelButton='确定', dismissString='确定')
- return list(set(curves) - set(legacy_curves))
-
- @no_undo
- def update_texture(self):
- """更新纹理"""
- sel = self.core.utils.select_part(2, just_return=True)
- if not sel:
- self.editor.remove_texture()
- self.editor.diffuse_path = ''
- return
- geo = mc.filterExpand(sel, sm=12)
- if not geo:
- return
- dag = mc.ls(geo[-1], dag=1, s=1)
- shader = mc.listConnections(dag, d=1, s=1, t='shadingEngine')
- if not shader:
- return
- diffuse_file_node, alpha_file_node = self.core.utils.find_diffuse_alpha(shader[0])
- if not diffuse_file_node and (not alpha_file_node):
- return
- texture_path = None
- alpha_path = None
- if diffuse_file_node:
- texture_path = mc.getAttr(diffuse_file_node + '.fileTextureName')
- if alpha_file_node:
- alpha_path = mc.getAttr(alpha_file_node + '.fileTextureName') if alpha_file_node else None
- if not texture_path and alpha_path:
- texture_path = alpha_path
- diffuse_file_node = alpha_file_node
- place_2d_texture = None
- if mc.attributeQuery('coverage', n=diffuse_file_node, ex=1):
- info = mc.connectionInfo(diffuse_file_node + '.coverage', sfd=1)
- if info:
- place_2d_texture = info.split('.')
- if place_2d_texture:
- place_2d_texture = place_2d_texture[0]
- cov, trans = (None, None)
- if place_2d_texture and mc.objExists(place_2d_texture) and self.widget_manager.get('UVEditorUseTransforms').isChecked() and mc.attributeQuery('coverage', ex=1, n=place_2d_texture) and mc.attributeQuery('translateFrame', ex=1, n=place_2d_texture):
- try:
- cov = mc.getAttr(place_2d_texture + '.coverage')[0]
- trans = mc.getAttr(place_2d_texture + '.translateFrame')[0]
- except BaseException as exc:
- logger.exception(exc)
- coverage = cov if cov else (1.0, 1.0)
- translation = (trans[0], trans[1]) if trans and trans else (0, 0)
- if not self.widget_manager.get('UVEditorTransparencyToggle').isChecked() and (not self.widget_manager.get('UVEditorAlphaOnlyToggle').isChecked()):
- alpha_path = None
- if texture_path:
- _, ext = os.path.splitext(texture_path)
- try:
- supported_formats = [str(x, encoding='ASCII').lower() for x in QtGui.QImageReader.supportedImageFormats()]
- except TypeError:
- supported_formats = [str(x).decode('ASCII').lower() for x in QtGui.QImageReader.supportedImageFormats()]
- if ext and ext[1:].lower() not in supported_formats:
- logger.warning('{} 格式不受支持。请使用 JPG/JPEG、PNG、TIF/TIFF(LZW 或无压缩)、TGA(24 位,无 RLE)'.format(ext[1:].upper()))
- return
- err = self.editor.set_texture('%s' % texture_path, alpha_path, coverage, translation)
- if err == 'SamePath':
- return
- if err == 'NoTexture':
- logger.warning('无法加载纹理文件。')
- elif err == 'ZeroTexture':
- logger.warning('无效路径或零纹理。请检查导出的纹理位深度和压缩方式。TIF/TIFF(LZW 或无压缩)、TGA(24 位,无 RLE)。')
-
- def manual_curve_update(self):
- """手动更新 UV 曲线"""
- try:
- self._update_curves()
- except BaseException as exc:
- logger.exception(exc)
- finally:
- self._stop_curves_update()
-
- def _update_curves(self):
- if self.uv_update_check == 0:
- mc.undoInfo(ock=1, cn='gsUVUpdate')
- self.uv_update_check = 1
- sel = mc.filterExpand(mc.ls(sl=1), sm=9)
- uvs = self.editor.get_uvs()
- self.current_selection *= 0
- if not sel:
- return
- for curve in sel:
- if curve in uvs:
- self.current_selection.append(curve)
- elif mc.attributeQuery('gsmessage', n=curve, ex=1) and mc.listConnections(curve + '.gsmessage'):
- bound_curves = self.core.utils.get_all_connected_curves(curve)
- if bound_curves:
- self.current_selection += bound_curves
- if not self.timer.increment(0.016666666666666666):
- return
- if not self.current_selection:
- return
- uvs = self.editor.get_uvs()
- for curve in self.current_selection:
- if curve in uvs:
- self.core.attributes.set_attributes(curve, uvs[curve])
-
- def _stop_curves_update(self):
- if self.uv_update_check == 1:
- mc.undoInfo(cck=1)
- self.uv_update_check = 0
- self.current_selection *= 0
- self.core.curve_control.update_ui()
-
- def update_buttons(self, controller_mode, scale_mode):
- """更新按钮状态"""
- assert self.controller_group is not None
- assert self.direction_switch is not None
- buttons = self.controller_group.buttons()
- direction = self.direction_switch.buttons()
- if controller_mode == 'SELECT':
- buttons[0].setChecked(True)
- elif controller_mode == 'MOVE':
- buttons[1].setChecked(True)
- elif controller_mode == 'ROTATE':
- buttons[2].setChecked(True)
- elif controller_mode == 'SCALE':
- buttons[3].setChecked(True)
- if scale_mode == 'H':
- direction[0].setChecked(True)
- else:
- direction[1].setChecked(True)
- elif controller_mode == 'DRAW':
- buttons[4].setChecked(True)
-
- def update_controller_mode(self):
- """更新控制模式"""
- assert self.controller_group is not None
- assert self.direction_switch is not None
- button_id = self.controller_group.checkedId()
- scale_id = self.direction_switch.checkedId()
- scale = 'H'
- if button_id == 0:
- mode = 'SELECT'
- elif button_id == 1:
- mode = 'MOVE'
- elif button_id == 2:
- mode = 'ROTATE'
- elif button_id == 3:
- mode = 'SCALE'
- if scale_id == 0:
- scale = 'H'
- else:
- scale = 'V'
- else:
- mode = 'DRAW'
- self.editor.controller_mode_change(mode, scale)
-
- def update_item_list(self):
- """更新项目列表"""
- sel = mc.filterExpand(mc.ls(sl=1), sm=9)
- if not sel:
- self.uv_list.clear_item_list()
- return
- final_dict = {}
- for curve in sel:
- if mc.attributeQuery('Orientation', n=curve, ex=1) and mc.connectionInfo(curve + '.Orientation', isSource=1):
- if mc.attributeQuery('gsmessage', n=curve, ex=1) and mc.listConnections(curve + '.gsmessage'):
- bound_curves = self.core.utils.get_all_connected_curves(curve)
- final_dict[curve] = bound_curves
- else:
- final_dict[curve] = []
- self.uv_list.update_item_list(final_dict)
-
- def update_visibility(self):
- """更新 UV 的可见性"""
- item_list = self.uv_list.get_selection()
- items = self.editor.get_all_uvs()
- for item in items:
- if item.name in item_list:
- item.setVisible(True)
- else:
- item.setVisible(False)
- self.editor.update()
-
- def hide(self):
- """隐藏选中的 UV 项目"""
- sel_uvs = self.editor.get_all_uvs(selected=True)
- sel_uvs_list = [i.name for i in sel_uvs]
- for uv_item in sel_uvs:
- uv_item.setVisible(False)
- item_list = self.uv_list.get_item_list()
- select_list = []
- for item in item_list:
- if item.curve_name in sel_uvs_list:
- select_list.append(item)
- self.uv_list.select_items(select_list)
-
- def isolate_select(self):
- """隔离选中的 UV 项目"""
- all_uvs = self.editor.get_all_uvs()
- sel_uvs = self.editor.get_all_uvs(selected=True)
- if not sel_uvs:
- return
- if self.isolate_mode:
- self.show_all()
- self.isolate_mode = False
- return
- self.isolate_mode = True
- sel_uvs_list = [i.name for i in sel_uvs]
- for uv_item in all_uvs:
- if uv_item.name not in sel_uvs_list:
- uv_item.setVisible(False)
- item_list = self.uv_list.get_item_list()
- deselect_list = []
- for item in item_list:
- if item.curve_name not in sel_uvs_list:
- deselect_list.append(item)
- self.uv_list.select_items(deselect_list)
-
- def horizontal_flip_uv(self):
- """水平翻转 UV"""
- items = self.editor.get_all_uvs(selected=True)
- for item in items:
- if item.name and mc.attributeQuery('flipUV', n=item.name, ex=1):
- flip = mc.getAttr(item.name + '.flipUV')
- mc.setAttr(item.name + '.flipUV', not flip)
- item.flip = flip
- item.update()
- if items:
- self.editor.update()
-
- def vertical_flip_uv(self):
- """垂直翻转 UV"""
- self.editor.vertical_flip_uvs()
- self.manual_curve_update()
-
- def function_switch(self, key):
- """功能切换"""
- if key == 'H':
- self.horizontal_flip_uv()
- elif key == 'V':
- self.vertical_flip_uv()
- elif key == 'X':
- self.reset_uvs()
- elif key == 'I':
- self.isolate_select()
- elif key == 'O':
- self.hide()
- elif key == 'A':
- self.show_all()
- elif key == 'S':
- self.sync_selection()
-
- def reset_uvs(self):
- """重置 UV"""
- self.editor.reset_uvs()
- self.manual_curve_update()
-
- def randomize_uvs(self):
- """随机化 UV"""
- if get_mod() == 'Shift':
- self.editor.randomize_uvs(True)
- else:
- self.editor.randomize_uvs(False)
- self.manual_curve_update()
-
- def sync_selection(self):
- """根据 UV 编辑器的选择在 Maya 视口中选择曲线"""
- sel = mc.filterExpand(mc.ls(sl=1), sm=9)
- if not sel:
- return
- sel_uvs = [x.name for x in self.editor.get_all_uvs(selected=True)]
- new_sel = [x for x in sel if x in sel_uvs]
- if new_sel:
- mc.select(new_sel, r=1)
-
- @deferred_lp
- def x():
- uvs = self.editor.get_all_uvs()
- for uv_item in uvs:
- uv_item.setSelected(True)
- self.editor.scene().update()
- x()
\ No newline at end of file
diff --git a/2024/scripts/modeling_tools/gs_curvetools/ui/main_window.py b/2024/scripts/modeling_tools/gs_curvetools/ui/main_window.py
deleted file mode 100644
index fc4851b..0000000
--- a/2024/scripts/modeling_tools/gs_curvetools/ui/main_window.py
+++ /dev/null
@@ -1,651 +0,0 @@
-# 字节码版本: 3.11a7e (3495)
-# 源代码时间戳: 2025-04-22 11:47:05 UTC (1745322425)
-
-"""
-GS曲线工具主窗口
----
-GS曲线工具许可协议:
-名为GS曲线工具的此代码集合归乔治·斯拉德科夫斯基(叶戈尔·斯拉德科夫斯基)所有,
-未经他的书面许可,不得复制或分发。
-
-GS曲线工具 v1.3.10 个人版
-版权所有 2025,乔治·斯拉德科夫斯基(叶戈尔·斯拉德科夫斯基)
-保留所有权利
-
-用户界面字体为Roboto,该字体根据Apache 2.0许可协议授权:
-http://www.apache.org/licenses/LICENSE-2.0
-
-Autodesk Maya是Autodesk公司的产品:
-https://www.autodesk.com/
-
-社交媒体和联系方式:
-
-Discord服务器: https://discord.gg/f4DH6HQ
-在线商店: https://sladkovsky3d.artstation.com/store
-在线文档: https://gs-curvetools.readthedocs.io/
-Twitch频道: https://www.twitch.tv/videonomad
-YouTube频道: https://www.youtube.com/c/GeorgeSladkovsky
-ArtStation作品集: https://www.artstation.com/sladkovsky3d
-联系邮箱: george.sladkovsky@gmail.com
-"""
-import os
-from functools import partial
-import maya.cmds as mc
-from gs_curvetools.api.maya_tools import deferred, get_mod, no_undo, undo
-from gs_curvetools.api.qt_compat import *
-from gs_curvetools.api.typing import *
-from gs_curvetools.api.utils import open_link
-from gs_curvetools.config.constants import *
-from gs_curvetools.config.folders import GetFolder
-from gs_curvetools.debug.logger import logger
-from gs_curvetools.managers.options_manager import OptionsManager
-from gs_curvetools.managers.script_jobs import ScriptJobs
-from gs_curvetools.ui import style
-from gs_curvetools.ui.components import AboutWindow, AttributesFilterWindow, CurveControlWindow, CurveThicknessWindow, CustomLayerColorsWindow, GeoToCurveWindow, RandomizeCurveWindow, ScaleFactorWindow, UVEditorWindow
-from gs_curvetools.ui.tooltips import Tooltips
-from gs_curvetools.ui.utils import maya_dockable_window
-from gs_curvetools.ui.widgets import ActionGroup, Button, Frame, Layer, LayerCollectionWidget, Layout, LineEdit, Menu, MenuItem, Row, get_unique_name, maya_slider, separator, wrap_control
-if TYPE_CHECKING:
- from gs_curvetools.core.core import Core
- from gs_curvetools.managers.widget_manager import WidgetManager
-
-class MainWindow(QWidget):
- """Main GS CurveTools window"""
-
- def __init__(self, manager, core):
- menu_height = 786 if MAYA_VER <= 2024 else 810
- dockable_window = maya_dockable_window(name=WINDOWS.MainWindow.name, label=WINDOWS.MainWindow.label, i_h=menu_height)
- mc.workspaceControl(WINDOWS.MainWindow.name, e=1, ui=UI_SCRIPT)
- super(MainWindow, self).__init__(dockable_window)
- self.setParent(dockable_window)
- dockable_layout = dockable_window.layout()
- assert dockable_layout is not None
- dockable_layout.addWidget(self)
- self.widget_manager = manager
- self.core = core
- self.script_jobs = ScriptJobs.singleton()
- self.script_jobs.check_script_jobs(WINDOWS.MainWindow.name)
- self.options_manager = OptionsManager()
- self.tooltips = Tooltips()
- QtGui.QFontDatabase.removeAllApplicationFonts()
- fonts = os.listdir(GetFolder.fonts())
- for font in fonts:
- QtGui.QFontDatabase.addApplicationFont(os.path.join(GetFolder.fonts(), font))
- self.about_window = AboutWindow()
- self.attributes_filter_window = AttributesFilterWindow(self)
- self.curve_control_window = CurveControlWindow(self)
- self.curve_thickness_window = CurveThicknessWindow(self)
- self.custom_layer_colors_window = CustomLayerColorsWindow(self)
- self.geo_to_curve_window = GeoToCurveWindow(self)
- self.randomize_curve_window = RandomizeCurveWindow(self)
- self.scale_factor_window = ScaleFactorWindow(self)
- self.uv_editor = UVEditorWindow(self)
- self.widget_manager.add(WINDOWS.MainWindow.name, dockable_window)
- self._connect_signals()
-
- def _connect_signals(self):
- """Sets up the signals"""
- self.curve_control_window.update_curve_control_ui.connect(self.core.curve_control.update_ui)
- self.curve_control_window.update_main_ui.connect(self.core.updates.update_main_ui)
-
- def create_ui(self):
- """Creates the UI"""
- main_layout = QVBoxLayout(self)
- main_layout.setContentsMargins(*style.scale([2, 0, 2, 0]))
- scroll_area = QScrollArea(self)
- scroll_widget = QWidget()
- scroll_widget.setFocus()
- scroll_layout = QVBoxLayout(scroll_widget)
- scroll_area.setWidget(scroll_widget)
- main_layout.addWidget(scroll_area)
- scroll_layout.setContentsMargins(0, 0, 0, 0)
- scroll_layout.setSpacing(style.scale(2))
- scroll_layout.setAlignment(QtCore.Qt.AlignmentFlag.AlignTop)
- scroll_area.setFrameShape(QtWidgets.QFrame.Shape.NoFrame)
- scroll_area.setWidgetResizable(True)
- menu_bar_widget = QWidget(scroll_area)
- menu_bar_layout = QHBoxLayout(menu_bar_widget)
- menu_bar_layout.setContentsMargins(0, 0, 0, 0)
- menu_bar_layout.setAlignment(QtCore.Qt.AlignmentFlag.AlignCenter)
- menu_bar = QMenuBar(menu_bar_widget)
- menu_bar.setSizePolicy(QtWidgets.QSizePolicy.Policy.Preferred, QtWidgets.QSizePolicy.Policy.Preferred)
- menu_bar_layout.addWidget(menu_bar)
- scroll_layout.addWidget(menu_bar_widget)
- with Menu('选项', menu_bar) as menu:
- menu.triggered.connect(self.options_manager.save)
- menu.addSection('导入 / 导出')
- import_curves = MenuItem('importCurves', '导入曲线', menu)
- import_curves.triggered.connect(no_undo(self.core.import_export.import_curves))
- export_curves = MenuItem('exportCurves', '导出曲线', menu)
- export_curves.triggered.connect(self.core.import_export.export_curves)
- menu.addSection('全局修改器')
- change_scale_factor = MenuItem('changeScaleFactor', '更改比例因子和精度', menu)
- change_scale_factor.triggered.connect(self.scale_factor_window.show_window)
- global_curve_thickness = MenuItem('globalCurveThickness', '全局曲线厚度', menu)
- global_curve_thickness.triggered.connect(self.curve_thickness_window.show_window)
- menu.addSection('视图端口命令')
- ao_settings = MenuItem('setAOSettings', '设置AO设置', menu)
- ao_settings.triggered.connect(self.options_manager.set_ao_settings)
- with Menu('透明度设置', menu) as transparency_settings_menu:
- simple_transparency = MenuItem('setSimpleTransparency', '简单透明度(快速,不准确)', transparency_settings_menu)
- simple_transparency.triggered.connect(partial(no_undo(self.options_manager.set_transparency_settings), 0))
- object_sorting_transparency = MenuItem('setObjectSortingTransparency', '对象排序透明度(中等)', transparency_settings_menu)
- object_sorting_transparency.triggered.connect(partial(no_undo(self.options_manager.set_transparency_settings), 1))
- set_depth_transparency = MenuItem('setDepthTransparency', '深度透明度(准确,缓慢,推荐)', transparency_settings_menu)
- set_depth_transparency.triggered.connect(partial(no_undo(self.options_manager.set_transparency_settings), 2))
- menu.addSection('转换曲线')
- with Menu('转换曲线', menu) as convert_curves_submenu:
- convert_to_warp_card = MenuItem('convertToWarpCard', '转换为变形面片', convert_curves_submenu)
- convert_to_warp_card.triggered.connect(partial(undo(self.core.functions.convert_selection_to), 0))
- convert_to_warp_tube = MenuItem('convertToWarpTube', '转换为变形管', convert_curves_submenu)
- convert_to_warp_tube.triggered.connect(partial(undo(self.core.functions.convert_selection_to), 1))
- convert_to_extrude_card = MenuItem('convertToExtrudeCard', '转换为挤压面片', convert_curves_submenu)
- convert_to_extrude_card.triggered.connect(partial(undo(self.core.functions.convert_selection_to), 2))
- convert_to_extrude_tube = MenuItem('convertToExtrudeTube', '转换为挤压管', convert_curves_submenu)
- convert_to_extrude_tube.triggered.connect(partial(undo(self.core.functions.convert_selection_to), 3))
- menu.addSection('实用功能')
- duplicate_unparent = MenuItem('duplicateUnparentCurves', '复制并取消父级关联曲线', menu)
- duplicate_unparent.triggered.connect(undo(self.core.functions.duplicate_unparent))
- menu.addSection('常规选项')
- MenuItem('keepCurveAttributes', '保留曲线属性', menu, True, self.options_manager.get('keepCurveAttributes'))
- MenuItem('addBetweenBlendAttributes', '添加面片/管混合属性', menu, True, self.options_manager.get('addBetweenBlendAttributes'))
- MenuItem('fillCreateCurvesOnly', '填充仅创建曲线', menu, True, self.options_manager.get('fillCreateCurvesOnly'))
- MenuItem('convertInstances', '自动转换实例', menu, True, self.options_manager.get('convertInstances'))
- MenuItem('useAutoSamplingOnNewCurves', '对新曲线使用自动采样', menu, True, self.options_manager.get('useAutoSamplingOnNewCurves'))
- MenuItem('useAutoRefineOnNewCurves', '对新曲线使用自动细化', menu, True, self.options_manager.get('useAutoRefineOnNewCurves'))
- MenuItem('flipUVsAfterMirror', '镜像后翻转UV', menu, True, self.options_manager.get('flipUVsAfterMirror'))
- enable_tooltips_menu = MenuItem('enableTooltips', '启用工具提示', menu, True, self.options_manager.get('enableTooltips'))
- enable_tooltips_menu.triggered.connect(self.toggle_tooltips)
- menu.addSection('颜色选项')
- sync_color = MenuItem('syncCurveColor', '同步曲线颜色到图层颜色', menu, True, self.options_manager.get('syncCurveColor'))
- sync_color.triggered.connect(self.core.color_mode.sync_curve_colors)
- MenuItem('colorizedRegroup', '对重新分组的图层进行颜色化', menu, True, self.options_manager.get('colorizedRegroup'))
- color_only_diffuse = MenuItem('colorOnlyDiffuse', '颜色仅影响漫反射', menu, True, self.options_manager.get('colorOnlyDiffuse'))
- color_only_diffuse.triggered.connect(self.core.color_mode.update_color_options)
- checker_pattern = MenuItem('checkerPattern', '颜色模式使用棋盘格图案', menu, True, self.options_manager.get('checkerPattern'))
- checker_pattern.triggered.connect(self.core.color_mode.update_color_options)
- menu.addSection('绑定选项')
- MenuItem('boundCurvesFollowParent', '绑定曲线跟随父级', menu, True, self.options_manager.get('boundCurvesFollowParent'))
- MenuItem('massBindOption', '绑定到所有可用的空曲线', menu, True, self.options_manager.get('massBindOption'))
- MenuItem('bindDuplicatesCurves', '绑定前复制曲线', menu, True, self.options_manager.get('bindDuplicatesCurves'))
- MenuItem('bindFlipUVs', '绑定前翻转UV', menu, True, self.options_manager.get('bindFlipUVs'))
- menu.addSection('解绑/解包选项')
- MenuItem('unpackDeleteOriginalObject', '解包时删除原始对象', menu, True, self.options_manager.get('unpackDeleteOriginalObject'))
- MenuItem('unpackCVMatch', '解包匹配原始CV数量', menu, True, self.options_manager.get('unpackCVMatch'))
- menu.addSection('图层选项')
- MenuItem('ignoreLastLayer', '忽略最后一个图层', menu, True, self.options_manager.get('ignoreLastLayer'))
- MenuItem('syncOutlinerLayerVis', '同步大纲/图层可见性', menu, True, self.options_manager.get('syncOutlinerLayerVis'))
- MenuItem('replacingCurveLayerSelection', '替换曲线图层选择', menu, True, self.options_manager.get('replacingCurveLayerSelection'))
- only_numbers_in_layers = MenuItem('layerNumbersOnly', '图层仅使用数字', menu, True, self.options_manager.get('layerNumbersOnly'))
- only_numbers_in_layers.triggered.connect(self.core.layer_manager.change_layers_to_numbers)
- only_numbers_in_layers.triggered.connect(self.update_layer_list)
- with Menu('活动图层数量', menu) as layer_number_menu, ActionGroup('layerRowsActionGroup', layer_number_menu) as action_group:
- MenuItem('2layerRows', '20个图层', layer_number_menu, True, self.options_manager.get('2layerRows'), collection=action_group)
- MenuItem('3layerRows', '30个图层', layer_number_menu, True, self.options_manager.get('3layerRows'), collection=action_group)
- MenuItem('4layerRows', '40个图层', layer_number_menu, True, self.options_manager.get('4layerRows'), collection=action_group)
- MenuItem('6layerRows', '60个图层', layer_number_menu, True, self.options_manager.get('6layerRows'), collection=action_group)
- MenuItem('8layerRows', '80个图层', layer_number_menu, True, self.options_manager.get('8layerRows'), collection=action_group)
- action_group.triggered.connect(self.core.updates.update_main_ui)
- menu.addSection('图层集合选项')
- MenuItem('ignoreTemplateCollections', '忽略“模板”集合名称', menu, True, self.options_manager.get('ignoreTemplateCollections'))
- MenuItem('groupTemplateCollections', '将“模板”集合分组在一起', menu, True, self.options_manager.get('groupTemplateCollections'))
- layer_collections_toggle = MenuItem('showLayerCollectionsMenu', '显示图层集合菜单', menu, True, self.options_manager.get('showLayerCollectionsMenu'))
- layer_collections_toggle.triggered.connect(self.core.layer_manager.layer_collections.toggle_widget)
- MenuItem('importIntoANewCollection', '导入到新集合中', menu, True, self.options_manager.get('importIntoANewCollection'))
- menu.addSection('其他选项')
- with Menu('其他选项', menu) as other_options_menu:
- other_options_menu.addSection('更新功能')
- convert_to_new_layer_system = MenuItem('convertToNewLayerSystem', '转换为新图层系统', other_options_menu)
- convert_to_new_layer_system.triggered.connect(undo(self.core.utils.convert_to_new_layer_system))
- update_layers = MenuItem('updateLayers', '更新图层', other_options_menu)
- update_layers.triggered.connect(undo(self.core.layer_manager.delete_unused_layers))
- from gs_curvetools.main import reset as reset_gs_curvetools
- reset_to_defaults = MenuItem('resetToDefaults', '恢复默认设置', other_options_menu)
- reset_to_defaults.triggered.connect(reset_gs_curvetools)
- other_options_menu.addSection('修复')
- maya_2020_uv_fix = MenuItem('maya2020UVFix', '修复Maya 2020 - 2022 UV错误', other_options_menu)
- maya_2020_uv_fix.triggered.connect(undo(self.core.fixes.fix_maya_2020_uvs))
- fix_broken_graphs = MenuItem('mayaFixBrokenGraphs', '修复损坏的图表', other_options_menu)
- fix_broken_graphs.triggered.connect(undo(self.core.fixes.fix_broken_graphs))
- convert_bezier_to_nurbs = MenuItem('convertBezierToNurbs', '将所选贝塞尔曲线转换为NURBS曲线', other_options_menu)
- convert_bezier_to_nurbs.triggered.connect(undo(self.core.fixes.convert_bezier_to_nurbs))
- maya_2020_twist_fix = MenuItem('maya2020TwistAttribute', '修复Maya 2020.4扭曲属性', other_options_menu)
- maya_2020_twist_fix.triggered.connect(undo(self.core.fixes.fix_maya_2020_twist))
- maya_2020_unbind_fix = MenuItem('maya2020UnbindFix', '修复Maya 2020.4解绑功能', other_options_menu)
- maya_2020_unbind_fix.triggered.connect(undo(self.core.fixes.fix_maya_2020_unbind))
- delete_all_animation_keys = MenuItem('deleteAllAnimationKeys', '删除所有动画关键帧', other_options_menu)
- delete_all_animation_keys.triggered.connect(undo(self.core.fixes.delete_keys_on_all_objects))
- disable_curve_smooth = MenuItem('disableCurveSmooth', '重置旧版曲线平滑属性', other_options_menu)
- disable_curve_smooth.triggered.connect(self.core.fixes.reset_curve_smooth)
- reset_legacy_magnitude = MenuItem('resetLegacyMagnitude', '重置旧版轮廓幅度属性', other_options_menu)
- reset_legacy_magnitude.triggered.connect(self.core.fixes.reset_legacy_profile_magnitude)
- with Menu('帮助', menu_bar) as menu:
- open_log_file = MenuItem('openLogFile', '打开日志文件', menu)
- open_log_file.triggered.connect(logger.open_log_file)
- open_online_documentation = MenuItem('openOnlineDocumentation', '打开在线文档', menu)
- open_online_documentation.triggered.connect(lambda: open_link(USER_DOCS))
- useful_links = MenuItem('usefulLinks', '有用的链接和联系方式', menu)
- useful_links.triggered.connect(self.about_window.social_window)
- with Menu('关于', menu_bar) as menu:
- about_action = MenuItem('gsAbout', '关于', menu)
- about_action.triggered.connect(self.about_window.about_window)
- menu.addSeparator()
- menu.addAction('Made by George Sladkovsky (%s)' % YEAR).setEnabled(False)
- scroll_layout.addWidget(separator())
- with Row(scroll_layout) as row:
- extrude_warp_switch_group = QtWidgets.QButtonGroup(scroll_layout.widget())
- self.widget_manager.add('gsExtrudeWarpSwitchGroup', extrude_warp_switch_group)
- extrude_warp_switch_group.buttonToggled.connect(self.extrude_warp_toggle)
- extrude_warp_switch_group.buttonClicked.connect(self.options_manager.save)
- warp_switch = Button(row.layout(), 'warpSwitch')
- warp_switch.set_label('变形', line_height=100)
- warp_switch.set_button_style('small')
- warp_switch.setCheckable(True)
- extrude_switch = Button(row.layout(), 'extrudeSwitch')
- extrude_switch.set_label('挤压', line_height=100)
- extrude_switch.set_button_style('small')
- extrude_switch.setCheckable(True)
- extrude_warp_switch_group.addButton(warp_switch, 0)
- extrude_warp_switch_group.addButton(extrude_switch, 1)
- with Row(scroll_layout) as row:
- new_card = Button(row.layout(), 'newCard')
- new_card.set_label('新面片')
- new_card.clicked.connect(partial(undo(self.core.create.new), 0))
- new_tube = Button(row.layout(), 'newTube')
- new_tube.set_label('新管')
- new_tube.clicked.connect(partial(undo(self.core.create.new), 1))
- with Row(scroll_layout) as row:
- curve_card = Button(row.layout(), 'curveCard')
- curve_card.set_label('曲线面片')
- curve_card.clicked.connect(partial(undo(self.core.create.from_curves), 0))
- curve_tube = Button(row.layout(), 'curveTube')
- curve_tube.set_label('曲线管')
- curve_tube.clicked.connect(partial(undo(self.core.create.from_curves), 1))
- with Row(scroll_layout) as row:
- bind = Button(row.layout(), 'gsBind')
- bind.set_label('绑定')
- bind.set_icon('mod-top')
- bind.clicked.connect(undo(self.core.create.bind))
- unbind = Button(row.layout(), 'gsUnbind')
- unbind.set_label('解绑')
- unbind.set_icon('mod-top')
- unbind.clicked.connect(undo(lambda: self.core.create.unpack() if get_mod() == 'Shift' else self.core.create.unbind()))
- scroll_layout.addWidget(separator())
- with Row(scroll_layout) as row:
- add_cards = Button(row.layout(), 'addCards')
- add_cards.set_label('添加面片')
- add_cards.set_icon('mod-top')
- add_cards.clicked.connect(partial(undo(self.core.create.add_between), 0))
- add_tubes = Button(row.layout(), 'addTubes')
- add_tubes.set_label('添加管')
- add_tubes.set_icon('mod-top')
- add_tubes.clicked.connect(partial(undo(self.core.create.add_between), 1))
- with Row(scroll_layout) as row:
- fill = Button(row.layout(), 'gsFill')
- fill.set_label('填充')
- fill.set_icon('mod-top')
- fill.clicked.connect(undo(self.core.create.fill))
- subdivide = Button(row.layout(), 'gsSubdivide')
- subdivide.set_label('细分')
- subdivide.set_icon('mod-top')
- subdivide.clicked.connect(undo(self.core.functions.subdivide_curve))
- with Row(scroll_layout) as row:
- m_add_cards_slider = mc.intSliderGrp('gsCurvesSlider', l='添加', f=1, adj=3, cw=[(1, 20), (2, 25), (3, 1)], min=1, max=10, v=3)
- add_cards_slider = maya_slider(m_add_cards_slider, layout=row.layout())
- self.widget_manager.add('gsCurvesSlider', add_cards_slider)
- add_cards_slider.setContentsMargins(0, 0, 0, 0)
- c = add_cards_slider.children()[2]
- if isinstance(c, QWidget):
- c.setFocusPolicy(QtCore.Qt.FocusPolicy.NoFocus)
- scroll_layout.addWidget(separator())
- with Row(scroll_layout) as row:
- edge_to_curve = Button(row.layout(), 'gsEdgeToCurve')
- edge_to_curve.set_label('边转曲线')
- edge_to_curve.set_icon('mod-top')
- edge_to_curve.clicked.connect(undo(self.core.conversion.edge_to_curve))
- geo_to_curve = Button(row.layout(), 'gsGeoToCurve')
- geo_to_curve.set_label('几何体转曲线')
- geo_to_curve.clicked.connect(self.geo_to_curve_window.open_ui)
- scroll_layout.addWidget(separator())
- with Row(scroll_layout, obj_name='LayerCollectionsLayout', spacing=1) as layer_collections_layout:
- layer_combo_box = LayerCollectionWidget('layerCollectionsComboBox')
- layer_combo_box.setStyleSheet(style.SMALL_COMBO_BOX)
-
- def collection_changed():
- self.core.updates.update_visibility_based_on_active_collection()
- self.core.updates.update_main_ui()
- layer_combo_box.currentIndexChanged.connect(lambda *_: deferred(collection_changed)())
- layer_combo_box.setSizeAdjustPolicy(QtWidgets.QComboBox.SizeAdjustPolicy.AdjustToMinimumContentsLengthWithIcon)
- layer_combo_box.setDuplicatesEnabled(False)
- layer_combo_box.setMinimumWidth(0)
- layer_combo_box.setFixedHeight(style.scale(16))
- mc.popupMenu(mm=1, p=layer_combo_box.objectName())
- mc.menuItem(rp='N', l='清除', c=lambda *_: undo(self.core.layer_manager.layer_collections.clear)())
- mc.menuItem(rp='E', l='复制', c=lambda *_: no_undo(self.core.layer_manager.layer_collections.copy)())
- mc.menuItem(rp='NE', l='上移', c=lambda *_: no_undo(self.core.layer_manager.layer_collections.move_up)())
- mc.menuItem(rp='NW', l='合并上移', c=lambda *_: no_undo(self.core.layer_manager.layer_collections.merge_up)())
- mc.menuItem(rp='W', l='粘贴', c=lambda *_: undo(self.core.layer_manager.layer_collections.paste)())
- mc.menuItem(rp='SW', l='合并下移', c=lambda *_: no_undo(self.core.layer_manager.layer_collections.merge_down)())
- mc.menuItem(rp='SE', l='下移', c=lambda *_: no_undo(self.core.layer_manager.layer_collections.move_down)())
- mc.menuItem(rp='S', l='重命名', c=lambda *_: no_undo(self.core.layer_manager.layer_collections.rename)())
- with Row(layer_collections_layout.layout(), margins=style.scale([1, 0, 0, 0])) as plus_minus_buttons_layout:
- layer_combo_plus = Button(obj_name='layerCollectionsPlus', layout=plus_minus_buttons_layout.layout())
- layer_combo_plus.setFixedHeight(style.scale(16))
- layer_combo_plus.set_label('+', line_height=100)
- layer_combo_plus.setMinimumWidth(1)
- layer_combo_plus.set_button_style('small-filled')
- layer_combo_plus.clicked.connect(self.core.layer_manager.layer_collections.create)
- layer_combo_minus = Button(obj_name='layerCollectionsMinus', layout=plus_minus_buttons_layout.layout())
- layer_combo_minus.setEnabled(False)
- layer_combo_minus.setFixedHeight(style.scale(16))
- layer_combo_minus.setMinimumWidth(1)
- layer_combo_minus.set_label('-', line_height=100)
- layer_combo_minus.set_button_style('small-filled')
- layer_combo_minus.clicked.connect(undo(self.core.layer_manager.layer_collections.delete))
- lcl = layer_collections_layout.layout()
- if isinstance(lcl, QHBoxLayout):
- lcl.addWidget(layer_combo_box, 3)
- lcl.addWidget(plus_minus_buttons_layout, 1)
- layer_combo_box.insertItem(0, '主集合')
- with Row(scroll_layout) as row:
- all_filter = Button(row.layout(), 'gsAllFilter')
- all_filter.set_button_style('small-filled')
- all_filter.set_label('全部', line_height=100)
- all_filter.set_icon('mod-top')
- all_filter.clicked.connect(partial(undo(self.core.layer_manager.layers_filter_toggle), True, True))
- curve_filter = Button(row.layout(), 'gsCurveFilter')
- curve_filter.set_button_style('small-filled')
- curve_filter.set_label('曲线', line_height=100)
- curve_filter.clicked.connect(partial(undo(self.core.layer_manager.layers_filter_toggle), True, False, ignore=['Shift+Ctrl']))
- mc.popupMenu(mm=1, p=curve_filter.objectName())
- mc.menuItem(rp='N', l='切换始终置顶', c=lambda *_: undo(self.core.functions.always_on_top_toggle)())
- mc.menuItem(rp='S', l='在非活动集合上自动隐藏曲线', cb=self.options_manager.get('AutoHideCurvesOnInactiveCollections'), c=undo(self.core.layer_manager.collection_visibility_toggle))
- geo_filter = Button(row.layout(), 'gsGeoFilter')
- geo_filter.set_button_style('small-filled')
- geo_filter.set_label('几何体', line_height=100)
- geo_filter.clicked.connect(partial(undo(self.core.layer_manager.layers_filter_toggle), False, True, ignore=['Shift+Ctrl']))
- color_mode = Button(row.layout(), 'colorMode')
- color_mode.set_button_style('small-filled')
- color_mode.setCheckable(True)
- color_mode.setChecked(False)
- color_mode.set_label('颜色', line_height=100)
- color_mode.clicked.connect(undo(self.core.color_mode.toggle_color_vis))
- mc.popupMenu(mm=1, p=color_mode.objectName())
- mc.menuItem(rp='N', l='随机化颜色', c=lambda *_: undo(self.core.color_mode.randomize_colors)())
- mc.menuItem(rp='E', l='重置曲线颜色', c=lambda *_: self.core.color_mode.reset_curve_colors())
- mc.menuItem(rp='W', l='应用曲线颜色', c=lambda *_: self.core.color_mode.sync_curve_colors(True))
- mc.menuItem(rp='S', l='自定义颜色窗口', c=lambda *_: self.custom_layer_colors_window.window())
- with Layout(scroll_layout, obj_name='LayerLayout') as layer_layout:
- layer_button_grp = QtWidgets.QButtonGroup(layer_layout)
- layer_button_grp.setObjectName(get_unique_name('LayerGroup'))
- layer_button_grp.setExclusive(True)
- self.widget_manager.add('LayerGroup', layer_button_grp)
- with Row(layer_layout.layout(), 'layerRow0', spacing=0) as row:
- for i in range(10):
- layer_button_grp.addButton(self.selection_sets(i, row.layout(), str(i)))
- with Row(layer_layout.layout(), 'layerRow1', spacing=0) as row:
- letter = ord('A')
- letters = [chr(i) for i in range(letter, letter + 10)]
- if self.widget_manager.get('layerNumbersOnly').isChecked():
- letters = list(range(10, 20))
- for i in range(10):
- layer_button_grp.addButton(self.selection_sets(i + 10, row.layout(), str(letters[i])))
- with Row(layer_layout.layout(), 'layerRow2', spacing=0) as row:
- for i in range(10):
- layer_button_grp.addButton(self.selection_sets(i + 20, row.layout(), str(i + 20)))
- self.widget_manager.get('layerRow2').setHidden(True)
- with Row(layer_layout.layout(), 'layerRow3', spacing=0) as row:
- for i in range(10):
- layer_button_grp.addButton(self.selection_sets(i + 30, row.layout(), str(i + 30)))
- self.widget_manager.get('layerRow3').setHidden(True)
- with Row(layer_layout.layout(), 'layerRow4', spacing=0) as row:
- for i in range(10):
- layer_button_grp.addButton(self.selection_sets(i + 40, row.layout(), str(i + 40)))
- self.widget_manager.get('layerRow4').setHidden(True)
- with Row(layer_layout.layout(), 'layerRow5', spacing=0) as row:
- for i in range(10):
- layer_button_grp.addButton(self.selection_sets(i + 50, row.layout(), str(i + 50)))
- self.widget_manager.get('layerRow5').setHidden(True)
- with Row(layer_layout.layout(), 'layerRow6', spacing=0) as row:
- for i in range(10):
- layer_button_grp.addButton(self.selection_sets(i + 60, row.layout(), str(i + 60)))
- self.widget_manager.get('layerRow6').setHidden(True)
- with Row(layer_layout.layout(), 'layerRow7', spacing=0) as row:
- for i in range(10):
- layer_button_grp.addButton(self.selection_sets(i + 70, row.layout(), str(i + 70)))
- self.widget_manager.get('layerRow7').setHidden(True)
- self.widget_manager.get('curveGrp0').setChecked(True)
- with Row(scroll_layout) as row:
- extract_selected = Button(row.layout(), 'gsExtractSelected')
- extract_selected.set_label('提取 所选')
- extract_selected.set_icon('mod-bottom')
- extract_selected.clicked.connect(undo(self.core.functions.extract_selected_curves))
- extract_all = Button(row.layout(), 'gsExtractAll')
- extract_all.set_label('提取 全部')
- extract_all.set_icon('mod-bottom')
- extract_all.clicked.connect(undo(self.core.functions.extract_all_curves))
- scroll_layout.addWidget(separator())
- with Row(scroll_layout) as row:
- select_curve = Button(row.layout(), 'gsSelectCurve')
- select_curve.set_label('选择 曲线')
- select_curve.clicked.connect(partial(undo(self.core.utils.select_part), 1))
- select_geo = Button(row.layout(), 'gsSelectGeo')
- select_geo.set_label('选择 几何体')
- select_geo.clicked.connect(partial(undo(self.core.utils.select_part), 2))
- select_group = Button(row.layout(), 'gsSelectGroup')
- select_group.set_label('选择 组')
- select_group.clicked.connect(partial(undo(self.core.utils.select_part), 0))
- with Row(scroll_layout) as row:
- group_curves = Button(row.layout(), 'gsGroupCurves')
- group_curves.set_label('分组 曲线')
- group_curves.clicked.connect(undo(self.core.functions.group_curves))
- regroup_by_layer = Button(row.layout(), 'gsRegroupByLayer')
- regroup_by_layer.set_label('按图层 重新分组')
- regroup_by_layer.clicked.connect(undo(self.core.functions.regroup_by_layer))
- group_name = LineEdit('gsGroupNameTextField', scroll_layout)
- group_name.setAlignment(QtCore.Qt.AlignmentFlag.AlignCenter)
- group_name.set_auto_format(True)
- group_name.setClearButtonEnabled(True)
- group_name.setPlaceholderText('组名称')
- custom_layer_names_colors = Button(scroll_layout, 'gsCustomLayerNamesAndColors')
- custom_layer_names_colors.set_button_style('small-filled')
- custom_layer_names_colors.set_label('图层名称和颜色')
- custom_layer_names_colors.clicked.connect(self.custom_layer_colors_window.window)
- scroll_layout.addWidget(separator())
- scroll_layout.addWidget(wrap_control(mc.text(l='选择控制点')))
- slider_widget = wrap_control(mc.floatSliderGrp('gsSelectCVSlider', w=1, min=0, max=1, step=0.05, dc=self.core.sliders.select_cv_slider, cc=self.core.sliders.release))
- self.widget_manager.add('gsSelectCVSlider', slider_widget)
- scroll_layout.addWidget(slider_widget)
- with Row(scroll_layout) as row:
- transfer_attributes = Button(row.layout(), 'gsTransferAttributes')
- transfer_attributes.set_label('转移 属性.')
-
- transfer_attributes.set_icon('mod-bottom')
- transfer_attributes.clicked.connect(undo(self.core.attributes.transfer_attributes))
- mc.popupMenu(mm=1, p=transfer_attributes.objectName())
- mc.menuItem('gsCopyAttributes', rp='N', l='复制属性', aob=1, c=lambda _: self.core.attributes.copy_attributes())
- mc.menuItem(ob=1, c=lambda _: self.attributes_filter_window.open_ui())
- mc.menuItem('gsPasteAttributes', rp='S', l='粘贴属性', aob=1, c=lambda _: self.core.attributes.paste_attributes())
- mc.menuItem(ob=1, c=lambda _: self.attributes_filter_window.open_ui())
- transfer_uvs = Button(row.layout(), 'gsTransferUVs')
- transfer_uvs.set_label('转移\nUV')
- transfer_uvs.set_icon('mod-bottom')
- transfer_uvs.clicked.connect(undo(self.core.attributes.transfer_uvs))
- mc.popupMenu(mm=1, p=transfer_uvs.objectName())
- mc.menuItem('gsCopyUVs', aob=1, rp='N', l='复制UV', c=lambda _: self.core.attributes.copy_uvs())
- mc.menuItem(ob=1, c=lambda _: self.attributes_filter_window.open_ui())
- mc.menuItem('gsPasteUVs', aob=1, rp='S', l='粘贴UV', c=lambda _: self.core.attributes.paste_uvs())
- mc.menuItem(ob=1, c=lambda _: self.attributes_filter_window.open_ui())
- reset_pivot = Button(row.layout(), 'gsResetPivot')
- reset_pivot.set_label('重置\n轴心点')
- reset_pivot.clicked.connect(undo(self.core.functions.reset_curve_pivot_point))
- reset_pivot.set_icon('mod-bottom')
- mc.popupMenu(mm=1, p=reset_pivot.objectName())
- mc.menuItem('gsResetPivotToRoot', rp='N', l='重置到根部', c=lambda _: self.core.functions.reset_curve_pivot_point())
- mc.menuItem('gsResetPivotToTip', rp='S', l='重置到尖端', c=lambda _: self.core.functions.reset_curve_pivot_point(2))
- scroll_layout.addWidget(separator())
-
- def rebuild_slider_release():
- self.core.sliders.rebuild_slider_release()
- self.core.sliders.release()
-
- def rebuild_button_clicked():
- self.core.sliders.rebuild_slider_drag()
- rebuild_slider_release()
- with Row(scroll_layout, margins=style.scale([1.5, 0, 1.5, 0])) as rebuild_reset_row:
- rebuild_button = Button(obj_name='gsRebuildWithCurrentValue')
- rebuild_button.set_button_style('small-filled')
- rebuild_button.set_label('R', line_height=100)
- rebuild_button.setMinimumWidth(1)
- rebuild_button.setMaximumSize(*style.scale([16, 16]))
- rebuild_button.clicked.connect(rebuild_button_clicked)
- reset_button = Button(obj_name='gsResetRebuildSliderRange')
- reset_button.set_button_style('small-filled')
- reset_button.set_icon('reset')
- reset_button.setMinimumWidth(1)
- reset_button.setMaximumSize(*style.scale([16, 16]))
- reset_button.clicked.connect(lambda: mc.intSliderGrp('gsRebuildSlider', e=1, min=1, max=50))
- rrr = rebuild_reset_row.layout()
- if isinstance(rrr, QHBoxLayout):
- rrr.addWidget(rebuild_button, 1)
- rrr.addWidget(wrap_control(mc.text(l='重建曲线')), 3)
- rrr.addWidget(reset_button, 1)
- rebuild_curve_slider = wrap_control(mc.intSliderGrp('gsRebuildSlider', f=1, cw=[(1, 32), (2, 28)], min=1, max=50, fmx=999, v=1, dc=self.core.sliders.rebuild_slider_drag, cc=lambda *_: rebuild_slider_release()))
- self.widget_manager.add('gsRebuildSlider', rebuild_curve_slider)
- scroll_layout.addWidget(rebuild_curve_slider)
- with Row(scroll_layout) as row:
- duplicate_curve = Button(row.layout(), 'gsDuplicateCurve')
- duplicate_curve.set_label('复制')
- duplicate_curve.clicked.connect(undo(self.core.functions.duplicate_curve))
- randomize_curve = Button(row.layout(), 'gsRandomizeCurve')
- randomize_curve.set_label('随机化')
- randomize_curve.clicked.connect(self.randomize_curve_window.open_ui)
- with Row(scroll_layout) as row:
- extend_curve = Button(row.layout(), 'gsExtendCurve')
- extend_curve.set_label('延伸')
- extend_curve.clicked.connect(undo(self.core.functions.extend_curve))
- reduce_curve = Button(row.layout(), 'gsReduceCurve')
- reduce_curve.set_label('缩减')
- reduce_curve.clicked.connect(undo(self.core.functions.reduce_curve))
- with Row(scroll_layout) as row:
- smooth = Button(row.layout(), 'gsSmooth')
- smooth.set_label('平滑')
- smooth.clicked.connect(undo(self.core.functions.smooth_curve))
- smooth.set_icon('marking-top')
- mc.popupMenu(mm=1, p=smooth.objectName())
- mc.radioMenuItemCollection()
- mc.menuItem('gsSmoothMult1', rp='N', rb=1, l='x1')
- mc.menuItem('gsSmoothMult3', rp='E', rb=0, l='x3')
- mc.menuItem('gsSmoothMult5', rp='S', rb=0, l='x5')
- mc.menuItem('gsSmoothMult10', rp='W', rb=0, l='x10')
- factor_slider = wrap_control(mc.floatSliderGrp('gsFactorSlider', l='因子', adj=3, w=1, cw=[(1, 32), (2, 28)], min=1, max=100))
- self.widget_manager.add('gsFactorSlider', factor_slider)
- scroll_layout.addWidget(factor_slider)
- scroll_layout.addWidget(separator())
- with Frame(scroll_layout, obj_name='MirrorFrame', label='镜像', margins=[1, 1, 1, 1]) as frame:
- with Row(frame.get_frame_layout()) as row:
- mirror_x = Button(row.layout(), 'mirrorX')
- mirror_x.set_label('X')
- mirror_x.set_font_size(16)
- mirror_x.clicked.connect(partial(undo(self.core.functions.mirror_hair), 0))
- mirror_y = Button(row.layout(), 'mirrorY')
- mirror_y.set_label('Y')
- mirror_y.set_font_size(16)
- mirror_y.clicked.connect(partial(undo(self.core.functions.mirror_hair), 1))
- mirror_z = Button(row.layout(), 'mirrorZ')
- mirror_z.set_label('Z')
- mirror_z.set_font_size(16)
- mirror_z.clicked.connect(partial(undo(self.core.functions.mirror_hair), 2))
- with Row(frame.get_frame_layout()) as row:
- mirror_flip_grp = QtWidgets.QButtonGroup(row)
- mirror = Button(row.layout(), 'mirrorRadio')
- mirror.set_label('镜像')
- mirror.set_button_style('small')
- mirror.setCheckable(True)
- mirror.setChecked(True)
- flip = Button(row.layout(), 'flipRadio')
- flip.set_label('翻转')
- flip.set_button_style('small')
- flip.setCheckable(True)
- mirror_flip_grp.addButton(mirror)
- mirror_flip_grp.addButton(flip)
- scroll_layout.addWidget(separator())
- with Row(scroll_layout) as row:
- control_curve = Button(row.layout(), 'gsControlCurve')
- control_curve.set_label('控制曲线')
- control_curve.clicked.connect(undo(self.core.functions.control_curve_create))
- apply_control_curve = Button(row.layout(), 'gsApplyControlCurve')
- apply_control_curve.set_label('应用')
- apply_control_curve.setFixedWidth(style.scale(48))
- apply_control_curve.clicked.connect(undo(self.core.functions.control_curve_apply))
- scroll_layout.addWidget(separator())
- with Row(scroll_layout) as row:
- curve_control_window = Button(row.layout(), 'gsCurveControlWindow')
- curve_control_window.set_label('曲线控制窗口')
- curve_control_window.pressed.connect(self.curve_control_window.open_ui)
- scroll_layout.addWidget(separator())
- with Row(scroll_layout) as row:
- uv_editor = Button(row.layout(), 'gsUVEditorMain')
- uv_editor.set_label('UV编辑器窗口')
- uv_editor.pressed.connect(self.uv_editor.open_ui)
- scroll_layout.addWidget(separator())
- scroll_layout.addWidget(wrap_control(mc.text(l=VERSION)))
- warp_switch.setChecked(self.options_manager.get('warpSwitch'))
- extrude_switch.setChecked(not self.options_manager.get('warpSwitch'))
- self.core.layer_manager.layer_collections.toggle_widget()
- self.tooltips.toggle_custom_tooltips_main(self.options_manager.get('enableTooltips'))
-
- def selection_sets(self, i, layout, label):
- def toggle_geometry_edit(*_):
- self.core.layer_manager.curve_geometry_edit_toggle(i)
- self.core.updates.update_main_ui()
-
- def toggle_curve_visibility(*_):
- self.core.layer_manager.toggle_obj_visibility(i, 0)
- self.core.updates.update_main_ui()
-
- def toggle_geo_visibility(*_):
- self.core.layer_manager.toggle_obj_visibility(i, 1)
- self.core.updates.update_main_ui()
-
- def toggle_layer_visibility(*_):
- self.core.layer_manager.toggle_layer_visibility(i)
- self.core.updates.update_main_ui()
- sel_set = Layer(layout=layout, obj_name='curveGrp%s' % i)
- sel_set.setStyleSheet(style.layer())
- sel_set.set_label(str(label))
- mc.popupMenu(mm=1, p=sel_set.objectName())
- mc.menuItem(rp='N', l='将所选内容添加到图层', c=lambda _: self.core.layer_manager.curve_add_to_layer(i))
- mc.menuItem(rp='NW', l='提取几何体', c=lambda _: self.core.functions.extract_curve_geo(i))
- mc.menuItem(rp='NE', l='切换几何体编辑', c=toggle_geometry_edit)
- mc.menuItem(rp='W', l='选择曲线', c=lambda _: self.core.layer_manager.curve_layer_select_obj(i, 0))
- mc.menuItem(rp='E', l='选择几何体', c=lambda _: self.core.layer_manager.curve_layer_select_obj(i, 1))
- mc.menuItem(rp='SW', l='切换曲线可见性', c=toggle_curve_visibility)
- mc.menuItem(rp='SE', l='切换几何体可见性', c=toggle_geo_visibility)
- mc.menuItem(rp='S', l='切换图层可见性', c=toggle_layer_visibility)
- sel_set.clicked.connect(partial(undo(self.core.layer_manager.layer_clicked), i))
- return sel_set
-
- def extrude_warp_toggle(self):
- """Toggle the extrude/warp switch"""
- buttons = ['newCard', 'newTube', 'curveCard', 'curveTube', 'addCards', 'addTubes']
- button_style = style.BUTTON_NORMAL
- if self.widget_manager.get('extrudeSwitch').isChecked():
- button_style = style.BUTTON_NORMAL_BLUE_BORDER
- for button in buttons:
- self.widget_manager.get(button).setStyleSheet(button_style)
-
- def update_layer_list(self):
- """Update the layer list"""
- if self.widget_manager.exists('gsLayerSelector'):
- self.widget_manager.get('gsLayerSelector').updateLayerList()
- self.core.curve_control.update_ui()
-
- def toggle_tooltips(self):
- """Toggle the custom tooltips"""
- for widget in self.widget_manager.get_widgets():
- if hasattr(widget, 'enable_tooltip') and callable(getattr(widget, 'enable_tooltip')):
- widget.enable_tooltip(self.options_manager.get('enableTooltips'))
- self.tooltips.toggle_custom_tooltips_main(self.options_manager.get('enableTooltips'))
- self.tooltips.toggle_custom_tooltips_curve_control(self.options_manager.get('enableTooltips'))
- self.tooltips.toggle_custom_tooltips_scale_factor(self.options_manager.get('enableTooltips'))
\ No newline at end of file
diff --git a/2024/scripts/modeling_tools/gs_curvetools/ui/tooltips.md b/2024/scripts/modeling_tools/gs_curvetools/ui/tooltips.md
deleted file mode 100644
index e1b7897..0000000
--- a/2024/scripts/modeling_tools/gs_curvetools/ui/tooltips.md
+++ /dev/null
@@ -1,967 +0,0 @@
-
-
-
-
-
-# importCurves
-Imports Curves that were Exported using the Export Button.
-NOTE: Only import files that were exported using Export Curves button.
-WARNING: This operation is NOT undoable!
-
-# exportCurves
-Exports selected curves into a .curves (or .ma) file. Can then be Imported using Import Curves.
-
-# changeScaleFactor
-Opens a window that controls the Scale Factor and Precision Scale.
-***
-Scale factor determines the initial size of the created curve and adjusts other parameters.
-Scale factor is stored in a global preset, in the scene and on each curve.
-Priority of scale factors Curve>Scene>Global.
-Setting the appropriate scale factor before starting a project can help to have a good initial Width and size of the cards.
-***
-Precision Scale controls the world scale of the curve without changing the curve appearance, CV positions and other parameters.
-Lowering the Precision scale (from 1.0 to 0.05 for example) helps to fix the geometry deformation on very small curves.
-The default value of 0.05 should be sufficient for most cases. Values lower than 0.01 can affect performance.
-***
-Normalize Selected and Normalize Selected to Default will change the Scale Factor and Precision Scale of the selected curves, without changing their appearance or CV positions.
-Normalize Selected to Default will reset the slider values to default (0.5 and 0.05) and Normalize Selected will use the current slider values.
-
-# normalizeSelectedButton
-Normalize selected curves to the chosen slider values.
-Normalization will not change the CV positions or geometry appearance, but the selected objects will have new Scale Factor and Precision Scale applied.
-
-# normalizeSelectedToDefaultButton
-Normalize selected curves to the default slider values (0.5, 0.05).
-Resets the slider values to the default.
-Normalization will not change the CV positions or geometry appearance, but the selected objects will have new Scale Factor and Precision Scale applied.
-
-# saveScaleFactorAndPrecisionScaleButton
-Saves the selected slider values to the global storage and to the current scene.
-New scenes will automatically have these Scale Factor and Precision Scale values.
-NOTE: This will not apply the new values to already existing objects. See Normalize buttons.
-
-# saveScaleFactorAndPrecisionScaleButtonAndClose
-Saves the selected slider values to the global storage and to the current scene.
-New scenes will automatically have these Scale Factor and Precision Scale values.
-Closes the window after save.
-NOTE: This will not apply the new values to already existing objects. See Normalize buttons.
-
-# closePrecisionScaleWindow
-Close this window without save
-
-# globalCurveThickness
-Opens a window that controls the thickness of the curves in the scene as well as the global curve thickness preset across the scenes.
-
-# setAOSettings
-Manually sets the recommended AO settings for older Maya versions.
-These AO settings are needed to use the "See Through" or "Toggle Always on Top" functions.
-Are applied automatically by those functions.
-
-# setTransparencySettings
-Sets recommended transparency settings for Maya viewport.
-***
-Simple Transparency is fast but very inaccurate render mode. Only suitable for simple, one layer hair.
-Object Sorting Transparency has average performance impact and quality. Can have issues on complex multi-layered grooms.
-Depth Transparency - these are the optimal settings for the highest quality of the hair cards preview. Can have performance impact on slower systems.
-
-# convertToWarpCard
-Converts selection to Warp Cards.
-Compatible attributes are retained.
-
-# convertToWarpTube
-Converts selection to Warp Tubes.
-Compatible attributes are retained.
-
-# convertToExtrudeCard
-Converts selection to Extrude Cards.
-Compatible attributes are retained.
-
-# convertToExtrudeTube
-Converts selection to Extrude Tubes.
-Compatible attributes are retained.
-
-# duplicateUnparentCurves
-Duplicates selected NURBS curves and unparents them (parents them to the world).
-Original curves are not deleted.
-Can be used to easily extract and export curves from GS CurveTools objects.
-
-# syncCurveColor
-Toggles the syncing of the curve color to the layer color.
-
-# colorizedRegroup
-Toggles the colorization of the regrouped layers when Regroup by Layer function is used.
-
-# colorOnlyDiffuse
-Colorize only the diffuse component of the card material.
-Alpha will stay the same.
-
-# checkerPattern
-Toggles the use of the checker pattern when the Color mode is enabled.
-
-# ignoreLastLayer
-Toggles the filtering (All, Curve, Geo) and Extraction (Extract All) of the last layer. If enabled, the last layer is ignored.
-NOTE: Last layer is typically used for templates, so it is ignored by default.
-
-# ignoreTemplateCollections
-Ignores the filtering (All, Curve, Geo) and Extraction (Extract All) of all the collections that have "template" in their name. Case insensitive.
-
-# groupTemplateCollections
-Collections that have "template" in their name (case insensitive) will be grouped together into "CT_Templates" group by Regroup By Layer function.
-
-# syncOutlinerLayerVis
-Syncs the outliner and layer visibility. If enabled, hiding the layer will also hide the curve groups in the outliner.
-
-# keepCurveAttributes
-If enabled, the attributes that are stored in the curve will be restored if the curve that was duplicated (on its own, without the geo) is used to create other cards or tubes.
-If disabled, the attributes will be ignored and reset.
-Example:
-1. Create a card and change its twist value.
-2. Ctrl+D and Shift+P the curve (not the curve group).
-3. Click Curve Card and the twist value will be restored on a newly created card.
-
-# boundCurvesFollowParent
-Will ensure that moving a parent curve in a Bound Object (Bound Group) will also move all the child curves along with it to a new layer. Recommended to keep this enabled.
-
-# massBindOption
-Will bind selected hair clump (or geometry) to all selected "empty" curves.
-
-# bindDuplicatesCurves
-Will automatically duplicate the curves before binding them to the curve, leaving old curves behind with no edits.
-
-# bindFlipUVs
-Enabling this option will flip the UVs of the original cards before binding them to the curve.
-This option will also flip the UVs back when using Unbind for better workflow.
-Disabling this option will result in an old Bind/Unbind behaviour.
-
-# unpackDeleteOriginalObject
-Unpack (Shift + Click on Unbind) will delete the original Bind object.
-
-# unpackCVMatch
-Unpack (Shift + Click on Unbind) will match the CVs of the original Bind object.
-
-# addBetweenBlendAttributes
-Enables blending of the attributes when using Add Cards/Tubes or Fill functions.
-
-# fillCreateCurvesOnly
-When enabled Fill function will only create curves (not the geo).
-
-# convertInstances
-Will automatically convert instanced curves to normal curves before any other function is applied.
-
-# replacingCurveLayerSelection
-Will disable additive selection for the layers. When holding Ctrl and clicking on a new layer, old layer will be deselected automatically.
-
-# useAutoRefineOnNewCurves
-Automatically enables auto-refine on the new curves.
-
-# flipUVsAfterMirror
-Enabling this option will flip the UVs horizontally after mirroring the cards to achieve exact mirroring.
-
-# enableTooltips
-Will toggle the visibility of these tooltips you are reading right now.
-
-# showLayerCollectionsMenu
-Shows layer collections menu widget.
-
-# importIntoANewCollection
-If enabled, all the imported curves will be placed into a new "Imported Curves" layer collection.
-If disabled, all the imported curves will be placed into the "Main" layer collection
-
-# layerNumbersOnly
-Layers will use only numbers if enabled.
-
-# convertToNewLayerSystem
-Converts all the layers in the scene to a new layer system that is hidden from the Channel Box Display Layers window.
-Layers can still be accessed from Window->Relationship Editors->Display Layer window.
-
-# updateLayers
-Utility function that will manually update all layers. Used for if layers are correct for some reason.
-
-# resetToDefaults
-Resets every option and the GS CurveTools to the default "factory" state.
-
-# maya2020UVFix
-This function will fix any broken UVs when trying to open old scenes in Maya 2020 or 2022 or when opening scenes in 2020 and 2022 when using Maya Binary file type. This will have no effect on older versions of Maya (<2020). This bug is native to Maya and thus can’t be fixed in GS CurveTools plug-in.
-
-# mayaFixBrokenGraphs
-This function will attempt to fix all the broken graphs in the scene.
-Use if one of the graphs (Width, Twist or Profile) is in a broken state.
-
-# convertBezierToNurbs
-Converts the selected Bezier curves to NURBS curves.
-Bezier curves are not supported by the GS CurveTools.
-
-# maya2020TwistAttribute
-This function will fix any broken cards created in Maya 2020.4 before v1.2.2 update.
-
-# maya2020UnbindFix
-This function will fix any cards that are not unbinding properly and were created before v1.2.3 update in Maya 2020.4.
-
-# deleteAllAnimationKeys
-This function will delete all the animation keys on all the curves present in the scene.
-This can fix deformation issues when using duplicate or other GS CurveTools functions.
-Some functions (like duplicate) will delete the keys automatically, however the keys can still cause issues.
-
-
-
-# warpSwitch
-Advanced cards and tubes suitable for longer hair.
-Additional options and controls.
-Slower than Extrude (viewport performance).
-Can have issues on very small scales.
-
-# extrudeSwitch
-Simple cards and tubes suitable for shorter hair and brows.
-Has limited controls.
-Much faster than Warp (viewport performance).
-Better for small scales.
-
-# newCard
-Creates a new Card in the middle of the world. Used at the beginning of the project to create templates.
-
-# newTube
-Creates a new Tube in the middle of the world. Used at the beginning of the project to create templates.
-
-# curveCard
-Converts selected Maya curve to CurveTools Card.
-
-# curveTube
-Converts selected Maya curve to CurveTools Tube.
-
-# gsBind
-Binds selection to a single curve. Creates a Bind Group. Selection options:
-1. Single "empty" curve (default Maya curve) and single combined geometry.
-2. Single "empty" curve (default Maya curve) and any number of Curve Cards and Curve Tubes.
-***
-Shift + Click will duplicate the original curves/geo before binding it to the empty curve.
-Same option is available in the Options menu (Duplicate Curves Before Bind).
-
-# gsUnbind
-Normal Click:
-UnBinds geometry or Cards/Tubes from selected Bound object.
-Geometry and Cards/Tubes will be placed at the origin.
-***
-Shift + Click:
-Will UNPACK the selected Bind object in-place.
-Unpack will attempt to create an in-place approximation of the cards and tubes that Bind object consists of.
-Basically it will extract the geometry and create cards (or tubes) based on that geometry.
-The original Bind object will be deleted in the process. Optionally, you can keep it (toggle in the options menu).
-This operation is not procedural, so you will not be able to return back to the Bind object after (unlike regular UnBind).
-WARNING: Unpack is not a 1 to 1 conversion. It will try its best to approximate the shape, but complex twists and bends will not be captured.
-
-# addCards
-Creates Cards in-between selected Cards based on the Add slider value.
-Shift + Click: creates objects but does not blend the attributes.
-Bound objects are NOT supported.
-
-NOTE: Selection order defines the direction of added Cards if more than 2 initial Cards are selected.
-
-# addTubes
-Creates Tubes in-between selected Tubes based on the Add slider value.
-Shift + Click: creates objects but does not blend the attributes.
-Bound objects are NOT supported.
-
-NOTE: Selection order defines the direction of added Tubes if more than 2 initial Tubes are selected.
-
-# gsFill
-Creates Cards/Tubes or Bound Groups in between selected Cards/Tubes or Bound Groups based on the Add slider value.
-Shift + Click: creates objects but does not blend the attributes.
-
-NOTE 1: Selection order defines the direction of added curves if more than 2 initial curves are selected.
-NOTE 2: The type of Card or Tube or Bound Group is defined by the previous curve in the selection chain.
-NOTE 3: Options -> Fill Creates Only Curves option will make the Fill function create only NURBS curves, but not the geo.
-
-# gsSubdivide
-Subdivides selected curve into multiple curves based on the Add slider value
-Shift + Click subdivides selected curve but does not delete the original curve
-
-# gsEdgeToCurve
-Converts selected geometry edges to curves.
-Multiple unconnected edge groups can be selected at the same time.
-***
-Key Combinations:
-Shift + Click will create a curve without the curvature (first degree curve or simply a line)
-
-# gsGeoToCurve
-Opens the Geo-to-Curve UI
-Geo to Curve algorithm will attempt to generate GS CurveTools cards and tubes from selected geometry.
-Selected geometry should be either one-sided cards or regular tubes without caps (or both).
-Multi-selection compatible, but selected geometries should be separate objects and not one combined object.
-
-# layerCollectionsComboBox
-Layer collections drop-down menu.
-Allows to separate the project into different layer collections, up to 80 layers in each collection.
-Has additional functionality in marking menu (Hold RMB):
-***
-Marking menu:
-1. Clear - will delete all the cards from the current layer. Undoable operation.
-2. Merge Up, Merge Down - merge all the cards from the current layer to the layer above or below it.
-3. Copy, Paste - will copy all the cards from the current layer and paste them to the layer that user selects.
-4. Move Up, Move Down - will rearrange the current layer collections by moving the currently selected collection up or down in the list.
-5. Rename - will rename the current layer collection
-
-# layerCollectionsPlus
-Add additional layer collection after the current one.
-
-# layerCollectionsMinus
-Remove current layer collection. All the cards from the removed collection will be merged one layer UP.
-
-# gsAllFilter
-Layer filter. Controls the visibility of all objects in all layers:
-Normal click will show all curves and geometry in all layers.
-Shift + Click will hide all curves and geometry in all layers
-Ctrl + Click will show all the curves and geometry in all layers and all collections.
-Ctrl + Shift + Click will hide all curves and geometry in all layers and all collections.
-
-# gsCurveFilter
-Layer filter. Hides all geometry and shows all the curves in all layers.
-Ctrl + Click will do the same thing, but for all layers and all collections.
-NOTE: Holding RMB will open a marking menu with Toggle Always on Top function as well as "Auto-Hide Inactive Curves" function.
-Toggle Always on Top function will toggle the Always on Top feature that will show the curve component always on top. The effect is different in different Maya versions
-Auto-Hide Inactive Curves will hide all the curve components on all inactive layer collections when switching between collections.
-
-# gsGeoFilter
-Layer filter. Hides all curves and shows only geometry.
-Ctrl + Click will do the same thing, but for all layers and all collections.
-
-# colorMode
-Color mode toggle. Enables colors for each layer and (optionally) UV checker material.
-NOTE: Checker pattern can be disabled in the Options menu
-
-# curveGrp0
-Curve Layers that are used for organization of the cards and tubes in the scene.
-Selected layer (white outline) will be used to store newly created cards.
-Holding RMB will open a marking menu with all the functions of current layer.
-***
-Key Combinations:
-Shift + Click: additively select the contents of the layers.
-Ctrl + Click: exclusively select the contents of the layer.
-Alt + Click: show/hide selected layer.
-Ctrl + Shift: show/hide curve component on selected layer.
-Ctrl + Alt: show/hide geo component for the selected layer.
-Shift + Alt + Click: isolate select the layer.
-Shift + Ctrl + Alt + Click: enable Always on Top for each layer (only for Maya 2022+).
-***
-Layer MMB Dragging:
-MMB + Drag: move the contents of one layer to another layer. Combine if target layer has contents.
-MMB + Shift + Drag: copy the contents of one layer to another layer. Copy and Add if target layer has contents.
-
-# gsExtractSelected
-Extracts (Duplicates) the geometry component from the selected curves:
-***
-Key Combinations:
-Normal click will extract geometry and combine it.
-Shift + Click will extract geometry as individual cards.
-Ctrl + Click will extract geometry, combine it, open export menu and delete the extracted geo after export.
-Shift + Ctrl click will extract geometry, open export menu and delete the extracted geo after export.
-
-# gsExtractAll
-Extracts (Duplicates) the geometry component from all layers and collections. Original layers are HIDDEN, NOT deleted:
-Last Layer in the current Collection is ignored by default. Can be changed in the options.
-Collections with "template" in their name (case insensitive) will be ignored by default. Can be changed in the options.
-***
-Key Combinations:
-Normal click will extract geometry and combine it.
-Shift + Click will extract geometry as individual cards grouped by layers.
-Ctrl + Click will extract geometry, combine it, open export menu and delete the extracted geo after export.
-Shift + Ctrl click will extract geometry, open export menu and delete the extracted geo after export.
-
-# gsSelectCurve
-Selects the curve components of the selected Curve Cards/Tubes.
-NOTE: Useful during the selection in the outliner.
-
-# gsSelectGeo
-Selects the geometry component of the selected Curve Cards/Tubes.
-NOTE: Useful for quick assignment of the materials.
-
-# gsSelectGroup
-Selects the group component of the selected Curve Cards/Tubes.
-NOTE: Useful when you are deleting curves from viewport selection.
-
-# gsGroupCurves
-Groups the selected curves and assigns the name from Group Name input field (or default name if empty).
-
-# gsRegroupByLayer
-Regroups all the curves based on their layer number, group names and collection names.
-Group names can be changed in the Layer Names & Colors menu.
-Groups can be colorized if the "Colorize Regrouped Layers" is enabled in the Options menu.
-Collections with "template" in their name will be grouped under "CT_Templates". Can be changed in the options.
-
-# gsGroupNameTextField
-The name used by the Group Curves function.
-If empty, uses the default name.
-
-# gsCustomLayerNamesAndColors
-Opens a menu where group names and colors can be changed and stored in a global preset.
-
-# gsTransferAttributes
-Transfers attributes from the FIRST selected curve to ALL the other curves in the selection.
-NOTE: Shift + Click transfers the attributes from the LAST selected curve to ALL others.
-NOTE2: Holding RMB on this button opens a marking menu with Copy-Paste and Filter functionality
-
-# gsTransferUVs
-Transfers UVs from the FIRST selected curve to ALL the other curves in the selection.
-NOTE: Shift + Click transfers the UVs from the LAST selected curve to ALL others.
-NOTE2: Holding RMB on this button opens a marking menu with Copy-Paste and Filter functionality
-
-# gsResetPivot
-Resets the pivot on all selected curves to the default position (root CV).
-
-# gsRebuildWithCurrentValue
-Rebuild selected curves using current rebuild slider value
-
-# gsResetRebuildSliderRange
-Reset rebuild slider range (1 to 50)
-
-# gsDuplicateCurve
-Duplicates all the selected curves and selects them.
-NOTE: You can select either NURBS curve component, geometry component or group to duplicate.
-
-# gsRandomizeCurve
-Opens a window where different attributes of the selected curves can be randomized:
-1. Enable the sections of interest and change the parameters.
-2. Dragging the sliders in each section enables a PREVIEW of the randomization. Releasing the slider will reset the curves.
-3. Click Randomize if you wish to apply the current randomization.
-
-# gsExtendCurve
-Lengthens a selected curves based on the Factor slider.
-
-# gsReduceCurve
-Shortens the selected curves based on the Factor slider.
-
-# gsSmooth
-Smoothes selected curves or curve CVs based on the Factor slider.
-NOTE 1: At least 3 CVs should be selected for component smoothing.
-NOTE 2: Holding RMB will open a marking menu where you can select a stronger smoothing algorithm.
-
-# mirrorX
-Mirrors or Flips all the selected curves on the World X axis.
-
-# mirrorY
-Mirrors or Flips all the selected curves on the World Y axis.
-
-# mirrorZ
-Mirrors or Flips all the selected curves on the World Z axis.
-
-# gsControlCurve
-Adds a Control Curve Deformer to the selected curves. Can be used to adjust groups of curves.
-NOTE 1: Should NOT be used to permanently control clumps of cards. Use Bind instead.
-
-# gsApplyControlCurve
-Applies the Control Curve Deformer.
-Either the Control Curve or any controlled Curves can be selected for this to work.
-
-# gsCurveControlWindow
-Opens a Curve Control Window. Contains all the available controls for curves.
-
-# gsUVEditorMain
-Opens a UV editor that can be used to setup and adjust UVs on multiple cards.
-NOTE 1: Lambert material with PNG, JPG/JPEG or TIF/TIFF (LZW or No Compression) texture file is recommended. TGA (24bit and no RLE) is also supported.
-NOTE 2: Make sure to select the curves or the group, not the geo, to adjust the UVs.
-NOTE 3: Using default Maya UV editor will break GS CurveTools Cards, Tubes and Bound Groups.
-NOTE 4: Default UV editor can be used when custom geometry is used in a Bound Groups.
-
-
-
-
-# gsLayerSelector
-Shows the Layer of the selected curve.
-Selecting different layer will change the layer of all the selected curves.
-
-# gsColorPicker
-Layer/Card Color Picker.
-
-# gsCurveColorPicker
-Curve Color Picker.
-
-# selectedObjectName
-Selected object name. Editing this field will rename all the selected objects.
-
-# lineWidth
-Controls the thickness of the selected curves.
-
-# gsBindAxisAuto
-Automatic selection of the bind Axis (recommended).
-NOTE: Change to manual X, Y, Z axis if bind operation result is not acceptable.
-
-# AxisFlip
-Flips the direction of the bound geometry.
-
-# editOrigObj
-Temporarily disables curve bind and shows the original objects.
-Used to adjust the objects after the bind.
-To add or remove from the Bound group use Unbind.
-
-# selectOriginalCurves
-Selects the original curves that were attached to a bind curve.
-Allows to edit their attributes without using Unbind or Edit Original Objects
-
-# twistCurveFrame
-Advanced twist control graph. Allows for precise twisting of the geometry along the curve. Click to expand.
-
-# Magnitude
-Twist multiplier. The larger the values, the more the twist. Default is 0.5.
-
-# gsTwistGraphResetButton
-Resets the graph to the default state.
-
-# gsTwistGraphPopOut
-Opens a larger graph in a separate window that is synced to the main graph.
-
-# widthLockSwitch
-Links/Unlinks the X and Z width sliders.
-If linked, the sliders will move as one.
-
-# LengthLock
-Locks/Unlocks the length slider.
-When Locked the geometry is stretched to the length of the curve and the slider is ignored.
-
-# widthCurveFrame
-Advanced width control graph. Allows for precise scaling of the geometry along the curve. Click to expand.
-
-# gsWidthGraphResetButton
-Resets the graph to the default state.
-
-# gsWidthGraphPopOut
-Opens a larger graph in a separate window that is synced to the main graph.
-
-# profileCurveGraph
-Advanced control over the profile of the card. Modifies the profile applied by the Profile slider. Click to expand.
-Add or remove points and change them to increase or decrease the Profile value along the curve.
-
-# autoEqualizeSwitchOn
-Locks the points horizontally to equal intervals to avoid geometry deformation.
-
-# autoEqualizeSwitchOff
-Unlocks the points and allows for the full control.
-
-# equalizeCurveButton
-Snaps the points to the equal horizontal intervals.
-
-# gsResetProfileGraphButton
-Resets the curve to the default state.
-
-# gsProfileGraphPopOut
-Opens a larger graph in a separate window that is synced to the main graph.
-
-# reverseNormals
-Reverses the normals on the selected cards/tubes.
-
-# orientToNormalsFrame
-Orient selected cards/tubes to the normals of the selected geo.
-
-# gsOrientToNormalsSelectTarget
-Set selected mesh as a target for the algorithm.
-
-# orientRefreshViewport
-Toggles the viewport update during the alignment process.
-Disabling can speed up the process.
-
-# gsOrientToNormals
-Starts the alignment process.
-Will align the selected cards to the normals of the selected geometry.
-
-# flipUV
-Flips the UVs of the card/tube horizontally.
-
-# resetControlSliders
-Resets the range of the sliders to the default state.
-
-# UVFrame
-Legacy controls for the UVs. Just use the new UV Editor.
-
-# solidifyFrame
-Expands controls that control the thickness of the cards/tubes.
-
-# solidify
-Toggles the thickness of the geometry.
-
-
-
-# lengthDivisions
-Change the length divisions of the selected cards/tubes.
-
-# dynamicDivisions
-Toggles the dynamic divisions mode.
-Dynamic divisions will change the divisions of the cards/tubes based on the length of the curves.
-In dynamic divisions mode, L-Div slider will control the density of the divisions, not the fixed divisions count.
-
-# widthDivisions
-Change the width divisions of the selected cards/tubes.
-
-# Orientation
-Change the orientation of the card/tube around the curve.
-
-# Twist
-Smoothly twist the entire geometry card/tube. Twists the tip of the card.
-
-# invTwist
-Smoothly twist the entire geometry card. Twists the root of the card.
-
-# Width
-Change the width of the selected card.
-
-# Taper
-Linearly changes the width of the card/tube along the length of the curve.
-
-# WidthX
-Change the width of the tube along the X axis.
-
-# WidthZ
-Change the width of the tube along the Z axis.
-
-# Length
-Change the length of the attached geometry. Works only when Length Unlock button is checked.
-
-# Offset
-Offset the geometry along the curve.
-
-# Profile
-Change the profile of the card along the length of the curve uniformly.
-
-# profileSmoothing
-Smoothing will smooth the profile transition.
-
-# otherFrame
-Other less used options
-
-# curveRefine
-Controls the number of "virtual" vertices on the curve. These are the vertices that are used to calculate the geometry deformation.
-Zero (0) value will disable the refinement and the geometry will be attached directly to the curve. The fastest option.
-Larger refine values means smoother geometry that is a closer fit to the curve.
-Only increase past 20 if you need additional precision or if there are any visual glitches with the geometry.
-Large refine values can cause significant performance drop, lag and other issues on smaller curve sizes.
-Recommended values are:
-20 for curves with less than 20 CVs.
-0 (disabled) or same as the number of CVs for curves with more than 20 CVs.
-
-# autoRefine
-Enables auto-refine for selected curves. Recommended to keep this on.
-Manual refinement can be helpful if the geometry deformation is wrong or not precise enough.
-
-# samplingAccuracy
-Increases the sampling accuracy of the deformer that attaches the geometry to a curve.
-Larger values = more precise geometry fit to a curve and more lag.
-
-# surfaceNormals
-Changes the smoothing angle of the normals of the geometry.
-
-# gsIterationsSlider
-Controls the number of iterations per card.
-
-# gsMinimumAngle
-Controls the target angle difference between the normal of the mesh and the card.
-
-# solidifyThickness
-Controls the amount of thickness on the geometry.
-
-# solidifyDivisions
-Controls the number of divisions on the solidify extrusion.
-
-# solidifyScaleX
-Changes the scale on the X axis.
-
-# solidifyScaleY
-Changes the scale on the Y axis.
-
-# solidifyOffset
-Controls the offset of the solidify extrusion.
-
-# solidifyNormals
-Controls the smoothing angle for normals of the solidify extrusion.
-
-# geometryHighlight
-If enabled, selecting the curve will also highlight the geometry component that is attached to that curve.
-Works only on GS CurveTools curves and geo.
-
-# curveHighlight
-If enabled, selected curves and their components will be additionally highlighted for better visibility.
-The curves and components will be in X-Ray mode by default.
-Colors and transparency values can be changes in the menu below.
-
-# gsSelectedCVColor
-Selected CV highlight color
-
-# gsSelectedCVAlpha
-Selected CV highlight transparency (alpha)
-
-# gsDeselectedCVColor
-Deselected CV highlight color
-
-# gsDeselectedCVAlpha
-Deselected CV highlight transparency (alpha)
-
-# curveVisibility
-Toggle selected curves highlight
-
-# gsCurveHighlightColor
-Selected curve highlight color
-
-# gsCurveHighlightAlpha
-Selected curve highlight transparency (alpha)
-
-# hullVisibility
-Toggle hull visibility.
-Hull is a line that connects all the CVs on the curve.
-
-# gsHullHighlightColor
-Hull highlight color
-
-# gsHullHighlightAlpha
-Hull highlight transparency (alpha)
-
-# advancedVisibilityFrame
-Better highlights for selected curves and components.
-
-# lazyUpdate
-Enables lazy update for selected curves.
-Lazy update can slightly increase the performance of the highlight,
-however it has some visual drawbacks (curve highlight can fail to update when switching curves in component selection mode)
-
-# alwaysOnTop
-Toggles X-Ray (always on top) drawing for highlighted components.
-Disabling this defeats the purpose of the advanced visibility, but hey, it's your choice.
-
-# curveDistanceColor
-Toggles the distance color effect on the curve highlight.
-Distance color darkens the curve color the further it is from the camera.
-
-# cvDistanceColor
-Toggles the distance color effect on the CV highlight.
-Distance color darkens the CVs color the further it is from the camera.
-
-# hullDistanceColor
-Toggles the distance color effect on the hull highlight.
-Distance color darkens the hull color the further it is from the camera.
-
-# gsDistanceColorMinValue
-Distance color minimum.
-This value is the minimum allowed color multiplier for the Distance Color effect.
-The lower this value, the darker further parts of the curve will be.
-Black at 0.0
-Original color at 1.0
-
-# gsDistanceColorMaxValue
-Distance color maximum.
-This value is the maximum allowed color multiplier for the Distance Color effect.
-The higher this value, the brighter closest parts of the curve will be.
-Black at 0.0
-Original color at 1.0
-
-# CVocclusion
-Toggles the experimental CV occlusion mode (hull is affected as well)
-When the appropriate mesh name is added to Occluder Mesh input field,
-this function will automatically hide CVs and hull lines that are behind this mesh (even in X-Ray mode).
-Warning: enabling this mode can negatively impart viewport performance.
-
-# gsSelectOccluderButton
-This button adds the selected mesh name to the Occluder Mesh input field.
-
-# gsOccluderMeshName
-Type the full path for the occluder mesh here, or use the "Select Occluder" button on the left <-
-
-
-
-
-# gsGenerateLayerColorGradient
-Generate a color gradient for the layer colors.
-Rows control the number of Rows to generate.
-Left color picker sets the initial color.
-Right color picker sets the final color.
-
-# gsRandomizeLayerColors
-Generate random colors for the layers.
-SatMin controls the minimum allowed saturation.
-SatMax controls the maximum allowed saturation.
-
-# gsResetAllLayerColors
-Resets all the color swatches to the default color.
-
-# gsGetCurrentSceneLayers
-Populates the menu with the names and colors stored in the scene.
-
-# gsSetAsCurrentSceneLayers
-Applies the names and colors from the menu to the scene.
-
-# gsLoadGlobalLayerPreset
-Load the global names and colors preset to the menu.
-NOTE: Don't forget to Set to Scene before closing the menu.
-
-# gsSaveGlobalLayerPreset
-Saves the current names and colors from the menu to the global preset.
-
-
-
-# gsUVSelect
-Enables the selection of the UVs.
-Drag to draw a box selection.
-
-# gsUVMove
-Enables the Move tool.
-Move the selected UVs or move individual UVs if nothing is selected.
-
-# gsUVRotate
-Enables the Rotation of the selected UVs.
-Hold LMB and drag anywhere in the viewport to rotate the selected UVs.
-Rotation pivot is the center of the individual unscaled UV.
-
-# gsUVScale
-Enables the Scaling of the selected UVs.
-Hold LMB and drag in the viewport to scale the card Horizontally of Vertically.
-Repeated hotkey click will toggle between Horizontal and Vertical scaling.
-
-# gsUVHorizontalScale
-Horizontal scaling mode selector.
-
-# gsUVVerticalScale
-Vertical scaling mode selector.
-
-# gsDrawUVs
-Enables the UVs Drawing Tool:
-1. Select UVs using Selection Mode.
-2. Enable the UV Drawing Tool.
-3. Draw a UV Rectangle anywhere in the viewport to create/move the UVs there.
-
-# gsHorizontalFlipUV
-Flips the selected UVs horizontally.
-Flipped UVs have the blue circle indicator inside the root rectangle.
-
-# gsVerticalFlipUV
-Flips the selected UVs vertically.
-
-# gsResetUVs
-Resets the selected UVs to the default 0,1 rectangle.
-
-# gsSyncSelectionUVs
-Syncs selection between UV editor and Maya Viewport.
-
-# gsRandomizeUVs
-Randomize selected UV positions between already existing UV positions.
-***
-Normal click will keep the overall density distribution of the UVs.
-This means that if there is one card in one position and twenty cards in the other,
-it will keep this distribution of 1 to 20.
-***
-Shift+Click will ignore the original density distribution
-and simply randomize the UVs between the original positions.
-
-# gsFocusUVs
-Focuses on the selected UVs or on all the UVs if nothing is selected.
-
-# gsUVIsolateSelect
-Hides all the unselected UVs and shows only the selected ones.
-
-# gsUVShowAll
-Shows all the hidden UVs.
-
-# UVEditorUseTransforms
-Use "Coverage" and "Translate Frame" parameters from place2dTexture node for texture.
-Offset is not supported.
-Diffuse and Alpha channel MUST have the same coverage and translate frame values.
-
-# UVEditorTransparencyToggle
-Enable texture map transparency using Alpha map from Transparency plug in the material node
-
-# UVEditorBGColorPicker
-Background Color
-
-# UVEditorGridColorPicker
-Grid Color
-
-# UVEditorFrameColorPicker
-Frame Color
-
-# UVEditorUVFrameSelectedColorPicker
-Selected UV frame color
-
-# UVEditorUVFrameDeselectedColorPicker
-Deselected UV frame color
-
-# UVEditorUVCardFillColorPicker
-UV frame background color
-
-
-
-# gsGeoToCurve_outputTypeSwitch
-Controls the output of Geo-to-Curve algorithm
-
-# gsGeoToCurve_generateAuto
-Automatically determine the final object type (card or tube) based on the selected geometry.
-
-# gsGeoToCurve_generateCards
-Generate cards from selected geometry (one-sided cards or tubes)
-
-# gsGeoToCurve_generateTubes
-Generate tubes from selected geometry (one-sided cards or tubes)
-
-# gsGeoToCurve_generateCurves
-Generate curves from selected geometry (one-sided cards or tubes)
-
-# gsGeoToCurve_cardType
-Controls the type of generated objects (Warp or Extrude)
-
-# gsGeoToCurve_warp
-Generate Warp cards or tubes
-
-# gsGeoToCurve_extrude
-Generate Extrude cards or tubes
-
-# gsGeoToCurve_matchAttributes
-Controls which attributes on the new cards/tubes should be approximated from the original geometry.
-NOTE: This process is not perfect and final result can be inaccurate.
-
-# gsGeoToCurve_orientation
-Match orientation attribute during the generation process
-
-# gsGeoToCurve_width
-Match orientation attribute during the generation process
-
-# gsGeoToCurve_taper
-Match taper attribute during the generation process
-
-# gsGeoToCurve_twist
-Match twist attribute during the generation process
-
-# gsGeoToCurve_profile
-Match profile attribute during the generation process
-
-# gsGeoToCurve_material
-Copy material (shader) from the original geometry
-
-# gsGeoToCurve_UVs
-Tries to approximate the UVs from the original geometry
-NOTE: Matches the bounding box of the UVs. Rotated and deformed UVs are not matched precisely.
-
-# gsGeoToCurve_UVMatchOptions
-Controls UV matching behaviour
-
-# gsGeoToCurve_verticalFlip
-Vertically flip matched UVs
-
-# gsGeoToCurve_horizontalFlip
-Horizontally flip matched UVs
-
-# gsGeoToCurve_reverseCurve
-Reverse generated curve direction
-Root CV should be generated near the scalp of the model.
-Enable or disable if resulting card direction and taper are reversed.
-
-# gsGeoToCurve_convertSelected
-Convert selected geometry to cards, tubes or curves based on the selected options.
-Newly created procedural objects will be placed in the currently selected layer.
-NOTE: if the currently selected layer is hidden (grayed out), the newly created objects will be hidden as well.
-
-# gsGeoToCurve_deleteOriginalObject
-Delete the original geometry after converting it to cards, tubes or curves.
-
-# gsGeoToCurve_useAimMesh
-Use the aim mesh (selected below) to place the root CV of the generated cards, tubes or curves close to the target mesh.
-Placing CVs close to the target mesh will help with the alignment process and general adjustments later on.
-The aim mesh should be a polygonal mesh.
-
-# gsGeoToCurve_selectAimMesh
-Select the aim mesh in the scene and click this button to add its name to the input field.
diff --git a/2024/scripts/rigging_tools/ngskintools2/README.md b/2024/scripts/rigging_tools/ngskintools2/README.md
deleted file mode 100644
index 1d112fa..0000000
--- a/2024/scripts/rigging_tools/ngskintools2/README.md
+++ /dev/null
@@ -1,61 +0,0 @@
-# ngSkinTools2 模块
-
-ngSkinTools2 是一个强大的 Maya 蒙皮权重编辑工具。
-
-## 📁 文件夹结构
-
-```
-ngskintools2/ # ngSkinTools2 核心模块
-├── __init__.py # 模块初始化(原始)
-├── launcher.py # 启动器脚本(新增)
-├── api/ # API 接口
-├── ui/ # 用户界面
-├── operations/ # 操作功能
-└── README.md # 本文档
-```
-
-## 🚀 使用方法
-
-### 从工具架启动
-
-1. 打开 Maya
-2. 切换到 **Nexus_Rigging** 工具架
-3. 点击 **ngSkin** 按钮
-
-### 从 Python 启动
-
-```python
-from rigging_tools.ngskintools2 import launcher
-launcher.LaunchNgSkinTools()
-```
-
-### 直接使用 ngSkinTools2 API
-
-```python
-from rigging_tools.ngskintools2 import open_ui
-open_ui()
-```
-
-## ✨ 主要功能
-
-- 高级权重绘制和编辑
-- 权重镜像和传递
-- 多层权重管理
-- 权重导入/导出
-- 影响对象管理
-
-## 📝 注意事项
-
-- 自动检测 Maya 版本并加载对应插件
-- 支持 Maya 2018-2026 版本
-- 如果当前版本没有完全匹配的插件,会自动使用向下兼容的版本
-- 建议在绑定工作流程中使用
-
-## 🔧 版本兼容性
-
-启动器会自动检测当前 Maya 版本并加载对应的插件:
-- **完全匹配**:优先使用与 Maya 版本完全匹配的插件
-- **向下兼容**:如果没有完全匹配,使用小于等于当前版本的最高版本插件
-- **兜底策略**:如果当前版本比所有可用插件都旧,使用最旧的可用插件
-
-支持的 Maya 版本:2018, 2019, 2020, 2022, 2023, 2024, 2025, 2026
diff --git a/2024/scripts/rigging_tools/ngskintools2/api/influenceMapping.py b/2024/scripts/rigging_tools/ngskintools2/api/influenceMapping.py
index 40d1cb4..7a82137 100644
--- a/2024/scripts/rigging_tools/ngskintools2/api/influenceMapping.py
+++ b/2024/scripts/rigging_tools/ngskintools2/api/influenceMapping.py
@@ -432,7 +432,7 @@ class InfluenceMappingConfig(Object):
return
if axis is not None and not isinstance(axis, int):
- raise Exception("invalid axis type, need int")
+ raise Exception("无效的轴类型,需要整数")
self.__mirror_axis = axis
@@ -487,10 +487,10 @@ class InfluenceMapping(Object):
def __init__(self):
self.config = InfluenceMappingConfig() # type:InfluenceMappingConfig
- "assigned config"
+ "分配的配置"
self.influences = [] # type: list[InfluenceInfo]
- "Source influences list. Can be assigned to result of :py:meth:`Layers.list_influences`"
+ "源影响列表. 可以分配给结果 :py:meth:`Layers.list_influences`"
self.destinationInfluences = None
self.calculatedMapping = None
@@ -498,7 +498,7 @@ class InfluenceMapping(Object):
def calculate(self):
mirror_mode = self.config.mirror_axis is not None
- log.info("calculate influence mapping, mirror mode: %s", mirror_mode)
+ log.info("计算影响映射,镜像模式: %s", mirror_mode)
if self.destinationInfluences is None:
self.destinationInfluences = self.influences
diff --git a/2024/scripts/rigging_tools/ngskintools2/api/layers.py b/2024/scripts/rigging_tools/ngskintools2/api/layers.py
index 9f4dc4e..5de8c37 100644
--- a/2024/scripts/rigging_tools/ngskintools2/api/layers.py
+++ b/2024/scripts/rigging_tools/ngskintools2/api/layers.py
@@ -56,7 +56,7 @@ class LayerEffects(Object):
mirror_mask = mirror_dq = mirror_weights = everything
logger.info(
- "configure mirror: layer %s mask %r weights %r dq %r direction %r",
+ "配置镜像: 图层 %s 遮罩 %r 权重 %r dq %r 方向 %r",
self.__layer.name,
mirror_mask,
mirror_weights,
@@ -103,7 +103,7 @@ class Layer(Object):
@classmethod
def load(cls, mesh, layer_id):
if layer_id < 0:
- raise Exception("invalid layer ID: %s" % layer_id)
+ raise Exception("无效图层 ID: %s" % layer_id)
result = Layer(mesh, layer_id)
result.reload()
return result
@@ -112,7 +112,7 @@ class Layer(Object):
self.mesh = mesh
self.id = id
self.effects = LayerEffects(self) # type: LayerEffects
- "configure effects for this layer"
+ "配置此图层的效果"
self.__state = None
if state is not None:
diff --git a/2024/scripts/rigging_tools/ngskintools2/api/mirror.py b/2024/scripts/rigging_tools/ngskintools2/api/mirror.py
index e9f0e37..041df27 100644
--- a/2024/scripts/rigging_tools/ngskintools2/api/mirror.py
+++ b/2024/scripts/rigging_tools/ngskintools2/api/mirror.py
@@ -63,7 +63,7 @@ class Mirror(Object):
"""
:type mapping: map[int] -> int
"""
- log.info("mapping updated: %r", mapping)
+ log.info("映射已更新: %r", mapping)
mapping_as_string = ','.join(str(k) + "," + str(v) for (k, v) in list(mapping.items()))
plugin.ngst2Layers(self.target, configureMirrorMapping=True, influencesMapping=mapping_as_string)
@@ -119,7 +119,7 @@ class Mirror(Object):
existing_ref_mesh = self.get_reference_mesh()
if existing_ref_mesh:
cmds.select(existing_ref_mesh)
- raise Exception("symmetry mesh already configured for %s: %s" % (str(sc), existing_ref_mesh))
+ raise Exception("对称网格已配置为 %s: %s" % (str(sc), existing_ref_mesh))
def get_shape(node):
return cmds.listRelatives(node, shapes=True)[0]
@@ -177,7 +177,7 @@ def set_reference_mesh_from_selection():
selection = cmds.ls(sl=True, long=True)
if len(selection) != 2:
- log.debug("wrong selection size")
+ log.debug("错误的选择尺寸")
return
m = Mirror(selection[1])
diff --git a/2024/scripts/rigging_tools/ngskintools2/api/session.py b/2024/scripts/rigging_tools/ngskintools2/api/session.py
index 4423c92..094a1fb 100644
--- a/2024/scripts/rigging_tools/ngskintools2/api/session.py
+++ b/2024/scripts/rigging_tools/ngskintools2/api/session.py
@@ -83,7 +83,7 @@ class Session(Object):
@signal.on(self.events.targetChanged)
def on_target_change():
- log.info("target changed: clearing target context")
+ log.info("目标已更改:清除目标上下文")
self.context.selected_layers.set([])
self.events.nodeSelectionChanged.emit()
diff --git a/2024/scripts/rigging_tools/ngskintools2/api/target_info.py b/2024/scripts/rigging_tools/ngskintools2/api/target_info.py
index c5ea229..67b987b 100644
--- a/2024/scripts/rigging_tools/ngskintools2/api/target_info.py
+++ b/2024/scripts/rigging_tools/ngskintools2/api/target_info.py
@@ -67,7 +67,7 @@ def add_influences(influences, target):
def long_names(names):
result = set(cmds.ls(names, long=True))
if len(result) != len(names):
- raise Exception("could not convert to a list of influences names: " + str(names))
+ raise Exception("无法转换为影响名称列表: " + str(names))
return result
existing = long_names([i.name if not i.path else i.path for i in list_influences(skin_cluster)])
diff --git a/2024/scripts/rigging_tools/ngskintools2/api/tools.py b/2024/scripts/rigging_tools/ngskintools2/api/tools.py
index c10a304..228ed97 100644
--- a/2024/scripts/rigging_tools/ngskintools2/api/tools.py
+++ b/2024/scripts/rigging_tools/ngskintools2/api/tools.py
@@ -103,7 +103,7 @@ def merge_layers(layers):
# verify that all layers are from the same parent
for i, j in zip(layers[:-1], layers[1:]):
if i.mesh != j.mesh:
- raise Exception("layers are not from the same mesh")
+ raise Exception("层不是来自同一个网格")
result = plugin.ngst2tools(
tool="mergeLayers",
diff --git a/2024/scripts/rigging_tools/ngskintools2/api/transfer.py b/2024/scripts/rigging_tools/ngskintools2/api/transfer.py
index 9c175c9..87c70b5 100644
--- a/2024/scripts/rigging_tools/ngskintools2/api/transfer.py
+++ b/2024/scripts/rigging_tools/ngskintools2/api/transfer.py
@@ -49,7 +49,7 @@ class LayersTransfer(Object):
def calc_influences_mapping_as_flat_list(self):
mapping_pairs = list(self.influences_mapping.asIntIntMapping(self.influences_mapping.calculate()).items())
if len(mapping_pairs) == 0:
- raise Exception("no mapping between source and destination influences")
+ raise Exception("源和目标影响之间没有映射")
# convert dict to flat array
return list(itertools.chain.from_iterable(mapping_pairs))
diff --git a/2024/scripts/rigging_tools/ngskintools2/decorators.py b/2024/scripts/rigging_tools/ngskintools2/decorators.py
index f2f03b2..92a7f0d 100644
--- a/2024/scripts/rigging_tools/ngskintools2/decorators.py
+++ b/2024/scripts/rigging_tools/ngskintools2/decorators.py
@@ -54,12 +54,12 @@ class Undo(Object):
self.name = name
def __enter__(self):
- log.debug("UNDO chunk %r: start", self.name)
+ log.debug("UNDO chunk %r: 开始", self.name)
cmds.undoInfo(openChunk=True, chunkName=self.name)
return self
def __exit__(self, _type, value, traceback):
- log.debug("UNDO chunk %r: end", self.name)
+ log.debug("UNDO chunk %r: 结束", self.name)
cmds.undoInfo(closeChunk=True)
diff --git a/2024/scripts/rigging_tools/ngskintools2/docs/Resources/appstore-combined.min.css b/2024/scripts/rigging_tools/ngskintools2/docs/Resources/appstore-combined.min.css
deleted file mode 100644
index 6fa4209..0000000
--- a/2024/scripts/rigging_tools/ngskintools2/docs/Resources/appstore-combined.min.css
+++ /dev/null
@@ -1,9 +0,0 @@
-/*!
- * Bootstrap v2.3.2
- *
- * Copyright 2013 Twitter, Inc
- * Licensed under the Apache License v2.0
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Designed and built with all the love in the world by @mdo and @fat.
- */.clearfix{*zoom:1}.clearfix:before,.clearfix:after{display:table;line-height:0;content:""}.clearfix:after{clear:both}.hide-text{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.input-block-level{display:block;width:100%;min-height:30px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}article,aside,details,figcaption,figure,footer,header,hgroup,nav,section{display:block}audio,canvas,video{display:inline-block;*display:inline;*zoom:1}audio:not([controls]){display:none}html{font-size:100%;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}a:focus{outline:thin dotted #333;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}a:hover,a:active{outline:0}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sup{top:-0.5em}sub{bottom:-0.25em}img{width:auto\9;height:auto;max-width:100%;vertical-align:middle;border:0;-ms-interpolation-mode:bicubic}#map_canvas img,.google-maps img{max-width:none}button,input,select,textarea{margin:0;font-size:100%;vertical-align:middle}button,input{*overflow:visible;line-height:normal}button::-moz-focus-inner,input::-moz-focus-inner{padding:0;border:0}button,html input[type="button"],input[type="reset"],input[type="submit"]{cursor:pointer;-webkit-appearance:button}label,select,button,input[type="button"],input[type="reset"],input[type="submit"],input[type="radio"],input[type="checkbox"]{cursor:pointer}input[type="search"]{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;-webkit-appearance:textfield}input[type="search"]::-webkit-search-decoration,input[type="search"]::-webkit-search-cancel-button{-webkit-appearance:none}textarea{overflow:auto;vertical-align:top}@media print{*{color:#000!important;text-shadow:none!important;background:transparent!important;box-shadow:none!important}a,a:visited{text-decoration:underline}a[href]:after{content:" (" attr(href) ")"}abbr[title]:after{content:" (" attr(title) ")"}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100%!important}@page{margin:.5cm}p,h2,h3{orphans:3;widows:3}h2,h3{page-break-after:avoid}}body{margin:0;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;line-height:20px;color:#333;background-color:#fff}a{color:#08c;text-decoration:none}a:hover,a:focus{color:#005580;text-decoration:underline}.img-rounded{-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px}.img-polaroid{padding:4px;background-color:#fff;border:1px solid #ccc;border:1px solid rgba(0,0,0,0.2);-webkit-box-shadow:0 1px 3px rgba(0,0,0,0.1);-moz-box-shadow:0 1px 3px rgba(0,0,0,0.1);box-shadow:0 1px 3px rgba(0,0,0,0.1)}.img-circle{-webkit-border-radius:500px;-moz-border-radius:500px;border-radius:500px}.row{margin-left:-20px;*zoom:1}.row:before,.row:after{display:table;line-height:0;content:""}.row:after{clear:both}[class*="span"]{float:left;min-height:1px;margin-left:20px}.container,.navbar-static-top .container,.navbar-fixed-top .container,.navbar-fixed-bottom .container{width:940px}.span12{width:940px}.span11{width:860px}.span10{width:780px}.span9{width:700px}.span8{width:620px}.span7{width:540px}.span6{width:460px}.span5{width:380px}.span4{width:300px}.span3{width:220px}.span2{width:140px}.span1{width:60px}.offset12{margin-left:980px}.offset11{margin-left:900px}.offset10{margin-left:820px}.offset9{margin-left:740px}.offset8{margin-left:660px}.offset7{margin-left:580px}.offset6{margin-left:500px}.offset5{margin-left:420px}.offset4{margin-left:340px}.offset3{margin-left:260px}.offset2{margin-left:180px}.offset1{margin-left:100px}.row-fluid{width:100%;*zoom:1}.row-fluid:before,.row-fluid:after{display:table;line-height:0;content:""}.row-fluid:after{clear:both}.row-fluid [class*="span"]{display:block;float:left;width:100%;min-height:30px;margin-left:2.127659574468085%;*margin-left:2.074468085106383%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.row-fluid [class*="span"]:first-child{margin-left:0}.row-fluid .controls-row [class*="span"]+[class*="span"]{margin-left:2.127659574468085%}.row-fluid .span12{width:100%;*width:99.94680851063829%}.row-fluid .span11{width:91.48936170212765%;*width:91.43617021276594%}.row-fluid .span10{width:82.97872340425532%;*width:82.92553191489361%}.row-fluid .span9{width:74.46808510638297%;*width:74.41489361702126%}.row-fluid .span8{width:65.95744680851064%;*width:65.90425531914893%}.row-fluid .span7{width:57.44680851063829%;*width:57.39361702127659%}.row-fluid .span6{width:48.93617021276595%;*width:48.88297872340425%}.row-fluid .span5{width:40.42553191489362%;*width:40.37234042553192%}.row-fluid .span4{width:31.914893617021278%;*width:31.861702127659576%}.row-fluid .span3{width:23.404255319148934%;*width:23.351063829787233%}.row-fluid .span2{width:14.893617021276595%;*width:14.840425531914894%}.row-fluid .span1{width:6.382978723404255%;*width:6.329787234042553%}.row-fluid .offset12{margin-left:104.25531914893617%;*margin-left:104.14893617021275%}.row-fluid .offset12:first-child{margin-left:102.12765957446808%;*margin-left:102.02127659574467%}.row-fluid .offset11{margin-left:95.74468085106382%;*margin-left:95.6382978723404%}.row-fluid .offset11:first-child{margin-left:93.61702127659574%;*margin-left:93.51063829787232%}.row-fluid .offset10{margin-left:87.23404255319149%;*margin-left:87.12765957446807%}.row-fluid .offset10:first-child{margin-left:85.1063829787234%;*margin-left:84.99999999999999%}.row-fluid .offset9{margin-left:78.72340425531914%;*margin-left:78.61702127659572%}.row-fluid .offset9:first-child{margin-left:76.59574468085106%;*margin-left:76.48936170212764%}.row-fluid .offset8{margin-left:70.2127659574468%;*margin-left:70.10638297872339%}.row-fluid .offset8:first-child{margin-left:68.08510638297872%;*margin-left:67.9787234042553%}.row-fluid .offset7{margin-left:61.70212765957446%;*margin-left:61.59574468085106%}.row-fluid .offset7:first-child{margin-left:59.574468085106375%;*margin-left:59.46808510638297%}.row-fluid .offset6{margin-left:53.191489361702125%;*margin-left:53.085106382978715%}.row-fluid .offset6:first-child{margin-left:51.063829787234035%;*margin-left:50.95744680851063%}.row-fluid .offset5{margin-left:44.68085106382979%;*margin-left:44.57446808510638%}.row-fluid .offset5:first-child{margin-left:42.5531914893617%;*margin-left:42.4468085106383%}.row-fluid .offset4{margin-left:36.170212765957444%;*margin-left:36.06382978723405%}.row-fluid .offset4:first-child{margin-left:34.04255319148936%;*margin-left:33.93617021276596%}.row-fluid .offset3{margin-left:27.659574468085104%;*margin-left:27.5531914893617%}.row-fluid .offset3:first-child{margin-left:25.53191489361702%;*margin-left:25.425531914893618%}.row-fluid .offset2{margin-left:19.148936170212764%;*margin-left:19.04255319148936%}.row-fluid .offset2:first-child{margin-left:17.02127659574468%;*margin-left:16.914893617021278%}.row-fluid .offset1{margin-left:10.638297872340425%;*margin-left:10.53191489361702%}.row-fluid .offset1:first-child{margin-left:8.51063829787234%;*margin-left:8.404255319148938%}[class*="span"].hide,.row-fluid [class*="span"].hide{display:none}[class*="span"].pull-right,.row-fluid [class*="span"].pull-right{float:right}.container{margin-right:auto;margin-left:auto;*zoom:1}.container:before,.container:after{display:table;line-height:0;content:""}.container:after{clear:both}.container-fluid{padding-right:20px;padding-left:20px;*zoom:1}.container-fluid:before,.container-fluid:after{display:table;line-height:0;content:""}.container-fluid:after{clear:both}p{margin:0 0 10px}.lead{margin-bottom:20px;font-size:21px;font-weight:200;line-height:30px}small{font-size:85%}strong{font-weight:bold}em{font-style:italic}cite{font-style:normal}.muted{color:#999}a.muted:hover,a.muted:focus{color:#808080}.text-warning{color:#c09853}a.text-warning:hover,a.text-warning:focus{color:#a47e3c}.text-error{color:#b94a48}a.text-error:hover,a.text-error:focus{color:#953b39}.text-info{color:#3a87ad}a.text-info:hover,a.text-info:focus{color:#2d6987}.text-success{color:#468847}a.text-success:hover,a.text-success:focus{color:#356635}.text-left{text-align:left}.text-right{text-align:right}.text-center{text-align:center}h1,h2,h3,h4,h5,h6{margin:10px 0;font-family:inherit;font-weight:bold;line-height:20px;color:inherit;text-rendering:optimizelegibility}h1 small,h2 small,h3 small,h4 small,h5 small,h6 small{font-weight:normal;line-height:1;color:#999}h1,h2,h3{line-height:40px}h1{font-size:38.5px}h2{font-size:31.5px}h3{font-size:24.5px}h4{font-size:17.5px}h5{font-size:14px}h6{font-size:11.9px}h1 small{font-size:24.5px}h2 small{font-size:17.5px}h3 small{font-size:14px}h4 small{font-size:14px}.page-header{padding-bottom:9px;margin:20px 0 30px;border-bottom:1px solid #eee}ul,ol{padding:0;margin:0 0 10px 25px}ul ul,ul ol,ol ol,ol ul{margin-bottom:0}li{line-height:20px}ul.unstyled,ol.unstyled{margin-left:0;list-style:none}ul.inline,ol.inline{margin-left:0;list-style:none}ul.inline>li,ol.inline>li{display:inline-block;*display:inline;padding-right:5px;padding-left:5px;*zoom:1}dl{margin-bottom:20px}dt,dd{line-height:20px}dt{font-weight:bold}dd{margin-left:10px}.dl-horizontal{*zoom:1}.dl-horizontal:before,.dl-horizontal:after{display:table;line-height:0;content:""}.dl-horizontal:after{clear:both}.dl-horizontal dt{float:left;width:160px;overflow:hidden;clear:left;text-align:right;text-overflow:ellipsis;white-space:nowrap}.dl-horizontal dd{margin-left:180px}hr{margin:20px 0;border:0;border-top:1px solid #eee;border-bottom:1px solid #fff}abbr[title],abbr[data-original-title]{cursor:help;border-bottom:1px dotted #999}abbr.initialism{font-size:90%;text-transform:uppercase}blockquote{padding:0 0 0 15px;margin:0 0 20px;border-left:5px solid #eee}blockquote p{margin-bottom:0;font-size:17.5px;font-weight:300;line-height:1.25}blockquote small{display:block;line-height:20px;color:#999}blockquote small:before{content:'\2014 \00A0'}blockquote.pull-right{float:right;padding-right:15px;padding-left:0;border-right:5px solid #eee;border-left:0}blockquote.pull-right p,blockquote.pull-right small{text-align:right}blockquote.pull-right small:before{content:''}blockquote.pull-right small:after{content:'\00A0 \2014'}q:before,q:after,blockquote:before,blockquote:after{content:""}address{display:block;margin-bottom:20px;font-style:normal;line-height:20px}code,pre{padding:0 3px 2px;font-family:Monaco,Menlo,Consolas,"Courier New",monospace;font-size:12px;color:#333;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}code{padding:2px 4px;color:#d14;white-space:nowrap;background-color:#f7f7f9;border:1px solid #e1e1e8}pre{display:block;padding:9.5px;margin:0 0 10px;font-size:13px;line-height:20px;word-break:break-all;word-wrap:break-word;white-space:pre;white-space:pre-wrap;background-color:#f5f5f5;border:1px solid #ccc;border:1px solid rgba(0,0,0,0.15);-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}pre.prettyprint{margin-bottom:20px}pre code{padding:0;color:inherit;white-space:pre;white-space:pre-wrap;background-color:transparent;border:0}.pre-scrollable{max-height:340px;overflow-y:scroll}form{margin:0 0 20px}fieldset{padding:0;margin:0;border:0}legend{display:block;width:100%;padding:0;margin-bottom:20px;font-size:21px;line-height:40px;color:#333;border:0;border-bottom:1px solid #e5e5e5}legend small{font-size:15px;color:#999}label,input,button,select,textarea{font-size:14px;font-weight:normal;line-height:20px}input,button,select,textarea{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif}label{display:block;margin-bottom:5px}select,textarea,input[type="text"],input[type="password"],input[type="datetime"],input[type="datetime-local"],input[type="date"],input[type="month"],input[type="time"],input[type="week"],input[type="number"],input[type="email"],input[type="url"],input[type="search"],input[type="tel"],input[type="color"],.uneditable-input{display:inline-block;height:20px;padding:4px 6px;margin-bottom:10px;font-size:14px;line-height:20px;color:#555;vertical-align:middle;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}input,textarea,.uneditable-input{width:206px}textarea{height:auto}textarea,input[type="text"],input[type="password"],input[type="datetime"],input[type="datetime-local"],input[type="date"],input[type="month"],input[type="time"],input[type="week"],input[type="number"],input[type="email"],input[type="url"],input[type="search"],input[type="tel"],input[type="color"],.uneditable-input{background-color:#fff;border:1px solid #ccc;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-webkit-transition:border linear .2s,box-shadow linear .2s;-moz-transition:border linear .2s,box-shadow linear .2s;-o-transition:border linear .2s,box-shadow linear .2s;transition:border linear .2s,box-shadow linear .2s}textarea:focus,input[type="text"]:focus,input[type="password"]:focus,input[type="datetime"]:focus,input[type="datetime-local"]:focus,input[type="date"]:focus,input[type="month"]:focus,input[type="time"]:focus,input[type="week"]:focus,input[type="number"]:focus,input[type="email"]:focus,input[type="url"]:focus,input[type="search"]:focus,input[type="tel"]:focus,input[type="color"]:focus,.uneditable-input:focus{border-color:rgba(82,168,236,0.8);outline:0;outline:thin dotted \9;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(82,168,236,0.6);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(82,168,236,0.6);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(82,168,236,0.6)}input[type="radio"],input[type="checkbox"]{margin:4px 0 0;margin-top:1px \9;*margin-top:0;line-height:normal}input[type="file"],input[type="image"],input[type="submit"],input[type="reset"],input[type="button"],input[type="radio"],input[type="checkbox"]{width:auto}select,input[type="file"]{height:30px;*margin-top:4px;line-height:30px}select{width:220px;background-color:#fff;border:1px solid #ccc}select[multiple],select[size]{height:auto}select:focus,input[type="file"]:focus,input[type="radio"]:focus,input[type="checkbox"]:focus{outline:thin dotted #333;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.uneditable-input,.uneditable-textarea{color:#999;cursor:not-allowed;background-color:#fcfcfc;border-color:#ccc;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,0.025);-moz-box-shadow:inset 0 1px 2px rgba(0,0,0,0.025);box-shadow:inset 0 1px 2px rgba(0,0,0,0.025)}.uneditable-input{overflow:hidden;white-space:nowrap}.uneditable-textarea{width:auto;height:auto}input:-moz-placeholder,textarea:-moz-placeholder{color:#999}input:-ms-input-placeholder,textarea:-ms-input-placeholder{color:#999}input::-webkit-input-placeholder,textarea::-webkit-input-placeholder{color:#999}.radio,.checkbox{min-height:20px;padding-left:20px}.radio input[type="radio"],.checkbox input[type="checkbox"]{float:left;margin-left:-20px}.controls>.radio:first-child,.controls>.checkbox:first-child{padding-top:5px}.radio.inline,.checkbox.inline{display:inline-block;padding-top:5px;margin-bottom:0;vertical-align:middle}.radio.inline+.radio.inline,.checkbox.inline+.checkbox.inline{margin-left:10px}.input-mini{width:60px}.input-small{width:90px}.input-medium{width:150px}.input-large{width:210px}.input-xlarge{width:270px}.input-xxlarge{width:530px}input[class*="span"],select[class*="span"],textarea[class*="span"],.uneditable-input[class*="span"],.row-fluid input[class*="span"],.row-fluid select[class*="span"],.row-fluid textarea[class*="span"],.row-fluid .uneditable-input[class*="span"]{float:none;margin-left:0}.input-append input[class*="span"],.input-append .uneditable-input[class*="span"],.input-prepend input[class*="span"],.input-prepend .uneditable-input[class*="span"],.row-fluid input[class*="span"],.row-fluid select[class*="span"],.row-fluid textarea[class*="span"],.row-fluid .uneditable-input[class*="span"],.row-fluid .input-prepend [class*="span"],.row-fluid .input-append [class*="span"]{display:inline-block}input,textarea,.uneditable-input{margin-left:0}.controls-row [class*="span"]+[class*="span"]{margin-left:20px}input.span12,textarea.span12,.uneditable-input.span12{width:926px}input.span11,textarea.span11,.uneditable-input.span11{width:846px}input.span10,textarea.span10,.uneditable-input.span10{width:766px}input.span9,textarea.span9,.uneditable-input.span9{width:686px}input.span8,textarea.span8,.uneditable-input.span8{width:606px}input.span7,textarea.span7,.uneditable-input.span7{width:526px}input.span6,textarea.span6,.uneditable-input.span6{width:446px}input.span5,textarea.span5,.uneditable-input.span5{width:366px}input.span4,textarea.span4,.uneditable-input.span4{width:286px}input.span3,textarea.span3,.uneditable-input.span3{width:206px}input.span2,textarea.span2,.uneditable-input.span2{width:126px}input.span1,textarea.span1,.uneditable-input.span1{width:46px}.controls-row{*zoom:1}.controls-row:before,.controls-row:after{display:table;line-height:0;content:""}.controls-row:after{clear:both}.controls-row [class*="span"],.row-fluid .controls-row [class*="span"]{float:left}.controls-row .checkbox[class*="span"],.controls-row .radio[class*="span"]{padding-top:5px}input[disabled],select[disabled],textarea[disabled],input[readonly],select[readonly],textarea[readonly]{cursor:not-allowed;background-color:#eee}input[type="radio"][disabled],input[type="checkbox"][disabled],input[type="radio"][readonly],input[type="checkbox"][readonly]{background-color:transparent}.control-group.warning .control-label,.control-group.warning .help-block,.control-group.warning .help-inline{color:#c09853}.control-group.warning .checkbox,.control-group.warning .radio,.control-group.warning input,.control-group.warning select,.control-group.warning textarea{color:#c09853}.control-group.warning input,.control-group.warning select,.control-group.warning textarea{border-color:#c09853;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.control-group.warning input:focus,.control-group.warning select:focus,.control-group.warning textarea:focus{border-color:#a47e3c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #dbc59e;-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #dbc59e;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #dbc59e}.control-group.warning .input-prepend .add-on,.control-group.warning .input-append .add-on{color:#c09853;background-color:#fcf8e3;border-color:#c09853}.control-group.error .control-label,.control-group.error .help-block,.control-group.error .help-inline{color:#b94a48}.control-group.error .checkbox,.control-group.error .radio,.control-group.error input,.control-group.error select,.control-group.error textarea{color:#b94a48}.control-group.error input,.control-group.error select,.control-group.error textarea{border-color:#b94a48;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.control-group.error input:focus,.control-group.error select:focus,.control-group.error textarea:focus{border-color:#953b39;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #d59392;-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #d59392;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #d59392}.control-group.error .input-prepend .add-on,.control-group.error .input-append .add-on{color:#b94a48;background-color:#f2dede;border-color:#b94a48}.control-group.success .control-label,.control-group.success .help-block,.control-group.success .help-inline{color:#468847}.control-group.success .checkbox,.control-group.success .radio,.control-group.success input,.control-group.success select,.control-group.success textarea{color:#468847}.control-group.success input,.control-group.success select,.control-group.success textarea{border-color:#468847;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.control-group.success input:focus,.control-group.success select:focus,.control-group.success textarea:focus{border-color:#356635;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #7aba7b;-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #7aba7b;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #7aba7b}.control-group.success .input-prepend .add-on,.control-group.success .input-append .add-on{color:#468847;background-color:#dff0d8;border-color:#468847}.control-group.info .control-label,.control-group.info .help-block,.control-group.info .help-inline{color:#3a87ad}.control-group.info .checkbox,.control-group.info .radio,.control-group.info input,.control-group.info select,.control-group.info textarea{color:#3a87ad}.control-group.info input,.control-group.info select,.control-group.info textarea{border-color:#3a87ad;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.control-group.info input:focus,.control-group.info select:focus,.control-group.info textarea:focus{border-color:#2d6987;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #7ab5d3;-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #7ab5d3;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #7ab5d3}.control-group.info .input-prepend .add-on,.control-group.info .input-append .add-on{color:#3a87ad;background-color:#d9edf7;border-color:#3a87ad}input:focus:invalid,textarea:focus:invalid,select:focus:invalid{color:#b94a48;border-color:#ee5f5b}input:focus:invalid:focus,textarea:focus:invalid:focus,select:focus:invalid:focus{border-color:#e9322d;-webkit-box-shadow:0 0 6px #f8b9b7;-moz-box-shadow:0 0 6px #f8b9b7;box-shadow:0 0 6px #f8b9b7}.form-actions{padding:19px 20px 20px;margin-top:20px;margin-bottom:20px;background-color:#f5f5f5;border-top:1px solid #e5e5e5;*zoom:1}.form-actions:before,.form-actions:after{display:table;line-height:0;content:""}.form-actions:after{clear:both}.help-block,.help-inline{color:#595959}.help-block{display:block;margin-bottom:10px}.help-inline{display:inline-block;*display:inline;padding-left:5px;vertical-align:middle;*zoom:1}.input-append,.input-prepend{display:inline-block;margin-bottom:10px;font-size:0;white-space:nowrap;vertical-align:middle}.input-append input,.input-prepend input,.input-append select,.input-prepend select,.input-append .uneditable-input,.input-prepend .uneditable-input,.input-append .dropdown-menu,.input-prepend .dropdown-menu,.input-append .popover,.input-prepend .popover{font-size:14px}.input-append input,.input-prepend input,.input-append select,.input-prepend select,.input-append .uneditable-input,.input-prepend .uneditable-input{position:relative;margin-bottom:0;*margin-left:0;vertical-align:top;-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0}.input-append input:focus,.input-prepend input:focus,.input-append select:focus,.input-prepend select:focus,.input-append .uneditable-input:focus,.input-prepend .uneditable-input:focus{z-index:2}.input-append .add-on,.input-prepend .add-on{display:inline-block;width:auto;height:20px;min-width:16px;padding:4px 5px;font-size:14px;font-weight:normal;line-height:20px;text-align:center;text-shadow:0 1px 0 #fff;background-color:#eee;border:1px solid #ccc}.input-append .add-on,.input-prepend .add-on,.input-append .btn,.input-prepend .btn,.input-append .btn-group>.dropdown-toggle,.input-prepend .btn-group>.dropdown-toggle{vertical-align:top;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.input-append .active,.input-prepend .active{background-color:#a9dba9;border-color:#46a546}.input-prepend .add-on,.input-prepend .btn{margin-right:-1px}.input-prepend .add-on:first-child,.input-prepend .btn:first-child{-webkit-border-radius:4px 0 0 4px;-moz-border-radius:4px 0 0 4px;border-radius:4px 0 0 4px}.input-append input,.input-append select,.input-append .uneditable-input{-webkit-border-radius:4px 0 0 4px;-moz-border-radius:4px 0 0 4px;border-radius:4px 0 0 4px}.input-append input+.btn-group .btn:last-child,.input-append select+.btn-group .btn:last-child,.input-append .uneditable-input+.btn-group .btn:last-child{-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0}.input-append .add-on,.input-append .btn,.input-append .btn-group{margin-left:-1px}.input-append .add-on:last-child,.input-append .btn:last-child,.input-append .btn-group:last-child>.dropdown-toggle{-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0}.input-prepend.input-append input,.input-prepend.input-append select,.input-prepend.input-append .uneditable-input{-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.input-prepend.input-append input+.btn-group .btn,.input-prepend.input-append select+.btn-group .btn,.input-prepend.input-append .uneditable-input+.btn-group .btn{-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0}.input-prepend.input-append .add-on:first-child,.input-prepend.input-append .btn:first-child{margin-right:-1px;-webkit-border-radius:4px 0 0 4px;-moz-border-radius:4px 0 0 4px;border-radius:4px 0 0 4px}.input-prepend.input-append .add-on:last-child,.input-prepend.input-append .btn:last-child{margin-left:-1px;-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0}.input-prepend.input-append .btn-group:first-child{margin-left:0}input.search-query{padding-right:14px;padding-right:4px \9;padding-left:14px;padding-left:4px \9;margin-bottom:0;-webkit-border-radius:15px;-moz-border-radius:15px;border-radius:15px}.form-search .input-append .search-query,.form-search .input-prepend .search-query{-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.form-search .input-append .search-query{-webkit-border-radius:14px 0 0 14px;-moz-border-radius:14px 0 0 14px;border-radius:14px 0 0 14px}.form-search .input-append .btn{-webkit-border-radius:0 14px 14px 0;-moz-border-radius:0 14px 14px 0;border-radius:0 14px 14px 0}.form-search .input-prepend .search-query{-webkit-border-radius:0 14px 14px 0;-moz-border-radius:0 14px 14px 0;border-radius:0 14px 14px 0}.form-search .input-prepend .btn{-webkit-border-radius:14px 0 0 14px;-moz-border-radius:14px 0 0 14px;border-radius:14px 0 0 14px}.form-search input,.form-inline input,.form-horizontal input,.form-search textarea,.form-inline textarea,.form-horizontal textarea,.form-search select,.form-inline select,.form-horizontal select,.form-search .help-inline,.form-inline .help-inline,.form-horizontal .help-inline,.form-search .uneditable-input,.form-inline .uneditable-input,.form-horizontal .uneditable-input,.form-search .input-prepend,.form-inline .input-prepend,.form-horizontal .input-prepend,.form-search .input-append,.form-inline .input-append,.form-horizontal .input-append{display:inline-block;*display:inline;margin-bottom:0;vertical-align:middle;*zoom:1}.form-search .hide,.form-inline .hide,.form-horizontal .hide{display:none}.form-search label,.form-inline label,.form-search .btn-group,.form-inline .btn-group{display:inline-block}.form-search .input-append,.form-inline .input-append,.form-search .input-prepend,.form-inline .input-prepend{margin-bottom:0}.form-search .radio,.form-search .checkbox,.form-inline .radio,.form-inline .checkbox{padding-left:0;margin-bottom:0;vertical-align:middle}.form-search .radio input[type="radio"],.form-search .checkbox input[type="checkbox"],.form-inline .radio input[type="radio"],.form-inline .checkbox input[type="checkbox"]{float:left;margin-right:3px;margin-left:0}.control-group{margin-bottom:10px}legend+.control-group{margin-top:20px;-webkit-margin-top-collapse:separate}.form-horizontal .control-group{margin-bottom:20px;*zoom:1}.form-horizontal .control-group:before,.form-horizontal .control-group:after{display:table;line-height:0;content:""}.form-horizontal .control-group:after{clear:both}.form-horizontal .control-label{float:left;width:160px;padding-top:5px;text-align:right}.form-horizontal .controls{*display:inline-block;*padding-left:20px;margin-left:180px;*margin-left:0}.form-horizontal .controls:first-child{*padding-left:180px}.form-horizontal .help-block{margin-bottom:0}.form-horizontal input+.help-block,.form-horizontal select+.help-block,.form-horizontal textarea+.help-block,.form-horizontal .uneditable-input+.help-block,.form-horizontal .input-prepend+.help-block,.form-horizontal .input-append+.help-block{margin-top:10px}.form-horizontal .form-actions{padding-left:180px}table{max-width:100%;background-color:transparent;border-collapse:collapse;border-spacing:0}.table{width:100%;margin-bottom:20px}.table th,.table td{padding:8px;line-height:15px;text-align:left;vertical-align:top;border-top:1px solid #ddd}.table th{font-weight:bold}.table thead th{vertical-align:bottom}.table caption+thead tr:first-child th,.table caption+thead tr:first-child td,.table colgroup+thead tr:first-child th,.table colgroup+thead tr:first-child td,.table thead:first-child tr:first-child th,.table thead:first-child tr:first-child td{border-top:0}.table tbody+tbody{border-top:2px solid #ddd}.table .table{background-color:#fff}.table-condensed th,.table-condensed td{padding:4px 5px}.table-bordered{border:1px solid #ddd;border-collapse:separate;*border-collapse:collapse;border-left:0;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.table-bordered th,.table-bordered td{border-left:1px solid #ddd}.table-bordered caption+thead tr:first-child th,.table-bordered caption+tbody tr:first-child th,.table-bordered caption+tbody tr:first-child td,.table-bordered colgroup+thead tr:first-child th,.table-bordered colgroup+tbody tr:first-child th,.table-bordered colgroup+tbody tr:first-child td,.table-bordered thead:first-child tr:first-child th,.table-bordered tbody:first-child tr:first-child th,.table-bordered tbody:first-child tr:first-child td{border-top:0}.table-bordered thead:first-child tr:first-child>th:first-child,.table-bordered tbody:first-child tr:first-child>td:first-child,.table-bordered tbody:first-child tr:first-child>th:first-child{-webkit-border-top-left-radius:4px;border-top-left-radius:4px;-moz-border-radius-topleft:4px}.table-bordered thead:first-child tr:first-child>th:last-child,.table-bordered tbody:first-child tr:first-child>td:last-child,.table-bordered tbody:first-child tr:first-child>th:last-child{-webkit-border-top-right-radius:4px;border-top-right-radius:4px;-moz-border-radius-topright:4px}.table-bordered thead:last-child tr:last-child>th:first-child,.table-bordered tbody:last-child tr:last-child>td:first-child,.table-bordered tbody:last-child tr:last-child>th:first-child,.table-bordered tfoot:last-child tr:last-child>td:first-child,.table-bordered tfoot:last-child tr:last-child>th:first-child{-webkit-border-bottom-left-radius:4px;border-bottom-left-radius:4px;-moz-border-radius-bottomleft:4px}.table-bordered thead:last-child tr:last-child>th:last-child,.table-bordered tbody:last-child tr:last-child>td:last-child,.table-bordered tbody:last-child tr:last-child>th:last-child,.table-bordered tfoot:last-child tr:last-child>td:last-child,.table-bordered tfoot:last-child tr:last-child>th:last-child{-webkit-border-bottom-right-radius:4px;border-bottom-right-radius:4px;-moz-border-radius-bottomright:4px}.table-bordered tfoot+tbody:last-child tr:last-child td:first-child{-webkit-border-bottom-left-radius:0;border-bottom-left-radius:0;-moz-border-radius-bottomleft:0}.table-bordered tfoot+tbody:last-child tr:last-child td:last-child{-webkit-border-bottom-right-radius:0;border-bottom-right-radius:0;-moz-border-radius-bottomright:0}.table-bordered caption+thead tr:first-child th:first-child,.table-bordered caption+tbody tr:first-child td:first-child,.table-bordered colgroup+thead tr:first-child th:first-child,.table-bordered colgroup+tbody tr:first-child td:first-child{-webkit-border-top-left-radius:4px;border-top-left-radius:4px;-moz-border-radius-topleft:4px}.table-bordered caption+thead tr:first-child th:last-child,.table-bordered caption+tbody tr:first-child td:last-child,.table-bordered colgroup+thead tr:first-child th:last-child,.table-bordered colgroup+tbody tr:first-child td:last-child{-webkit-border-top-right-radius:4px;border-top-right-radius:4px;-moz-border-radius-topright:4px}.table-striped tbody>tr:nth-child(odd)>td,.table-striped tbody>tr:nth-child(odd)>th{background-color:#f9f9f9}.table-hover tbody tr:hover>td,.table-hover tbody tr:hover>th{background-color:#f5f5f5}table td[class*="span"],table th[class*="span"],.row-fluid table td[class*="span"],.row-fluid table th[class*="span"]{display:table-cell;float:none;margin-left:0}.table td.span1,.table th.span1{float:none;width:44px;margin-left:0}.table td.span2,.table th.span2{float:none;width:124px;margin-left:0}.table td.span3,.table th.span3{float:none;width:204px;margin-left:0}.table td.span4,.table th.span4{float:none;width:284px;margin-left:0}.table td.span5,.table th.span5{float:none;width:364px;margin-left:0}.table td.span6,.table th.span6{float:none;width:444px;margin-left:0}.table td.span7,.table th.span7{float:none;width:524px;margin-left:0}.table td.span8,.table th.span8{float:none;width:604px;margin-left:0}.table td.span9,.table th.span9{float:none;width:684px;margin-left:0}.table td.span10,.table th.span10{float:none;width:764px;margin-left:0}.table td.span11,.table th.span11{float:none;width:844px;margin-left:0}.table td.span12,.table th.span12{float:none;width:924px;margin-left:0}.table tbody tr.success>td{background-color:#dff0d8}.table tbody tr.error>td{background-color:#f2dede}.table tbody tr.warning>td{background-color:#fcf8e3}.table tbody tr.info>td{background-color:#d9edf7}.table-hover tbody tr.success:hover>td{background-color:#d0e9c6}.table-hover tbody tr.error:hover>td{background-color:#ebcccc}.table-hover tbody tr.warning:hover>td{background-color:#faf2cc}.table-hover tbody tr.info:hover>td{background-color:#c4e3f3}[class^="icon-"],[class*=" icon-"]{display:inline-block;width:14px;height:14px;margin-top:1px;*margin-right:.3em;line-height:14px;vertical-align:text-top;background-image:url("../img/glyphicons-halflings.png");background-position:14px 14px;background-repeat:no-repeat}.icon-white,.nav-pills>.active>a>[class^="icon-"],.nav-pills>.active>a>[class*=" icon-"],.nav-list>.active>a>[class^="icon-"],.nav-list>.active>a>[class*=" icon-"],.navbar-inverse .nav>.active>a>[class^="icon-"],.navbar-inverse .nav>.active>a>[class*=" icon-"],.dropdown-menu>li>a:hover>[class^="icon-"],.dropdown-menu>li>a:focus>[class^="icon-"],.dropdown-menu>li>a:hover>[class*=" icon-"],.dropdown-menu>li>a:focus>[class*=" icon-"],.dropdown-menu>.active>a>[class^="icon-"],.dropdown-menu>.active>a>[class*=" icon-"],.dropdown-submenu:hover>a>[class^="icon-"],.dropdown-submenu:focus>a>[class^="icon-"],.dropdown-submenu:hover>a>[class*=" icon-"],.dropdown-submenu:focus>a>[class*=" icon-"]{background-image:url("../img/glyphicons-halflings-white.png")}.icon-glass{background-position:0 0}.icon-music{background-position:-24px 0}.icon-search{background-position:-48px 0}.icon-envelope{background-position:-72px 0}.icon-heart{background-position:-96px 0}.icon-star{background-position:-120px 0}.icon-star-empty{background-position:-144px 0}.icon-user{background-position:-168px 0}.icon-film{background-position:-192px 0}.icon-th-large{background-position:-216px 0}.icon-th{background-position:-240px 0}.icon-th-list{background-position:-264px 0}.icon-ok{background-position:-288px 0}.icon-remove{background-position:-312px 0}.icon-zoom-in{background-position:-336px 0}.icon-zoom-out{background-position:-360px 0}.icon-off{background-position:-384px 0}.icon-signal{background-position:-408px 0}.icon-cog{background-position:-432px 0}.icon-trash{background-position:-456px 0}.icon-home{background-position:0 -24px}.icon-file{background-position:-24px -24px}.icon-time{background-position:-48px -24px}.icon-road{background-position:-72px -24px}.icon-download-alt{background-position:-96px -24px}.icon-download{background-position:-120px -24px}.icon-upload{background-position:-144px -24px}.icon-inbox{background-position:-168px -24px}.icon-play-circle{background-position:-192px -24px}.icon-repeat{background-position:-216px -24px}.icon-refresh{background-position:-240px -24px}.icon-list-alt{background-position:-264px -24px}.icon-lock{background-position:-287px -24px}.icon-flag{background-position:-312px -24px}.icon-headphones{background-position:-336px -24px}.icon-volume-off{background-position:-360px -24px}.icon-volume-down{background-position:-384px -24px}.icon-volume-up{background-position:-408px -24px}.icon-qrcode{background-position:-432px -24px}.icon-barcode{background-position:-456px -24px}.icon-tag{background-position:0 -48px}.icon-tags{background-position:-25px -48px}.icon-book{background-position:-48px -48px}.icon-bookmark{background-position:-72px -48px}.icon-print{background-position:-96px -48px}.icon-camera{background-position:-120px -48px}.icon-font{background-position:-144px -48px}.icon-bold{background-position:-167px -48px}.icon-italic{background-position:-192px -48px}.icon-text-height{background-position:-216px -48px}.icon-text-width{background-position:-240px -48px}.icon-align-left{background-position:-264px -48px}.icon-align-center{background-position:-288px -48px}.icon-align-right{background-position:-312px -48px}.icon-align-justify{background-position:-336px -48px}.icon-list{background-position:-360px -48px}.icon-indent-left{background-position:-384px -48px}.icon-indent-right{background-position:-408px -48px}.icon-facetime-video{background-position:-432px -48px}.icon-picture{background-position:-456px -48px}.icon-pencil{background-position:0 -72px}.icon-map-marker{background-position:-24px -72px}.icon-adjust{background-position:-48px -72px}.icon-tint{background-position:-72px -72px}.icon-edit{background-position:-96px -72px}.icon-share{background-position:-120px -72px}.icon-check{background-position:-144px -72px}.icon-move{background-position:-168px -72px}.icon-step-backward{background-position:-192px -72px}.icon-fast-backward{background-position:-216px -72px}.icon-backward{background-position:-240px -72px}.icon-play{background-position:-264px -72px}.icon-pause{background-position:-288px -72px}.icon-stop{background-position:-312px -72px}.icon-forward{background-position:-336px -72px}.icon-fast-forward{background-position:-360px -72px}.icon-step-forward{background-position:-384px -72px}.icon-eject{background-position:-408px -72px}.icon-chevron-left{background-position:-432px -72px}.icon-chevron-right{background-position:-456px -72px}.icon-plus-sign{background-position:0 -96px}.icon-minus-sign{background-position:-24px -96px}.icon-remove-sign{background-position:-48px -96px}.icon-ok-sign{background-position:-72px -96px}.icon-question-sign{background-position:-96px -96px}.icon-info-sign{background-position:-120px -96px}.icon-screenshot{background-position:-144px -96px}.icon-remove-circle{background-position:-168px -96px}.icon-ok-circle{background-position:-192px -96px}.icon-ban-circle{background-position:-216px -96px}.icon-arrow-left{background-position:-240px -96px}.icon-arrow-right{background-position:-264px -96px}.icon-arrow-up{background-position:-289px -96px}.icon-arrow-down{background-position:-312px -96px}.icon-share-alt{background-position:-336px -96px}.icon-resize-full{background-position:-360px -96px}.icon-resize-small{background-position:-384px -96px}.icon-plus{background-position:-408px -96px}.icon-minus{background-position:-433px -96px}.icon-asterisk{background-position:-456px -96px}.icon-exclamation-sign{background-position:0 -120px}.icon-gift{background-position:-24px -120px}.icon-leaf{background-position:-48px -120px}.icon-fire{background-position:-72px -120px}.icon-eye-open{background-position:-96px -120px}.icon-eye-close{background-position:-120px -120px}.icon-warning-sign{background-position:-144px -120px}.icon-plane{background-position:-168px -120px}.icon-calendar{background-position:-192px -120px}.icon-random{width:16px;background-position:-216px -120px}.icon-comment{background-position:-240px -120px}.icon-magnet{background-position:-264px -120px}.icon-chevron-up{background-position:-288px -120px}.icon-chevron-down{background-position:-313px -119px}.icon-retweet{background-position:-336px -120px}.icon-shopping-cart{background-position:-360px -120px}.icon-folder-close{width:16px;background-position:-384px -120px}.icon-folder-open{width:16px;background-position:-408px -120px}.icon-resize-vertical{background-position:-432px -119px}.icon-resize-horizontal{background-position:-456px -118px}.icon-hdd{background-position:0 -144px}.icon-bullhorn{background-position:-24px -144px}.icon-bell{background-position:-48px -144px}.icon-certificate{background-position:-72px -144px}.icon-thumbs-up{background-position:-96px -144px}.icon-thumbs-down{background-position:-120px -144px}.icon-hand-right{background-position:-144px -144px}.icon-hand-left{background-position:-168px -144px}.icon-hand-up{background-position:-192px -144px}.icon-hand-down{background-position:-216px -144px}.icon-circle-arrow-right{background-position:-240px -144px}.icon-circle-arrow-left{background-position:-264px -144px}.icon-circle-arrow-up{background-position:-288px -144px}.icon-circle-arrow-down{background-position:-312px -144px}.icon-globe{background-position:-336px -144px}.icon-wrench{background-position:-360px -144px}.icon-tasks{background-position:-384px -144px}.icon-filter{background-position:-408px -144px}.icon-briefcase{background-position:-432px -144px}.icon-fullscreen{background-position:-456px -144px}.dropup,.dropdown{position:relative}.dropdown-toggle{*margin-bottom:-3px}.dropdown-toggle:active,.open .dropdown-toggle{outline:0}.caret{display:inline-block;width:0;height:0;vertical-align:top;border-top:4px solid #000;border-right:4px solid transparent;border-left:4px solid transparent;content:""}.dropdown .caret{margin-top:8px;margin-left:2px}.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:160px;padding:5px 0;margin:2px 0 0;list-style:none;background-color:#fff;border:1px solid #ccc;border:1px solid rgba(0,0,0,0.2);*border-right-width:2px;*border-bottom-width:2px;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0,0,0,0.2);-moz-box-shadow:0 5px 10px rgba(0,0,0,0.2);box-shadow:0 5px 10px rgba(0,0,0,0.2);-webkit-background-clip:padding-box;-moz-background-clip:padding;background-clip:padding-box}.dropdown-menu.pull-right{right:0;left:auto}.dropdown-menu .divider{*width:100%;height:1px;margin:9px 1px;*margin:-5px 0 5px;overflow:hidden;background-color:#e5e5e5;border-bottom:1px solid #fff}.dropdown-menu>li>a{display:block;padding:3px 20px;clear:both;font-weight:normal;line-height:20px;color:#333;white-space:nowrap}.dropdown-menu>li>a:hover,.dropdown-menu>li>a:focus,.dropdown-submenu:hover>a,.dropdown-submenu:focus>a{color:#fff;text-decoration:none;background-color:#0081c2;background-image:-moz-linear-gradient(top,#08c,#0077b3);background-image:-webkit-gradient(linear,0 0,0 100%,from(#08c),to(#0077b3));background-image:-webkit-linear-gradient(top,#08c,#0077b3);background-image:-o-linear-gradient(top,#08c,#0077b3);background-image:linear-gradient(to bottom,#08c,#0077b3);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc',endColorstr='#ff0077b3',GradientType=0)}.dropdown-menu>.active>a,.dropdown-menu>.active>a:hover,.dropdown-menu>.active>a:focus{color:#fff;text-decoration:none;background-color:#0081c2;background-image:-moz-linear-gradient(top,#08c,#0077b3);background-image:-webkit-gradient(linear,0 0,0 100%,from(#08c),to(#0077b3));background-image:-webkit-linear-gradient(top,#08c,#0077b3);background-image:-o-linear-gradient(top,#08c,#0077b3);background-image:linear-gradient(to bottom,#08c,#0077b3);background-repeat:repeat-x;outline:0;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc',endColorstr='#ff0077b3',GradientType=0)}.dropdown-menu>.disabled>a,.dropdown-menu>.disabled>a:hover,.dropdown-menu>.disabled>a:focus{color:#999}.dropdown-menu>.disabled>a:hover,.dropdown-menu>.disabled>a:focus{text-decoration:none;cursor:default;background-color:transparent;background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.open{*z-index:1000}.open>.dropdown-menu{display:block}.dropdown-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:990}.pull-right>.dropdown-menu{right:0;left:auto}.dropup .caret,.navbar-fixed-bottom .dropdown .caret{border-top:0;border-bottom:4px solid #000;content:""}.dropup .dropdown-menu,.navbar-fixed-bottom .dropdown .dropdown-menu{top:auto;bottom:100%;margin-bottom:1px}.dropdown-submenu{position:relative}.dropdown-submenu>.dropdown-menu{top:0;left:100%;margin-top:-6px;margin-left:-1px;-webkit-border-radius:0 6px 6px 6px;-moz-border-radius:0 6px 6px 6px;border-radius:0 6px 6px 6px}.dropdown-submenu:hover>.dropdown-menu{display:block}.dropup .dropdown-submenu>.dropdown-menu{top:auto;bottom:0;margin-top:0;margin-bottom:-2px;-webkit-border-radius:5px 5px 5px 0;-moz-border-radius:5px 5px 5px 0;border-radius:5px 5px 5px 0}.dropdown-submenu>a:after{display:block;float:right;width:0;height:0;margin-top:5px;margin-right:-10px;border-color:transparent;border-left-color:#ccc;border-style:solid;border-width:5px 0 5px 5px;content:" "}.dropdown-submenu:hover>a:after{border-left-color:#fff}.dropdown-submenu.pull-left{float:none}.dropdown-submenu.pull-left>.dropdown-menu{left:-100%;margin-left:10px;-webkit-border-radius:6px 0 6px 6px;-moz-border-radius:6px 0 6px 6px;border-radius:6px 0 6px 6px}.dropdown .dropdown-menu .nav-header{padding-right:20px;padding-left:20px}.typeahead{z-index:1051;margin-top:2px;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.well{min-height:20px;padding:19px;margin-bottom:20px;background-color:#f5f5f5;border:1px solid #e3e3e3;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.05);box-shadow:inset 0 1px 1px rgba(0,0,0,0.05)}.well blockquote{border-color:#ddd;border-color:rgba(0,0,0,0.15)}.well-large{padding:24px;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px}.well-small{padding:9px;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.fade{opacity:0;-webkit-transition:opacity .15s linear;-moz-transition:opacity .15s linear;-o-transition:opacity .15s linear;transition:opacity .15s linear}.fade.in{opacity:1}.collapse{position:relative;height:0;overflow:hidden;-webkit-transition:height .35s ease;-moz-transition:height .35s ease;-o-transition:height .35s ease;transition:height .35s ease}.collapse.in{height:auto}.close{float:right;font-size:20px;font-weight:bold;line-height:20px;color:#000;text-shadow:0 1px 0 #fff;opacity:.2;filter:alpha(opacity=20)}.close:hover,.close:focus{color:#000;text-decoration:none;cursor:pointer;opacity:.4;filter:alpha(opacity=40)}button.close{padding:0;cursor:pointer;background:transparent;border:0;-webkit-appearance:none}.btn{display:inline-block;*display:inline;padding:4px 12px;margin-bottom:0;*margin-left:.3em;font-size:14px;line-height:20px;color:#333;text-align:center;text-shadow:0 1px 1px rgba(255,255,255,0.75);vertical-align:middle;cursor:pointer;background-color:#f5f5f5;*background-color:#e6e6e6;background-image:-moz-linear-gradient(top,#fff,#e6e6e6);background-image:-webkit-gradient(linear,0 0,0 100%,from(#fff),to(#e6e6e6));background-image:-webkit-linear-gradient(top,#fff,#e6e6e6);background-image:-o-linear-gradient(top,#fff,#e6e6e6);background-image:linear-gradient(to bottom,#fff,#e6e6e6);background-repeat:repeat-x;border:1px solid #ccc;*border:0;border-color:#e6e6e6 #e6e6e6 #bfbfbf;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);border-bottom-color:#b3b3b3;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff',endColorstr='#ffe6e6e6',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);*zoom:1;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05)}.btn:hover,.btn:focus,.btn:active,.btn.active,.btn.disabled,.btn[disabled]{color:#333;background-color:#e6e6e6;*background-color:#d9d9d9}.btn:active,.btn.active{background-color:#ccc \9}.btn:first-child{*margin-left:0}.btn:hover,.btn:focus{color:#333;text-decoration:none;background-position:0 -15px;-webkit-transition:background-position .1s linear;-moz-transition:background-position .1s linear;-o-transition:background-position .1s linear;transition:background-position .1s linear}.btn:focus{outline:thin dotted #333;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.btn.active,.btn:active{background-image:none;outline:0;-webkit-box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05)}.btn.disabled,.btn[disabled]{cursor:default;background-image:none;opacity:.65;filter:alpha(opacity=65);-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}.btn-large{padding:11px 19px;font-size:17.5px;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px}.btn-large [class^="icon-"],.btn-large [class*=" icon-"]{margin-top:4px}.btn-small{padding:2px 10px;font-size:11.9px;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.btn-small [class^="icon-"],.btn-small [class*=" icon-"]{margin-top:0}.btn-mini [class^="icon-"],.btn-mini [class*=" icon-"]{margin-top:-1px}.btn-mini{padding:0 6px;font-size:10.5px;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.btn-block{display:block;width:100%;padding-right:0;padding-left:0;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.btn-block+.btn-block{margin-top:5px}input[type="submit"].btn-block,input[type="reset"].btn-block,input[type="button"].btn-block{width:100%}.btn-primary.active,.btn-warning.active,.btn-danger.active,.btn-success.active,.btn-info.active,.btn-inverse.active{color:rgba(255,255,255,0.75)}.btn-primary{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#006dcc;*background-color:#04c;background-image:-moz-linear-gradient(top,#08c,#04c);background-image:-webkit-gradient(linear,0 0,0 100%,from(#08c),to(#04c));background-image:-webkit-linear-gradient(top,#08c,#04c);background-image:-o-linear-gradient(top,#08c,#04c);background-image:linear-gradient(to bottom,#08c,#04c);background-repeat:repeat-x;border-color:#04c #04c #002a80;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc',endColorstr='#ff0044cc',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.btn-primary:hover,.btn-primary:focus,.btn-primary:active,.btn-primary.active,.btn-primary.disabled,.btn-primary[disabled]{color:#fff;background-color:#04c;*background-color:#003bb3}.btn-primary:active,.btn-primary.active{background-color:#039 \9}.btn-warning{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#faa732;*background-color:#f89406;background-image:-moz-linear-gradient(top,#fbb450,#f89406);background-image:-webkit-gradient(linear,0 0,0 100%,from(#fbb450),to(#f89406));background-image:-webkit-linear-gradient(top,#fbb450,#f89406);background-image:-o-linear-gradient(top,#fbb450,#f89406);background-image:linear-gradient(to bottom,#fbb450,#f89406);background-repeat:repeat-x;border-color:#f89406 #f89406 #ad6704;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffbb450',endColorstr='#fff89406',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.btn-warning:hover,.btn-warning:focus,.btn-warning:active,.btn-warning.active,.btn-warning.disabled,.btn-warning[disabled]{color:#fff;background-color:#f89406;*background-color:#df8505}.btn-warning:active,.btn-warning.active{background-color:#c67605 \9}.btn-danger{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#da4f49;*background-color:#bd362f;background-image:-moz-linear-gradient(top,#ee5f5b,#bd362f);background-image:-webkit-gradient(linear,0 0,0 100%,from(#ee5f5b),to(#bd362f));background-image:-webkit-linear-gradient(top,#ee5f5b,#bd362f);background-image:-o-linear-gradient(top,#ee5f5b,#bd362f);background-image:linear-gradient(to bottom,#ee5f5b,#bd362f);background-repeat:repeat-x;border-color:#bd362f #bd362f #802420;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffee5f5b',endColorstr='#ffbd362f',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.btn-danger:hover,.btn-danger:focus,.btn-danger:active,.btn-danger.active,.btn-danger.disabled,.btn-danger[disabled]{color:#fff;background-color:#bd362f;*background-color:#a9302a}.btn-danger:active,.btn-danger.active{background-color:#942a25 \9}.btn-success{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#5bb75b;*background-color:#51a351;background-image:-moz-linear-gradient(top,#62c462,#51a351);background-image:-webkit-gradient(linear,0 0,0 100%,from(#62c462),to(#51a351));background-image:-webkit-linear-gradient(top,#62c462,#51a351);background-image:-o-linear-gradient(top,#62c462,#51a351);background-image:linear-gradient(to bottom,#62c462,#51a351);background-repeat:repeat-x;border-color:#51a351 #51a351 #387038;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff62c462',endColorstr='#ff51a351',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.btn-success:hover,.btn-success:focus,.btn-success:active,.btn-success.active,.btn-success.disabled,.btn-success[disabled]{color:#fff;background-color:#51a351;*background-color:#499249}.btn-success:active,.btn-success.active{background-color:#408140 \9}.btn-info{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#49afcd;*background-color:#2f96b4;background-image:-moz-linear-gradient(top,#5bc0de,#2f96b4);background-image:-webkit-gradient(linear,0 0,0 100%,from(#5bc0de),to(#2f96b4));background-image:-webkit-linear-gradient(top,#5bc0de,#2f96b4);background-image:-o-linear-gradient(top,#5bc0de,#2f96b4);background-image:linear-gradient(to bottom,#5bc0de,#2f96b4);background-repeat:repeat-x;border-color:#2f96b4 #2f96b4 #1f6377;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de',endColorstr='#ff2f96b4',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.btn-info:hover,.btn-info:focus,.btn-info:active,.btn-info.active,.btn-info.disabled,.btn-info[disabled]{color:#fff;background-color:#2f96b4;*background-color:#2a85a0}.btn-info:active,.btn-info.active{background-color:#24748c \9}.btn-inverse{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#363636;*background-color:#222;background-image:-moz-linear-gradient(top,#444,#222);background-image:-webkit-gradient(linear,0 0,0 100%,from(#444),to(#222));background-image:-webkit-linear-gradient(top,#444,#222);background-image:-o-linear-gradient(top,#444,#222);background-image:linear-gradient(to bottom,#444,#222);background-repeat:repeat-x;border-color:#222 #222 #000;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff444444',endColorstr='#ff222222',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.btn-inverse:hover,.btn-inverse:focus,.btn-inverse:active,.btn-inverse.active,.btn-inverse.disabled,.btn-inverse[disabled]{color:#fff;background-color:#222;*background-color:#151515}.btn-inverse:active,.btn-inverse.active{background-color:#080808 \9}button.btn,input[type="submit"].btn{*padding-top:3px;*padding-bottom:3px}button.btn::-moz-focus-inner,input[type="submit"].btn::-moz-focus-inner{padding:0;border:0}button.btn.btn-large,input[type="submit"].btn.btn-large{*padding-top:7px;*padding-bottom:7px}button.btn.btn-small,input[type="submit"].btn.btn-small{*padding-top:3px;*padding-bottom:3px}button.btn.btn-mini,input[type="submit"].btn.btn-mini{*padding-top:1px;*padding-bottom:1px}.btn-link,.btn-link:active,.btn-link[disabled]{background-color:transparent;background-image:none;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}.btn-link{color:#08c;cursor:pointer;border-color:transparent;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.btn-link:hover,.btn-link:focus{color:#005580;text-decoration:underline;background-color:transparent}.btn-link[disabled]:hover,.btn-link[disabled]:focus{color:#333;text-decoration:none}.btn-group{position:relative;display:inline-block;*display:inline;*margin-left:.3em;font-size:0;white-space:nowrap;vertical-align:middle;*zoom:1}.btn-group:first-child{*margin-left:0}.btn-group+.btn-group{margin-left:5px}.btn-toolbar{margin-top:10px;margin-bottom:10px;font-size:0}.btn-toolbar>.btn+.btn,.btn-toolbar>.btn-group+.btn,.btn-toolbar>.btn+.btn-group{margin-left:5px}.btn-group>.btn{position:relative;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.btn-group>.btn+.btn{margin-left:-1px}.btn-group>.btn,.btn-group>.dropdown-menu,.btn-group>.popover{font-size:14px}.btn-group>.btn-mini{font-size:10.5px}.btn-group>.btn-small{font-size:11.9px}.btn-group>.btn-large{font-size:17.5px}.btn-group>.btn:first-child{margin-left:0;-webkit-border-bottom-left-radius:4px;border-bottom-left-radius:4px;-webkit-border-top-left-radius:4px;border-top-left-radius:4px;-moz-border-radius-bottomleft:4px;-moz-border-radius-topleft:4px}.btn-group>.btn:last-child,.btn-group>.dropdown-toggle{-webkit-border-top-right-radius:4px;border-top-right-radius:4px;-webkit-border-bottom-right-radius:4px;border-bottom-right-radius:4px;-moz-border-radius-topright:4px;-moz-border-radius-bottomright:4px}.btn-group>.btn.large:first-child{margin-left:0;-webkit-border-bottom-left-radius:6px;border-bottom-left-radius:6px;-webkit-border-top-left-radius:6px;border-top-left-radius:6px;-moz-border-radius-bottomleft:6px;-moz-border-radius-topleft:6px}.btn-group>.btn.large:last-child,.btn-group>.large.dropdown-toggle{-webkit-border-top-right-radius:6px;border-top-right-radius:6px;-webkit-border-bottom-right-radius:6px;border-bottom-right-radius:6px;-moz-border-radius-topright:6px;-moz-border-radius-bottomright:6px}.btn-group>.btn:hover,.btn-group>.btn:focus,.btn-group>.btn:active,.btn-group>.btn.active{z-index:2}.btn-group .dropdown-toggle:active,.btn-group.open .dropdown-toggle{outline:0}.btn-group>.btn+.dropdown-toggle{*padding-top:5px;padding-right:8px;*padding-bottom:5px;padding-left:8px;-webkit-box-shadow:inset 1px 0 0 rgba(255,255,255,0.125),inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:inset 1px 0 0 rgba(255,255,255,0.125),inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 1px 0 0 rgba(255,255,255,0.125),inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05)}.btn-group>.btn-mini+.dropdown-toggle{*padding-top:2px;padding-right:5px;*padding-bottom:2px;padding-left:5px}.btn-group>.btn-small+.dropdown-toggle{*padding-top:5px;*padding-bottom:4px}.btn-group>.btn-large+.dropdown-toggle{*padding-top:7px;padding-right:12px;*padding-bottom:7px;padding-left:12px}.btn-group.open .dropdown-toggle{background-image:none;-webkit-box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05)}.btn-group.open .btn.dropdown-toggle{background-color:#e6e6e6}.btn-group.open .btn-primary.dropdown-toggle{background-color:#04c}.btn-group.open .btn-warning.dropdown-toggle{background-color:#f89406}.btn-group.open .btn-danger.dropdown-toggle{background-color:#bd362f}.btn-group.open .btn-success.dropdown-toggle{background-color:#51a351}.btn-group.open .btn-info.dropdown-toggle{background-color:#2f96b4}.btn-group.open .btn-inverse.dropdown-toggle{background-color:#222}.btn .caret{margin-top:8px;margin-left:0}.btn-large .caret{margin-top:6px}.btn-large .caret{border-top-width:5px;border-right-width:5px;border-left-width:5px}.btn-mini .caret,.btn-small .caret{margin-top:8px}.dropup .btn-large .caret{border-bottom-width:5px}.btn-primary .caret,.btn-warning .caret,.btn-danger .caret,.btn-info .caret,.btn-success .caret,.btn-inverse .caret{border-top-color:#fff;border-bottom-color:#fff}.btn-group-vertical{display:inline-block;*display:inline;*zoom:1}.btn-group-vertical>.btn{display:block;float:none;max-width:100%;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.btn-group-vertical>.btn+.btn{margin-top:-1px;margin-left:0}.btn-group-vertical>.btn:first-child{-webkit-border-radius:4px 4px 0 0;-moz-border-radius:4px 4px 0 0;border-radius:4px 4px 0 0}.btn-group-vertical>.btn:last-child{-webkit-border-radius:0 0 4px 4px;-moz-border-radius:0 0 4px 4px;border-radius:0 0 4px 4px}.btn-group-vertical>.btn-large:first-child{-webkit-border-radius:6px 6px 0 0;-moz-border-radius:6px 6px 0 0;border-radius:6px 6px 0 0}.btn-group-vertical>.btn-large:last-child{-webkit-border-radius:0 0 6px 6px;-moz-border-radius:0 0 6px 6px;border-radius:0 0 6px 6px}.alert{padding:8px 35px 8px 14px;margin-bottom:20px;text-shadow:0 1px 0 rgba(255,255,255,0.5);background-color:#fcf8e3;border:1px solid #fbeed5;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.alert,.alert h4{color:#c09853}.alert h4{margin:0}.alert .close{position:relative;top:-2px;right:-21px;line-height:20px}.alert-success{color:#468847;background-color:#dff0d8;border-color:#d6e9c6}.alert-success h4{color:#468847}.alert-danger,.alert-error{color:#b94a48;background-color:#f2dede;border-color:#eed3d7}.alert-danger h4,.alert-error h4{color:#b94a48}.alert-info{color:#3a87ad;background-color:#d9edf7;border-color:#bce8f1}.alert-info h4{color:#3a87ad}.alert-block{padding-top:14px;padding-bottom:14px}.alert-block>p,.alert-block>ul{margin-bottom:0}.alert-block p+p{margin-top:5px}.nav{margin-bottom:20px;margin-left:0;list-style:none}.nav>li>a{display:block}.nav>li>a:hover,.nav>li>a:focus{text-decoration:none;background-color:#eee}.nav>li>a>img{max-width:none}.nav>.pull-right{float:right}.nav-header{display:block;padding:3px 15px;font-size:11px;font-weight:bold;line-height:20px;color:#999;text-shadow:0 1px 0 rgba(255,255,255,0.5);text-transform:uppercase}.nav li+.nav-header{margin-top:9px}.nav-list{padding-right:15px;padding-left:15px;margin-bottom:0}.nav-list>li>a,.nav-list .nav-header{margin-right:-15px;margin-left:-15px;text-shadow:0 1px 0 rgba(255,255,255,0.5)}.nav-list>li>a{padding:3px 15px}.nav-list>.active>a,.nav-list>.active>a:hover,.nav-list>.active>a:focus{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.2);background-color:#08c}.nav-list [class^="icon-"],.nav-list [class*=" icon-"]{margin-right:2px}.nav-list .divider{*width:100%;height:1px;margin:9px 1px;*margin:-5px 0 5px;overflow:hidden;background-color:#e5e5e5;border-bottom:1px solid #fff}.nav-tabs,.nav-pills{*zoom:1}.nav-tabs:before,.nav-pills:before,.nav-tabs:after,.nav-pills:after{display:table;line-height:0;content:""}.nav-tabs:after,.nav-pills:after{clear:both}.nav-tabs>li,.nav-pills>li{float:left}.nav-tabs>li>a,.nav-pills>li>a{padding-right:12px;padding-left:12px;margin-right:2px;line-height:14px}.nav-tabs{border-bottom:1px solid #ddd}.nav-tabs>li{margin-bottom:-1px}.nav-tabs>li>a{padding-top:8px;padding-bottom:8px;line-height:20px;border:1px solid transparent;-webkit-border-radius:4px 4px 0 0;-moz-border-radius:4px 4px 0 0;border-radius:4px 4px 0 0}.nav-tabs>li>a:hover,.nav-tabs>li>a:focus{border-color:#eee #eee #ddd}.nav-tabs>.active>a,.nav-tabs>.active>a:hover,.nav-tabs>.active>a:focus{color:#555;cursor:default;background-color:#fff;border:1px solid #ddd;border-bottom-color:transparent}.nav-pills>li>a{padding-top:8px;padding-bottom:8px;margin-top:2px;margin-bottom:2px;-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px}.nav-pills>.active>a,.nav-pills>.active>a:hover,.nav-pills>.active>a:focus{color:#fff;background-color:#08c}.nav-stacked>li{float:none}.nav-stacked>li>a{margin-right:0}.nav-tabs.nav-stacked{border-bottom:0}.nav-tabs.nav-stacked>li>a{border:1px solid #ddd;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.nav-tabs.nav-stacked>li:first-child>a{-webkit-border-top-right-radius:4px;border-top-right-radius:4px;-webkit-border-top-left-radius:4px;border-top-left-radius:4px;-moz-border-radius-topright:4px;-moz-border-radius-topleft:4px}.nav-tabs.nav-stacked>li:last-child>a{-webkit-border-bottom-right-radius:4px;border-bottom-right-radius:4px;-webkit-border-bottom-left-radius:4px;border-bottom-left-radius:4px;-moz-border-radius-bottomright:4px;-moz-border-radius-bottomleft:4px}.nav-tabs.nav-stacked>li>a:hover,.nav-tabs.nav-stacked>li>a:focus{z-index:2;border-color:#ddd}.nav-pills.nav-stacked>li>a{margin-bottom:3px}.nav-pills.nav-stacked>li:last-child>a{margin-bottom:1px}.nav-tabs .dropdown-menu{-webkit-border-radius:0 0 6px 6px;-moz-border-radius:0 0 6px 6px;border-radius:0 0 6px 6px}.nav-pills .dropdown-menu{-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px}.nav .dropdown-toggle .caret{margin-top:6px;border-top-color:#08c;border-bottom-color:#08c}.nav .dropdown-toggle:hover .caret,.nav .dropdown-toggle:focus .caret{border-top-color:#005580;border-bottom-color:#005580}.nav-tabs .dropdown-toggle .caret{margin-top:8px}.nav .active .dropdown-toggle .caret{border-top-color:#fff;border-bottom-color:#fff}.nav-tabs .active .dropdown-toggle .caret{border-top-color:#555;border-bottom-color:#555}.nav>.dropdown.active>a:hover,.nav>.dropdown.active>a:focus{cursor:pointer}.nav-tabs .open .dropdown-toggle,.nav-pills .open .dropdown-toggle,.nav>li.dropdown.open.active>a:hover,.nav>li.dropdown.open.active>a:focus{color:#fff;background-color:#999;border-color:#999}.nav li.dropdown.open .caret,.nav li.dropdown.open.active .caret,.nav li.dropdown.open a:hover .caret,.nav li.dropdown.open a:focus .caret{border-top-color:#fff;border-bottom-color:#fff;opacity:1;filter:alpha(opacity=100)}.tabs-stacked .open>a:hover,.tabs-stacked .open>a:focus{border-color:#999}.tabbable{*zoom:1}.tabbable:before,.tabbable:after{display:table;line-height:0;content:""}.tabbable:after{clear:both}.tab-content{overflow:auto}.tabs-below>.nav-tabs,.tabs-right>.nav-tabs,.tabs-left>.nav-tabs{border-bottom:0}.tab-content>.tab-pane,.pill-content>.pill-pane{display:none}.tab-content>.active,.pill-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{-webkit-border-radius:0 0 4px 4px;-moz-border-radius:0 0 4px 4px;border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:hover,.tabs-below>.nav-tabs>li>a:focus{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:hover,.tabs-below>.nav-tabs>.active>a:focus{border-color:transparent #ddd #ddd #ddd}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{min-width:74px;margin-right:0;margin-bottom:3px}.tabs-left>.nav-tabs{float:left;margin-right:19px;border-right:1px solid #ddd}.tabs-left>.nav-tabs>li>a{margin-right:-1px;-webkit-border-radius:4px 0 0 4px;-moz-border-radius:4px 0 0 4px;border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:hover,.tabs-left>.nav-tabs>li>a:focus{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs .active>a,.tabs-left>.nav-tabs .active>a:hover,.tabs-left>.nav-tabs .active>a:focus{border-color:#ddd transparent #ddd #ddd;*border-right-color:#fff}.tabs-right>.nav-tabs{float:right;margin-left:19px;border-left:1px solid #ddd}.tabs-right>.nav-tabs>li>a{margin-left:-1px;-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:hover,.tabs-right>.nav-tabs>li>a:focus{border-color:#eee #eee #eee #ddd}.tabs-right>.nav-tabs .active>a,.tabs-right>.nav-tabs .active>a:hover,.tabs-right>.nav-tabs .active>a:focus{border-color:#ddd #ddd #ddd transparent;*border-left-color:#fff}.nav>.disabled>a{color:#999}.nav>.disabled>a:hover,.nav>.disabled>a:focus{text-decoration:none;cursor:default;background-color:transparent}.navbar{*position:relative;*z-index:2;margin-bottom:20px;overflow:visible}.navbar-inner{min-height:40px;padding-right:20px;padding-left:20px;background-color:#fafafa;background-image:-moz-linear-gradient(top,#fff,#f2f2f2);background-image:-webkit-gradient(linear,0 0,0 100%,from(#fff),to(#f2f2f2));background-image:-webkit-linear-gradient(top,#fff,#f2f2f2);background-image:-o-linear-gradient(top,#fff,#f2f2f2);background-image:linear-gradient(to bottom,#fff,#f2f2f2);background-repeat:repeat-x;border:1px solid #d4d4d4;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff',endColorstr='#fff2f2f2',GradientType=0);*zoom:1;-webkit-box-shadow:0 1px 4px rgba(0,0,0,0.065);-moz-box-shadow:0 1px 4px rgba(0,0,0,0.065);box-shadow:0 1px 4px rgba(0,0,0,0.065)}.navbar-inner:before,.navbar-inner:after{display:table;line-height:0;content:""}.navbar-inner:after{clear:both}.navbar .container{width:auto}.nav-collapse.collapse{height:auto;overflow:visible}.navbar .brand{display:block;float:left;padding:10px 20px 10px;margin-left:-20px;font-size:20px;font-weight:200;color:#777;text-shadow:0 1px 0 #fff}.navbar .brand:hover,.navbar .brand:focus{text-decoration:none}.navbar-text{margin-bottom:0;line-height:40px;color:#777}.navbar-link{color:#777}.navbar-link:hover,.navbar-link:focus{color:#333}.navbar .divider-vertical{height:40px;margin:0 9px;border-right:1px solid #fff;border-left:1px solid #f2f2f2}.navbar .btn,.navbar .btn-group{margin-top:5px}.navbar .btn-group .btn,.navbar .input-prepend .btn,.navbar .input-append .btn,.navbar .input-prepend .btn-group,.navbar .input-append .btn-group{margin-top:0}.navbar-form{margin-bottom:0;*zoom:1}.navbar-form:before,.navbar-form:after{display:table;line-height:0;content:""}.navbar-form:after{clear:both}.navbar-form input,.navbar-form select,.navbar-form .radio,.navbar-form .checkbox{margin-top:5px}.navbar-form input,.navbar-form select,.navbar-form .btn{display:inline-block;margin-bottom:0}.navbar-form input[type="image"],.navbar-form input[type="checkbox"],.navbar-form input[type="radio"]{margin-top:3px}.navbar-form .input-append,.navbar-form .input-prepend{margin-top:5px;white-space:nowrap}.navbar-form .input-append input,.navbar-form .input-prepend input{margin-top:0}.navbar-search{position:relative;float:left;margin-top:5px;margin-bottom:0}.navbar-search .search-query{padding:4px 14px;margin-bottom:0;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:13px;font-weight:normal;line-height:1;-webkit-border-radius:15px;-moz-border-radius:15px;border-radius:15px}.navbar-static-top{position:static;margin-bottom:0}.navbar-static-top .navbar-inner{-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.navbar-fixed-top,.navbar-fixed-bottom{position:fixed;right:0;left:0;z-index:1030;margin-bottom:0}.navbar-fixed-top .navbar-inner,.navbar-static-top .navbar-inner{border-width:0 0 1px}.navbar-fixed-bottom .navbar-inner{border-width:1px 0 0}.navbar-fixed-top .navbar-inner,.navbar-fixed-bottom .navbar-inner{padding-right:0;padding-left:0;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.navbar-static-top .container,.navbar-fixed-top .container,.navbar-fixed-bottom .container{width:940px}.navbar-fixed-top{top:0}.navbar-fixed-top .navbar-inner,.navbar-static-top .navbar-inner{-webkit-box-shadow:0 1px 10px rgba(0,0,0,0.1);-moz-box-shadow:0 1px 10px rgba(0,0,0,0.1);box-shadow:0 1px 10px rgba(0,0,0,0.1)}.navbar-fixed-bottom{bottom:0}.navbar-fixed-bottom .navbar-inner{-webkit-box-shadow:0 -1px 10px rgba(0,0,0,0.1);-moz-box-shadow:0 -1px 10px rgba(0,0,0,0.1);box-shadow:0 -1px 10px rgba(0,0,0,0.1)}.navbar .nav{position:relative;left:0;display:block;float:left;margin:0 10px 0 0}.navbar .nav.pull-right{float:right;margin-right:0}.navbar .nav>li{float:left}.navbar .nav>li>a{float:none;padding:10px 15px 10px;color:#777;text-decoration:none;text-shadow:0 1px 0 #fff}.navbar .nav .dropdown-toggle .caret{margin-top:8px}.navbar .nav>li>a:focus,.navbar .nav>li>a:hover{color:#333;text-decoration:none;background-color:transparent}.navbar .nav>.active>a,.navbar .nav>.active>a:hover,.navbar .nav>.active>a:focus{color:#555;text-decoration:none;background-color:#e5e5e5;-webkit-box-shadow:inset 0 3px 8px rgba(0,0,0,0.125);-moz-box-shadow:inset 0 3px 8px rgba(0,0,0,0.125);box-shadow:inset 0 3px 8px rgba(0,0,0,0.125)}.navbar .btn-navbar{display:none;float:right;padding:7px 10px;margin-right:5px;margin-left:5px;color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#ededed;*background-color:#e5e5e5;background-image:-moz-linear-gradient(top,#f2f2f2,#e5e5e5);background-image:-webkit-gradient(linear,0 0,0 100%,from(#f2f2f2),to(#e5e5e5));background-image:-webkit-linear-gradient(top,#f2f2f2,#e5e5e5);background-image:-o-linear-gradient(top,#f2f2f2,#e5e5e5);background-image:linear-gradient(to bottom,#f2f2f2,#e5e5e5);background-repeat:repeat-x;border-color:#e5e5e5 #e5e5e5 #bfbfbf;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2f2f2',endColorstr='#ffe5e5e5',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.075);-moz-box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.075);box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.075)}.navbar .btn-navbar:hover,.navbar .btn-navbar:focus,.navbar .btn-navbar:active,.navbar .btn-navbar.active,.navbar .btn-navbar.disabled,.navbar .btn-navbar[disabled]{color:#fff;background-color:#e5e5e5;*background-color:#d9d9d9}.navbar .btn-navbar:active,.navbar .btn-navbar.active{background-color:#ccc \9}.navbar .btn-navbar .icon-bar{display:block;width:18px;height:2px;background-color:#f5f5f5;-webkit-border-radius:1px;-moz-border-radius:1px;border-radius:1px;-webkit-box-shadow:0 1px 0 rgba(0,0,0,0.25);-moz-box-shadow:0 1px 0 rgba(0,0,0,0.25);box-shadow:0 1px 0 rgba(0,0,0,0.25)}.btn-navbar .icon-bar+.icon-bar{margin-top:3px}.navbar .nav>li>.dropdown-menu:before{position:absolute;top:-7px;left:9px;display:inline-block;border-right:7px solid transparent;border-bottom:7px solid #ccc;border-left:7px solid transparent;border-bottom-color:rgba(0,0,0,0.2);content:''}.navbar .nav>li>.dropdown-menu:after{position:absolute;top:-6px;left:10px;display:inline-block;border-right:6px solid transparent;border-bottom:6px solid #fff;border-left:6px solid transparent;content:''}.navbar-fixed-bottom .nav>li>.dropdown-menu:before{top:auto;bottom:-7px;border-top:7px solid #ccc;border-bottom:0;border-top-color:rgba(0,0,0,0.2)}.navbar-fixed-bottom .nav>li>.dropdown-menu:after{top:auto;bottom:-6px;border-top:6px solid #fff;border-bottom:0}.navbar .nav li.dropdown>a:hover .caret,.navbar .nav li.dropdown>a:focus .caret{border-top-color:#333;border-bottom-color:#333}.navbar .nav li.dropdown.open>.dropdown-toggle,.navbar .nav li.dropdown.active>.dropdown-toggle,.navbar .nav li.dropdown.open.active>.dropdown-toggle{color:#555;background-color:#e5e5e5}.navbar .nav li.dropdown>.dropdown-toggle .caret{border-top-color:#777;border-bottom-color:#777}.navbar .nav li.dropdown.open>.dropdown-toggle .caret,.navbar .nav li.dropdown.active>.dropdown-toggle .caret,.navbar .nav li.dropdown.open.active>.dropdown-toggle .caret{border-top-color:#555;border-bottom-color:#555}.navbar .pull-right>li>.dropdown-menu,.navbar .nav>li>.dropdown-menu.pull-right{right:0;left:auto}.navbar .pull-right>li>.dropdown-menu:before,.navbar .nav>li>.dropdown-menu.pull-right:before{right:12px;left:auto}.navbar .pull-right>li>.dropdown-menu:after,.navbar .nav>li>.dropdown-menu.pull-right:after{right:13px;left:auto}.navbar .pull-right>li>.dropdown-menu .dropdown-menu,.navbar .nav>li>.dropdown-menu.pull-right .dropdown-menu{right:100%;left:auto;margin-right:-1px;margin-left:0;-webkit-border-radius:6px 0 6px 6px;-moz-border-radius:6px 0 6px 6px;border-radius:6px 0 6px 6px}.navbar-inverse .navbar-inner{background-color:#1b1b1b;background-image:-moz-linear-gradient(top,#222,#111);background-image:-webkit-gradient(linear,0 0,0 100%,from(#222),to(#111));background-image:-webkit-linear-gradient(top,#222,#111);background-image:-o-linear-gradient(top,#222,#111);background-image:linear-gradient(to bottom,#222,#111);background-repeat:repeat-x;border-color:#252525;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff222222',endColorstr='#ff111111',GradientType=0)}.navbar-inverse .brand,.navbar-inverse .nav>li>a{color:#999;text-shadow:0 -1px 0 rgba(0,0,0,0.25)}.navbar-inverse .brand:hover,.navbar-inverse .nav>li>a:hover,.navbar-inverse .brand:focus,.navbar-inverse .nav>li>a:focus{color:#fff}.navbar-inverse .brand{color:#999}.navbar-inverse .navbar-text{color:#999}.navbar-inverse .nav>li>a:focus,.navbar-inverse .nav>li>a:hover{color:#fff;background-color:transparent}.navbar-inverse .nav .active>a,.navbar-inverse .nav .active>a:hover,.navbar-inverse .nav .active>a:focus{color:#fff;background-color:#111}.navbar-inverse .navbar-link{color:#999}.navbar-inverse .navbar-link:hover,.navbar-inverse .navbar-link:focus{color:#fff}.navbar-inverse .divider-vertical{border-right-color:#222;border-left-color:#111}.navbar-inverse .nav li.dropdown.open>.dropdown-toggle,.navbar-inverse .nav li.dropdown.active>.dropdown-toggle,.navbar-inverse .nav li.dropdown.open.active>.dropdown-toggle{color:#fff;background-color:#111}.navbar-inverse .nav li.dropdown>a:hover .caret,.navbar-inverse .nav li.dropdown>a:focus .caret{border-top-color:#fff;border-bottom-color:#fff}.navbar-inverse .nav li.dropdown>.dropdown-toggle .caret{border-top-color:#999;border-bottom-color:#999}.navbar-inverse .nav li.dropdown.open>.dropdown-toggle .caret,.navbar-inverse .nav li.dropdown.active>.dropdown-toggle .caret,.navbar-inverse .nav li.dropdown.open.active>.dropdown-toggle .caret{border-top-color:#fff;border-bottom-color:#fff}.navbar-inverse .navbar-search .search-query{color:#fff;background-color:#515151;border-color:#111;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,0.1),0 1px 0 rgba(255,255,255,0.15);-moz-box-shadow:inset 0 1px 2px rgba(0,0,0,0.1),0 1px 0 rgba(255,255,255,0.15);box-shadow:inset 0 1px 2px rgba(0,0,0,0.1),0 1px 0 rgba(255,255,255,0.15);-webkit-transition:none;-moz-transition:none;-o-transition:none;transition:none}.navbar-inverse .navbar-search .search-query:-moz-placeholder{color:#ccc}.navbar-inverse .navbar-search .search-query:-ms-input-placeholder{color:#ccc}.navbar-inverse .navbar-search .search-query::-webkit-input-placeholder{color:#ccc}.navbar-inverse .navbar-search .search-query:focus,.navbar-inverse .navbar-search .search-query.focused{padding:5px 15px;color:#333;text-shadow:0 1px 0 #fff;background-color:#fff;border:0;outline:0;-webkit-box-shadow:0 0 3px rgba(0,0,0,0.15);-moz-box-shadow:0 0 3px rgba(0,0,0,0.15);box-shadow:0 0 3px rgba(0,0,0,0.15)}.navbar-inverse .btn-navbar{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#0e0e0e;*background-color:#040404;background-image:-moz-linear-gradient(top,#151515,#040404);background-image:-webkit-gradient(linear,0 0,0 100%,from(#151515),to(#040404));background-image:-webkit-linear-gradient(top,#151515,#040404);background-image:-o-linear-gradient(top,#151515,#040404);background-image:linear-gradient(to bottom,#151515,#040404);background-repeat:repeat-x;border-color:#040404 #040404 #000;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff151515',endColorstr='#ff040404',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.navbar-inverse .btn-navbar:hover,.navbar-inverse .btn-navbar:focus,.navbar-inverse .btn-navbar:active,.navbar-inverse .btn-navbar.active,.navbar-inverse .btn-navbar.disabled,.navbar-inverse .btn-navbar[disabled]{color:#fff;background-color:#040404;*background-color:#000}.navbar-inverse .btn-navbar:active,.navbar-inverse .btn-navbar.active{background-color:#000 \9}.breadcrumb{padding:8px 15px;margin:0 0 20px;list-style:none;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.breadcrumb>li{display:inline-block;*display:inline;text-shadow:0 1px 0 #fff;*zoom:1}.breadcrumb>li>.divider{padding:0 5px;color:#ccc}.breadcrumb>.active{color:#999}.pagination{margin:20px 0}.pagination ul{display:inline-block;*display:inline;margin-bottom:0;margin-left:0;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;*zoom:1;-webkit-box-shadow:0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:0 1px 2px rgba(0,0,0,0.05);box-shadow:0 1px 2px rgba(0,0,0,0.05)}.pagination ul>li{display:inline}.pagination ul>li>a,.pagination ul>li>span{float:left;padding:4px 12px;line-height:20px;text-decoration:none;background-color:#fff;border:1px solid #ddd;border-left-width:0}.pagination ul>li>a:hover,.pagination ul>li>a:focus,.pagination ul>.active>a,.pagination ul>.active>span{background-color:#f5f5f5}.pagination ul>.active>a,.pagination ul>.active>span{color:#999;cursor:default}.pagination ul>.disabled>span,.pagination ul>.disabled>a,.pagination ul>.disabled>a:hover,.pagination ul>.disabled>a:focus{color:#999;cursor:default;background-color:transparent}.pagination ul>li:first-child>a,.pagination ul>li:first-child>span{border-left-width:1px;-webkit-border-bottom-left-radius:4px;border-bottom-left-radius:4px;-webkit-border-top-left-radius:4px;border-top-left-radius:4px;-moz-border-radius-bottomleft:4px;-moz-border-radius-topleft:4px}.pagination ul>li:last-child>a,.pagination ul>li:last-child>span{-webkit-border-top-right-radius:4px;border-top-right-radius:4px;-webkit-border-bottom-right-radius:4px;border-bottom-right-radius:4px;-moz-border-radius-topright:4px;-moz-border-radius-bottomright:4px}.pagination-centered{text-align:center}.pagination-right{text-align:right}.pagination-large ul>li>a,.pagination-large ul>li>span{padding:11px 19px;font-size:17.5px}.pagination-large ul>li:first-child>a,.pagination-large ul>li:first-child>span{-webkit-border-bottom-left-radius:6px;border-bottom-left-radius:6px;-webkit-border-top-left-radius:6px;border-top-left-radius:6px;-moz-border-radius-bottomleft:6px;-moz-border-radius-topleft:6px}.pagination-large ul>li:last-child>a,.pagination-large ul>li:last-child>span{-webkit-border-top-right-radius:6px;border-top-right-radius:6px;-webkit-border-bottom-right-radius:6px;border-bottom-right-radius:6px;-moz-border-radius-topright:6px;-moz-border-radius-bottomright:6px}.pagination-mini ul>li:first-child>a,.pagination-small ul>li:first-child>a,.pagination-mini ul>li:first-child>span,.pagination-small ul>li:first-child>span{-webkit-border-bottom-left-radius:3px;border-bottom-left-radius:3px;-webkit-border-top-left-radius:3px;border-top-left-radius:3px;-moz-border-radius-bottomleft:3px;-moz-border-radius-topleft:3px}.pagination-mini ul>li:last-child>a,.pagination-small ul>li:last-child>a,.pagination-mini ul>li:last-child>span,.pagination-small ul>li:last-child>span{-webkit-border-top-right-radius:3px;border-top-right-radius:3px;-webkit-border-bottom-right-radius:3px;border-bottom-right-radius:3px;-moz-border-radius-topright:3px;-moz-border-radius-bottomright:3px}.pagination-small ul>li>a,.pagination-small ul>li>span{padding:2px 10px;font-size:11.9px}.pagination-mini ul>li>a,.pagination-mini ul>li>span{padding:0 6px;font-size:10.5px}.pager{margin:20px 0;text-align:center;list-style:none;*zoom:1}.pager:before,.pager:after{display:table;line-height:0;content:""}.pager:after{clear:both}.pager li{display:inline}.pager li>a,.pager li>span{display:inline-block;padding:5px 14px;background-color:#fff;border:1px solid #ddd;-webkit-border-radius:15px;-moz-border-radius:15px;border-radius:15px}.pager li>a:hover,.pager li>a:focus{text-decoration:none;background-color:#f5f5f5}.pager .next>a,.pager .next>span{float:right}.pager .previous>a,.pager .previous>span{float:left}.pager .disabled>a,.pager .disabled>a:hover,.pager .disabled>a:focus,.pager .disabled>span{color:#999;cursor:default;background-color:#fff}.modal-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1040;background-color:#000}.modal-backdrop.fade{opacity:0}.modal-backdrop,.modal-backdrop.fade.in{opacity:.8;filter:alpha(opacity=80)}.modal{position:fixed;top:10%;left:50%;z-index:1050;width:560px;margin-left:-280px;background-color:#fff;border:1px solid #999;border:1px solid rgba(0,0,0,0.3);*border:1px solid #999;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;outline:0;-webkit-box-shadow:0 3px 7px rgba(0,0,0,0.3);-moz-box-shadow:0 3px 7px rgba(0,0,0,0.3);box-shadow:0 3px 7px rgba(0,0,0,0.3);-webkit-background-clip:padding-box;-moz-background-clip:padding-box;background-clip:padding-box}.modal.fade{top:-25%;-webkit-transition:opacity .3s linear,top .3s ease-out;-moz-transition:opacity .3s linear,top .3s ease-out;-o-transition:opacity .3s linear,top .3s ease-out;transition:opacity .3s linear,top .3s ease-out}.modal.fade.in{top:20%}.modal-header{padding:9px 15px;border-bottom:1px solid #eee}.modal-header .close{margin-top:2px}.modal-header h3{margin:0;line-height:30px}.modal-body{position:relative;max-height:400px;padding:15px;overflow-y:auto}.modal-form{margin-bottom:0}.modal-footer{padding:14px 15px 15px;margin-bottom:0;text-align:right;background-color:#f5f5f5;border-top:1px solid #ddd;-webkit-border-radius:0 0 6px 6px;-moz-border-radius:0 0 6px 6px;border-radius:0 0 6px 6px;*zoom:1;-webkit-box-shadow:inset 0 1px 0 #fff;-moz-box-shadow:inset 0 1px 0 #fff;box-shadow:inset 0 1px 0 #fff}.modal-footer:before,.modal-footer:after{display:table;line-height:0;content:""}.modal-footer:after{clear:both}.modal-footer .btn+.btn{margin-bottom:0;margin-left:5px}.modal-footer .btn-group .btn+.btn{margin-left:-1px}.modal-footer .btn-block+.btn-block{margin-left:0}.tooltip{position:absolute;z-index:1030;display:block;font-size:11px;line-height:1.4;opacity:0;filter:alpha(opacity=0);visibility:visible}.tooltip.in{opacity:.8;filter:alpha(opacity=80)}.tooltip.top{padding:5px 0;margin-top:-3px}.tooltip.right{padding:0 5px;margin-left:3px}.tooltip.bottom{padding:5px 0;margin-top:3px}.tooltip.left{padding:0 5px;margin-left:-3px}.tooltip-inner{max-width:200px;padding:8px;color:#fff;text-align:center;text-decoration:none;background-color:#000;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.tooltip-arrow{position:absolute;width:0;height:0;border-color:transparent;border-style:solid}.tooltip.top .tooltip-arrow{bottom:0;left:50%;margin-left:-5px;border-top-color:#000;border-width:5px 5px 0}.tooltip.right .tooltip-arrow{top:50%;left:0;margin-top:-5px;border-right-color:#000;border-width:5px 5px 5px 0}.tooltip.left .tooltip-arrow{top:50%;right:0;margin-top:-5px;border-left-color:#000;border-width:5px 0 5px 5px}.tooltip.bottom .tooltip-arrow{top:0;left:50%;margin-left:-5px;border-bottom-color:#000;border-width:0 5px 5px}.popover{position:absolute;top:0;left:0;z-index:1010;display:none;max-width:276px;padding:1px;text-align:left;white-space:normal;background-color:#fff;border:1px solid #ccc;border:1px solid rgba(0,0,0,0.2);-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0,0,0,0.2);-moz-box-shadow:0 5px 10px rgba(0,0,0,0.2);box-shadow:0 5px 10px rgba(0,0,0,0.2);-webkit-background-clip:padding-box;-moz-background-clip:padding;background-clip:padding-box}.popover.top{margin-top:-10px}.popover.right{margin-left:10px}.popover.bottom{margin-top:10px}.popover.left{margin-left:-10px}.popover-title{padding:8px 14px;margin:0;font-size:14px;font-weight:normal;line-height:18px;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;-webkit-border-radius:5px 5px 0 0;-moz-border-radius:5px 5px 0 0;border-radius:5px 5px 0 0}.popover-title:empty{display:none}.popover-content{padding:9px 14px}.popover .arrow,.popover .arrow:after{position:absolute;display:block;width:0;height:0;border-color:transparent;border-style:solid}.popover .arrow{border-width:11px}.popover .arrow:after{border-width:10px;content:""}.popover.top .arrow{bottom:-11px;left:50%;margin-left:-11px;border-top-color:#999;border-top-color:rgba(0,0,0,0.25);border-bottom-width:0}.popover.top .arrow:after{bottom:1px;margin-left:-10px;border-top-color:#fff;border-bottom-width:0}.popover.right .arrow{top:50%;left:-11px;margin-top:-11px;border-right-color:#999;border-right-color:rgba(0,0,0,0.25);border-left-width:0}.popover.right .arrow:after{bottom:-10px;left:1px;border-right-color:#fff;border-left-width:0}.popover.bottom .arrow{top:-11px;left:50%;margin-left:-11px;border-bottom-color:#999;border-bottom-color:rgba(0,0,0,0.25);border-top-width:0}.popover.bottom .arrow:after{top:1px;margin-left:-10px;border-bottom-color:#fff;border-top-width:0}.popover.left .arrow{top:50%;right:-11px;margin-top:-11px;border-left-color:#999;border-left-color:rgba(0,0,0,0.25);border-right-width:0}.popover.left .arrow:after{right:1px;bottom:-10px;border-left-color:#fff;border-right-width:0}.thumbnails{margin-left:-20px;list-style:none;*zoom:1}.thumbnails:before,.thumbnails:after{display:table;line-height:0;content:""}.thumbnails:after{clear:both}.row-fluid .thumbnails{margin-left:0}.thumbnails>li{float:left;margin-bottom:20px;margin-left:20px}.thumbnail{display:block;padding:4px;line-height:20px;border:1px solid #ddd;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;-webkit-box-shadow:0 1px 3px rgba(0,0,0,0.055);-moz-box-shadow:0 1px 3px rgba(0,0,0,0.055);box-shadow:0 1px 3px rgba(0,0,0,0.055);-webkit-transition:all .2s ease-in-out;-moz-transition:all .2s ease-in-out;-o-transition:all .2s ease-in-out;transition:all .2s ease-in-out}a.thumbnail:hover,a.thumbnail:focus{border-color:#08c;-webkit-box-shadow:0 1px 4px rgba(0,105,214,0.25);-moz-box-shadow:0 1px 4px rgba(0,105,214,0.25);box-shadow:0 1px 4px rgba(0,105,214,0.25)}.thumbnail>img{display:block;max-width:100%;margin-right:auto;margin-left:auto}.thumbnail .caption{padding:9px;color:#555}.media,.media-body{overflow:hidden;*overflow:visible;zoom:1}.media,.media .media{margin-top:15px}.media:first-child{margin-top:0}.media-object{display:block}.media-heading{margin:0 0 5px}.media>.pull-left{margin-right:10px}.media>.pull-right{margin-left:10px}.media-list{margin-left:0;list-style:none}.label,.badge{display:inline-block;padding:2px 4px;font-size:11.844px;font-weight:bold;line-height:14px;color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);white-space:nowrap;vertical-align:baseline;background-color:#999}.label{-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.badge{padding-right:9px;padding-left:9px;-webkit-border-radius:9px;-moz-border-radius:9px;border-radius:9px}.label:empty,.badge:empty{display:none}a.label:hover,a.label:focus,a.badge:hover,a.badge:focus{color:#fff;text-decoration:none;cursor:pointer}.label-important,.badge-important{background-color:#b94a48}.label-important[href],.badge-important[href]{background-color:#953b39}.label-warning,.badge-warning{background-color:#f89406}.label-warning[href],.badge-warning[href]{background-color:#c67605}.label-success,.badge-success{background-color:#468847}.label-success[href],.badge-success[href]{background-color:#356635}.label-info,.badge-info{background-color:#3a87ad}.label-info[href],.badge-info[href]{background-color:#2d6987}.label-inverse,.badge-inverse{background-color:#333}.label-inverse[href],.badge-inverse[href]{background-color:#1a1a1a}.btn .label,.btn .badge{position:relative;top:-1px}.btn-mini .label,.btn-mini .badge{top:0}@-webkit-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@-moz-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@-ms-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@-o-keyframes progress-bar-stripes{from{background-position:0 0}to{background-position:40px 0}}@keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}.progress{height:20px;margin-bottom:20px;overflow:hidden;background-color:#f7f7f7;background-image:-moz-linear-gradient(top,#f5f5f5,#f9f9f9);background-image:-webkit-gradient(linear,0 0,0 100%,from(#f5f5f5),to(#f9f9f9));background-image:-webkit-linear-gradient(top,#f5f5f5,#f9f9f9);background-image:-o-linear-gradient(top,#f5f5f5,#f9f9f9);background-image:linear-gradient(to bottom,#f5f5f5,#f9f9f9);background-repeat:repeat-x;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5',endColorstr='#fff9f9f9',GradientType=0);-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,0.1);-moz-box-shadow:inset 0 1px 2px rgba(0,0,0,0.1);box-shadow:inset 0 1px 2px rgba(0,0,0,0.1)}.progress .bar{float:left;width:0;height:100%;font-size:12px;color:#fff;text-align:center;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#0e90d2;background-image:-moz-linear-gradient(top,#149bdf,#0480be);background-image:-webkit-gradient(linear,0 0,0 100%,from(#149bdf),to(#0480be));background-image:-webkit-linear-gradient(top,#149bdf,#0480be);background-image:-o-linear-gradient(top,#149bdf,#0480be);background-image:linear-gradient(to bottom,#149bdf,#0480be);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff149bdf',endColorstr='#ff0480be',GradientType=0);-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,0.15);-moz-box-shadow:inset 0 -1px 0 rgba(0,0,0,0.15);box-shadow:inset 0 -1px 0 rgba(0,0,0,0.15);-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;-webkit-transition:width .6s ease;-moz-transition:width .6s ease;-o-transition:width .6s ease;transition:width .6s ease}.progress .bar+.bar{-webkit-box-shadow:inset 1px 0 0 rgba(0,0,0,0.15),inset 0 -1px 0 rgba(0,0,0,0.15);-moz-box-shadow:inset 1px 0 0 rgba(0,0,0,0.15),inset 0 -1px 0 rgba(0,0,0,0.15);box-shadow:inset 1px 0 0 rgba(0,0,0,0.15),inset 0 -1px 0 rgba(0,0,0,0.15)}.progress-striped .bar{background-color:#149bdf;background-image:-webkit-gradient(linear,0 100%,100% 0,color-stop(0.25,rgba(255,255,255,0.15)),color-stop(0.25,transparent),color-stop(0.5,transparent),color-stop(0.5,rgba(255,255,255,0.15)),color-stop(0.75,rgba(255,255,255,0.15)),color-stop(0.75,transparent),to(transparent));background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-moz-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);-webkit-background-size:40px 40px;-moz-background-size:40px 40px;-o-background-size:40px 40px;background-size:40px 40px}.progress.active .bar{-webkit-animation:progress-bar-stripes 2s linear infinite;-moz-animation:progress-bar-stripes 2s linear infinite;-ms-animation:progress-bar-stripes 2s linear infinite;-o-animation:progress-bar-stripes 2s linear infinite;animation:progress-bar-stripes 2s linear infinite}.progress-danger .bar,.progress .bar-danger{background-color:#dd514c;background-image:-moz-linear-gradient(top,#ee5f5b,#c43c35);background-image:-webkit-gradient(linear,0 0,0 100%,from(#ee5f5b),to(#c43c35));background-image:-webkit-linear-gradient(top,#ee5f5b,#c43c35);background-image:-o-linear-gradient(top,#ee5f5b,#c43c35);background-image:linear-gradient(to bottom,#ee5f5b,#c43c35);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffee5f5b',endColorstr='#ffc43c35',GradientType=0)}.progress-danger.progress-striped .bar,.progress-striped .bar-danger{background-color:#ee5f5b;background-image:-webkit-gradient(linear,0 100%,100% 0,color-stop(0.25,rgba(255,255,255,0.15)),color-stop(0.25,transparent),color-stop(0.5,transparent),color-stop(0.5,rgba(255,255,255,0.15)),color-stop(0.75,rgba(255,255,255,0.15)),color-stop(0.75,transparent),to(transparent));background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-moz-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent)}.progress-success .bar,.progress .bar-success{background-color:#5eb95e;background-image:-moz-linear-gradient(top,#62c462,#57a957);background-image:-webkit-gradient(linear,0 0,0 100%,from(#62c462),to(#57a957));background-image:-webkit-linear-gradient(top,#62c462,#57a957);background-image:-o-linear-gradient(top,#62c462,#57a957);background-image:linear-gradient(to bottom,#62c462,#57a957);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff62c462',endColorstr='#ff57a957',GradientType=0)}.progress-success.progress-striped .bar,.progress-striped .bar-success{background-color:#62c462;background-image:-webkit-gradient(linear,0 100%,100% 0,color-stop(0.25,rgba(255,255,255,0.15)),color-stop(0.25,transparent),color-stop(0.5,transparent),color-stop(0.5,rgba(255,255,255,0.15)),color-stop(0.75,rgba(255,255,255,0.15)),color-stop(0.75,transparent),to(transparent));background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-moz-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent)}.progress-info .bar,.progress .bar-info{background-color:#4bb1cf;background-image:-moz-linear-gradient(top,#5bc0de,#339bb9);background-image:-webkit-gradient(linear,0 0,0 100%,from(#5bc0de),to(#339bb9));background-image:-webkit-linear-gradient(top,#5bc0de,#339bb9);background-image:-o-linear-gradient(top,#5bc0de,#339bb9);background-image:linear-gradient(to bottom,#5bc0de,#339bb9);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de',endColorstr='#ff339bb9',GradientType=0)}.progress-info.progress-striped .bar,.progress-striped .bar-info{background-color:#5bc0de;background-image:-webkit-gradient(linear,0 100%,100% 0,color-stop(0.25,rgba(255,255,255,0.15)),color-stop(0.25,transparent),color-stop(0.5,transparent),color-stop(0.5,rgba(255,255,255,0.15)),color-stop(0.75,rgba(255,255,255,0.15)),color-stop(0.75,transparent),to(transparent));background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-moz-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent)}.progress-warning .bar,.progress .bar-warning{background-color:#faa732;background-image:-moz-linear-gradient(top,#fbb450,#f89406);background-image:-webkit-gradient(linear,0 0,0 100%,from(#fbb450),to(#f89406));background-image:-webkit-linear-gradient(top,#fbb450,#f89406);background-image:-o-linear-gradient(top,#fbb450,#f89406);background-image:linear-gradient(to bottom,#fbb450,#f89406);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffbb450',endColorstr='#fff89406',GradientType=0)}.progress-warning.progress-striped .bar,.progress-striped .bar-warning{background-color:#fbb450;background-image:-webkit-gradient(linear,0 100%,100% 0,color-stop(0.25,rgba(255,255,255,0.15)),color-stop(0.25,transparent),color-stop(0.5,transparent),color-stop(0.5,rgba(255,255,255,0.15)),color-stop(0.75,rgba(255,255,255,0.15)),color-stop(0.75,transparent),to(transparent));background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-moz-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent)}.accordion{margin-bottom:20px}.accordion-group{margin-bottom:2px;border:1px solid #e5e5e5;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.accordion-heading{border-bottom:0}.accordion-heading .accordion-toggle{display:block;padding:8px 15px}.accordion-toggle{cursor:pointer}.accordion-inner{padding:9px 15px;border-top:1px solid #e5e5e5}.carousel{position:relative;margin-bottom:20px;line-height:1}.carousel-inner{position:relative;width:100%;overflow:hidden}.carousel-inner>.item{position:relative;display:none;-webkit-transition:.6s ease-in-out left;-moz-transition:.6s ease-in-out left;-o-transition:.6s ease-in-out left;transition:.6s ease-in-out left}.carousel-inner>.item>img,.carousel-inner>.item>a>img{display:block;line-height:1}.carousel-inner>.active,.carousel-inner>.next,.carousel-inner>.prev{display:block}.carousel-inner>.active{left:0}.carousel-inner>.next,.carousel-inner>.prev{position:absolute;top:0;width:100%}.carousel-inner>.next{left:100%}.carousel-inner>.prev{left:-100%}.carousel-inner>.next.left,.carousel-inner>.prev.right{left:0}.carousel-inner>.active.left{left:-100%}.carousel-inner>.active.right{left:100%}.carousel-control{position:absolute;top:40%;left:15px;width:40px;height:40px;margin-top:-20px;font-size:60px;font-weight:100;line-height:30px;color:#fff;text-align:center;background:#222;border:3px solid #fff;-webkit-border-radius:23px;-moz-border-radius:23px;border-radius:23px;opacity:.5;filter:alpha(opacity=50)}.carousel-control.right{right:15px;left:auto}.carousel-control:hover,.carousel-control:focus{color:#fff;text-decoration:none;opacity:.9;filter:alpha(opacity=90)}.carousel-indicators{position:absolute;top:15px;right:15px;z-index:5;margin:0;list-style:none}.carousel-indicators li{display:block;float:left;width:10px;height:10px;margin-left:5px;text-indent:-999px;background-color:#ccc;background-color:rgba(255,255,255,0.25);border-radius:5px}.carousel-indicators .active{background-color:#fff}.carousel-caption{position:absolute;right:0;bottom:0;left:0;padding:15px;background:#333;background:rgba(0,0,0,0.75)}.carousel-caption h4,.carousel-caption p{line-height:20px;color:#fff}.carousel-caption h4{margin:0 0 5px}.carousel-caption p{margin-bottom:0}.hero-unit{padding:60px;margin-bottom:30px;font-size:18px;font-weight:200;line-height:30px;color:inherit;background-color:#eee;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px}.hero-unit h1{margin-bottom:0;font-size:60px;line-height:1;letter-spacing:-1px;color:inherit}.hero-unit li{line-height:30px}.pull-right{float:right}.pull-left{float:left}.hide{display:none}.show{display:block}.invisible{visibility:hidden}.affix{position:fixed}article,aside,details,figcaption,figure,footer,header,hgroup,nav,section{display:block}audio,canvas,video{display:inline-block;*display:inline;*zoom:1}audio:not([controls]){display:none}[hidden]{display:none}html{font-size:100%;overflow-y:scroll;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}body{margin:0;font-size:13px;line-height:1.231}body,button,input,select,textarea{font-family:sans-serif;color:#222}::-moz-selection{background:#7c85d8;color:#fff;text-shadow:none}::selection{background:#7c85d8;color:#fff;text-shadow:none}a{color:#08e}a:visited{color:#08e}a:hover{color:#04e}a:focus{outline:thin dotted}a:hover,a:active{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:bold}blockquote{margin:1em 40px}dfn{font-style:italic}hr{display:block;height:1px;border:0;border-top:1px solid #ccc;margin:1em 0;padding:0}ins{background:#ff9;color:#000;text-decoration:none}mark{background:#ff0;color:#000;font-style:italic;font-weight:bold}pre,code,kbd,samp{font-family:monospace,monospace;_font-family:'courier new',monospace;font-size:1em}pre{white-space:pre;white-space:pre-wrap;word-wrap:break-word}q{quotes:none}q:before,q:after{content:"";content:none}small{font-size:85%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-0.5em}sub{bottom:-0.25em}ul,ol{margin:0;padding:0 0 0 20px}dd{margin:0 0 0 40px}nav ul,nav ol{list-style:none;list-style-image:none;margin:0;padding:2px 0 0}img{border:0;-ms-interpolation-mode:bicubic;vertical-align:middle}svg:not(:root){overflow:hidden}figure{margin:0}form{margin:0}fieldset{border:0;margin:0;padding:0}label{cursor:pointer}legend{border:0;*margin-left:-7px;padding:0}button,input,select,textarea{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle}button,input{line-height:normal;*overflow:visible}table button,table input{*overflow:auto}button,input[type="button"],input[type="reset"],input[type="submit"]{cursor:pointer;-webkit-appearance:button}input[type="checkbox"],input[type="radio"]{box-sizing:border-box}input[type="search"]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}input[type="search"]::-webkit-search-decoration{-webkit-appearance:none}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}textarea{overflow:auto;vertical-align:top;resize:none}input:invalid,textarea:invalid{background-color:#f0dddd}table{border-collapse:collapse;border-spacing:0}td{vertical-align:top}.ir{display:block;border:0;text-indent:-999em;overflow:hidden;background-color:transparent;background-repeat:no-repeat;text-align:left;direction:ltr}.ir br{display:none}.hidden{display:none!important;visibility:hidden}.visuallyhidden{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.visuallyhidden.focusable:active,.visuallyhidden.focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}.invisible{visibility:hidden}.clearfix:before,.clearfix:after{content:"";display:table}.clearfix:after{clear:both}.clearfix{zoom:1}@media print{*{background:transparent!important;color:black!important;text-shadow:none!important;filter:none!important;-ms-filter:none!important}a,a:visited{text-decoration:underline}a[href]:after{content:" (" attr(href) ")"}abbr[title]:after{content:" (" attr(title) ")"}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100%!important}@page{margin:.5cm}p,h2,h3{orphans:3;widows:3}h2,h3{page-break-after:avoid}}.ui-resizable{position:relative}.ui-resizable-handle{position:absolute;font-size:.1px;z-index:99999;display:block}.ui-resizable-disabled .ui-resizable-handle,.ui-resizable-autohide .ui-resizable-handle{display:none}.ui-resizable-n{cursor:n-resize;height:7px;width:100%;top:-5px;left:0}.ui-resizable-s{cursor:s-resize;height:7px;width:100%;bottom:-5px;left:0}.ui-resizable-e{cursor:e-resize;cursor:col-resize;width:5px;right:-2px;top:0;height:100%}.ui-resizable-w{cursor:w-resize;width:7px;left:-5px;top:0;height:100%}.ui-resizable-se{cursor:se-resize;width:12px;height:12px;right:1px;bottom:1px}.ui-resizable-sw{cursor:sw-resize;width:9px;height:9px;left:-5px;bottom:-5px}.ui-resizable-nw{cursor:nw-resize;width:9px;height:9px;left:-5px;top:-5px}.ui-resizable-ne{cursor:ne-resize;width:9px;height:9px;right:-5px;top:-5px}.ui-button{display:inline-block;position:relative;padding:0;margin:0;text-decoration:none!important;cursor:pointer;text-align:center;zoom:1;overflow:hidden;color:#2a2a2a;background:#d8d8d8 url(../images/buttons/ui-button.png) repeat-x left top;border:1px solid #a8a8a8;border-bottom-color:#9e9e9e;font-size:12px;height:24px;-moz-box-shadow:0 1px 0 rgba(0,0,0,0.05);-webkit-box-shadow:0 1px 0 rgba(0,0,0,0.05);box-shadow:0 1px 0 rgba(0,0,0,0.05);-moz-border-radius:2px;-webkit-border-radius:2px;border-radius:2px}input.ui-button{border-color:#888}.ie7 .ui-button{overflow:visible}a.ui-button,span.ui-button{height:22px;line-height:22px;color:#2a2a2a}input.ui-button,.ui-button .ui-button-text{line-height:23px;color:#2a2a2a;text-shadow:0 1px 1px #f2f2f2;padding:0 10px}.ui-button-text-only .ui-button-text{padding:0 20px}button.ui-button::-moz-focus-inner{border:0;padding:0}.ie7 input.ui-button,.ie7 button.ui-button .ui-button-text{line-height:20px}.ie9 .ui-button .ui-button-text{line-height:24px}.ui-button:focus{outline:0 none}.ui-button:focus,.ui-button:hover,.ui-state-focus,.ui-state-hover{background-position:left -40px}.ui-custom-active,.ui-custom-active:focus,.ui-custom-active:hover,.ui-state-active,.ui-state-active:focus,.ui-state-active:hover,.ui-button:active{background-position:left -120px;border-color:#909090}.ui-button[disabled],.ui-button[disabled]:hover,.ui-button.default[disabled],.ui-custom-active[disabled],.ui-button[disabled]:active{background-position:left top;border-color:#999;cursor:default;-moz-box-shadow:0 1px 0 rgba(0,0,0,0.05);-webkit-box-shadow:0 1px 0 rgba(0,0,0,0.05);box-shadow:0 1px 0 rgba(0,0,0,0.05)}input.ui-button[disabled],input.ui-button[disabled]:hover{border-color:#ccc;color:#999;text-shadow:0 0 transparent}.ui-button.transparent[disabled]:hover{background:none!important;border-color:transparent!important;-moz-box-shadow:0 0 transparent!important;-webkit-box-shadow:0 0 transparent!important;box-shadow:0 0 transparent!important}.ui-button[disabled] .ui-button-text,.ui-button[disabled]:hover .ui-button-text,.ui-custom-active[disabled] .ui-button-text,.ui-button[disabled]:active .ui-button-text{color:#777;text-shadow:0 1px 1px #ddd}.ui-button.default{border-color:#2e52bc;-moz-box-shadow:0 0 3px #2e52bc,0 0 2px #2e52bc;-webkit-box-shadow:0 0 3px #2e52bc,0 0 2px #2e52bc;box-shadow:0 0 3px #2e52bc,0 0 2px #2e52bc}.ui-button-medium,a.ui-button-medium,span.ui-button-medium{height:30px;background-image:url(../images/buttons/ui-button-medium.png)}a.ui-button-medium,span.ui-button-medium{height:28px;line-height:28px}.ui-button-medium .ui-button-text{line-height:28px}.ie7 button.ui-button.ui-button-medium .ui-button-text{line-height:26px}.ie9 .ui-button-medium .ui-button-text{line-height:28px}.ui-button-medium-blue,a.ui-button-medium-blue,span.ui-button-medium-blue{font-weight:bold;font-size:14px;border-color:#2e6dc5;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;-moz-box-shadow:0 1px 0 rgba(0,0,0,0.15);-webkit-box-shadow:0 1px 0 rgba(0,0,0,0.15);box-shadow:0 1px 0 rgba(0,0,0,0.15)}.ui-button-medium-blue:active,.ui-button-medium-blue.ui-custom-active{border-color:#1e5be6}.cssgradients .ui-button-medium-blue{background:-webkit-gradient(linear,left top,left bottom,from(#699bdc),to(#3464b1));background:-moz-linear-gradient(#699bdc,#3464b1);background:-webkit-linear-gradient(#699bdc,#3464b1)}.cssgradients .ui-button-medium-blue:hover,.cssgradients .ui-button-medium-blue:focus{background:-webkit-gradient(linear,left top,left bottom,from(#7ca9e8),to(#4575c1));background:-moz-linear-gradient(#7ca9e8,#4575c1);background:-webkit-linear-gradient(#7ca9e8,#4575c1)}.cssgradients .ui-button-medium-blue:active,.cssgradients .ui-button-medium-blue.ui-custom-active{background:-webkit-gradient(linear,left top,left bottom,from(#5e8bca),to(#2757a3));background:-moz-linear-gradient(#5e8bca,#2757a3);background:-webkit-linear-gradient(#5e8bca,#2757a3)}.no-cssgradients .ui-button-medium-blue{background-color:#5b88c8;background-image:url(../images/buttons/btn_blue_28.png)}.no-cssgradients .ui-button-medium-blue:focus,.no-cssgradients .ui-button-medium-blue:hover{background-position:0 -30px}.no-cssgradients .ui-button-medium-blue:active{background-position:0 -60px}.ui-button-medium-blue .ui-button-text{line-height:26px;color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.60);font-size:14px;letter-spacing:-0.01em;padding:0}.ui-button-small,span.ui-button-small{height:16px;line-height:15px;background-image:url(../images/buttons/ui-button-small.png)}.ui-button-icon-only .ui-button-text{height:16px;display:block}span.ui-button-thin{height:21px;line-height:22px}.ui-button-thin .ui-button-text{line-height:20px}.ui-button-small.ui-button-icon-only{width:16px}.ui-button.transparent{min-width:0;background-image:none;background-color:transparent;border-color:transparent;-moz-box-shadow:0 0 transparent;-webkit-box-shadow:0 0 transparent;box-shadow:0 0 transparent}.ui-button.transparent:focus,.ui-button.transparent:hover,.ui-button.transparent:active,.ui-custom-active.transparent{background-color:#d8d8d8;background-image:url(../images/buttons/ui-button.png);-moz-box-shadow:0 1px 0 rgba(0,0,0,0.05);-webkit-box-shadow:0 1px 0 rgba(0,0,0,0.05);box-shadow:0 1px 0 rgba(0,0,0,0.05)}.ui-button-medium.ui-button.transparent:focus,.ui-button-medium.ui-button.transparent:hover,.ui-button-medium.ui-button.transparent:active,.ui-button-medium.ui-custom-active.transparent{background-image:url(../images/buttons/ui-button-medium.png);-moz-box-shadow:0 1px 0 rgba(0,0,0,0.05);-webkit-box-shadow:0 1px 0 rgba(0,0,0,0.05);box-shadow:0 1px 0 rgba(0,0,0,0.05)}.ui-button-small.ui-button.transparent:focus,.ui-button-small.ui-button.transparent:hover,.ui-button-small.ui-button.transparent:active,.ui-button-small.ui-custom-active.transparent{background-image:url(../images/buttons/ui-button-small.png);-moz-box-shadow:0 1px 0 rgba(0,0,0,0.05);-webkit-box-shadow:0 1px 0 rgba(0,0,0,0.05);box-shadow:0 1px 0 rgba(0,0,0,0.05)}.ui-button-small.ui-button.transparent:active,.ui-button-small.ui-custom-active.transparent{background-color:#a7a7a7;outline:0 none}.ui-button.transparent:focus,.ui-button.transparent:hover{border-color:#a8a8a8;border-bottom-color:#9e9e9e;-moz-box-shadow:0 1px 0 rgba(0,0,0,0.05);-webkit-box-shadow:0 1px 0 rgba(0,0,0,0.05);box-shadow:0 1px 0 rgba(0,0,0,0.05)}.ui-button.transparent:active,.ui-state-active.transparent,.ui-state-active.transparent:focus,.ui-state-active.transparent:hover,.ui-custom-active.transparent,.ui-custom-active.transparent:focus,.ui-custom-active.transparent:hover{border-color:#909090;-moz-box-shadow:0 1px 0 rgba(0,0,0,0.05);-webkit-box-shadow:0 1px 0 rgba(0,0,0,0.05);box-shadow:0 1px 0 rgba(0,0,0,0.05)}.ui-button.transparent .ui-button-text{padding:0 10px}.ui-button.ui-plain-button:focus,.ui-button.ui-plain-button:hover{border-color:#e0e0e0;border-top-color:#e7e7e7;border-bottom-color:#ddd;background:#e7e7e7;background:-webkit-gradient(linear,left top,left bottom,from(#e7e7e7),to(#ddd));background:-moz-linear-gradient(#e7e7e7,#ddd);background:-webkit-linear-gradient(#e7e7e7,#ddd);-moz-box-shadow:0 0 transparent;-webkit-box-shadow:0 0 transparent;box-shadow:0 0 transparent}.ui-button.ui-plain-button:active,.ui-custom-active.ui-plain-button:focus,.ui-custom-active.ui-plain-button:hover,.ui-custom-active.ui-plain-button{border-color:#b2b2b2;border-top-color:#b7b7b7;border-bottom-color:#a8a8a8;background:#b7b7b7;background:-webkit-gradient(linear,left top,left bottom,from(#b7b7b7),to(#a8a8a8));background:-moz-linear-gradient(#b7b7b7,#a8a8a8);background:-webkit-linear-gradient(#b7b7b7,#a8a8a8);-moz-box-shadow:0 0 transparent;-webkit-box-shadow:0 0 transparent;box-shadow:0 0 transparent}.ui-button.selected,.ui-button.selected:focus,.ui-button.selected:active,.ui-button.selected:hover,.ui-state-focus.selected,.ui-state-hover.selected{background-image:url(../images/buttons/ui-button.png);background-position:left -80px;border-color:#404e69;background-color:#536587}.ui-icon{display:block;text-indent:-99999px;overflow:hidden;background-repeat:no-repeat;width:16px;height:16px}.ui-button-medium .ui-icon{width:24px;height:24px;margin-left:4px}.ui-button-icon-only .ui-icon,.ui-button-text-icon-primary .ui-icon,.ui-button-text-icon-secondary .ui-icon,.ui-button-text-icons .ui-icon,.ui-button-icons-only .ui-icon,.ui-button .spinner{position:absolute;top:50%;margin-top:-8px}.ui-button-icon-only .ui-icon{left:50%;margin-left:-8px}.ui-button-text-icon-primary .ui-button-icon-primary,.ui-button-icons-only .ui-button-icon-primary{position:static;margin-top:0;float:left}.ui-button-text-icon-secondary .ui-button-icon-secondary,.ui-button-text-icons .ui-button-icon-secondary,.ui-button-icons-only .ui-button-icon-secondary{right:.5em}.ui-button-text-icons .ui-button-icon-secondary,.ui-button-icons-only .ui-button-icon-secondary{right:.5em}.ui-button-icons-only .ui-icon{margin-left:0!important}.ui-icon-menu{background-image:url(../images/buttons/btn_popup_sort.png);background-position:right 7px}.ui-icon-add{background-image:url("../images/icons/ico_add.png");background-position:center center}.ui-icon-addressbook{background-image:url("../images/buttons/addressBook.png");background-position:left center}.ui-icon-addressbook:hover{background-position:-22px center}.ui-icon-grid-view{background-image:url("../images/icons/ico_view_modes.png");margin-top:-7px!important}.selected .ui-icon-grid-view{background-position:0 -25px}.ui-icon-list-view{background-image:url("../images/icons/ico_view_modes.png");background-position:-24px 0;margin-top:-7px!important}.selected .ui-icon-list-view{background-position:-23px -25px}.ui-icon-upload{background-image:url(../images/buttons/upload.png);margin-left:4px;margin-right:-4px;height:17px!important;margin-top:3px!important}.ui-icon-new-folder{background-image:url(../images/buttons/new_folder.png);background-position:left bottom;margin-left:3px;margin-right:-3px;margin-top:3px!important;height:18px!important;width:18px!important}.ui-icon-back{background-image:url('../images/buttons/back_button.png');background-position:8px 0;margin-top:2px!important}.ui-icon-empty-trash{background-image:url(../images/buttons/empty_trash.png);height:18px!important;width:18px;margin-left:5px;margin-top:3px!important}.ui-icon-drop-down{background-image:url(../images/buttons/btn_drop_down.png);background-position:50% 6px}.ui-icon-up-button{background-image:url(../images/icons/ico_up_button.png);background-position:2px 1px}.ui-icon-comment{background-image:url("../images/icons/ico_comment.png");background-position:center center}.ie7 .ui-icon-comment,.ie9 .ui-icon-comment{margin-top:-7px!important}.ie8 .ui-icon-comment{margin-top:-9px!important}.ui-icon-comment+.ui-button-text{height:19px}.ui-icon-actions{background-image:url("../images/buttons/btn_file_actions.png");background-position:-20px 0;width:16px!important;height:17px!important;left:4px}.ui-icon-categories{background-image:url("../images/buttons/btn_file_actions.png");background-position:-40px 0;width:18px!important;height:18px!important;left:3px;margin-top:-8px!important}.ui-icon-comments{background-image:url("../images/buttons/btn_file_actions.png");background-position:-100px -41px;width:18px;margin-left:3px;margin-top:4px!important}.ui-icon-actions-big{background-image:url("../images/buttons/btn_file_actions.png");background-position:-20px 0;width:16px!important;height:17px!important;left:4px!important;top:3px!important;position:relative!important}.ui-icon-categories-big{background-image:url("../images/buttons/btn_file_actions.png");background-position:-40px 0;width:18px!important;height:18px!important;left:3px!important;top:3px!important;position:relative!important}.ui-button.ui-button-text-icon-primary .ui-button-text{padding-left:5px;vertical-align:middle}.ui-button-medium.ui-button.ui-button-text-icon-primary .ui-button-text{padding-left:4px;line-height:28px}.ui-button.ui-button-text-icon-secondary .ui-button-text{padding-right:16px}.ui-button.with_spinner{padding-left:6px}.ui-button .spinner{margin-top:-11px}.ui-icon-wrench{background:url('../images/buttons/wrench.png') no-repeat 0 0;left:4px!important}.ui-menu{display:block;float:left;list-style:none outside none;margin:0;padding:0}.ui-autocomplete{border:1px solid #666;border-top:0 none;background-color:white}.ui-menu .ui-menu-item{clear:left;float:left;margin:0;padding:0;width:100%;overflow:hidden}.ui-autocomplete .ui-menu-item a{display:block;padding:5px;cursor:pointer}.ui-autocomplete .ui-menu-item a:focus,.ui-autocomplete .ui-menu-item a:hover,.ui-autocomplete .ui-menu-item a.ui-state-hover{color:#222;background-position:top left}.ui-autocomplete .ui-menu-item a.ui-state-hover{background:#f2f2f2}#fancybox-loading{position:fixed;top:50%;left:50%;width:40px;height:40px;margin-top:-20px;margin-left:-20px;cursor:pointer;overflow:hidden;z-index:1104;display:none}#fancybox-loading div{position:absolute;top:0;left:0;width:40px;height:480px;background-image:url('../images/layout/fancybox/fancybox.png')}#fancybox-overlay{position:absolute;top:0;left:0;width:100%;z-index:1100;display:none}#fancybox-tmp{padding:0;margin:0;border:0;overflow:auto;display:none}#fancybox-wrap{position:absolute;top:0;left:0;padding:20px;z-index:1101;outline:0;display:none}#fancybox-outer{position:relative;width:100%;height:100%;background:#fff}#fancybox-content{width:0;height:0;padding:0;outline:0;position:relative;overflow:hidden;z-index:1102;border:0 solid #fff}#fancybox-hide-sel-frame{position:absolute;top:0;left:0;width:100%;height:100%;background:transparent;z-index:1101}#fancybox-close{position:absolute;top:-15px;right:-15px;width:30px;height:30px;background:transparent url('../images/layout/fancybox/fancybox.png') -40px 0;cursor:pointer;z-index:1103;display:none}#fancybox-error{color:#444;font:normal 12px/20px Arial;padding:14px;margin:0}#fancybox-img{width:100%;height:100%;padding:0;margin:0;border:0;outline:0;line-height:0;vertical-align:top}#fancybox-frame{width:100%;height:100%;border:0;display:block}#fancybox-left,#fancybox-right{position:absolute;bottom:0;height:100%;width:35%;cursor:pointer;outline:0;background:transparent url('../images/layout/fancybox/blank.gif');z-index:1102;display:none}#fancybox-left{left:0}#fancybox-right{right:0}#fancybox-left-ico,#fancybox-right-ico{position:absolute;top:50%;left:-9999px;width:30px;height:30px;margin-top:-15px;cursor:pointer;z-index:1102;display:block}#fancybox-left-ico{background-image:url('../images/layout/fancybox/fancybox.png');background-position:-40px -30px}#fancybox-right-ico{background-image:url('../images/layout/fancybox/fancybox.png');background-position:-40px -60px}#fancybox-left:hover,#fancybox-right:hover{visibility:visible}#fancybox-left:hover span{left:20px}#fancybox-right:hover span{left:auto;right:20px}.fancybox-bg{position:absolute;padding:0;margin:0;border:0;width:20px;height:20px;z-index:1001}#fancybox-bg-n{top:-20px;left:0;width:100%;background-image:url('../images/layout/fancybox/fancybox-x.png')}#fancybox-bg-ne{top:-20px;right:-20px;background-image:url('../images/layout/fancybox/fancybox.png');background-position:-40px -162px}#fancybox-bg-e{top:0;right:-20px;height:100%;background-image:url('../images/layout/fancybox/fancybox-y.png');background-position:-20px 0}#fancybox-bg-se{bottom:-20px;right:-20px;background-image:url('../images/layout/fancybox/fancybox.png');background-position:-40px -182px}#fancybox-bg-s{bottom:-20px;left:0;width:100%;background-image:url('../images/layout/fancybox/fancybox-x.png');background-position:0 -20px}#fancybox-bg-sw{bottom:-20px;left:-20px;background-image:url('../images/layout/fancybox/fancybox.png');background-position:-40px -142px}#fancybox-bg-w{top:0;left:-20px;height:100%;background-image:url('../images/layout/fancybox/fancybox-y.png')}#fancybox-bg-nw{top:-20px;left:-20px;background-image:url('../images/layout/fancybox/fancybox.png');background-position:-40px -122px}#fancybox-title{font-family:Helvetica;font-size:12px;z-index:1102}.fancybox-title-inside{padding-bottom:10px;text-align:center;color:#333;background:#fff;position:relative}.fancybox-title-outside{padding-top:10px;color:#fff}.fancybox-title-over{position:absolute;bottom:0;left:0;color:#FFF;text-align:left}#fancybox-title-over{padding:10px;background-image:url('../images/layout/fancybox/fancy_title_over.png');display:block}.fancybox-title-float{position:absolute;left:0;bottom:-20px;height:32px}#fancybox-title-float-wrap{border:0;border-collapse:collapse;width:auto}#fancybox-title-float-wrap td{border:0;white-space:nowrap}#fancybox-title-float-left{padding:0 0 0 15px;background:url('../images/layout/fancybox/fancybox.png') -40px -90px no-repeat}#fancybox-title-float-main{color:#FFF;line-height:29px;font-weight:bold;padding:0 0 3px 0;background:url('../images/layout/fancybox/fancybox-x.png') 0 -40px}#fancybox-title-float-right{padding:0 0 0 15px;background:url('../images/layout/fancybox/fancybox.png') -55px -90px no-repeat}.fancybox-ie6 #fancybox-close{background:transparent;filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='../images/layout/fancybox/fancy_close.png',sizingMethod='scale')}.fancybox-ie6 #fancybox-left-ico{background:transparent;filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='../images/layout/fancybox/fancy_nav_left.png',sizingMethod='scale')}.fancybox-ie6 #fancybox-right-ico{background:transparent;filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='../images/layout/fancybox/fancy_nav_right.png',sizingMethod='scale')}.fancybox-ie6 #fancybox-title-over{background:transparent;filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='../images/layout/fancybox/fancy_title_over.png',sizingMethod='scale');zoom:1}.fancybox-ie6 #fancybox-title-float-left{background:transparent;filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='../images/layout/fancybox/fancy_title_left.png',sizingMethod='scale')}.fancybox-ie6 #fancybox-title-float-main{background:transparent;filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='../images/layout/fancybox/fancy_title_main.png',sizingMethod='scale')}.fancybox-ie6 #fancybox-title-float-right{background:transparent;filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='../images/layout/fancybox/fancy_title_right.png',sizingMethod='scale')}.fancybox-ie6 #fancybox-bg-w,.fancybox-ie6 #fancybox-bg-e,.fancybox-ie6 #fancybox-left,.fancybox-ie6 #fancybox-right,#fancybox-hide-sel-frame{height:expression(this.parentNode.clientHeight+"px")}#fancybox-loading.fancybox-ie6{position:absolute;margin-top:0;top:expression((-20+(document.documentElement.clientHeight ? document.documentElement.clientHeight/2:document.body.clientHeight/2)+(ignoreMe = document.documentElement.scrollTop ? document.documentElement.scrollTop:document.body.scrollTop))+'px')}#fancybox-loading.fancybox-ie6 div{background:transparent;filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='../images/layout/fancybox/fancy_loading.png',sizingMethod='scale')}.fancybox-ie .fancybox-bg{background:transparent!important}.fancybox-ie #fancybox-bg-n{filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='../images/layout/fancybox/fancy_shadow_n.png',sizingMethod='scale')}.fancybox-ie #fancybox-bg-ne{filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='../images/layout/fancybox/fancy_shadow_ne.png',sizingMethod='scale')}.fancybox-ie #fancybox-bg-e{filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='../images/layout/fancybox/fancy_shadow_e.png',sizingMethod='scale')}.fancybox-ie #fancybox-bg-se{filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='../images/layout/fancybox/fancy_shadow_se.png',sizingMethod='scale')}.fancybox-ie #fancybox-bg-s{filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='../images/layout/fancybox/fancy_shadow_s.png',sizingMethod='scale')}.fancybox-ie #fancybox-bg-sw{filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='../images/layout/fancybox/fancy_shadow_sw.png',sizingMethod='scale')}.fancybox-ie #fancybox-bg-w{filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='../images/layout/fancybox/fancy_shadow_w.png',sizingMethod='scale')}.fancybox-ie #fancybox-bg-nw{filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='../images/layout/fancybox/fancy_shadow_nw.png',sizingMethod='scale')}.jcarousel-skin-tango .jcarousel-container{background:#FFF;border:1px solid #cecece;-moz-border-radius:0 0 4px 4px;-webkit-border-radius:0 0 4px 4px;border-radius:0 0 4px 4px}.jcarousel-skin-tango .jcarousel-item.jcarousel-item-horizontal.jcarousel-item-selected{border:solid 2px #09c}.jcarousel-skin-tango .jcarousel-container-horizontal{padding:15px 23px 15px 22px}.jcarousel-skin-tango .jcarousel-clip{overflow:hidden}.jcarousel-skin-tango .jcarousel-clip-horizontal{height:90px;width:843px}.jcarousel-skin-tango .jcarousel-item{width:93px;height:70px}.jcarousel-skin-tango .jcarousel-item-horizontal{margin:0 10px;padding:3px;border:solid 1px #ccc;background:#fafafa}.jcarousel-skin-tango .jcarousel-item-horizontal:hover,.jcarousel-skin-tango .jcarousel-item-horizontal:focus{padding:2px;border:solid 2px #bfbfbf}.jcarousel-skin-tango .jcarousel-direction-rtl .jcarousel-item-horizontal{margin-left:10px;margin-right:0}.jcarousel-skin-tango .jcarousel-item-vertical{margin-bottom:10px}.jcarousel-skin-tango .jcarousel-item-placeholder{background:#fff;color:#000}.jcarousel-skin-tango .jcarousel-next-horizontal{position:absolute;top:32px;right:5px;width:12px;height:16px;cursor:pointer;background:transparent url(../images/icons/carousel/icon_slideshow_triangle.png) no-repeat 0 -60px}.jcarousel-skin-tango .jcarousel-next-horizontal:hover,.jcarousel-skin-tango .jcarousel-next-horizontal:focus,.jcarousel-skin-tango .jcarousel-next-horizontal:active{background-position:0 -100px}.jcarousel-skin-tango .jcarousel-next-disabled-horizontal,.jcarousel-skin-tango .jcarousel-next-disabled-horizontal:hover,.jcarousel-skin-tango .jcarousel-next-disabled-horizontal:focus,.jcarousel-skin-tango .jcarousel-next-disabled-horizontal:active{cursor:default;background:0}.jcarousel-skin-tango .jcarousel-prev-horizontal{position:absolute;top:32px;left:5px;width:12px;height:16px;cursor:pointer;background:transparent url(../images/icons/carousel/icon_slideshow_triangle.png) no-repeat 0 0}.jcarousel-skin-tango .jcarousel-prev-horizontal:hover,.jcarousel-skin-tango .jcarousel-prev-horizontal:focus,.jcarousel-skin-tango .jcarousel-prev-horizontal:active{background-position:0 -40px}.jcarousel-skin-tango .jcarousel-prev-disabled-horizontal,.jcarousel-skin-tango .jcarousel-prev-disabled-horizontal:hover,.jcarousel-skin-tango .jcarousel-prev-disabled-horizontal:focus,.jcarousel-skin-tango .jcarousel-prev-disabled-horizontal:active{cursor:default;background:0}.about_contents div,.about_contents span,.about_contents object,.about_contents p,.about_contents strong,.about_contents ul,.about_contents li,.about_contents label,.about_contents header,.about_contents section{background:none repeat scroll 0 0 transparent;border:0 none;font-size:100%;margin:0;outline:0 none;padding:0;vertical-align:baseline}.about_contents{width:500px}.about_contents header{background-color:#000;height:28px;border-radius:6px 6px 0 0;border-bottom:1px solid #333;color:#fff;font-size:13px;font-weight:bold;padding:10px 0 0 10px}.about_contents .about_banner{background:url("../images/layout/Exchangebanner.png") no-repeat scroll 0 0 transparent;height:74px}.about_contents .about_banner p{font-size:16px;color:#fff;text-shadow:0 2px 2px rgba(0,0,0,0.65);width:344px;padding-top:18px;padding-left:30px}.about_contents .about_content{height:212px;overflow-y:scroll;overflow-x:hidden;background-color:#eee;font-size:9px;color:#2a2a2a}.about_contents .margin_top{height:20px;left:0;position:absolute;right:0;top:113px;width:483px;background-color:#eee}.about_contents .margin_bottom{bottom:0;height:15px;left:0;position:absolute;right:0;width:483px;border-bottom:20px solid #eee;background:-webkit-gradient(linear,left top,left bottom,from(rgba(238,238,238,0)),to(rgba(238,238,238,1)));background:-webkit-linear-gradient(rgba(238,238,238,0),rgba(238,238,238,1));background:-moz-linear-gradient(rgba(238,238,238,0),rgba(238,238,238,1));background:-ms-linear-gradient(rgba(238,238,238,0),rgba(238,238,238,1))}.no-cssgradients .about_contents .margin_bottom{background:url("../images/layout/about_box_gradient_fade.png") repeat-x 0 0 transparent}.about_contents div.about_terms{margin-left:15px;margin-right:20px;padding-top:20px}.about_contents .about_terms p{margin-bottom:15px}.about_contents .about_terms p a{color:#06e}.about_contents .about_wrapper{padding-bottom:30px}.no_border{border:0!important;border-radius:6px 6px 0 0!important}.dropdown,.dropdown div,.dropdown li,.dropdown div::after{-webkit-transition:all 150ms ease-in-out;-moz-transition:all 150ms ease-in-out;-ms-transition:all 150ms ease-in-out;transition:all 150ms ease-in-out}.dropdown .selected::after,.dropdown.scrollable div::after{-webkit-pointer-events:none;-moz-pointer-events:none;-ms-pointer-events:none;pointer-events:none}.dropdown{position:relative;width:200px;border:1px solid #ccc;cursor:pointer;background:#fff;border-radius:3px;-webkit-user-select:none;-moz-user-select:none;user-select:none}.dropdown.open{z-index:2}.dropdown:hover{box-shadow:0 0 5px rgba(82,168,236,0.8);border:solid 1px #52a8ec}.dropdown.focus{box-shadow:0 0 5px rgba(51,102,248,.4)}.dropdown .carat{position:absolute;right:12px;top:50%;margin-top:-4px;border:6px solid transparent;border-top:8px solid #000}.dropdown.open .carat{margin-top:-10px;border-top:6px solid transparent;border-bottom:8px solid #000}.dropdown.disabled .carat{border-top-color:#999}.dropdown .old{position:absolute;left:0;top:0;height:0;width:0;overflow:hidden}.dropdown select{position:absolute;left:0;top:0}.dropdown.touch .old{width:100%;height:100%}.dropdown.touch select{width:100%;height:100%;opacity:0}.dropdown .selected,.dropdown li{display:block;font-size:12px;line-height:1;color:#000;padding:9px 12px;overflow:hidden;white-space:nowrap}.dropdown.disabled .selected{color:#999}.dropdown .selected::after{content:'';position:absolute;right:0;top:0;bottom:0;width:60px;border-radius:0 2px 2px 0;box-shadow:inset -55px 0 25px -20px #fff}.dropdown div{position:absolute;height:0;left:-1px;right:-1px;top:100%;margin-top:-1px;background:#fff;border:1px solid #ccc;border-top:1px solid #eee;border-radius:0 0 3px 3px;overflow:hidden;opacity:0}.dropdown.open div{opacity:1;z-index:2}.dropdown.scrollable div::after{content:'';position:absolute;left:0;right:0;bottom:0;height:50px;box-shadow:inset 0 -50px 30px -35px #fff}.dropdown.scrollable.bottom div::after{opacity:0}.dropdown ul{position:absolute;left:0;top:0;height:100%;width:100%;list-style:none;overflow:hidden}.dropdown.scrollable.open ul{overflow-y:auto}.dropdown li{list-style:none;padding:8px 12px}.dropdown li.focus{background:#d24a67;position:relative;z-index:3;color:#fff}.dropdown li.active{font-weight:700}.bootstrap-tagsinput{display:inline-block;padding-right:6px;color:#555;vertical-align:middle;border-radius:4px;max-width:200px;line-height:22px;position:relative;top:-1px}.bootstrap-tagsinput input{display:none;border:0;box-shadow:none;background-color:transparent;padding:0;margin:0;width:auto!important;max-width:inherit}.bootstrap-tagsinput input:focus{border:0;box-shadow:none}.bootstrap-tagsinput .tag{margin-right:2px;color:#666;padding:5px 5px 5px 5px;font-size:12px;background:white;text-shadow:none;font-weight:lighter}.bootstrap-tagsinput .tag [data-role="remove"]{margin-left:2px;cursor:pointer;font-size:15px;color:#aaa;position:relative;top:0}.bootstrap-tagsinput .tag [data-role="remove"]:after{content:"| x";padding:0 2px}.bootstrap-tagsinput .tag [data-role="remove"]:hover{box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05)}.bootstrap-tagsinput .tag [data-role="remove"]:hover:active{box-shadow:inset 0 3px 5px rgba(0,0,0,0.125)}.search-page span{font-family:Arial;color:#666}.search-page a{font-size:12px;color:#29abe2}.overview-title{min-width:1220px}.search-page .overview-title{border-bottom:1px solid #CCC;font-size:16px;height:36px;left:0;padding:10px 0 6px 0;-moz-box-align:initial;-moz-box-pack:initial;-ms-flex-align:start;-webkit-box-pack:initial;-webkit-box-align:baseline;-ms-flex-pack:inherit}.overview-title>div>a{font-size:16px;font-weight:bold;color:#666}.overview-title div:first-child{padding-top:7px;margin-left:30px}.overview-title .emphasized{font-weight:bold;color:#333}.overview-title .view-selection input{display:none}.overview-title .view-selection input+label{padding:0}.overview-title .view-selection input:checked+label{background:#DDD;border-radius:5px}.search-page .list-display-options{height:50px;left:0;-moz-box-align:initial;-ms-flex-align:start;position:relative}.widget-element-app-search-list-view.widget-hoverable{width:auto;height:auto}.widget-element-app-search-list-view{padding:15px 10px;border:1px solid #e3e3e3;width:initial}.widget-element-app-search-list-view:nth-child(2n){margin-left:-5px}.widget-element-app-search-list-view:nth-child(n+2){margin-top:-5px}.list-display-options .list-display-option-left{left:0;margin-top:18px;position:absolute}.list-display-option-left span{color:#29abe2}.list-header-fancy .list-display-options .list-display-option-left{margin-top:0}.list-display-options .list-display-option-right{position:absolute;right:0;margin-top:10px;display:block;align-items:baseline;width:auto;min-width:400px;text-align:right}.list-display-option-right span{color:#29abe2}.list-display-option-right .dropdown{width:50px;height:24px;float:right;margin-left:4px;text-align:left;border:1px solid #b3b3b3;border-radius:3px}.list-display-option-right .dropdown .selected{padding:6px}.list-display-option-right .dropdown .selected::after{box-shadow:none}.list-display-options input{width:16px;margin-bottom:0;height:16px;border:1px solid #b3b3b3}.list-display-options select{width:70px}.list-display-options span{font-size:12px}.filter-catalog-container{width:200px;margin-right:5px}a.filter-catalog-show-more{color:#808080}.filter-catalog-seperator{height:1px;background:#AAA}.filter-catalog span{width:120px;flex-shrink:0;-webkit-flex-shrink:0;-ms-flex:0 0 auto;font-size:12px;padding-right:5px}.filter-title label{height:24px;width:16px;padding:0;border:0}.filter-catalog label[class="radio"]{margin-right:25px}.filter-catalog .radio{position:relative;bottom:1px;font-size:12px;display:inline-block}.filter-catalog input{position:absolute;left:0;top:-1px}.filter-catalog .filter-catalog-item label{font-size:12px}.filter-catalog .filter-title{margin-top:20px;margin-bottom:5px}.filter-catalog .filter-title span{font-size:14px;color:#29abe2}.filter-catalog .filter-catalog-item{line-height:20px;position:relative;padding-left:20px;margin-bottom:5px;color:#808080;font-size:12px}.filter-catalog-container .filter-tag-input{margin-top:10px}.filter-catalog-container .bootstrap-tagsinput .tag{margin-top:5px;margin-right:5px;background:#29abe2;color:white;white-space:normal}.bootstrap-tagsinput .tag [data-role="remove"]{color:white}.bootstrap-tagsinput .tag [data-role="remove"]:after{content:"x"}#clear-all-tags{margin-top:6px;display:inline-block}.view-selection{float:right;margin-right:3px}.view-selection input{width:0;height:0;visibility:collapse}.view-selection .btn{padding:0;height:24px;width:24px;border:0}.search-page span.message-with-link{color:#29abe2}.show_all{cursor:pointer;color:#369} html,body{background-color:#f8f8f8}.bold{font-weight:bold}.float-left{float:left}.float-right{float:right}.busy{cursor:progress}.hidden{display:none}body a{cursor:pointer}body a:focus{outline:0}.min-size{min-width:975px}.clear{clear:both;display:block;overflow:hidden;visibility:hidden;width:0;height:0}.highlight-text{color:#29abe2!important}.display-table{display:table!important}.display-table .row{display:table-row!important}.display-table .cell{display:table-cell!important}.text-center-align-container{text-align:center}.text-right-align-container{text-align:right}.vertical-top-align-container>*{vertical-align:top}.vertical-middle-align-container>*{vertical-align:middle}.vertical-bottom-align-container>*{vertical-align:bottom}.inline-container>*{display:inline-block}.inline{display:inline}.inline-block{display:inline-block}.block{display:block!important}.message-with-link,.message-with-link a{font-size:12px;color:#29abe2}.message-with-link a{font-weight:normal;text-decoration:underline!important}.thin-border{border:solid 1px #CCC}.color-blue1{color:#29abe2}a.flat-button:visited,.flat-button{color:white;width:auto;text-align:center;font-size:14px;border-radius:6px;border:0;padding:4px 20px;margin:1px;-webkit-transition:opacity .8s;-moz-transition:opacity .8s;-o-transition:opacity .8s;transition:opacity .8s;display:inline-block}.flat-button-slim{font-size:12px;line-height:14px}.flat-button[disabled]{opacity:.5}.flat-button[disabled]:hover{cursor:not-allowed;opacity:.5}.flat-button:hover{color:white;cursor:pointer;opacity:.8;-webkit-transition:opacity .2s;-moz-transition:opacity .2s;-o-transition:opacity .2s;transition:opacity .2s}.flat-button:active{opacity:1}.flat-button.flat-button-normal{background:#29abe2}.flat-button.app-os-lang-btn{background:#dcdcdc}.flat-button.flat-button-emphasis{background:#0071bc}.flat-button.flat-button-radio{min-width:100px}.flat-button.flat-button-radio input[type=radio]{display:none;border-radius:0}.flat-button.flat-button-radio input:checked+span{background:#29abe2;color:white;border-color:transparent}.flat-button.flat-button-radio input+span{background:#f2f2f2;display:inline-block;color:black;min-width:100px;padding:7px 15px;border:1px #ccc solid;width:100%}.flat-button.flat-button-group{width:100%;background:#e6e6e6;color:black;border-radius:0;border:1px #b8b8b8 solid;margin:5px 5px;padding:5px 3px}.flat-button.flat-button-group-active{background:#29abe2;color:white;border-radius:0;border-style:none}.flat-button.flat-button-positive{background:#77bb68}.flat-button.flat-button-negative{color:#29abe2;background:white;border:1px #29abe2 solid}.flat-button.flat-button-warning{background:#fcb237}.table{color:#595959;font-size:12px}.table .color-bar-left{border-left:5px solid #e6e6e6}.color-bar-right{display:inline-block;width:5px!important;padding:0!important;height:20px;right:30px;position:relative}.table th,.table td{padding:5px 10px;border:0;vertical-align:middle;text-align:center}.table.left-align th,.table.left-align td{text-align:left}.table td:first-child~td{border-left:solid 1px #e6e6e6}.table th{background:#e6e6e6}.table th .order-arrow{float:right;color:#4d4d4d;display:block}.table th .order-arrow.up:after{content:"▴"}.table th .order-arrow.down:after{content:"▾"}.table tr{border-bottom:solid 1px #29abe2;background:white}.table .show-all:hover~div{visibility:visible}.table .show-all-container{border:solid 1px #29abe2;background:white;position:absolute;padding:5px 10px;visibility:hidden}.table .show-all-container ul{padding:0;margin:0}.table .show-all-container ul li{padding:3px}.table .show-all-container i{display:block;background:url(../images/icons/dialog-arrow.png) no-repeat;width:15px;height:6px;position:absolute;top:-6px;left:23px}a{text-decoration:none!important}h1,h2,h3,h4,h5,h6{font-weight:bold;font-size:100%;margin:0;padding:0;line-height:normal}ul,ol,li,dl,dd,dt{list-style:none}li{line-height:normal}.nomarginpadding{margin:0;padding:0}.detail-main .description ul,.developer-submit-product ul,.helpdoc-page ul,.detail-main .description ol,.developer-submit-product ol,.helpdoc-page ol{padding-left:17px}.detail-main .description ul li,.developer-submit-product ul li,.helpdoc-page ul li{list-style:disc}.detail-main .description ol li,.developer-submit-product ol li,.helpdoc-page ol li{list-style:decimal}.details-main .seller{float:left}body,button,input,select,textarea{font-family:Arial,Verdana,Sans-Serif}.overlay_text{color:#999;line-height:18px;font-weight:normal!important;position:absolute;cursor:text!important;text-shadow:none!important}.spinner{width:16px;height:16px;background:url(../images/icons/spinner_16.png) no-repeat left top}.spinned{display:none!important}.spinner_container{padding-left:20px;line-height:24px;position:relative;cursor:wait;white-space:nowrap;display:inline-block}.spinner_container .spinner{position:absolute;top:4px;left:0}.popup_menu.flat_menu .spinner_container{padding-left:25px;padding-right:3px}.popup_menu.flat_menu .spinner_container .spinner{left:5px}.local_spinner{padding-left:31px}.local_spinner .spinner{left:9px}.line-separator{height:1px;width:100%;background:#CCC;margin:6px 0 6px 0}.sub-title{font-size:12px;color:black;display:inline-block}#flash_message{z-index:11203;position:fixed;left:50%;padding:11px 30px 9px 50px;color:#fff;font-size:14px;cursor:default;text-shadow:0 1px 0 #000;text-shadow:0 1px 0 rgba(0,0,0,0.85);border:1px solid #75a3ff;border-color:rgba(117,163,255,0.7);background-color:#1e3559;background:-webkit-gradient(linear,left top,left bottom,from(#1e3559),to(#172944));background:-webkit-linear-gradient(#1e3559,#172944);background:-moz-linear-gradient(#1e3559,#172944);-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px}#flash_message img,#flash_message .spinner{position:absolute;left:26px;top:13px}#flash_message #off_button_div{width:24px;height:24px;position:absolute;right:5px;top:8px;background-image:url(../images/buttons/close_24.png);cursor:pointer}#flash_message.success{background:#1e3559 url(../images/icons/flash_success.png) no-repeat 26px 13px;background:url(../images/icons/flash_success.png) no-repeat 26px 13px,-webkit-gradient(linear,left top,left bottom,from(#1e3559),to(#172944));background:url(../images/icons/flash_success.png) no-repeat 26px 13px,-webkit-linear-gradient(#1e3559,#172944);background:url(../images/icons/flash_success.png) no-repeat 26px 13px,-moz-linear-gradient(#1e3559,#172944)}#flash_message.error{background:#1e3559 url(../images/icons/error_16.png) no-repeat 26px 13px;background:url(../images/icons/error_16.png) no-repeat 26px 13px,-webkit-gradient(linear,left top,left bottom,from(#1e3559),to(#172944));background:url(../images/icons/error_16.png) no-repeat 26px 13px,-webkit-linear-gradient(#1e3559,#172944);background:url(../images/icons/error_16.png) no-repeat 26px 13px,-moz-linear-gradient(#1e3559,#172944)}.header-icon{width:18px!important;height:23px!important;margin:0 10px 0 5px!important;position:relative;top:-4px}.icon-my-downloads{background:url('../images/icons/mydownloads_idle.png') no-repeat!important}li.disabled .icon-my-downloads{background:url('../images/icons/mydownloads_disabled.png')!important}li:hover .icon-my-downloads{background:url('../images/icons/mydownloads_hover.png') no-repeat!important}.icon-my-uploads{background:url('../images/icons/myuploads_idle.png') no-repeat!important}li.disabled .icon-my-uploads{background:url('../images/icons/myuploads_disabled.png') no-repeat!important}li:hover .icon-my-uploads{background:url('../images/icons/myuploads_hover.png') no-repeat!important}.main-middle-content{width:1280px;margin-left:auto;margin-right:auto;margin-top:15px;display:flex;padding-bottom:15px}.left-mainmiddlecontent{width:190px;margin-right:15px;float:left}.navigation-content .navigation-header,.filter-catalog-container .filter-catalog-title{border:1px solid #d3d3d3;min-height:30px;text-align:center;line-height:30px;background:#e6e6e6;font-size:18px;color:#4d4d4d}.navigation-content .navigation-a{position:relative;margin:0;padding:0}.dropdown-menu-store,.navigation-content .navigation-a .popover{min-width:190px}.navigation-content li{text-align:left;min-height:25px;line-height:24px;color:#808080}.first-a{margin-left:35px}.sub-a{margin-left:5px}.second-a{margin-left:5px}.navigation-content .navigation-a-li{border-bottom:1px solid #838383;position:relative}.navigation-content li:hover{background:#29abe2;color:White}.navigation-content li a{font-size:12px;color:inherit}.navigation-content .btn-group .dropdown-toggle{width:189px}.apps-wrapper{margin:0 auto}.right-mainmiddlecontent{min-height:500px;width:1050px;padding-left:14px;float:left;border-left:1px solid #b3b3b3}.apps-content .apps-section .show-all{float:right;font-size:13px;text-decoration:none}.apps-section h2{margin-bottom:10px;margin-top:10px;color:#777;line-height:40px;font-size:24px;font-family:Arial}.apps-content .apps-carousel{width:1051px;padding:10px 0}.apps-content .apps-carousel h2{margin-bottom:12px}.apps-content .apps-carousel-box{float:left}.short-carousel-wrapper .apps-carousel-box{width:525px}.long-carousel-wrapper .apps-carousel-box{width:100%}.apps-carousel .apps-carousel-box .carousel .carousel-item-ul{margin:0;padding:0}.short-carousel-wrapper .apps-carousel-box-not-first h2{margin-left:10px}.widget-title{height:40px;overflow:hidden;text-overflow:ellipsis}ul.apps-list .s-price-cont{float:left!important;height:18px}ul.apps-list .s-price-cont>span.price,ul.apps-list .s-price-cont .sr-subscriberonly{color:#29abe2!important;font-size:12px!important}ul.apps-list .badge-hover-stub div{text-align:left}ul.apps-list li{background-color:rgba(255,255,255,0.7);cursor:pointer}ul.apps-list li:hover,#result-list .widget-element-app-layout:hover{-moz-box-shadow:0 0 5px rgba(170,170,170,0.4);-webkit-box-shadow:0 0 5px rgba(170,170,170,0.4);-ms-box-shadow:0 0 5px rgba(170,170,170,0.4);box-shadow:0 0 5px rgba(170,170,170,0.4);background-color:rgba(255,255,255,1)}ul.apps-list li img,ul.apps-list li .product-data-container{float:left}ul.apps-list li .product-data-container{padding-left:10px;width:90px}ul.apps li.small-widget-element .product-data-container{max-width:85px}ul.apps li.middle-widget-element .product-data-container{max-width:128px}ul.apps li.large-widget-element .product-data-container{max-width:110px}ul.apps-list li .product-data-container .seller{color:grey}ul.apps-list li.large-widget-element .product-data-container .seller{font-size:11px;height:17px}ul.apps-list li.middle-widget-element .product-data-container .seller,ul.apps-list li.small-widget-element .product-data-container .seller{font-size:12px;height:14px;line-height:13px}ul.apps-list li.small-widget-element .product-data-container .product-rating-small{margin:0}ul.apps-list li .product-data-image{float:left}ul.apps-list li.large-widget-element{width:260px;height:90px}ul.apps-list li.middle-widget-element{width:208px}ul.apps-list li.small-widget-element{width:165px;height:72px}.apps-section-middle ul.apps-list li.small-widget-element{margin:12px 12px 0}.apps-content .apps-section-last{margin-bottom:0;padding-bottom:27px}ul.apps-list li.large-widget-element .product-data-image{margin-left:5px}ul.apps-list li.middle-widget-element .product-data-image,ul.apps-list li.small-widget-element .product-data-image{margin-left:3px}ul.apps-list li h3{color:#444;font-weight:bold;font-family:Arial}ul.apps-list li .product-comment{margin:0;font-size:12px;width:13px!important}ul.apps-list li.large-widget-element h3{line-height:14px;font-size:12px;color:#4d4d4d;height:30px}ul.apps-list li.middle-widget-element h3,ul.apps-list li.small-widget-element h3{line-height:15px;font-size:12px}ul.apps-list li.large-widget-element .ellipsis{width:160px!important}ul.apps-list li.middle-widget-element .ellipsis{width:125px!important}ul.apps-list li.small-widget-element .ellipsis{width:85px!important}ul.apps-list li.large-widget-element h3.ellipsis{white-space:normal!important}ul.apps-list .product-data-image img{-o-border-radius:5px;-ms-border-radius:5px;-moz-border-radius:5px;-webkit-border-radius:5px;border-radius:5px;border:1px solid #e3e3e3}ul.apps-list li.large-widget-element img{width:80px;height:80px}ul.apps-list li.middle-widget-element img,ul.apps-list li.small-widget-element img{width:60px;height:60px}.long-carousel-wrapper #carousel-slider-widget-layout-0{padding-right:0}.short-carousel-wrapper #carousel-slider-widget-layout-1{padding-left:5px;border-left:1px solid #ccc}.long-carousel-wrapper #carousel-slider-widget-layout-1{padding-left:0}.short-carousel-wrapper .carousel-slider-widget-sub-layout{width:525px}.long-carousel-wrapper .carousel-slider-widget-sub-layout{width:1030px}.carousel-slider-widget{margin:0 13px 0 12px}.carousel-slider-widget .carousel-inner{overflow:visible}.carousel-slider-widget .carousel-inner .item{height:auto;overflow:visible}.carousel-slider-widget .carousel-control{top:55%!important;width:12px!important;height:20px!important;background-position:center!important;background-repeat:no-repeat!important}.carousel-slider-widget .left.carousel-control{left:-15px;background:url('../images/buttons/Arrow_Left.png')}.carousel-slider-widget .right.carousel-control{right:-15px;background:url('../images/buttons/Arrow_Right.png')}.carousel-slider-widget .carousel-item-ul{float:left}.apps-list-big .widget-element-app-content{height:80px}#header #base{max-width:1205px;min-width:1110px;padding:4px 0;margin:0 auto}#header .branding{color:#CCC;text-decoration:none;float:left;position:relative;top:7px;line-height:16px;border:0}#header .branding h1{margin:0;padding:0;line-height:27px;font-size:22px}#header .language-changer{float:left;margin:10px 0 0 20px}#header .btn-group .dropdown-toggle:focus{outline:0}#header .dropdown-toggle{background-color:transparent;border:1px solid #ccc;box-shadow:none;-webkit-box-shadow:none;-moz-box-shadhow:none}#header .language-changer .dropdown-menu>li:hover{background-color:#0081c2}#header .language-changer .dropdown-menu{border-radius:6px;-webkit-border-radius:6px;-moz-border-radius:6px}#logged_user_name{cursor:default;padding-right:10px;color:#29abe2;background:url("../images/icons/menu_arrow_blue.png") no-repeat right center}nav.user-panel .signin_link{cursor:pointer;color:#29abe2}nav.user-panel .drop_down ul,#neck .drop_down ul{background-color:#000;background-color:rgba(0,0,0,0.75);border:1px solid #222;border-color:rgba(204,204,204,0.33);padding:5px 5px 3px;margin:0;white-space:nowrap;min-width:0;position:absolute;right:0;top:90%;z-index:9999;line-height:1.75;list-style-type:none;visibility:hidden}.product-info .drop_down ul{background-color:#f2f2f2;border-color:#555;border-style:solid;border-width:1px;padding:0 0 3px 0;margin-top:0;white-space:nowrap;min-width:0;position:absolute;z-index:9999;line-height:1.75;list-style-type:none;visibility:hidden}.product-info .drop_down .details_link{cursor:default;padding-right:10px;background:url(../images/buttons/btn_popup_sort.png) no-repeat right 7px}#neck .drop_down ul{left:0;top:25px;width:150px;background-color:#d7d7d7;border:1px solid #222;border-color:rgba(204,204,204,0.33);padding:5px;margin:0;white-space:nowrap;min-width:0;-moz-border-radius:2px;-webkit-border-radius:2px;border-radius:2px;position:absolute;z-index:9999;line-height:1;list-style-type:none;visibility:hidden}nav.user-panel .drop_down ul li,#neck .drop_down ul li{padding-top:5px;padding-bottom:0;margin-top:5px;border-top:1px solid #383838;height:auto!important;line-height:normal!important}nav.user-panel .drop_down ul li:first-child,#neck .drop_down ul li:first-child{border:0 none;padding:0;margin:0}.product-info .drop_down ul li{padding-left:3px;padding-right:3px;padding-top:3px}.drop_down a{padding:0 5px;text-decoration:none;cursor:pointer}.product-info a.details_link,.product-info .drop_down{float:left}.product-info .drop_down a{padding-right:5px}nav.user-panel .drop_down a{display:block;line-height:22px!important;height:22px!important;font-size:12px;color:#fff!important;filter:alpha(opacity=100)!important;-moz-opacity:1!important;-khtml-opacity:1!important;opacity:1!important;padding:0;border:none!important}.product-info .drop_down a,#neck .drop_down a{display:block;line-height:22px;font-size:12px;-moz-border-radius:2px;-webkit-border-radius:2px;border-radius:2px;color:#000!important}.product-info .drop_down a:hover{color:#fff!important}nav.user-panel .drop_down a:hover,.product-info .drop_down a:hover,#neck .drop_down a:hover{background:#29abe2}nav.user-panel li.drop_down:hover,#neck span.drop_down:hover{position:relative;z-index:599;cursor:default}.product-info .drop_down :hover{z-index:599;cursor:default}nav.user-panel li.drop_down:hover>ul,.product-info .drop_down:hover>ul,#neck span.drop_down:hover>ul{visibility:visible}.bannertext{left:250px;position:absolute;right:150px;text-align:center;top:11px;color:#dc0719;font-style:italic;overflow:hidden;white-space:nowrap}.error_page{margin:20px auto}#neck .neck-content{height:50px;width:100%;margin:auto;padding-top:15px}#neck .breadcrumb{float:left;padding:0;margin-right:10px;margin-left:20px;margin-bottom:0}#neck .breadcrumb>a,#neck .breadcrumb>span:not(.breadcrumb-divider){display:inline-block;vertical-align:-2px;font-size:20px}#neck .breadcrumb .breadcrumb-divider{color:#111}#neck .breadcrumb a:link,#neck .breadcrumb a:visited{color:#343434}#neck .breadcrumb a:hover,#neck .breadcrumb a:active{color:#06e}#neck .breadcrumb .home{display:inline-block;width:22px;height:22px;background:url(../images/icons/icon_home.svg) no-repeat;vertical-align:-4px}#neck .breadcrumb span.drop_down{padding:0 12px 0 10px}#neck .breadcrumb span span.arrow{background:url(../images/buttons/btn_popup_sort.png) no-repeat right 6px;padding:0 10px 0 0}#my-drafts .details_link,#my-drafts .details_link:hover,#my-drafts .details_link:active,#my-drafts .details_link:visited,#my-publishedlist .details_link,#my-publishedlist .details_link:hover,#my-publishedlist .details_link:active,#my-publishedlist .details_link:visited,#my-published .details_link,#my-published .details_link:hover,#my-published .details_link:active,#my-published .details_link:visited,#detail .app-benefit-notification a:focus{border:0;width:400px;text-align:left;word-wrap:break-word;outline-style:none}.navbar-toolbar #search-plugin{margin-top:9px}#search-plugin .dropdown{float:left}#fancybox-outer{padding:0;background:transparent;-ms-box-shadow:0 0 12px rgba(0,0,0,0.65);-moz-box-shadow:0 0 12px rgba(0,0,0,0.65);-webkit-box-shadow:0 0 12px rgba(0,0,0,0.65);box-shadow:0 0 12px rgba(0,0,0,0.65);-moz-background-clip:padding;-webkit-background-clip:padding;background-clip:padding-box}#fancybox-content{background:transparent;border:1px solid #5b5b5b;-moz-background-clip:padding;-webkit-background-clip:padding;background-clip:padding-box}#fancybox-close{top:10px;right:9px;width:13px;height:13px;background-image:url("../images/buttons/close_13.png");background-position:0 0}.license-add{top:10px;right:9px;width:13px;height:13px;background-image:url("../images/buttons/close_13.png");background-position:0 0;transform:rotate(45deg)}.license-remove{top:10px;right:9px;width:13px;height:13px;background-image:url("../images/buttons/close_13.png");background-position:0 0}#fancybox-close:focus,#fancybox-close:hover{background-position:0 bottom}.license-add:focus,.license-add:hover{background-position:0 bottom}.license-remove:focus,.license-remove:hover{background-position:0 bottom}.img-mask{position:absolute;left:0;top:0;width:100%;height:100%;background-color:rgba(255,255,255,0.7)}.overlay_window{background-color:#f5f5f5}.overlay_window>header{background-color:#e6e6e6;padding:0 10px;height:29px;position:relative}.overlay_window>header h1{overflow:hidden;white-space:nowrap;text-overflow:ellipsis;font-size:14px;font-weight:normal;padding-top:6px}.overlay_window .body_container{border-top:solid 1px #cfcfcf;background-color:#fff}.overlay_window .body{padding:15px;background-color:#f4f4f4}.overlay_window .un-body{margin:0 -15px;padding-bottom:1px;overflow:hidden}.overlay_window .body h2{font-size:16px}.overlay_window .body p{margin-bottom:15px}.overlay_window .body p:last-child{margin-bottom:0}.overlay_window .body label{font-size:12px}.overlay_window .body .title.simple{font-weight:normal}.overlay_window .body .title.error{color:#f00}.overlay_window .body #select_btn{margin-top:10px}.overlay_window .controls{text-align:right}.overlay_window .controls button.close_btn{float:left}.overlay_window .controls.highlighted{padding:10px;margin:0}.overlay_window header .minimize{position:absolute;right:0;top:6px;border-right:1px solid #999;padding:1px 6px 1px 0}.overlay_window header .minimize_btn{cursor:pointer;display:block;height:16px;width:16px;background:url(../images/buttons/btn_minimize.png) no-repeat left top}.overlay_window header .minimize_btn:focus,.overlay_window header .minimize_btn:hover{background-position:left bottom}#download-link-popup{font-size:12px}#download-link-popup>.body_container{padding:15px;text-align:center}#download-link-popup .body_container>span{margin-bottom:5px;display:inline-block}#download-link-popup .body_container>span:last-of-type{font-style:italic;font-size:11px}#main{margin:0 auto;width:1280px}.search-main#main,.detail-main#main,.language-os-selector#main,.boutique#main{padding-left:0}.search-main#main{width:1265px}.search-main #facets-pane{margin-left:30px}.my-uploads-page#main{padding-left:0}.developer-description#main{padding-left:0}#main.search-page,#main.boutique{overflow:auto}.boutique #content{margin-left:120px}#goTop{display:none;position:fixed;right:20px;bottom:145px;width:50px;height:50px;-webkit-transition:opacity .2s;-moz-transition:opacity .2s;-o-transition:opacity .2s;transition:opacity .2s;z-index:9999}#goTop:hover{-moz-opacity:.8;-khtml-opacity:.8;opacity:.8;cursor:pointer}.sort-option{height:25px;background:#fff;margin-right:6px;border-bottom:solid 1px #29abe2}.sort-img-group{width:12px;height:14px;margin-bottom:-3px;display:-moz-inline-box;display:inline-block}.sort-img-group-asc{background:url("../images/icons/up_arrow_idle.png"),url("../images/icons/down_arrow_selected.png") 0 7px;background-repeat:no-repeat}.sort-img-group-desc{background:url("../images/icons/up_arrow_selected.png"),url("../images/icons/down_arrow_idle.png") 0 7px;background-repeat:no-repeat}.sort-option .sort-common{font:12px arial;text-align:center;height:25px;line-height:25px;padding-left:15px;padding-right:15px;margin-right:-4px;display:-moz-inline-box;display:inline-block}.sort-option .sort-common:hover{color:#29abe2;background:#e6e6e6;cursor:pointer}.sort-option .sort-unhightlighted{color:#29abe2;background:#fff}.sort-option .sort-hightlighted{color:#fff;background:#29abe2}.widget-hoverable{width:200px;height:100px}.widget-hoverable{background:white;border:1px solid #e3e3e3}.widget-hoverable .default-area{width:100%;height:100%}.widget-drawer{height:0;width:260px;background:white;border:1px solid #e3e3e3;border-top:0;margin-left:-1px;overflow:hidden;outline:1px solid transparent;-webkit-transform:scaleY(0);-o-transform:scaleY(0);-ms-transform:scaleY(0);transform:scaleY(0);-webkit-transform-origin:top;-o-transform-origin:top;-ms-transform-origin:top;transform-origin:top;overflow:hidden;-webkit-transition:-webkit-transform .3s ease;-webkit-transition:-webkit-transform .3s ease;-webkit-transition:-webkit-transform .3s ease;transition:transform .3s ease}.widget-hoverable:hover .widget-drawer{max-height:120px;position:absolute;height:auto;z-index:999;-webkit-transform:scaleY(1);-o-transform:scaleY(1);-ms-transform:scaleY(1);transform:scaleY(1);box-shadow:0 2px 5px -2px rgba(170,170,170,0.4);-moz-box-shadow:0 2px 5px -2px rgba(170,170,170,0.4);-webkit-box-shadow:0 2px 5px -2px rgba(170,170,170,0.4);-ms-box-shadow:0 2px 5px -2px rgba(170,170,170,0.4)}.widget-drawer span{color:#666;font-size:12px;display:block;word-wrap:break-word;margin:6px}.apps-carousel-section .widget-hoverable{height:80px;margin-right:-5px}.apps-carousel-section .widget-drawer{width:165px}.apps-section-middle ul.apps-list .widget-hoverable{height:70px;width:203px}.apps-section-middle .widget-drawer{width:203px}ul.apps-list li{padding-top:8px}ul.apps-list li.widget-element-app.large-widget-element:not(:nth-child(4n+1)){margin-left:-5px}ul.apps-list li.widget-element-app.large-widget-element:nth-child(n+5){margin-top:-5px}.apps-section-middle ul.apps-list li.widget-element-app:not(:nth-child(5n+1)){margin-left:-5px}.apps-section-middle ul.apps-list li.widget-element-app:nth-child(n+5){margin-top:-5px}#result-list.apps-list-big .s-price-cont{position:absolute;right:auto;bottom:10px;left:310px;width:110px}#result-list.apps-list-big .s-price-cont .price{text-align:left;font-size:12px;color:#29abe2;overflow:hidden;text-overflow:ellipsis}#result-list.apps-list-big .title.ellipsis{width:305px;color:#444;font-weight:bold}#result-list .widget-element-app-layout{background-color:rgba(255,255,255,0.7);cursor:pointer}#result-list.apps-list-big .sr-subscriberonly.ellipsis{width:100px;text-align:left}.search-results h3{color:#4d4d4d;margin:0;font-size:12px;font-weight:bold;line-height:20px}#result-list-new-wrapper #result-list{margin:0;border:0;background-color:transparent}#result-list-new-wrapper ul.apps-list li.small-widget-element{margin:12px 12px 0;border:1px solid #b3b3b3;-ms-border-radius:3px;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px}ul.apps-list-big .product-data-container{float:left;width:411px;position:relative;height:82px;margin-left:8px}ul.apps-list-big .seller{position:absolute;left:230px;top:6px;color:#666;font-size:12px;text-align:right}ul.apps-list-big .rating-wrapper{position:absolute;left:310px;width:110px;top:0}ul.apps-list-big .small-widget-element{-ms-border-radius:18px;-moz-border-radius:18px;-webkit-border-radius:18px;border-radius:18px;border:1px solid #d3d3d3;padding:9px;box-shadow:3px 3px 2px rgba(0,0,0,0.2);-moz-box-shadow:3px 3px 2px rgba(0,0,0,0.2);-webkit-box-shadow:3px 3px 2px rgba(0,0,0,0.2);-ms-box-shadow:3px 3px 2px rgba(0,0,0,0.2)}ul.apps-list-big .small-widget-element .product-data-image{-o-border-radius:18px;-ms-border-radius:18px;-moz-border-radius:18px;-webkit-border-radius:18px;border-radius:18px;width:80px;border:1px solid #aaa}ul.apps-list-big .small-widget-element .product-data-image img{-o-border-radius:18px;-ms-border-radius:18px;-moz-border-radius:18px;-webkit-border-radius:18px;border-radius:18px;width:80px;height:80px}.widget-element-app-search-list-view .product-data-image{width:82px}.widget-element-app-search-list-view img{width:80px;height:80px;-webkit-border-radius:5px;border-radius:5px;border:1px solid #e3e3e3}ul.apps-list .short-description-wrapper{position:absolute;top:73px;word-wrap:break-word;width:150px;color:#666;font-size:12px}ul.apps-list-big .short-description-wrapper{display:block;color:#808080;width:305px;word-wrap:break-word;font-size:11px;height:60px;overflow-y:hidden}#content{width:700px;display:inline;float:left;margin:0 10px}.normal-search#search-form{float:left;width:600px}#search-form .search-form-filter{width:235px;height:22px;float:left;margin:1px 0}#search-form .search-form-keyword{color:#666;font-size:12px;height:16px;line-height:16px;width:90%;margin:0;border:0;background:transparent;margin-top:6px;margin-bottom:6px;-ms-box-shadow:none;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;padding-right:0;padding-left:4px;outline:0}.show-all-wrapper{float:left;line-height:38px;margin-left:10px}#search-form .show_all{font-size:12px;color:#4674a7;float:left;margin-left:8px;line-height:22px;cursor:pointer;width:140px;text-align:right}#search-form .show_all:hover{color:#039}#search-form #show_all_display{float:left;width:100px;height:18px;overflow:hidden;text-overflow:ellipsis}#search-form .search-form-submit,#app-management .app-search .search-form-submit{right:1px;padding:0;background:url(../images/icons/icon_search.png) no-repeat scroll center center transparent;border:0;cursor:pointer;position:relative}#categories-nav{margin-top:10px}ul.dropdown,ul.dropdown li,ul.dropdown ul{list-style:none;margin:0;padding:0}ul.dropdown{position:relative;z-index:597;float:left;width:660px;height:26px;background:#000;padding:0 20px}ul.dropdown li{float:left;line-height:26px;zoom:1;font-size:15px;padding:0 33px 0 0;cursor:default;border:0}ul.dropdown li a{color:#FFF;cursor:pointer}ul.dropdown li:hover{position:relative;z-index:599;cursor:default}ul.dropdown li:hover>ul{visibility:visible}ul.dropdown .dirr span{background:url(../images/icons/menu_arrow_white.png) no-repeat right 8px;padding-right:15px}ul.dropdown ul{visibility:hidden;position:absolute;top:100%;left:0;z-index:598;width:100%;background:#0d0d0d;-moz-box-shadow:2px 2px 2px rgba(24,24,24,0.33);-webkit-box-shadow:2px 2px 2px rgba(24,24,24,0.33);-ms-box-shadow:2px 2px 2px rgba(24,24,24,0.33);box-shadow:2px 2px 2px rgba(24,24,24,0.33)}ul.dropdown ul.nav-1{width:300px;left:0}ul.dropdown ul.nav-2{width:280px;left:0}ul.dropdown ul.nav-3{width:225px;left:-50px}ul.dropdown ul li{float:none;padding:2px 5px}ul.dropdown ul li:hover{background:#507fc1}ul.dropdown ul li a{color:#d9d9d9;font-size:13px}.homepage-module,.detailpage-module{margin-bottom:20px;float:left}.image-homepage{position:relative;min-height:220px}#image-title-homepage{position:absolute;left:23px;top:23px;color:#000;font-size:16px;width:654px;font-weight:bold;text-shadow:0 0 8px rgba(255,255,255,1)}#image-des-homepage{position:absolute;left:23px;top:48px;color:#000;font-size:12px;width:420px;line-height:1.3;text-shadow:0 0 8px rgba(255,255,255,1)}#carousel-slider{height:200px}.carousel-control{background:url('../images/sprite.png');width:35px;height:72px;border:0;zoom:60%}.left.carousel-control{background-position:-50px -50px}.right.carousel-control{background-position:-100px -50px}.carousel-indicators{bottom:15px;right:auto;top:auto;left:60px}.carousel-indicators li{cursor:pointer;border-radius:0;margin-left:20px;width:10px;height:10px;background-color:grey}.carousel-inner .item{width:100%;height:200px;overflow:hidden;background-repeat:no-repeat;background-position:center center}.landing-view #carousel-slider{-moz-box-shadow:0 0 5px rgba(0,0,0,0.4);-webkit-box-shadow:0 0 5px rgba(0,0,0,0.4);-ms-box-shadow:0 0 5px rgba(0,0,0,0.4);box-shadow:0 0 5px rgba(0,0,0,0.4);height:200px}.landing-view .carousel-caption,.home-view .carousel-caption{top:0;padding:35px 0 0 120px;position:absolute;top:0;background:-webkit-linear-gradient(left,rgba(35,35,35,0.8),rgba(35,35,35,0));background:-moz-linear-gradient(left,rgba(35,35,35,0.8),rgba(35,35,35,0));background:-o-linear-gradient(left,rgba(35,35,35,0.8),rgba(35,35,35,0));background:-ms-linear-gradient(left,rgba(35,35,35,0.8),rgba(35,35,35,0));background:linear,left,rgba(35,35,35,0.8),rgba(35,35,35,0);filter:alpha(opacity=80 finishopacity=0 style=1) progid:DXImageTransform.Microsoft.gradient(startColorstr='rgb(35,35,35)',endColorstr='rgb(35,35,35)',GradientType=0)}#landing-container{width:1280px;margin-left:auto;margin-right:auto}#landing-container .button-wrapper{position:absolute;z-index:4;top:150px;right:80px}#landing-container .carousel .button-wrapper button{height:30px;min-width:150px;font-size:14px;color:#fff;font-family:'Open Sans',Arial,'FrutigerNextPro',sans-serif;text-shadow:none;border-radius:0}#landing-container .carousel .button-wrapper .btn-signup{background:#00c000;border:0;margin-right:10px}#landing-container .carousel .button-wrapper .btn-fusion-hero{background:#f89706 url('../images/icons/fusion-download.png') no-repeat center right 10px;border:0;padding-right:35px}#landing-container .carousel .button-wrapper .btn-signin{background:#259fff;border:0}.landing-view .carousel .carousel-inner .item .carousel-caption h2,.home-view .carousel .carousel-inner .item .carousel-caption h2{font-family:'Open Sans',Arial,'FrutigerNextPro',sans-serif;font-size:20px;text-shadow:0 0 10px rgba(0,0,0,0.6);color:#FFF;padding:5px 10px;display:inline-block;font-weight:initial}.landing-view .carousel .carousel-inner .item .carousel-caption pre,.home-view .carousel .carousel-inner .item .carousel-caption pre{line-height:22px;font-family:'Open Sans',Arial,'FrutigerNextPro',sans-serif;font-size:16px;padding:5px 10px;color:#FFF;text-shadow:0 0 10px rgba(0,0,0,0.6);max-width:700px;border:0;background-color:transparent;overflow:hidden;word-wrap:normal;word-break:keep-all}.button-wrapper .signin_link{text-decoration:none}.page-tool-wrapper{width:1220px;margin:0 auto;border-top:1px solid #cecece;overflow:auto}#main .page-tool{margin:10px auto;width:730px;padding:20px 0}#main .page-tool #signup-box{height:48px;width:332px;padding-top:20px;padding-bottom:20px}#main .page-tool #signup-box .text{margin:10px 0 0;color:#666;font-size:12px}#main .overlay-link{margin-right:30px}#main .opening-soon{margin-left:auto;margin-right:auto;width:604px;height:270px;background-repeat:no-repeat;padding:20px;background-image:url("../images/layout/opening_soon_bg.png")}.landing-view #main,.home-view#main{margin:0!important;width:auto!important;background:#f1f0f0}.landing-view #landing-banner #banner-carousel .carousel-list li h1{color:#444;text-shadow:0 0 8px rgba(255,255,255,1);font-size:40px;font-weight:normal;margin:48px 0 0 130px}.landing-view #landing-banner #banner-carousel .carousel-list li h1.maintenance-header{margin-top:100px}.landing-view #landing-banner #banner-carousel .carousel-list li h2{color:#444;text-shadow:0 0 8px rgba(255,255,255,1);font-size:19px;width:600px;font-weight:bold;margin:20px 0 0 130px}.landing-view #landing-banner #banner-carousel .carousel-list li p{color:#444;text-shadow:0 0 8px rgba(255,255,255,1);font-size:14px;width:400px;margin:20px 0 0 130px}.landing-view #landing-banner{margin:0 auto;width:1180px;position:relative}.landing-view #learn-more{width:920px;margin:0 auto 80px auto}.landing-view #landing-banner #banner-carousel{width:1180px;height:400px;position:relative;overflow:hidden}.landing-view #landing-banner #banner-carousel .carousel-list{width:20000em;position:absolute;list-style:none;margin:0;padding:0}.landing-view #landing-banner #banner-carousel .carousel-list li{float:left;width:1180px;height:400px}.landing-view #landing-banner #banner-carousel .carousel-list li.banner-carousel-0{background:url('../images/layout/landing_hero.jpg') no-repeat 0 0}.landing-view #learn-more .maintenance-page{width:435px;margin:54px 0;float:right}.landing-view #learn-more .maintenance-page h1{font-size:16px;font-weight:bold}.landing-view #learn-more .maintenance-page p{font-size:14px}.landing-view #learn-more .maintenance-page{float:none}.landing-view #header #base{min-width:400px}.storenav-button{background:transparent url(../images/buttons/storenav_btn.png?timestamp=20131012) repeat-x 0 0;display:inline-block;margin:0;border:0;min-width:300px;height:45px;color:#555;text-align:center;line-height:45px;font-size:12pt;text-shadow:0 0 8px rgba(255,255,255,1);font-weight:normal;padding:0 10px;-moz-box-shadow:.5px .5px 1px 1px #959595;-webkit-box-shadow:.5px .5px 1px 1px #959595;-ms-box-shadow:.5px .5px 1px 1px #959595;box-shadow:.5px .5px 1px 1px #959595}.storenav-button:hover{background:transparent url(../images/buttons/storenav_btn.png?timestamp=20131012) repeat-x 0 -45px;cursor:pointer}.storenav-button:active,.storenav-button.ui-custom-active{background:transparent url(../images/buttons/storenav_btn.png?timestamp=20131012) repeat-x 0 -90px}a.storenav-button.select-store{color:#fff}.landing-view .dropdown-menu>li>a{line-height:25px}.navbar .dropdown-menu .popover-menu{padding:0;margin:5px 0!important}.navbar .dropdown-menu .popover-menu>li{line-height:25px}.navbar .dropdown-menu .popover-menu>li>a{display:block;padding:0 20px;text-decoration:none;color:black}.navbar .dropdown-menu .popover-menu>li>a:hover{color:white;background-color:#0081c2}.navbar .nav{padding:0}.navbar-header{margin-top:15px}.navbar-brand{background:url(../images/layout/Header_Logo.png) no-repeat;width:241px;height:23px;float:left;text-indent:-9999px;overflow:hidden;background-size:100%}.navbar-default{margin:0;padding:0 20px;border-bottom:1px solid #ccc;background:white}.navbar-toolbar{margin:0;padding:0 20px;background:#f1f0f0}.navbar-default .container{height:50px}.navbar-toolbar .container{height:52px}.navbar-toolbar .navbar{margin:14px 0 11px}.landing-view .navbar-toolbar .navbar{margin:11px 0}.navbar-toolbar .navbar .btn-group{margin-top:0}.btn{background-image:none}.navbar-collapse{height:auto;overflow:visible}.navbar .navbar-nav li{padding:5px 0;height:24px;line-height:24px}.user-panel li.drop_down{padding:0}.navbar .navbar-nav li a{cursor:pointer;padding:0 15px;height:45px;line-height:45px;position:relative;top:-2px;color:#29abe2}.navbar .navbar-nav li a:hover{color:#40cdf5}.login-panel li.depression,.login-panel li.depression{outline:1px solid lightgrey;background:-webkit-gradient(linear,top,bottom,from(#ccc),to(#ededed));background:-webkit-linear-gradient(#ccc,#ededed);background:-moz-linear-gradient(#ccc,#ededed)}.login-panel .depression-panel-myDownloads>li a{border-left:none}.login-panel .depression-panel-myUploads>li.myUploads-li a,.login-panel .depression-panel-myUploads .user-panel{border-left:none}.user-panel{border-left:solid 1px rgba(187,196,198,0.5);padding-left:15px;margin-top:8px}.navbar .navbar-nav li a.a-help-20{border-left:none;padding:0}[class^="icon-"],[class*=" icon-"]{width:20px;height:20px;margin-top:0}.icon-help-20{background:url(../images/icons/help-20x20.png) no-repeat}.search-wrapper .search-box-store-selector{visibility:visible;opacity:0;filter:alpha(opacity=0);-moz-opacity:0;-khtml-opacity:0;position:absolute;top:8px;right:-35px;width:180px}.search-wrapper .nav-search-scope{overflow:hidden;position:relative}.nav-right{float:right;width:auto;display:inline-block}.nav-fill{width:auto;height:35px;position:relative;margin-right:110px}.nav-search-field{position:relative;height:35px}.search-wrapper .search-form-content{border:1px solid lightgrey;background:white}.search-wrapper .search-form-content.active{border-color:#51a7e8;-ms-box-shadow:0 0 5px rgba(81,167,232,0.5);-webkit-box-shadow:0 0 5px rgba(81,167,232,0.5);-moz-box-shadow:0 0 5px rgba(81,167,232,0.5);box-shadow:0 0 5px rgba(81,167,232,0.5)}.search-wrapper .nav-search-scope{position:relative;float:left;height:37px;margin:0;overflow:hidden}.search-wrapper .nav-search-facade{position:relative;float:left;padding:6px 5px 7px 5px;font-size:12px;line-height:14px;margin:5px 0;cursor:pointer;border-left:1px solid lightgrey}.search-wrapper .nav-search-facade .caret{margin-top:5px;margin-left:2px}.search-wrapper .nav-search-submit{position:relative;float:left;height:35px;width:35px;overflow:hidden;cursor:pointer;background:#29abe2}.search-suggestions-box-ul{font:12px Arial;color:#666;position:relative;left:-1px;top:-1px;border:1px solid #ccc;background:#fff;z-index:99;overflow:hidden}.search-suggestions-box-ul li{line-height:25px;cursor:pointer;margin-left:-20px;padding-left:5px}.search-suggestions-box-ul li.selected{background-color:#eee}#search-suggestions-box li:hover{background:#eee}.detail-search-suggestion ul{overflow:hidden;top:0}.detail-search-suggestion li{margin-left:0}.nav-search-submit .nav-input{position:relative;display:block;height:100%;width:100%;line-height:33px;text-indent:-1000px;padding:0;border:0;cursor:pointer;outline:0}.navbar .popover{width:400px;-webkit-border-top-left-radius:0;-webkit-border-bottom-left-radius:0;border-top-left-radius:0;border-bottom-left-radius:0;overflow:hidden}.navbar .popover-content{text-align:center}.navbar .dropdown-menu{-webkit-border-top-right-radius:0;-webkit-border-bottom-right-radius:0;border-top-right-radius:0;border-bottom-right-radius:0;-ms-box-shadow:0 0 5px #000;-webkit-box-shadow:5px 5px 10px rgba(0,0,0,0.2);-moz-box-shadow:5px 5px 10px rgba(0,0,0,0.2);box-shadow:5px 5px 10px rgba(0,0,0,0.2)}.navbar .dropdown-menu>li>a:hover{background-image:none;color:white;background-color:#0081c2;background-color:rgba(0,129,194,0.5)}.navbar .dropdown-menu>li>a.maintainHover{color:white;background-color:#0081c2}#featured-products{margin-top:10px;margin-bottom:10px;background-color:White;border:1px solid #cecece;background-color:white;-moz-border-radius:0 0 4px 4px;-webkit-border-radius:0 0 4px 4px;border-radius:0 0 4px 4px;-ms-box-shadow:0 1px 0 #f1f1f1;-moz-box-shadow:0 1px 0 #f1f1f1;-webkit-box-shadow:0 1px 0 #f1f1f1;box-shadow:0 1px 0 #f1f1f1}#featured-products h2{font-size:16px;color:#404040;font-weight:bold;line-height:28px;height:28px;padding:10px 20px 10px;background-color:white}#featured-products h3{font-size:16px;color:black;margin:7px 0 0;font-weight:normal}#featured-products ul{padding:0 12px 8px;width:674px;color:black;margin:0}#featured-products ul li{position:relative;height:90px;float:left;width:216px;margin:3px 3px 12px 0;padding:0}#featured-products ul li:hover,#featured-products ul li:focus{background:#d5deeb;-moz-border-radius:4px;-webkit-border-radius:4px;border-radius:4px;cursor:pointer}#featured-products ul li:hover a{cursor:pointer}#featured-products ul li:active{background:#9fb3d1}#featured-products .featured_image{width:80px;height:80px;float:left;margin:0 5px 0 0;overflow:hidden}#featured-products ul li div.product-content-container{padding:5px}#featured-products .product-data-container{float:left}#featured-products .product-data-container #product-title{width:120px}#featured-products ul li .title{font-size:12px;color:#000;margin:0}#featured-products ul li .seller,#featured-products ul li .reviews{font-size:10px;color:#808080;display:block}#featured-products ul li .reviews{clear:both}#featured-products ul li .ratingamount{font-size:10px;color:#666;display:block;margin-bottom:3px}#featured-products ul li .price{color:#000;display:block}#featured-products ul li .price.free{color:green}#featured-products ul li .overlay-link{width:100%;height:100%;position:absolute;left:0;top:0;outline:0;z-index:100}#featured-products ul li.clear{height:0}#show_more_all div{text-align:right;padding-top:10px;padding-bottom:20px;padding-right:20px;vertical-align:bottom;font-family:Arial;font-size:12px;color:#4675a8}#show_more_all div a{color:#4675a8}.product-rating-small{float:left;width:65px;height:15px;margin:2px 0 0 0}.product-comment{float:left;height:15px;width:35px;margin:2px 0 0 10px;vertical-align:middle;font:12px arial,Helvetica,sans-serif;color:#808080}.product-comment img{margin:0 0 0 3px}.search-results-stars{float:right}.product-rating-small .star-rating{float:left;width:13px;height:12px;cursor:default;display:block;background:url(../images/icons/star_small.png) no-repeat 0 0;overflow:hidden}.product-rating-small .star-on{background-position:0 -12px!important}.product-rating-small .star-off{background-position:0 0!important}.product-rating-search{float:none}#add-comment .errors{color:red;float:right}#add-comment .not_visible{display:none}#add-comment .error_tag,#add-comment .error{color:red}#add-comment #title{margin-bottom:10px;width:351px;height:16px}#add-comment textarea.error_border,#add-comment input.error_border{border-color:red}#add-comment .comment-rate.error_border{border:1px solid red}.search-page #right{margin-left:20px}#right{width:220px;margin-left:10px;display:inline;float:left}#bestsellers{width:223px}.no-cssgradients #bestsellers h2{background:#e1e1e1 url(../images/layout/backgrounds/bg_h2_title.png) repeat-x 0 0}#bestsellers h2{font-size:16px;font-weight:normal;text-align:center;height:28px;color:#404040;margin:0;padding:0;border:1px solid #cecece;border-bottom:0;line-height:28px;-moz-border-radius:4px 4px 0 0;-webkit-border-radius:4px 4px 0 0;border-radius:4px 4px 0 0;background:-webkit-gradient(linear,left top,left bottom,from(#f0f0f0),to(#e3e3e3));background:-webkit-linear-gradient(#f0f0f0,#e3e3e3);background:-moz-linear-gradient(#f0f0f0,#e3e3e3)}#bestsellers ul{position:relative;top:0;margin:0;padding:0;border:1px solid #cecece;background-color:#fff;-moz-border-radius:0 0 4px 4px;-webkit-border-radius:0 0 4px 4px;border-radius:0 0 4px 4px;-ms-box-shadow:0 1px 0 #f1f1f1;-moz-box-shadow:0 1px 0 #f1f1f1;-webkit-box-shadow:0 1px 0 #f1f1f1;box-shadow:0 1px 0 #f1f1f1}#bestsellers li{border-top:1px solid #d9d9d9;position:relative;height:54px;padding:0;margin:0;display:block}#bestsellers .container{height:42px;width:auto;padding:6px 10px;cursor:pointer}#bestsellers ul li:first-child{border-top:0 none}#bestsellers li:hover,#bestsellers li:focus{background:#d5deeb}#bestsellers li:active{background:#9fb3d1}#bestsellers div.container img.bestseller-icon{width:40px;height:40px;float:left;margin-right:10px;overflow:hidden}#bestsellers .title{color:#000;font:12px arial,Helvetica,sans-serif;margin:0;display:inline-block;width:78px}#bestsellers .description{color:#666;font-size:10px;float:left;margin:0}#bestsellers .price{float:right;font:12px arial,Helvetica,sans-serif;color:#000;vertical-align:bottom}#bestsellers .price.free{color:#008000}#bestsellers .overlay-link{width:100%;height:100%;position:absolute;left:0;top:0;outline:0;z-index:100}.bestsellers-content{float:left;width:150px;height:40px}.leftwing #bestsellers{width:234px}.leftwing .bestsellers-content{width:161px}.leftwing #bestsellers .title{width:89px}.ga-data{text-align:center}.ga-value span{font-size:16px;color:#333}.ga-image-sliders{border-radius:4px;border:1px solid #cecece;overflow-x:hidden;width:348px!important}.ga-image-sliders ul{width:1400px;border:0;height:49px;margin:0;padding:0;background:#e4e4e4;border-bottom:1px solid #cecece}.ga-image-sliders li,.ga-image-sliders li span{width:350px;height:50px}.ga-image-sliders li .ga-title{padding-top:5px;padding-bottom:5px}.ga-image-sliders li .ga-title span{font-size:12px;color:#1c2e84}.ga-image-sliders li{float:left;color:#333;border-top:0}.ga-image-sliders .ga-more-static{height:38px;text-align:center;font-size:15px;background:#f2f2f2}.ga-image-sliders .ga-more-static div{padding-top:10px}.ga-image-sliders .ga-more-static a{font-weight:bold;font-size:12px}.ga-image-sliders .ga-more-static a:link,.ga-image-sliders .ga-more-static a:visited,.ga-image-sliders .ga-more-static a:hover{color:#1c2e84}#quicklinks{float:left;clear:both;padding:0;margin:0 10px 20px 0;display:inline-block;border:1px solid #cecece}#quicklinks a{color:#369}#quicklinks h2{font-size:16px;font-weight:normal;text-align:center;height:28px;color:#333;line-height:28px;-moz-border-radius:4px 4px 0 0;-webkit-border-radius:4px 4px 0 0;border-radius:4px 4px 0 0;background:-webkit-gradient(linear,left top,left bottom,from(#f0f0f0),to(#e3e3e3));background:-webkit-linear-gradient(#f0f0f0,#e3e3e3);background:-moz-linear-gradient(#f0f0f0,#e3e3e3)}#quicklinks ul{padding-left:10px;width:220px;float:left}#quicklinks ul li{padding-bottom:5px}#quicklinks .quicklinks-body{border-top:1px solid #cecece}#facets .facets-constraints .title,#quicklinks li .title{font-size:12px;color:#369;cursor:pointer}#quicklinks li .title{font-size:12px}#quicklinks li.hidden-links{display:none}#facets .facets-constraints .count,#quicklinks li .count{font-size:12px;color:#999}#quicklinks li .count{font-size:11px}#quicklinks .show-all-body{width:210px;padding:10px 10px 10px 12px;border-top:1px solid #cecece}#quicklinks .show-all-body span.show_all{cursor:pointer;font-size:12px;color:#4674a7;font-weight:bold}.no-cssgradients #signup-box{background:#eee}.no-cssgradients #signup-box:hover{background-color:#d9d9d9}#signup-box{float:left;width:205px;text-align:center;color:#222;font-size:11px;padding:13px 8px;background:#e4e4e4;-moz-border-radius:4px;-webkit-border-radius:4px;border-radius:4px;-ms-box-shadow:0 1px 0 #f1f1f1;-moz-box-shadow:0 1px 0 #f1f1f1;-webkit-box-shadow:0 1px 0 #f1f1f1;box-shadow:0 1px 0 #f1f1f1;border:1px solid #cecece;cursor:pointer;display:block}#signup-box .title{margin:0;color:#1c2e84;font-size:14px;font-weight:bold;line-height:1.2}#signup-box .text{margin:5px 0 5px}#signup-box .overlay-link{width:100%;height:100%;position:absolute;left:0;top:0;outline:0;z-index:100}#twitter-widget-0{width:85px!important;float:right}.fb-like{margin-right:2px;float:right}.s-price-cont.s-price-cont-hidden{display:none}.detail-page .detail-module{float:left}.detail-page #content{width:938px;margin:0;margin-bottom:100px}.detail-page #content-wrapper{margin-bottom:10px}.detail-page #detail{padding:10px;background:#fff;border:1px solid #ccc;-moz-border-radius:4px 4px 0 0;-webkit-border-radius:4px 4px 0 0;border-radius:4px 4px 0 0}.detail-page #detail subscriptionDes .subscriptionDes{vertical-align:middle}.detail-page #detail img.subscriptionBadge{float:none;width:24px;height:24px;margin:0}.detail-page #detail .strikeout-price{text-decoration:line-through;vertical-align:middle;padding:0 10px 0 0;cursor:default}.detail-page .description p{word-wrap:break-word;word-break:normal}.detail-page #detail img.product-icon,#app-detail-for-publisher img.product-icon{float:left;height:120px;width:120px;margin:0 15px 5px 0}#app-detail-for-publisher hr{width:960px}.detail-page #detail .title-rating{float:left}.detail-page #detail .icons-cont{width:100%;margin-top:20px}.detail-page #detail .badge-div{float:left}.detail-page #detail .badge-div-visible{visibility:visible}.detail-page #detail .badge-div-hidden{visibility:hidden}.detail-page .badge-div .subscriptionBadge{float:left}.detail-page .purchase-container .caret{border-top:4px solid #fff}#detail-title{margin:0 10px 2px 0;font-size:20px;padding:0;width:80%;color:#4d4d4d;overflow:hidden;text-overflow:Ellipsis;white-space:nowrap;-o-text-overflow:ellipsis;-ms-text-overflow:ellipsis}#detail-social{float:right}#detail .detail-versions-cont .detail-version-cat{float:left;cursor:default;line-height:26px;width:135px}#detail .detail-versions-cont{margin-bottom:10px}#detail .{background:left}.product-rating-big{float:left;width:90px;height:15px;margin:7px 0}.title-rating .product-rating-big{margin:0}.product-rating-big .star-rating{float:left;width:18px;height:16px;cursor:default;display:block;background:url(../images/icons/star_big.png) no-repeat 0 0;overflow:hidden}.product-rating-big .star-on{background-position:0 -16px!important}.product-rating-big .star-off{background-position:0 0!important}.product-rating-search{float:none}.detail-versions-cont .flat-button{border-radius:2px;min-width:150px}.detail-versions-cont .app-version-btn{color:#4d4d4d}#content-wrapper .reviews-count{line-height:32px;margin-left:5px;font-size:12px}#detail .seller{font-size:14px;color:#29abe2}#detail .release-date{font-size:12px;float:right;color:#808080}#detail .description{color:#333;margin:10px 0 10px;font-size:14px;line-height:130%;-ms-word-break:break-word;word-break:break-word;-ms-word-wrap:break-word;word-wrap:break-word}#detail .download-free-notification{clear:both;color:#4675a8;margin:20px 0 20px;font-size:12px;font-weight:bold}#detail .education-free-notification,#detail .app-benefit-notification{clear:both;color:gray;font-size:12px;float:right;font-style:italic}#detail .app-benefit-notification{float:left}#detail .education-free-notification a,#detail .app-benefit-notification a{color:#1a52ad}#detail .description p{margin:0}#detail #extra hr{margin-top:10px;margin-bottom:10px}#detail #extra .detail-versions-cont hr{margin-top:2px;margin-bottom:2px}#extra .purchase-container{height:25px;float:right;max-width:300px;cursor:pointer;margin-bottom:16px}#extra .purchase-container .btn{height:30px;line-height:30px}#extra .version-title{color:#808080;font-size:14px}.price_btn_blue{width:auto;padding:0 20px;border:0;font-size:14px;cursor:pointer;height:25px;text-align:center;line-height:25px;color:#fff}#extra a.price_btn_blue,#extra span.price_btn_blue,#extra a.price_btn_blue:hover{color:white}#detail #detail_testinfo{border:1px solid #00c;padding:5px}#detail .detail_testresult{margin-left:10px;font-style:italic}#extra .purchase_container{display:none}#screenshots .jcarousel-skin-tango .jcarousel-container{background:0;border:0;padding:0 22px}.no-cssgradients #screenshots h2.title,.no-cssgradients .jcarousel-skin-tango{background-color:#f0f0f0}#screenshots ul{height:140px;overflow:hidden;margin:0;padding:0}#screenshots ul li{position:relative}#screenshots .text-container{margin:0 50px 10px;font-size:12px;color:#666}#screenshots .text-container .title{font-weight:bold;line-height:26px}#screenshots ul li span{text-align:center;overflow:hidden;display:block;color:#4d4d4d}#screenshots ul li img{display:block;position:absolute;margin:auto;top:0;bottom:0;left:0;right:0;max-height:74px}.preview-container{height:505px;margin:0 50px 15px 50px;border:1px solid #cecece;position:relative}.preview-container>iframe{width:100%}.preview-container>img,.preview-container>iframe{position:absolute;max-height:100%;max-width:100%;top:0;bottom:0;right:0;left:0;margin:auto;border:0}.preview-next:hover,.preview-prev:hover{opacity:1}.preview-next,.preview-prev{width:20px;height:30px;top:160px;z-index:10;cursor:pointer;position:absolute;opacity:.5}.preview-container .preview-next{background:url(../images/icons/next.png) no-repeat;right:-30px}.preview-container .preview-prev{background:url(../images/icons/prev.png) no-repeat;left:-30px}.preview-overlay{z-index:10;position:relative;height:100%;cursor:pointer}.preview-overlay:hover{background:rgba(0,0,0,0.1) url(../images/icons/zoom.png) no-repeat center;background-size:10%}.video-overlay{background:rgba(0,0,0,0.15) url(../images/buttons/play.png) no-repeat center;height:100%;width:100%;position:absolute;z-index:10;margin:-3px}.video-overlay:hover{cursor:pointer;background:transparent url(../images/buttons/play.png) no-repeat center}.detail-page #right{width:328px;margin-bottom:100px}.side-panel{font-size:12px}.side-panel span#language{word-break:normal}.side-panel h2{font-size:16px;font-weight:normal;padding:0 10px;height:28px;color:#404040;border:1px solid #cecece;line-height:28px;-moz-border-radius:4px 4px 0 0;-webkit-border-radius:4px 4px 0 0;border-radius:4px 4px 0 0;background:-webkit-gradient(linear,left top,left bottom,from(#f0f0f0),to(#e3e3e3));background:-webkit-linear-gradient(#f0f0f0,#e3e3e3);background:-moz-linear-gradient(#f0f0f0,#e3e3e3);text-align:center}.side-panel h3{height:25px;background:-webkit-gradient(linear,left top,left bottom,from(#f0f0f0),to(#e3e3e3));background:-webkit-linear-gradient(#f0f0f0,#e3e3e3);background:-moz-linear-gradient(#f0f0f0,#e3e3e3);font-weight:normal;border:1px solid #cecece;border-bottom:0;border-top:0;line-height:25px;padding:0 8px;color:#000}.side-panel ul.compatible-with-list,ul.subscriber-benefit-product-list{margin:0;padding:0}.side-panel li.hidden-subscriber-benefit-products,li.hidden-compatible-with-list{display:none}.side-panel li.your-subscription{font-weight:bold}.side-panel #purchase{border:1px solid #bfbfbf;background-color:White;padding:10px;margin-bottom:10px;padding-bottom:42px}.side-panel #purchase .price-str{font-size:24px}#purchase .flat-button{width:100%;padding:4px 0}#price-options .flat-button{height:50px;border-radius:0;font-size:24px;color:#29abe2;border:2px solid #29abe2}#price-options .flat-button.selected{color:white}.side-panel .download-info{min-height:15px;padding:5px 0;margin-top:10px}.side-panel .download-info-subscription{padding-bottom:10px}.side-panel .show-more,.show-less{color:#1a52ad;display:inline-block;white-space:nowrap;cursor:pointer}.break-word{word-wrap:break-word;word-break:break-all}.side-panel .download-info .property{float:left}.side-panel .download-info-subscription .property{margin-bottom:10px}.side-panel #show-more-benefit-products,.side-panel #show-less-benefit-products{margin-bottom:10px}.side-panel .download-info .compatible-with-list .compatible-with-list-group{margin-top:8px}.side-panel .download-info .subscriber-benefit-product-list li,.side-panel .download-info .compatible-with-list li{margin:0 0 2px 0}.side-panel .download-info .value{float:right}.side-panel .detail-comptible{padding-bottom:0}.side-panel .promote-item:hover{background:#f0f0f0}.side-panel .promote-item>img{width:50px;height:50px;float:left;margin-right:10px}.side-panel .s-price-cont{float:none;margin-top:5px}.detail-page .product-rating-small{margin-right:5px}.side-panel .product-rating-small{width:auto}.side-panel .ellipsis{width:190px}.side-panel .show-more-apps{margin:5px;float:right}.side-panel .show-more-apps a{color:steelblue}.side-panel.apps-promote-panel{border:1px solid #cecece;background-color:white;padding-bottom:10px}.side-panel.apps-promote-panel H2{border:0;border-bottom:1px solid #cecece;padding:5px;text-align:center;margin-top:0}.side-panel.apps-promote-panel .company-title{font-size:18px}.side-panel.apps-promote-panel .company-numberitem{font-size:14px;color:#4d4d4d}.side-panel.apps-promote-panel .company-number{font-size:18px;font-weight:bold;color:#808080}.side-panel.apps-promote-panel .info-logo{width:80px;height:80px;margin-right:5px;margin-left:10px}.side-panel.apps-promote-panel .promote-item{height:80px;margin-top:5px;margin-bottom:5px;color:#4d4d4d}.side-panel.apps-promote-panel .company-info-cont{height:80px}.side-panel.apps-promote-panel .promote-item .product-title{margin-bottom:20px;font-size:14px;width:220px;font-weight:bold}.side-panel.apps-promote-panel .promote-item .s-price-cont{color:#29abe2}.side-panel.apps-promote-panel .company-info-cont .info-logo{float:left;margin-right:10px}.side-panel.apps-promote-panel .service-list li{font-size:12px;color:#4d4d4d;margin:0 0 10px 10px}.side-panel.apps-promote-panel ul{margin-top:15px}.side-panel.apps-promote-panel .list-title{font-size:18px;color:#4d4d4d;margin:5px 0 5px 10px}.detail-page h2{font-size:18px;margin:10px 0 10px 0;font-weight:normal;text-align:left;height:28px;color:#4d4d4d;border-bottom:0;line-height:28px}#reviews #summary{background-color:white;-moz-border-radius:4px 4px 4px 4px;-webkit-border-radius:4px 4px 4px 4px;border-radius:4px 4px 4px 4px;border:1px solid #cecece;padding:10px;overflow:hidden}#reviews #summary img{width:40px;padding-right:10px;float:left}#reviews #summary .title-author{display:inline-block;float:left}#reviews #summary .title-author span{padding-top:4px;float:left;max-width:100px}#reviews #summary .title-author h3{max-width:100px}#reviews #summary .reviews-info{display:inline-block;padding-left:10px;width:auto;overflow:hidden}#reviews #summary .write-review-link{width:auto;display:inline-block;float:left}.compatible-version{color:grey}.compatible-version-title{font-weight:bold}.reviews-info h3{float:left;line-height:35px;font-size:20px;font-weight:normal;color:#ccc}.get-tech-help{margin:0 5px;color:#1a52ad;line-height:35px}.reviews-info a.get-tech-help:hover{color:#1a52ad}.detail-page span.comment,.detail-page a.comment{padding:8px;margin-right:5px;color:#4d4d4d;cursor:pointer;float:left;border:1px solid #ccc;font-size:14px;width:auto}.detail-page span.noncomment{background:transparent url(../images/icons/comment.png) no-repeat 0 1px;padding-left:20px;margin-left:5px;color:Gray}.detail-page a.comment:hover{color:#3d87ff}#extra .log-in-to-comment span.pending:hover,.detail-page span.pending:hover{color:#1a52ad;cursor:default}.detail-page span.pending,.detail-page a.pending,.detail-page span.pending:hover,.detail-page a.pending:hover{color:#c3c3c3}#reviews #summary .reviews-stars{margin-top:6px}#reviews #summary .reviews-stars .product-rating-small{padding-right:5px}#reviews #summary .reviews-info .averagereview{float:left;margin-right:2px;max-width:190px;width:auto}#reviews #summary .reviews-info .reviews-count{display:block}#comments{width:650px;float:left;padding-bottom:30px}#comments-list{padding:0;margin:0}#comments .add-sub-comments{width:850px}.add-sub-comments .app-publisher{font-weight:bold}#comments .sub-comment-warning,#comments .delete-comment-warnning{color:#f60}#comments .delete-comment-warnning{display:inline}.sub-comment-form textarea{margin-bottom:10px;width:645px}.edit-a-comment-form textarea{margin-bottom:10px;width:600px}#comments .sub-comment-description-warning{border:1px solid #f60;padding:10px}.sub-comment-form-hidden,.sub-comment-link-hidden,.edit-a-comment-hidden,.edit-delete-comment-actions-hidden,.realdelete-cancel-comment-actions-hidden,.sub-comment-hidden,.edit-a-comment-form-hidden{display:none}.comment-action{color:#1a52ad;cursor:pointer}.comment-action:hover{color:#3d87ff;cursor:pointer}.comment-subject{display:block;font-size:13px;color:#595959;font-weight:bold;margin-bottom:10px}.comment-item{margin:20px 0;float:left;width:900px}.comment-item .add-sub-comments{float:left;margin-left:50px}#comments-list hr{width:938px;margin:0;float:left}#comments-list .sub-comment-entity hr{width:888px}.sub-comment-warning{margin-top:10px}.sub-comment-entity{margin-top:15px}.write-a-comment{margin-top:5px;float:left;padding-left:5px}.write-comment-form-submit,.write-a-comment-cancel{margin-right:10px;padding:2px}.sub-comment-description p{margin:0}.sub-comment-description{margin:10px 0;color:#595959}.comment-item .comment-info{float:left;padding-left:5px;width:895px}.comment-item .comment-date{display:inline;color:#a6a6a6;margin-bottom:15px}.comment-item .comment-name{margin-bottom:15px}.comment-item .comment-description{color:#595959}.comment-item .comment-description p{margin-bottom:0}.comment-item .veirified-download{font-size:11px;font-weight:bold;color:#f90}.comment-item .whats-verified-download{font-size:10px;color:#c9c9c9;text-decoration:underline;cursor:pointer}#add-comment{margin-bottom:40px;float:left;background-color:white;-moz-border-radius:4px 4px 4px 4px;-webkit-border-radius:4px 4px 4px 4px;border-radius:4px 4px 4px 4px;border:1px solid #cecece;padding:10px;display:none}#add-comment .title{font-weight:bold;margin-bottom:20px}#add-comment .title a{color:#1f5397}#comment-form .own-rate{float:left;width:260px;text-align:center}#comment-form .own-rate h2{display:inline}#comment-form .own-rate label{font-size:10px;font-weight:bold}#comment-form .own-rate span{font-size:10px}#comment-form .own-rate .product-rating-big{float:none;margin-left:auto;margin-right:auto;padding:10px}#comment-form .own-review{float:left;width:366px;text-align:center}#comment-form .own-review div{position:relative}#comment-form .own-review textarea{margin-top:0;margin-bottom:0;height:65px;width:351px;resize:none}#comment-form input,#comment-form textarea{padding:5px;border:solid 1px #bfbfbf;font-size:13px;font-style:normal;background:white url('../images/bg_form.png') left top repeat-x;background:-webkit-gradient(linear,left top,left 3,from(white),color-stop(1%,#f1f1f1),to(#fcfcfc));background:-moz-linear-gradient(top,white,#f1f1f1 1px,#fcfcfc 2px);box-shadow:rgba(0,0,0,0.1) 0 0 4px;-ms-box-shadow:rgba(0,0,0,0.1) 0 0 4px;-moz-box-shadow:rgba(0,0,0,0.1) 0 0 4px;-webkit-box-shadow:rgba(0,0,0,0.1) 0 0 4px}#comment-form .submit-comment,#comment-form .cancel-comment{width:auto;padding:0 11px;border:0;font-size:14px;color:white;cursor:pointer;height:25px;text-align:center;line-height:25px;margin-top:10px;-moz-box-shadow:none;-webkit-box-shadow:none;-ms-box-shadow:none;box-shadow:none}#comment-form .cancel-comment{margin-right:10px;display:inline-block;margin:0;border:1px solid #797979;white-space:nowrap;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;background-color:#999;-moz-box-shadow:none;-webkit-box-shadow:none}.gradient-button{background:linear-gradient(#6a91df,#314d7b);background:-webkit-gradient(linear,left top,left bottom,from(#6a91df),to(#314d7b));background:-webkit-linear-gradient(#6a91df,#314d7b);background:-moz-linear-gradient(#6a91df,#314d7b);background:-o-linear-gradient(#6a91df,#314d7b);display:inline-block;margin:0;border:1px solid #335080;white-space:nowrap;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;-ms-box-shadow:0 1px 0 rgba(0,0,0,0.4);-moz-box-shadow:0 1px 0 rgba(0,0,0,0.4);-webkit-box-shadow:0 1px 0 rgba(0,0,0,0.4);box-shadow:0 1px 0 rgba(0,0,0,0.4)}.no-cssgradients .gradient-button{background:#314d7b url(../images/icons/bg-gradient-dropdown.png) repeat-x 0 0}a .no-cssgradients .gradient-button:hover,a .no-cssgradients .gradient-button:focus{background-position:0 -26px}.no-cssgradients .gradient-button:active:hover{background-position:0 -32px}.no-cssgradients .gradient-button.disabled{color:#fff;background-position:0 -78px;cursor:default!important}.gradient-button:hover,.gradient-button:focus{background:linear-gradient(#80a1e4,#50688f);background:-webkit-gradient(linear,left top,left bottom,from(#80a1e4),to(#50688f));background:-webkit-linear-gradient(#80a1e4,#50688f);background:-moz-linear-gradient(#80a1e4,#50688f)}.gradient-button:active{background:linear-gradient(#5a7bbe,#2a4269);background:-webkit-gradient(linear,left top,left bottom,from(#5a7bbe),to(#2a4269));background:-webkit-linear-gradient(#5a7bbe,#2a4269);background:-moz-linear-gradient(#5a7bbe,#2a4269)}.gradient-button.disabled{color:#fff;opacity:.3;-moz-opacity:.3;-khtml-opacity:.3;background:linear-gradient(#96b1e9,#577ebc);background:-webkit-gradient(linear,left top,left bottom,from(#96b1e9),to(#577ebc));background:-webkit-linear-gradient(#96b1e9,#577ebc);background:-moz-linear-gradient(#96b1e9,#577ebc);cursor:default!important}.ui-button.disabled{opacity:.8;-moz-opacity:.8;-khtml-opacity:.8}.detail-page .helpdoc-element{margin-top:25px;width:830px}.detail-page .helpdoc-command{margin-top:10px}.detail-page .helpdoc-block{margin-top:10px;width:830px}.detail-page #helpdoc-element-screenshot{width:900px}.detail-page #helpdoc-tag{width:830px}.detail-page #helpdoc-tag a:link,.detail-page #helpdoc-tag a:hover,.detail-page #helpdoc-tag a:visited,.detail-page #helpdoc-tag a:active{float:left;font:12px arial,sans-serif;color:#4675a8;height:16px;padding:0 3px}.detail-page #helpdoc-tag a.helpdoc-breadcrumb{border-right:1px solid black}.detail-page .helpdoc-element a:link,.detail-page .helpdoc-element a:hover,.detail-page .helpdoc-element a:visited,.detail-page .helpdoc-element a:active{color:#4675a8}.detail-page .helpdoc-text{width:830px;word-wrap:break-word;font:12px arial,sans-serif black}.detail-page #helpdoc-head{margin-top:25px;width:830px}.detail-page #helpdoc-head-icon{float:left;width:80px;height:80px;margin-right:15px}.detail-page #helpdoc-head-description{width:735px;float:right}.detail-page #helpdoc-product-title{float:left}.detail-page #helpdoc-product-os{float:right;width:235px;text-align:right;overflow:hidden;font:12px arial,sans-serif black}.detail-page #helpdoc-head hr{margin-top:5px;margin-bottom:2px}.detail-page #helpdoc-head .seller{overflow:hidden;width:735px;font:12px arial,sans-serif #666}.detail-page #helpdoc-head .description{width:735px;margin-top:10px;height:32px;overflow:hidden;word-wrap:break-word}.detail-page a.helpdoc{color:#1a52ad}.detail-page #helpdoc-head .description p{width:735px;margin:0;overflow:hidden}.detail-page #helpdoc-tag{margin-top:10px}.detail-page .helpdoc-element-hidden{display:none}.detail-page .helpdoc-screenshot{float:left;width:215px;height:173px}.detail-page .helpdoc-img-container{width:180px;height:140px;text-align:center;border:1px solid #ccc}.detail-page .helpdoc-img-container:hover{border:1px solid gray}.detail-page .helpdoc-screenshot-img{max-height:130px;max-width:170px}.helpdoc-img-container .helper{display:inline-block;height:100%;vertical-align:middle}.detail-page .helpdoc-screenshot-label{text-align:center;text-overflow:ellipsis;width:180px;height:15px;float:left;overflow:hidden;margin-top:2px;font:12px arial,sans-serif black}.detail-page .helpdoc-table th{background-color:#f2f2f2}.detail-page .helpdoc-table td,.detail-page .helpdoc-table th{border:1px #b3b3b3 solid}.detail-page .helpdoc-version{margin-bottom:420px}.detail-page .helpdoc-table th{height:35px;text-align:left;padding-left:10px}.detail-page #helpdoc-table-command td{height:100px}.detail-page #helpdoc-table-version td{height:70px}.detail-page .helpdoc-table td img{max-width:80px;max-height:80px;margin:10px}.detail-page .helpdoc-table td p{margin-left:10px}.detail-page #helpdoc-head h1{font:bold 18px arial,sans-serif black;width:500px;overflow:hidden}.detail-page .helpdoc-element h1{font:bold 16px arial,sans-serif black;margin-bottom:5px}.detail-page #right-wrapper{color:#4d4d4d}.helpdoc-page #content{width:830px;margin:0 auto 100px auto;float:none;display:block}.detail-main .drawer{margin:0}.detail-main .subscriber-drawer{float:left}.no-result .purchase-panel{display:block}.no-result .purchase-result{display:none}.result-success .purchase-result-success{display:block}.result-success .purchase-result-not-success{display:none}.result-not-success .purchase-result-success{display:none}.result-not-success .purchase-result-not-success{display:block}.purchase-result-not-success-text a{color:red;text-decoration:underline}.multi-purchase-input-error{background:darksalmon!important}.purchase-panel{margin-top:5px}.purchase-panel>.purchase-action{margin-top:5px}.side-panel>span{font-size:14px}.purchase-panel #multi-purchase-btn{width:100%}.price-qty-total>.purchase-subtotal{font-weight:bold;font-size:14px}.purchase-action>.ui-button{width:100px;height:26px;border-radius:3px;font-size:14px;line-height:25px}.qty-purchased-limit>.off-button{background:url(../images/buttons/close_13.png) no-repeat 0 0;width:13px;height:13px;float:right;cursor:pointer}.qty-to-purchase{margin-top:10px}.qty-to-purchase-title{float:left;margin-right:5px;line-height:24px}.price-qty-total .stepper-input{float:left}.purchase-result-success-text{color:green}#multi-purchase-input{max-width:45px;padding:2px;text-align:center;margin-bottom:15px}.purchase-result-not-success-text{color:red}.purchase-result-info{margin:12px 0}.purchase-result-actions a{color:#1a52ad;cursor:pointer}.purchase-result-actions a:hover{color:#3d87ff}.purchase-result{margin-top:5px}.dealer-code{margin-top:10px}.dealer-code-title{float:left;margin-right:24px;line-height:24px}#dealer-code-input{max-width:45px;padding:2px;margin-bottom:4px}.dealer-code .explanation{display:inline-block;font-size:11px;color:#969696}.detail-page .dropdown.dropdown-wishlist{width:100%;margin-top:8px;border:0;box-shadow:none}.purchase-panel>.purchase-action{width:100%;border:0}#purchase>.dropdown-wishlist .dropdown-toggle{border:1px solid #29abe2;color:#29abe2;background:#fff;margin-top:0}.detail-page .purchase-container .dropdown-toggle .caret{border-top:4px solid #29abe2;position:relative;left:30%}.detail-page .purchase-container .dropdown-wishlist .dropdown-menu{border:1px solid #29abe2;color:#29abe2;background:#fff;text-align:center;height:inherit;margin-top:28px;color:#29abe2;border-top:0}.dropdown-wishlist .dropdown-menu>li>a:hover,.dropdown-menu>li>a:focus,.dropdown-submenu:hover>a,.dropdown-submenu:focus>a{background:0}.detail-page .purchase-container .dropdown-wishlist .divider{border-bottom:1px solid #29abe2;background-color:#fff;padding:0}.detail-page .purchase-container .dropdown-wishlist .dropdown-menu a{color:#29abe2}.side-panel .modal-header{border:0}.side-panel .modal-header h3{background:0;color:#29abe2;border:0;font-weight:700}.side-panel .modal-body .img-wrapper{padding-right:10px}.side-panel .modal-body input{width:97%;border:1px solid #29abe2}.side-panel .modal-footer{background:0;border:0}.side-panel .modal-footer .text-info{width:48%;background:0;border:1px solid #29abe2;color:#29abe2}.side-panel .modal-footer .btn-primary{width:49%;background:#29abe2}.side-panel #purchase #wishlistsmodel .price-str{font-size:20px;margin-top:14px}.pagination-content{display:inline-flex;display:-ms-flexbox;padding:0;border:1px solid #b3b3b3;border-radius:7px;background:white;height:24px}.pagination-content li.beginning-dots,.pagination-content li.final-dots{float:left;width:18px;line-height:20px;padding:0 6px;margin:0;text-align:center}.pagination-content li.beginning-dots:hover,.pagination-content li.final-dots:hover{background:0}.pagination-content li.pag,.pagination-content li.prev,.pagination-content li.next{float:left;width:22px;height:22px;line-height:20px;padding:2px 0 0 0;text-align:center;cursor:pointer}.pagination-content li.first{border-top-left-radius:7px;border-bottom-left-radius:7px}.pagination-content li.last{border-top-right-radius:7px;border-bottom-right-radius:7px}.pagination-content li.leftborder-pageitem{border-left:1px solid #b3b3b3}.pagination-content li.pag:hover,.pagination-content li.prev:hover,.pagination-content li.next:hover{background:#DDD;border-color:#999}.pagination-content li.current a{color:#29abe2}.pagination-content li a{color:#808080;display:block}.page_input_container{margin:4px 0 0 20px}.page_input_label{margin:3px 0 0 0;float:left}.page_input_textbox{float:left;height:16px;width:26px;border:1px solid #cecece;margin:0 4px 0 4px;padding:1px;text-align:center;height:10px!important}.page_input_go{float:left;border:1px solid #cecece;padding:2px 5px 1px 5px;height:15px;background:#f7f7f7}.page_input_go span,.page_input_go span:visited,.page_input_go span:hover{color:#4d4d4d}.quick-search-wrapper{margin-bottom:5px;height:22px}.quick-search-wrapper h3{float:left;margin:0 20px 0 0;height:22px;line-height:22px}.quick-search-wrapper .quick-search-form-filter{width:235px;height:22px;float:left}#search-results-extra hr{clear:both;margin:10px 0}.pagination-spinner{float:left;margin:7px;height:16px;width:16px;line-height:16px;display:none}.my-downloads-page#main{margin-bottom:50px}.my-downloads-page #content{width:1000px;display:block;float:none;margin:0 auto}.my-downloads-page .page-title{margin-bottom:30px;margin-left:-132px}.my-downloads-page .description-container{width:200px;word-wrap:break-word;word-break:normal}.my-downloads-page .cancel-subscription{text-align:right}#my-downloads table{margin:10px 0 20px 0;text-align:left;font-size:11px}#my-downloads table td,#my-downloads table thead th{border:0 none;padding:5px;vertical-align:middle}#my-downloads table td{border-left:1px solid #e6e6e6}#my-downloads table td:first-child{border:0}#my-downloads table tr{border-bottom:1px solid #e6e6e6}#my-downloads table td.info-cell{width:170px;min-width:147px}#my-downloads table td.description-cell{width:200px}#my-downloads table td.company-cell,#my-downloads table td.store-cell{width:90px}#my-downloads table td.update-cell{width:80px}#my-downloads table td.purchase-qty-cell{width:100px}#my-downloads table td.info-cell img{width:40px;height:40px;float:left;margin:3px 6px 3px 2px}#my-downloads table td.info-cell .product-info{float:left;width:95px;margin-top:4px}#my-downloads table td.info-cell .product-info a,#my-downloads table td.info-cell .product-info span{display:block;margin-bottom:5px;color:#595959}#my-downloads table td.info-cell .product-info a:focus,#my-downloads table td.info-cell .product-info a:hover{color:#06e}#my-downloads table td.update-cell img{margin:0 2px}#my-downloads table td.update-cell a{color:#1a52ad}#my-downloads table td.update-cell a:hover{color:#3d87ff}#my-downloads table td.help-cell img{margin:0 6px}#my-downloads table caption,#my-downloads h2{font:20px Arial;color:#4d4d4d;margin-bottom:2px;text-align:left}#my-downloads h2{margin-top:10px}#my-downloads h3{font-size:16px;font-weight:normal;color:#333}#my-downloads table thead tr{background:#999}#my-downloads table thead tr th{color:#FFF;text-align:left;font-size:12px}#my-downloads table tbody{color:#595959}#my-downloads table tbody .fullDescription-container p{margin:0 0 5px}#my-downloads table .odd-row{background:#f2f2f2}#my-downloads table .even-row{background:#FFF}.purchase-qty-cell,.purchase-date-cell{text-align:center}.purchase-date-div{width:120px}.purchase-date-span{float:left}.open .purchase-date-more{display:block}.purchase-date-more{display:none}.open .cell-more{display:none}.cell-more{cursor:pointer;display:inline}.open .cell-less{display:inline}.cell-less{cursor:pointer;display:none}td.description-cell .more_less{cursor:pointer;font-weight:bold;text-decoration:underline}.tooltip{display:none;position:absolute;min-height:10px;padding:7px 8px;z-index:84001;color:#666;border:1px solid #808080;border-color:rgba(0,0,0,.5);background-color:#f7f7f7;background:-webkit-gradient(linear,left top,left bottom,from(rgba(255,255,255,0.95)),to(rgba(230,230,230,0.95)));background:-webkit-linear-gradient(rgba(255,255,255,0.95),rgba(230,230,230,0.95));background:-moz-linear-gradient(rgba(255,255,255,0.95),rgba(230,230,230,0.95));-moz-border-radius:2px;-webkit-border-radius:2px;border-radius:2px;-moz-box-shadow:0 1px 2px rgba(0,0,0,.3);-webkit-box-shadow:0 1px 2px rgba(0,0,0,.3);box-shadow:0 1px 2px rgba(0,0,0,.3);-moz-background-clip:padding;-webkit-background-clip:padding;background-clip:padding-box;max-width:200px}.tooltip .pointer{position:absolute;top:-6px;left:5px;width:100%;height:6px;background:url(../images/icons/tooltip_pointer.png) no-repeat left top}.tooltip.right .pointer{left:auto;right:5px;background-position:right top}.tooltip.visible{display:block}.has_tooltip{cursor:help}#my-downloads table thead tr th.sortable{cursor:pointer}#my-downloads table thead tr th:hover,#my-downloads table thead tr th:focus{background:#575757}#my-downloads table thead tr th:active,#my-downloads table thead tr th.current{background:#3d3d3d}#my-downloads .order-arrow{float:right;margin:5px 3px 5px 5px;background:url(../images/icons/sort_arrow.png) no-repeat;height:4px;width:7px;display:none}#my-downloads .up{background-position:0 -4px}#my-downloads .down{background-position:0 0}#my-downloads table thead tr th.current a.order-arrow{display:block}#my-downloads table thead tr .th-titles{float:left;margin-right:2px}.my-uploads-page{padding-top:20px;width:960px}.my-uploads-page label{cursor:default}.my-uploads-page #content{width:960px;margin-left:122px}#my-published table input{cursor:pointer;background-color:transparent;text-decoration:none;border:0;color:blue}.detail-page-for-publisher#main{width:1260px}.detail-page-for-publisher#main>div{display:inline-block;vertical-align:top;width:18%}.detail-page-for-publisher#main .p-detail-tabs{width:1000px;margin-left:20px}.detail-page-for-publisher#main .p-detail-notification{width:98%}.developer-description #content{width:1280px}.developer-description #content div p{text-align:justify;text-justify:inter-word}.developer-description #content .headline{margin:10px 0;color:#29abe2;font-size:18px;font-weight:normal}.developer-description #content .legal-content{border:1px solid #ccc;padding:15px 30px;overflow-y:auto;height:453px;background:white;margin-bottom:20px}.developer-description #content .legal-content p:first-child{margin-top:0}.developer-description #content .sell-notice-level-1{font-size:16px;font-weight:bold;margin:10px 0;color:#4d4d4d}.developer-description #content .sell-notice-level-2{font-size:16px;font-weight:normal;color:#333}.developer-description #content .sell-notice-level-3{font-size:12px;color:#4d4d4d}.developer-description #content .sell-notice-note{font-style:italic;color:#333;font-size:12px}.developer-description #content ul.list-items{padding-left:20px;color:#4d4d4d}.developer-description #content ul.list-items li{margin:0 0 5px 15px;list-style-type:disc}.developer-description #content .actions{margin-bottom:24px;padding:30px 0;height:33px}.developer-description #content .publish-link{width:150px;padding:5px 0;border:0;font-size:14px;cursor:pointer;text-align:center;color:white}.developer-description #content .back,.developer-description #content .signin_link{width:150px;border:0;padding:5px 0;font-size:14px;cursor:pointer;height:25px;text-align:center;color:white}.developer-description #content .publish-link,.developer-description #content .signin_link{float:right}.grey-button{background:linear-gradient(#666,#2e2e2e);background:-webkit-gradient(linear,left top,left bottom,from(#666),to(#2e2e2e));background:-webkit-linear-gradient(#666,#2e2e2e);background:-moz-linear-gradient(#666,#2e2e2e);background:-o-linear-gradient(#666,#2e2e2e);border:1px solid #303030}.no-cssgradients .grey-button{background:#2e2e2e url(../images/icons/bg-gradient-button-gray.png) repeat-x 0 0}.no-cssgradients .grey-button:hover,.no-cssgradients .grey-button:focus{background-position:0 -32px}.no-cssgradients .grey-button:active{background-position:0 -64px}.no-cssgradients .grey-button:disabled{background-position:0 -78px;cursor:default!important}.no-cssgradients .grey-button[disabled],.no-cssgradients .grey-button[disabled]:hover,.no-cssgradients .grey-button[disabled]:active{background-position:0 -96px;cursor:default!important}.grey-button:hover,.grey-button:focus{background:linear-gradient(#808080,#474747);background:-webkit-gradient(linear,left top,left bottom,from(#808080),to(#474747));background:-webkit-linear-gradient(#808080,#474747);background:-moz-linear-gradient(#808080,#474747)}.grey-button:active{background:linear-gradient(#595959,#1f1f1f);background:-webkit-gradient(linear,left top,left bottom,from(#595959),to(#1f1f1f));background:-webkit-linear-gradient(#595959,#1f1f1f);background:-moz-linear-gradient(#595959,#1f1f1f)}.grey-button:disabled{background:linear-gradient(#a6a6a6,#6e6e6e);background:-webkit-gradient(linear,left top,left bottom,from(#a6a6a6),to(#6e6e6e));background:-webkit-linear-gradient(#a6a6a6,#6e6e6e);background:-moz-linear-gradient(#a6a6a6,#6e6e6e);cursor:default!important}.developer-terms-and-conditions #content{width:1280px}.developer-terms-and-conditions #content .headline{margin:10px 0;color:#4d4d4d;font-size:16pt}.developer-terms-and-conditions #content .legal-content{border:1px solid #bfbfbf;background:white;padding:10px;overflow-y:auto;height:553px}.developer-terms-and-conditions #content .legal-content .legal-left{width:49%;float:left;margin-right:10px;padding-right:10px;border-right:solid 1px}.developer-terms-and-conditions #content .legal-content .legal-right{float:left;width:49%}.developer-terms-and-conditions #content .actions{margin-bottom:30px;padding-top:20px}.developer-terms-and-conditions #content p{color:#4d4d4d}.developer-terms-and-conditions #content .legal-content p:first-child{margin-top:0}.publisher-agreement-item-level-1{margin-left:12px;text-indent:-12px}.publisher-agreement-items-level-2-container p{margin-left:22px;text-indent:-22px}.publisher-agreement-items-level-3-container p{margin-left:52px;text-indent:-42px}.developer-terms-and-conditions #content .exhibit-a{margin-top:50px;text-decoration:underline}.eula-term-1-container p{margin-left:15px;padding-left:15px;text-indent:-15px}.eula-term-2-container p{margin-left:30px}.eula-term-3-container p{margin-left:45px}.developer-terms-and-conditions #content .agree-continue{float:right}.developer-terms-and-conditions #content .legal-form{height:25px}.developer-terms-and-conditions #content .legal-form .not-agree{margin-left:10px}.developer-terms-and-conditions #content .continue{padding:0 20px;font-size:14px;cursor:pointer;text-align:center;line-height:25px;color:white;float:left;background:#29abe2;border:1px #29abe2 solid;width:150px;height:25px}.developer-terms-and-conditions #content .cancel{padding:0 20px;font-size:14px;cursor:pointer;text-align:center;line-height:25px;color:#29abe2;float:left;background:white;border:1px #29abe2 solid;width:115px;height:25px}.developer-terms-and-conditions #content .legal-form .fields{margin-top:5px;line-height:25px;float:left;color:#4d4d4d}.developer-terms-and-conditions #legal-agree{float:left}.developer-terms-and-conditions #content .legal-form .label{display:block;float:left;margin-left:8px;background-color:transparent;color:red;font-weight:normal}.developer-terms-and-conditions #content .legal-form .separator{height:25px;width:1px;border-left:1px solid #a6a6a6;margin:0 8px;float:left}.wizard-navigation ul li span.status{position:absolute;top:24px;right:0;z-index:105;padding:0!important}.wizard-navigation ul li span.status.ok{background:transparent url(../images/icons/wizard_nav_ok.png) no-repeat left center;width:13px;height:16px}.developer-submit-product #content{color:#29abe2;width:1080px;padding-bottom:30px;padding-left:80px}.developer-submit-product label{cursor:default;margin:0;display:inline-block}.developer-submit-product #paymentgateway-settings label{display:block}.developer-submit-product .templates{display:none}.developer-submit-product #content h3.wizard-init{text-align:center;margin-top:190px}.developer-submit-product #content h2{color:#29abe2;margin:15px 0 5px;font-size:18px;float:left;font-weight:normal}.developer-submit-product #content .wizard-navigation{overflow:hidden;width:1080px;position:relative}.developer-submit-product #content .wizard-navigation ul{margin:20px 0 0 0;padding:0;height:27px;float:right;list-style:none}.developer-submit-product #content .wizard-navigation ul li{margin:0;padding:0;list-style:none;cursor:default;visibility:collapse;width:0;float:right}.developer-submit-product .topEmphasis{font-family:Arial;font-size:15px;color:#29abe2;font-weight:bold;margin-bottom:10px}.developer-submit-product #promptFlash,.developer-submit-product #promptFlash a,.developer-submit-product #promptFlash a:hover,.developer-submit-product #promptFlash a:active,.developer-submit-product #promptFlash a:visited{font-family:Arial;font-size:11px;color:#4675a8;font-weight:bold;margin-bottom:5px}.developer-submit-product #content .wizard-navigation ul li span{display:block;padding:5px 20px 5px 0;line-height:17px;font-size:14px;font-weight:normal}.developer-submit-product #content .wizard-navigation ul li.active{visibility:visible;width:auto}.developer-submit-product #content .wizard-side{border-top:1px solid #bfbfbf;border-bottom:1px solid #bfbfbf;border-left:1px solid #bfbfbf;width:152px;background-color:#4d4d4c;height:508px;float:left;color:white}.developer-submit-product #content .wizard-side li.add{display:none}.developer-submit-product #content .wizard-side p{padding:0 8px;margin:0;color:#b2b2b2;font-size:10px}.developer-submit-product #content .wizard-side h4{color:white;padding-left:12px;border-bottom:1px solid #333;margin:0;font-weight:bold;font-size:12px;line-height:27px}.developer-submit-product #content .wizard-side h5{color:white;padding:2px 0 2px 22px;margin:0;font-weight:normal;font-size:10px;line-height:13px}.developer-submit-product #content .wizard-side h5.add-language{background:transparent url(../images/icons/add_remove_language.png) no-repeat -400px center}.developer-submit-product #content .wizard-side h5.remove-language{background:transparent url(../images/icons/add_remove_language.png) no-repeat 0 center}.developer-submit-product #content .wizard-side ul{margin:0;padding:0}.developer-submit-product #content .wizard-side ul li{color:white;margin:0;padding:8px}.developer-submit-product #content .wizard-side ul li.selected{color:#fff;font-size:12px;background:#496b9b url(../images/icons/selected_language.png) no-repeat right center;border-bottom:1px solid #333}.developer-submit-product #content .wizard-side ul li.remove,.developer-submit-product #content .wizard-side ul li.template{display:none}.developer-submit-product #content .wizard-side .wizard-progress{height:20px;line-height:20px}.developer-submit-product #content .wizard-side .wizard-progress .progress-bar{width:75px;height:6px;padding:2px;background-color:#b7b7b7;float:left;margin-top:8px;-moz-border-radius:4px;-webkit-border-radius:4px;border-radius:4px}.developer-submit-product #content .wizard-side .wizard-progress .progress-bar .bar{display:block;height:6px;width:0;background-color:#666;-moz-border-radius:4px;-webkit-border-radius:4px;border-radius:4px}.developer-submit-product #VersionListDiv{float:left;padding-bottom:5px;width:100%}.developer-submit-product #content .wizard-side .wizard-progress .progress-bar .bar.red{background-image:-webkit-linear-gradient(bottom,#c0262c 0,#ec1b23 50%,#c0262c 100%);background-image:-moz-linear-gradient(bottom,#c0262c 0,#ec1b23 50%,#c0262c 100%);background-image:-ms-linear-gradient(bottom,#c0262c 0,#ec1b23 50%,#c0262c 100%);background-image:linear-gradient(bottom,#c0262c 0,#ec1b23 50%,#c0262c 100%)}.developer-submit-product #content .wizard-side .wizard-progress .progress-bar .bar.orange{background-image:-webkit-linear-gradient(bottom,#f6721d 0,#f3a22b 50%,#f6721d 100%);background-image:-moz-linear-gradient(bottom,#f6721d 0,#f3a22b 50%,#f6721d 100%);background-image:-ms-linear-gradient(bottom,#f6721d 0,#f3a22b 50%,#f6721d 100%);background-image:linear-gradient(bottom,#f6721d 0,#f3a22b 50%,#f6721d 100%)}.developer-submit-product #content .wizard-side .wizard-progress .progress-bar .bar.green{background-image:-webkit-linear-gradient(bottom,#38b448 0,#8ac53e 50%,#38b448 100%);background-image:-moz-linear-gradient(bottom,#38b448 0,#8ac53e 50%,#38b448 100%);background-image:-ms-linear-gradient(bottom,#38b448 0,#8ac53e 50%,#38b448 100%);background-image:linear-gradient(bottom,#38b448 0,#8ac53e 50%,#38b448 100%)}.developer-submit-product #content .wizard-side .wizard-progress .progress-percentage{float:left;padding:3px 0 0 7px}.developer-submit-product #content .wizard-side .wizard-progress .progress-help{background:url(../images/icons/help.png) no-repeat 0 0;width:16px;height:16px;float:left;margin:5px 0 0 9px}.developer-submit-product #content .wizard-content{border:1px solid #ccc;overflow-y:auto;overflow-x:hidden;width:1040px;padding:0 20px 10px 20px;float:left;background-color:#fff;position:relative}.developer-submit-product .wizard-content input[type="text"],.developer-submit-product .wizard-content textarea{-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.developer-submit-product #content .wizard-actions{margin-top:15px;float:left;width:1080px}.developer-submit-product #content .wizard-actions input[type="button"],.developer-submit-product #content .wizard-actions a{width:auto;padding:0 20px;border:0;font-size:14px;cursor:pointer;height:25px;text-align:center;line-height:25px;color:white}.developer-submit-product #content .wizard-actions .cancel{float:left;color:#29abe2;background:white;border:1px #29abe2 solid;width:150px;height:25px}.developer-submit-product #content .wizard-actions .back{float:left;display:none}.developer-submit-product #content .wizard-actions .save{float:right;width:150px;height:25px}.developer-submit-product #content .wizard-actions .continue{float:right;margin-left:8px;width:150px;height:25px}.developer-submit-product #content .wizard-actions .backtosummary,.developer-submit-product #content .wizard-actions .submit,.developer-submit-product #content .wizard-actions .preview{float:right;display:none;margin-left:8px}.developer-submit-product #content .finish-link{width:auto;padding:0 20px;border:0;font-size:14px;cursor:pointer;height:25px;text-align:center;line-height:25px;color:white}.remindErrorDiv{margin-bottom:10px}.remindErrorDiv .errorRemind a{font-size:13px;font-weight:bold;color:red;padding-bottom:5px;text-decoration:underline}#publish-step2-products .compatibility-des-sep{margin:0}#publish-step2-products .compatibility-des{width:790px}#publish-step2-products .families-products td:first-child{width:200px}#publish-step2-products table.version-grid{width:100%}.fancy-layer-image{content:url(../images/icons/ajax-loader400.gif);width:30px}#fancy-layer{height:100px}#fancy-layer.overlay_window{background:white}.wizard-tab{font-size:12px;position:relative}.no_float{float:none!important}.wizard-tab h4{float:left;margin-bottom:5px}#wizard-help-documentation h4{float:left}#wizard-help-documentation>span.explanation{margin:0}.wizard-tab h4+span.explanation{margin-bottom:5px}.wizard-tab #contact-info+span.explanation{display:inline-block}.wizard-tab span.required{display:inline;color:Red;font-weight:bold}.wizard-tab .explanation{display:inline-block;color:#666;font-weight:normal;font-size:11px}.command_tools .explanation{display:block;color:#666;font-weight:normal;font-size:11px}.command_tools .commandName{width:400px}.command_tools .sub-title{display:block}.command_tools textarea{width:400px}.thumbnail-preview .browse-button{float:left;margin-right:5px;font-size:12px;height:25px;width:150px}.file-info .explanation{display:inline-block;color:#666;font-weight:normal;font-size:11px}#privacyDetail{font-size:15px}#privacyDetail ul{padding:0;margin-left:4px}#privacyDetail li{margin:8px;list-style:none}#publish-step2-products .explanation,#publish-step2-categories .explanation{float:left;display:inline;width:790px}.wizard-tab span.error,#contact-info span.error{display:none;margin:2px 27px 2px 15px;color:#c80000;font-size:11px;background:transparent url(../images/icons/wizard_error.png) no-repeat left center;padding-left:14px}#contact-info span.error{float:none;margin-right:2px;margin-top:4px}.wizard-tab .text span.error{margin:2px 0 2px 0;float:none}#contact-info span.error.visible,.wizard-tab span.error.visible{display:inline}.wizard-tab .separator{display:block;height:10px}#publish-step2-products .separator,#publish-step2-categories .separator{display:inline-block;width:790px;height:20px}.wizard-tab textarea,.wizard-tab input[type="text"]{width:100%;margin-bottom:1px;border:1px solid #bbb;padding:2px;display:block}.wizard-tab .command_tools textarea,.wizard-tab .command_tools input[type="text"]{width:772px}.wizard-tab textarea.error,.wizard-tab input[type="text"].error{border:1px solid #c80000}.wizard-tab textarea{resize:none}#wizard-help-documentation textarea{display:inline}.wizard-tab input[type="radio"]{display:inline}.wizard-tab input[type="checkbox"]{display:inline;margin-right:10px}.wizard-tab #prices label{margin:10px 0;cursor:pointer}.wizard-tab h5{font-weight:normal;margin:0}#app-file>*:not(label){margin-left:0;width:auto}#app-file>textarea{width:97%;margin-top:5px}#app-file>label{font-size:12px}#app-file>label>input{position:relative;top:1px;margin-right:4px}.wizard-tab h4+.file-uploader{margin-top:10px}.wizard-tab .file-uploader .file{width:auto;padding:4px 4px 4px 0;background-color:white;min-height:25px;margin:5px 0}.wizard-tab .file-uploader .file .plupload input{cursor:pointer}.wizard-tab .file-uploader .file .plupload input[disabled]{display:none}.wizard-tab .file-uploader .file .file-info .thumbnail{float:left}.wizard-tab .file-uploader .file .file-info .file-name,.wizard-tab .file-uploader .file .file-info .file-size{float:left;padding:6px 10px 4px}.wizard-tab .file-uploader .file[data-uploader-state="uploading"] .file-info .file-name{max-width:135px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.wizard-tab #app-screenshot.file-uploader .file[data-uploader-state="uploading"],.wizard-tab #app-screenshot.file-uploader .file[data-uploader-state="queuedOnHold"],.wizard-tab #app-screenshot.file-uploader .file[data-uploader-state="uploadedOnHold"],.wizard-tab #app-screenshot.file-uploader .file[data-uploader-state="queued"]{min-height:75px}.wizard-tab .file-uploader .file .file-info .upload-progress{width:280px;height:20px;line-height:20px;position:absolute;right:115px}.wizard-tab .file-uploader .file .file-info .progress-bar{width:230px;height:6px;padding:2px;background-color:white;float:left;margin-top:8px;-moz-border-radius:4px;-webkit-border-radius:4px;border-radius:4px}.wizard-tab .file-uploader .file .file-info .progress-bar .bar{display:block;height:6px;width:0;min-width:1%;background-color:white;background-image:-webkit-linear-gradient(bottom,#29abe2 0,#6ac6ed 50%,#29abe2 100%);background-image:-moz-linear-gradient(bottom,#29abe2 0,#6ac6ed 50%,#29abe2 100%);background-image:-ms-linear-gradient(bottom,#29abe2 0,#6ac6ed 50%,#29abe2 100%);background-image:linear-gradient(bottom,#29abe2 0,#6ac6ed 50%,#29abe2 100%);-moz-border-radius:4px;-webkit-border-radius:4px;border-radius:4px}.wizard-tab .file-uploader .file .file-info .progress-percentage{float:left;padding:3px 0 0 10px}.wizard-tab .upload-button,.wizard-tab .cancel-button,.wizard-tab .remove-button{float:right;width:100px}.wizard-tab .browse-button{float:left;margin-right:5px;font-size:12px;height:25px;width:150px}.wizard-tab .uploader-loading .browse-button{visibility:hidden}#app-screenshot .thumbnail{width:205px;min-height:120px;display:none}.screenshot_tools{position:absolute;right:5px;top:40px;left:219px;bottom:5px}.screenshot_tools .description_container{position:absolute;left:0;right:0}.screenshot_tools input[type="checkbox"]{float:left;margin-right:5px;padding:0}.screenshot_tools .description_container .description{width:519px;margin:0}#wizard-help-documentation .cert-span{margin-top:3px;display:block;float:none;margin-left:0}#wizard-help-documentation .cert-span .cert-explanation{margin-left:23px}#wizard-help-documentation .cert-image{margin-bottom:5px}#wizard-help-documentation h4+span.cert-explanation{margin-top:0;margin-bottom:8px}#wizard-help-documentation .cert-explanation a,#wizard-help-documentation .cert-explanation a:link,#wizard-help-documentation .cert-explanation a:hover,#wizard-help-documentation .cert-explanation a:active,#wizard-help-documentation .cert-explanation a:visited{color:#29abe2}#wizard-file-uploading .errors,wizard-help-documentation .errors{position:relative;float:right}#publish-step2-companyandprice #prices,#publish-step2-companyandprice #applogintypes{display:block;margin:5px 0 5px}#publish-step2-companyandprice input.priceinput{width:150px;display:inline}#wizard-app-information #app-versions{width:100%}#wizard-app-information #app-versions .version .remove,#wizard-help-documentation #app-commands .command .remove-command{background:url(../images/buttons/close_24.png) no-repeat 0 0;width:24px;height:24px;top:-7px;position:absolute;right:-12px;cursor:pointer}#version-changed-input .mceEditor{margin-bottom:10px}#wizard-help-documentation #app-commands .command .remove-command.with_spinner{background:0}.file-info{position:relative}.file-info .remove-button+.with_spinner{display:inline-block;right:5px;position:absolute;top:5px}#wizard-app-information #app-versions .version.template,#wizard-help-documentation #app-commands .template{display:none;position:relative}#wizard-app-information #app-versions .version{margin-top:10px}#wizard-app-information #app-versions .version .number input{width:120px;margin-top:5px}#wizard-app-information #app-versions .version .description textarea{width:560px;margin-top:5px}#wizard-app-information #app-versions .version .number{width:145px;float:left}#wizard-app-information #app-versions .description{float:left;width:100%}#wizard-app-information .new-version{width:auto;margin-top:6px;cursor:pointer;text-align:center}#wizard-app-information #app-versions .version .remove{background:url(../images/buttons/close_24.png) no-repeat 0 0;width:24px;height:24px;top:-7px;position:absolute;right:-12px;cursor:pointer}#wizard-app-information #app-versions .version.template{display:none;position:relative}#publish-step2-companyandprice #payment-settings{display:none}#publish-step2-companyandprice{margin-bottom:14px}#wizard-file-uploading .add-screenshot-container{margin-top:6px}#wizard-file-uploading .add-screenshot-container>*{vertical-align:middle;margin-bottom:10px}.wizard-app-compatibility input[type="checkbox"]{margin:0 5px 0 5px;position:relative;top:2px}table.expandable-grid tr.title{background-color:#e5e5e5;border-bottom:1px solid #797979}table.expandable-grid tr.title td{padding-left:10px;font-size:13px;font-weight:bold;height:30px;line-height:30px}table.expandable-grid tr.expansor{border-bottom:0 solid #797979}table.expandable-grid tr.expansor.expanded{border-bottom:0}table.expandable-grid tr.expandable{border-bottom:0 solid #797979}table.expandable-grid{margin-top:5px;float:left;width:100%;border:0 solid #797979;border-collapse:collapse}table.expandable-grid tr{width:100%;border-collapse:collapse}table.version-grid{width:100%;margin:5px 0 10px 0}table.version-grid tr{border:1px #29abe2 solid}table.version-grid thead .store-version{width:80px}table.expandable-grid tr.expansor td{height:20px;cursor:pointer}table.expandable-grid tr.expansor td span{font-size:13px}table.expandable-grid tr.expansor.expanded td span div.arrow{background:url(../images/icons/expand-collapse-sprite.png) no-repeat top right}table.expandable-grid tr.expansor td span div.arrow{background:url(../images/icons/expand-collapse-sprite.png) no-repeat top left;margin:0 5px 0 5px;width:13px;height:13px;display:inline-block}#wizard-app-categories #app-families,#wizard-app-categories #store-list{margin:8px 0 8px}#wizard-app-categories #store-list{width:755px}#wizard-app-categories #store-list .store-title{width:200px}#wizard-app-categories .families-products .store-title.disabled{color:#b1b1b1}#publish-step2-categories .families-products td.label{color:black;background:transparent;text-shadow:none}#publish-step2-categories table.version-grid{margin-top:2px}#wizard-app-categories #store-list .store-version{width:100px}#wizard-app-categories #store-list tbody tr:nth-child(even){background-color:#e8e8e8}#wizard-app-categories #recommend{margin-top:10px;background-color:#e8e8e8;padding:5px}#wizard-app-categories .othercategory-container{display:inline-block;margin-top:20px}#wizard-help-documentation #app-commands{width:100%}#wizard-help-documentation #app-commands .command{margin-top:10px;padding:5px;position:relative}#wizard-help-documentation #app-commands .command h3{margin:0;font-weight:normal}#wizard-help-documentation #app-commands .command .file{width:717px}#wizard-help-documentation #app-commands .command .save-command{right:7px;bottom:7px}#wizard-help-documentation .new-command{width:150px;margin-top:5px;cursor:pointer;height:25px;text-align:center;line-height:25px;font-size:12px;display:block}#wizard-help-documentation .mceEditor{margin-top:5px;display:block}#wizard-app-summary .info{min-height:20px;padding:2px 5px;line-height:20px}#wizard-app-summary .info:nth-child(even){background-color:#e8e8e8}#wizard-app-summary .info .description{float:left;width:210px;font-weight:normal;color:#666}#wizard-app-summary .info>*{display:inline-block;margin-left:10px;color:black}#wizard-app-summary .info .value p{margin:0}#wizard-app-summary .summary-icon{width:80px;height:80px}#wizard-app-summary .summary-screenshot{border:1px #29abe2 solid;width:200px;height:120px}#wizard-app-summary .summary-screenshot img{height:120px}.developer-submit-complete #content{width:940px}.developer-submit-complete #content h1,.developer-submit-complete #content h2{color:#4d4d4d}#footer{border-top:1px solid #c4c4c4;height:38px;line-height:38px;background-color:#f3f3f3;font-size:11px;color:#999}.footer_wrap{margin:0 auto;height:38px;line-height:38px;background:url(../images/icons/adsk_footer_logo.png) no-repeat right center}.footer_wrap .copy{line-height:38px;height:38px;float:left;color:#949494}.copy p{margin:0;padding:0}.footer_wrap .legalese{float:left;list-style-type:none;margin:0;padding:0;height:38px;line-height:38px;padding:0}.footer_wrap .btn-group button{font-size:12px}.footer_wrap .btn-group .dropdown-menu{top:auto;bottom:100%;min-width:80px}.footer_wrap .btn-group .dropdown-menu li{font-size:12px;padding-left:6px}.footer_wrap .btn-group .dropdown-menu li:hover{color:white;background-color:#0081c2}.legalese li{list-style-type:none;margin-left:12px;float:left;cursor:pointer;line-height:38px}.legalese li a{color:#999}.legalese li a:hover,.legalese li:hover{color:#666}.contact_us{font-size:104%;font-weight:bold!important;color:#666}.paynow_button form input[type="submit"]{background:none repeat scroll 0 0 transparent;border:0 none;color:#fff;margin:0;padding:0}#supported_languages{width:400px}#supported_languages ul{padding:0;margin:0}#supported_languages ul li{color:#000;padding-left:25px;line-height:23px;cursor:pointer}.odd{background-color:#fff}.even{background-color:#f2f2f2}#supported_languages ul li:hover{background-color:#dae2ef}#supported_languages ul li.selected{background-color:#8899b4;color:#fff}#accept_terms_section{font-size:12px;width:780px}#accept_terms_section label{display:inline}#accept_terms_section .group_body_container{margin:20px}#accept_terms_section .group_body_container input[type="checkbox"]{margin-right:10px}#accept_terms_section .group_body_container>div{margin-bottom:20px}#accept_terms_section .group_body_container a{color:#039}#accept_terms_section .group_body_container p.legal{font-size:10px;font-style:italic;margin-left:27px}#accept_terms_section .group_body_container .receiveEmail label{display:inline-block;margin-left:23px}#accept_terms_section .group_body_container .receiveEmail input{position:absolute}.input_text_readonly{background-color:#f4f4f4;color:#555}#accept_terms_section .alert{color:red;margin-left:13px}#confirmationPopup button[data-type="Cancel"]{margin-right:6px}#confirmationPopup button{min-width:35px}#wizard-app-categories .families-products td.categorycheck input[type=checkbox]{margin-left:0}#wizard-app-categories .families-products td.label{width:210px}#wizard-app-products .selectAll{font-size:10px}#wizard-app-products .version-grid td label{font-size:12px;white-space:normal;display:inline-block}.faq-page h1{font-size:15pt;margin:15px 0;text-align:center}.faq-page .leftalig-headline{text-align:left}.faq-page h3{font-size:11pt}.faq-page p{margin:0 0 15px}.faq-page ul{margin:0 0 15px;padding:0;list-style:square inside none}.faq-page ul li{list-style:square inside none;margin-top:10px;margin-bottom:3px;margin-left:20px}.faq-page .numbered-ul li{list-style-type:decimal}.faq-page .circled-ul li{list-style-type:disc}.faq-page .empty-circled-ul li{list-style-type:circle}.faq-page ul li img{margin-top:5px}.faq-page .faq_notediv{margin-top:5px;margin-bottom:5px;border-bottom:1px solid #5b9bd5;border-top:1px solid #5b9bd5;color:#5b9bd5;padding:5px}.faq-page .cancel_subscription ol,.faq-page .cancel_subscription ol li{list-style:decimal!important}.faq-page .cancel_subscription ul,.faq-page .cancel_subscription ul li{list-style:disc!important}.faq-page .cancel_subscription ul{padding-left:40px!important}#back-to-top,#back-to-top:visited{margin:7px 0 7px 0;text-align:center;float:left;color:#369}.strikeout-price{text-decoration:line-through;vertical-align:middle;font-size:10px;color:#808080;padding:0;margin-right:15px;display:inline;clear:both}.product-badge-div-placeholder{margin:1px 0 1px 0;height:16px}#detail-info span.subscriptionDes{vertical-align:middle;font-size:12px;float:right}.subscriptionBadge{float:none;position:relative;width:16px;height:16px;margin:0}.big-subscriptionbadge{width:24px;height:24px}.badge-popup-div{position:absolute;display:none;left:-82px;width:180px;font-size:10px;overflow:hidden;z-index:9999;text-align:center}.subscriber-pop-up{left:0;top:10px}.big-badge-popup-offset{left:-78px}.badge-popup-content-div{border-style:solid;border-width:0 1px 1px 1px;border-color:#6d6e70;background-color:white;margin:0;padding:10px}.badge-popup-content-div p{margin:0;padding:0;color:#000}.badge-popup-content-div a{color:blue}.badge-popup-header-div{height:0;margin:0;padding:0}.badge-popup-div img.badge-popup-header-img{float:none;height:10px;width:180px;margin:0}.badge-hover-stub:hover .badge-popup-div{display:block}.subscriber-hover-stub,.badge-hover-stub{position:relative}.product-rating-small-bestseller .star-rating{width:13px;height:12px;cursor:default;display:inline-block;background:url(../images/icons/star_small.png) no-repeat 0 0;overflow:hidden;vertical-align:middle;margin:0 0 4px 2px}.product-rating-small-bestseller .star-on{background-position:0 -12px!important}.product-rating-small-bestseller .star-off{background-position:0 0!important}.ellipsis{width:120px;overflow:hidden;text-overflow:ellipsis;-o-text-overflow:ellipsis;-ms-text-overflow:ellipsis;white-space:nowrap;display:inline-block}#restrict_access_wrapper h2{color:#000;font-size:20px;font-weight:normal}#restrict_access_wrapper h3{font-weight:normal;color:#666;font-size:14px;margin:0 0 15px 0}#restrict_access_wrapper label{font-weight:bold}#restrict_access_wrapper #no_passcode_label li{padding-bottom:20px}#restrict_access_wrapper #no_passcode_controls li{padding-bottom:10px}#restrict_access_wrapper .ui-button{width:70px}#restrict_access_wrapper .text-box{width:200px}#restrict_access_wrapper .multi-line{width:400px;height:100px}#restrict_access_wrapper{margin:10px auto;width:900px;padding:10px}#restrict_access_wrapper #left_panel{float:left;width:80px;margin:10px;padding:10px}#restrict_access_wrapper #right_panel{float:left;width:650px;margin:10px;padding:10px}#restrict_access_wrapper #passcode_label{float:left;width:100px;padding:5px;text-align:right;margin-top:5px}#restrict_access_wrapper #passcode_controls{float:left;width:200px;padding:5px}#restrict_access_wrapper #passcode_submit{position:relative;left:115px;top:5px;clear:both}#restrict_access_wrapper #divider{border-top:1px solid #666;margin:20px 0}#restrict_access_wrapper #no_passcode_label{float:left;width:100px;padding:5px;text-align:right;margin-top:5px}#restrict_access_wrapper #no_passcode_controls{float:left;width:200px;padding:5px}#restrict_access_wrapper #no_passcode_submit{position:relative;left:115px;top:5px;clear:both}#restrict_access_wrapper .validation-summary-errors{position:relative;clear:both;left:115px}#restrict_access_wrapper #passcode_description{margin-bottom:0}#restrict_access_wrapper a:link,#restrict_access_wrapper a:visited,#restrict_access_wrapper a:hover{color:#1a52ad}#HealthStatus table{margin:10px 0 20px 0;text-align:left;font-size:11px;width:700px}#HealthStatus table td,#HealthStatus table thead th{padding:5px;vertical-align:middle;text-align:left}div.developer-submit-product span.profile-notice{float:left;color:#666}#app-detail-for-publisher #icon{float:left}#app-detail-for-publisher #detail-info div.title-rating span{float:right;padding-top:2px}#app-detail-for-publisher #detail-info div.description{margin-top:10px}option.disabled{background-color:lightgray}#language-selector-title{color:#29abe2;font-weight:normal;font-family:Arial;font-size:18px;margin-top:20px}#language-os-selector-info{float:left;border:1px #a8a8a8 solid;border-radius:4px;padding:20px 20px 10px 20px;margin:5px 10px 30px 0;background:white}#os-selector-info{float:none}#language-os-selector-desc{clear:both;padding-top:15px;font-size:11px;color:#999;font-family:Arial}#detail .language-os-select,#language-os-selector-info .language-os-select{width:130px;height:28px;padding-left:8px;border:1px solid #666;border-radius:2px;margin-right:10px}#language-os-selector-info .language-selector-group .language-selector-title,#os-selector-info .os-selector-title{margin-right:10px;color:#29abe2;font-family:Arial;font-size:20px}#language-os-selector-info .language-selector-group{float:left}#detail .language-os-select option,#language-os-selector-info .language-os-select option{line-height:20px;color:#000;font-family:Arial!important;font-size:12px!important}#language-os-selector-info separator span{color:#666;font-weight:normal;font-family:Arial;font-size:11px}.language-selector-cancelButton{height:31px;width:100px;float:left;font-weight:normal;font-family:Arial;font-size:14px}.language-selector-continueButton{height:31px;width:100px;float:right;margin-right:10px;color:#fff;font-weight:normal;font-family:Arial;font-size:14px}#action-wrapper .flat-button,#app-detail-for-publisher{width:230px;float:left;margin-bottom:13px}#action-wrapper span#action-link{margin-left:10px}#my-published .product-info{width:150px;float:left}#my-published .info-cell>div{display:inline-block}#my-published .image-info{width:58px;height:58px;float:left;margin-right:6px}#my-published .product-info a.details_link{width:150px}#my-published .product-info div.details_div{height:16px}#my-published a.publish-link{display:block;width:160px;height:31px}#apps-description{margin:2px 0 2px 0}.product-info .details_dropdownul{margin-top:0;padding:0}.product-info .details_dropdownul .drop_down{padding-top:5px}.product-info .details_dropdownul .live_version_info,.product-info .details_dropdownul .preview_version_info{cursor:default;padding-right:10px;background:url(../images/buttons/btn_popup_sort.png) no-repeat right 7px}#my-published #published-products td.language-cell div.live_version_info,#my-published #published-products td.language-cell div.preview_version_info{height:40px;overflow:hidden}#my-published .has_preview_version .live_version_info{display:none}.keyword-font{font-weight:bold;font-size:13px;color:#000}.normal-font{font-size:13px;color:#595959;word-wrap:break-word}.link-font{font-family:Arial;font-size:12px;color:#4675a8}.cash-font{font-family:Arial;font-size:16px;color:#000}.submit-font{font-family:Arial;font-size:12px;color:#fff}.description-font{font-family:Arial;font-size:11px;color:#666}.learn-more-font{font-family:Arial;font-size:11px;color:#4675a8;margin-bottom:7px}.detail-page #detail .gotoUrl,.detail-page #detail #detailosselector{height:28px;width:130px;border-color:#a8a8a8;border-radius:2px;background:linear-gradient(#f9f9f9,#d5d5d5);color:#000;font-weight:normal;font-family:Arial;font-size:12px}#store-management{width:900px;margin:0 auto;min-height:1200px}#store-management h3,#store-management .show-top-title{float:left}#store-management h1{margin:33px 0 25px}#store-management h3,#store-management .show-top-title{display:inline;line-height:30px}@media only screen and (max-width:780px){#store-management{margin:5%;width:90%}}#store-management .section{margin:20px 0}#store-management #selection.section{height:50px}#store-management .section .resp-content-div ul.sortable{margin-top:40px}#horizontalTab .resp-tabs-container{margin:0 7px 15px 0}#horizontalTab .settings-button{float:right;margin:5px 10px 5px 10px}#storeActions input{margin:5px}#store-management .special-group-widget-img{float:left;margin-right:7px}.selection-div{display:inline;margin-right:10px}.selection-div *{font-size:12px}.selection-div select{width:130px}#languageSelection{margin-left:10px}#store-management ul{list-style-type:none;margin:0;padding:0;margin-bottom:10px}#store-management .sortable li{float:left;width:180px;height:100px;margin:10px 10px;background:#ddd;border:1px solid lightgray;padding:1px;border-radius:5px}#store-management .sortable li:hover{border:1px solid #2a6496}#store-management li#draggable{float:left}#store-management .store-apps-container .sortable{width:650px;min-height:900px}#store-management .store-apps-container .sortable img{width:80px;height:80px;float:left}#store-management div.product-info{float:left;width:98px;position:relative;top:-20px;padding-left:2px}#store-management .publisher-name{display:block;overflow:hidden;width:98px;height:15px;font-weight:bold}#store-management #visible-settings{display:inline;font-weight:bold;font-size:14px;margin-left:10px}#store-management #select-app{display:inline;font-weight:bold;font-size:14px}#store-management #select-app{float:right;margin-right:80px}#store-management #select-app input{display:block;float:right}#store-management #select-app span{display:block}#store-management .button{width:auto;border:0;font-size:14px;cursor:pointer;height:24px;text-align:center;color:white}#store-management .store-action-input{width:70px}#store-management #store-reset-input{width:auto}#store-management span.add-app-hint-hidden{visibility:hidden;text-align:center}#store-management span.add-app-hint-visible{visibility:visible;text-align:center}#store-management .app-name{overflow:hidden;width:98px;height:62px;line-height:16px;word-wrap:break-word}.resp-vtabs .resp-tabs-list li span,.resp-vtabs .resp-tabs-list .input_widget_title{float:left;max-width:172px;width:172px}.resp-vtabs .resp-tabs-list .input_widget_title{display:none}#store-images .file{background:lightgray;margin-bottom:10px;height:205px;width:900px}#store-images .thumbnail,#store-images .thumbnail img{max-width:400px;max-height:165px}#store-images .storeimage_tools{position:absolute;top:5px;left:415px}#store-images .storeimage_tools label{margin-bottom:0}#store-images .storeimage_tools input{margin-bottom:2px;width:450px}#store-images .storeimage_tools textarea{margin-bottom:2px;width:450px}.fancy-chosen-tr,.fancy-chosen-tr span{color:red!important}.fancy-remove-app{visibility:hidden;position:relative;top:-10px;left:-10px;width:24px;height:24px;z-index:1;background-image:url(../images/buttons/close_24.png);cursor:pointer}.remove-widget{float:left;width:15px;height:15px;background:url(../images/buttons/widgetgroup_buttons.png) no-repeat -15px 0;cursor:pointer}.wg_edit-hidden,.wg_edit-widget,.eg-edit-widget{visibility:hidden;float:left;width:15px;height:15px;background:url(../images/buttons/widgetgroup_buttons.png) no-repeat 0 0;cursor:pointer;margin-right:5px;margin-left:5px}.wg_edit-accept,.eg-edit-accept{display:none;float:left;width:15px;height:15px;background:url(../images/buttons/widgetgroup_buttons.png) no-repeat -30px 0;cursor:pointer;margin-right:5px;margin-left:5px}.eg-edit-widget,.eg-edit-accept{float:right}.eg-name-input{width:140px;float:left;margin-bottom:0}#search-fancy-iframe{width:1300px;height:800px}#search-fancy-iframe thead{text-align:left;font-size:13px;border:1px solid #797979;background:gray;color:white}#search-fancy-iframe table td{border:1px solid #797979;padding:8px;vertical-align:middle}.fancy-search-main{height:760px;overflow-y:scroll}#result-list-div thead{text-align:left;font-size:13px;color:white;background:#999}#result-list-div th{height:25px;border:1px gray solid}#result-list-div td{border:1px gray solid;height:45px;vertical-align:middle}#result-list-div th:hover{background:#575757}#result-list-div .row-odd{background:#ededed}#result-list-div{width:100%}.fancy-compatibility{float:left;width:190px}.fancy-compatibility-visible{display:inline}.fancy-compatibility-hidden{display:none}.fancy-show-option,span.fancy-show-option{width:180px;float:left;cursor:pointer;color:#4675a8!important}.copy-settings{margin:10px 0}#copy-settings-info{color:red}#copy-settings-title{font-weight:bold}.fancy-copy-tabs{margin-right:5px}#copy-settings-tabs-title{font-weight:bold}.container-with-fixed-footer{margin-bottom:39px}#analytics-report{width:1370px;position:relative}#analytics-report #myTab>li>a{color:black}#analytics-report #selection .selection-div>h3{line-height:38px;color:#333;font-size:14px;font-weight:bold;margin-right:10px}#analytics-report #selection #languageSelection .dropdown{width:100px}#analytics-report #selection .selection-div>h3,#analytics-report #selection .selection-div>div{float:left}#analytics-report #selection .radio-wrapper{float:right}#analytics-report #selection #go{float:right;margin-left:20px;height:38px}#analytics-report #selection .recent-wrapper{float:left}#analytics-report #selection .radio-wrapper input[type="radio"]{float:left;margin-top:14px;margin-right:5px}#analytics-report #selection .radio-wrapper>span,#analytics-report #selection .radio-wrapper .recent-wrapper>span{line-height:40px;font-size:14px;color:#333;float:left;margin-right:5px}#analytics-report #selection .or{float:right;font-size:14px;font-weight:bold;line-height:40px;margin:0 10px}#analytics-report #selection .recent-wrapper .dropdown,#analytics-report #selection .recent-wrapper h3{float:left}#analytics-report #selection .recent-wrapper h3{line-height:38px;font-size:14px;color:#333;font-weight:normal}#analytics-report #selection .selection-div{float:left}#analytics-report #selection .input-daterange{float:left}#analytics-report #selection .input-daterange .input-sm{height:30px;margin-bottom:0;width:100px}#analytics-report #selection .input-daterange .input-group-addon{padding:11px 5px;margin-left:-4px}#analytics-report .nav-tabs>li{width:25%;text-align:center}#analytics-report .nav-tabs{padding:0}#analytics-report #info-box{position:absolute;right:0;top:-50px;background-color:#d9edf7;font-size:14px;line-height:30px;width:500px;text-align:center;display:none}#analytics-report .chart_act{cursor:pointer}#analytics-report #Statistics{min-height:1000px}#analytics-report .statistics-chart-div{float:left;margin-right:12px;margin-top:12px;display:flex;display:-moz-flex;display:-ms-flex;display:-webkit-flex}#analytics-report .statistics-detail{margin-top:50px;min-height:500px}#analytics-report .statistics-detail-header .detail-header-wrapper{float:left}#analytics-report .statistics-detail-header #goLineChart{margin-left:30px}#analytics-report .statistics-detail-header #granularity-span{margin-left:30px}#analytics-report .statistics-detail-body{padding:10px}#analytics-report .statistics-detail-body .pie-chart{display:block;height:400px;width:650px;float:left;margin:0 5px}#analytics-report .statistics-detail-body .pie-chart-content{position:relative;padding:0;width:100%;height:100%}#analytics-report .statistics-detail-body #line-chart-placeholder{height:400px}#analytics-report .nav-tabs{margin-top:25px}#analytics-report .nav-tabs li{text-align:center;width:200px}#analytics-report .nav-tabs .active{font-weight:bold}#analytics-report .nav-tabs li a,#analytics-report .nav-tabs li a:visited{color:Black}.chart_title{display:-moz-box;display:-webkit-box;display:box;box-pack:center;box-align:center}.chart-title-left .dropdown{height:25px;border:0;background:transparent;width:initial;font-size:13px;font-weight:bold}.chart-title-left .dropdown.focus,.chart-title-left .dropdown:hover{box-shadow:none;border:0}.chart-title-left .dropdown.open>div:last-child{min-width:100px}.chart-title-left .dropdown .selected{margin-left:0}.chart-title-left .dropdown .selected::after{box-shadow:none}.statistics-chart-div .chart_title .chart-title-left{margin-left:0}.chart-title-left .dropdown .carat{right:-12px;top:16px}.title-bar-action{right:0;top:0;position:absolute;margin-right:10px}.title-bar-action a{font-size:12px;font-weight:lighter;color:#468eb2}.analytic_chart_FullWidth,.analytic_chart_FullWidth .chart_title{width:100%}.analytic_chart_Middle,.analytic_chart_Middle .chart_title,.analytic_chart_Large,.analytic_chart_Large .chart_title{width:440px}.analytic_chart_Small,.analytic_chart_Small .chart_title{width:213px}.analytic_chart .chart_act{float:right}.analytic_chart .chart_str{font-size:18px;font-weight:bold}.analytic_chart_Middle .chart_contdiv,.analytic_chart_Small .chart_contdiv{height:109px;padding-top:20px;padding-left:10px;padding-right:10px}.analytic_chart_Large .chart_contdiv{height:281px;padding-top:20px;padding-left:10px;padding-right:10px}.analytic_chart_FullWidth .chart_contdiv{height:290px;padding-top:20px;padding-left:10px;padding-right:10px;background:white}.chart_contdiv>a,.chart_contdiv>a:hover,.chart_contdiv>a:visited{color:#468eb2}.analytic_chart_Middle .chart_cont,.analytic_chart_Small .chart_cont{height:62px;margin-bottom:5px}.analytic_chart_Large .chart_cont,.analytic_chart_FullWidth .chart_cont{height:230px;margin-bottom:5px;margin-left:12px}.analytic_chart .chart_title,.top-50-quickview h2{border-bottom:1px solid #29abe2;height:28px;background:#e6e6e6;color:#468eb2;font-weight:bold;font-size:15px;line-height:28px}.analytic_chart .chart_title span{margin-left:10px}.admin-tool-footer{bottom:0;width:100%}#admin_home_title{margin:50px;font-size:18px;text-align:center}.admin_home_element{margin-bottom:10px}#admin_home_content h2{margin-bottom:20px}#comment-management{width:1600px}#comment-management #selection{float:left}#comment-management #searchBar{float:right}#comment-management .section{width:100%;margin:0 10px}#comment-management{margin-bottom:540px}#comment-management a{color:#1a52ad;text-decoration:none}#comment-management select,#comment-management #query-term{margin-top:10px}#comment-management #checkbox-th{text-align:center}#comment-management .title-comment{float:left;width:400px;height:auto;text-overflow:ellipsis;text-align:left;overflow-y:hidden}#comment-management .title-area{width:400px;height:18px;margin:0;font-weight:bold;text-overflow:ellipsis;overflow:hidden;white-space:nowrap}#comment-management .comment-area{width:400px;word-wrap:break-word}#comment-management .comment-area-more{height:auto}#comment-management .comment-area-hide{overflow:hidden;max-height:40px}#comment-management .appname-area{text-align:left;width:200px;word-wrap:break-word}#comment-management .review-author-area{width:130px;word-wrap:break-word}#comment-management .publisher-area{width:130px;word-wrap:break-word}#comment-management .title-comment-td{height:auto;width:400px;padding:5px;text-align:left}#comment-management #actions{margin-bottom:10px}#comment-management td{text-align:center}#comment-management .description{color:Gray;font-size:12px}#comment-management #number-area{margin-bottom:5px}.hidden-element{visibility:hidden}#comment-management .my-modal-note{width:500px;height:300px}#comment-management .action-td{text-align:left}#comment-management .comments-table{font-size:12px}.comment-mangement-hightlight{background-color:lightcoral}#comment-management .tooltip{border:0;background-color:transparent;background:0;box-shadow:none;-moz-box-shadow:none;-webkit-box-shadow:none}#comment-management .note-textarea{height:40px;width:130px;word-wrap:break-word;text-align:left;overflow:hidden;resize:none;margin-bottom:0;border:0;background-color:transparent;box-shadow:none;cursor:default}#comment-management .note{overflow:hidden;height:40px;line-height:20px}#comment-management .note:before{content:"";float:left;width:5px;height:40px}#comment-management .note>*:first-child{float:right;width:100%;margin-left:-5px}#comment-management .note:after{content:"\02026";float:right;position:relative;top:-25px;left:100%;width:3em;margin-left:-3em;padding-right:5px;text-align:right}#comment-management .note-area{text-align:left}#download-entitlement-management{width:1205px;min-height:800px;margin:0 auto}#download-entitlement-management #base h1{font-size:18px;margin:10px 0}#download-entitlement-management #app-name{margin-bottom:20px}#download-entitlement-management #add-new-entitlement{float:left}#download-entitlement-management #add-new-entitlement input{width:100px}#download-entitlement-management #search-form{float:right}#download-entitlement-management #action-search-wrapper{margin-bottom:20px}#add-download-entitlement-input{width:424px;margin:20px 0 10px 0}#add-download-entitlement-form .error-email{color:red}.entitlement-table .notes .display-block{display:block}.entitlement-table .notes .display-none{display:none}.entitlement-table .notes .notes-edit-button,.entitlement-table .notes .notes-cancel,.entitlement-table .notes .notes-save{float:right}#footerloglink{width:120px;height:38px;float:right}.dropdown{font-size:12px;border-radius:0}.search-brief-component .dropdown{width:65px;float:right}#store-management .dropdown{float:left}.detail-page .dropdown{float:left;width:150px;margin-right:5px;padding:0}.dropdown ul{margin:0;padding:0}.dropdown li.focus{background:#29abe1;color:#fff}.dropdown .carat,.dropdown.open .carat{border-width:5px}.btn-group>.btn:last-child:not(:first-child),.btn-group>.dropdown-toggle:not(:first-child){border-bottom-left-radius:0;border-top-left-radius:0}.btn-group>.btn:first-child:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:2px}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}.drawer{background:#f2f2f2;overflow:hidden}.drawer .drawercontent{border:1px solid #ccc;padding:15px;display:none}.drawer.open .drawercontent{display:block}.drawer .normal-text{font:12px/24px arial,sans-serif;color:#000}.drawer .bold-text{font:bold 15px/24px arial,sans-serif;color:#000}.drawer .description-text{font:11px arial,sans-serif;color:#666}.qty-purchased-limit>.qty-limit,.qty-purchased-limit>.qty-purchased{float:left;line-height:15px}.qty-purchased-limit>.qty-limit{padding-top:1px;margin-left:15px}.qty-purchased-limit>.qty-limit-roof{color:red}.purchase-roof{display:none}.drawer .purchase-grid:not(:first-child){margin-left:30px}.drawer.open .drawercontent .subscrib-list{font-style:italic}.waiting-layer{width:398px;height:113px;background:#fff;border:1px solid #4675a8;-moz-box-shadow:rgba(0,0,0,0.25) 1px 1px 8px 3px;-ms-box-shadow:rgba(0,0,0,0.25) 1px 1px 8px 3px;-webkit-box-shadow:rgba(0,0,0,0.25) 1px 1px 8px 3px;box-shadow:rgba(0,0,0,0.25) 1px 1px 8px 3px}.waiting-layer #wrapper{width:370px;margin:auto}.waiting-layer #wrapper p{font-size:14px;color:#666;text-align:left;margin-top:25px}.waiting-layer #loader-wrapper{text-align:center;margin-top:15px}.waiting-layer #loader{width:24px;height:24px}#error-board{width:604px;margin:0 auto 0 auto;min-height:230px;background-color:white;padding:20px;background-image:url("../images/layout/error_board_bg.png");background-repeat:no-repeat;background-position:right top;-moz-box-shadow:1px 1px 3px rgba(0,0,0,0.25);-ms-box-shadow:1px 1px 3px rgba(0,0,0,0.25);-webkit-box-shadow:1px 1px 3px rgba(0,0,0,0.25);box-shadow:1px 1px 3px rgba(0,0,0,0.25)}#error-board-title,#main .opening-soon span{margin-bottom:30px;font-size:48px;color:#033333;line-height:100%}#main .opening-soon span{font-size:42px}#error-board-desc,#main .opening-soon p{font-size:16px;color:#666;line-height:180%}.whats-verified-download-main .headline{font-size:20px;color:#f90}#bluesnap-promotion-landing{display:none;text-align:center}#bluesnap-promotion-landing-text{font-family:'Myriad Pro';font-weight:400;font-size:24px}#bluesnap-promotion-landing-text2{font-family:'Arial Italic','Arial';font-weight:400;font-style:italic;font-size:18px;color:#666}#bluesnap-promotion-landing-banner{width:660px;padding:10px 10px 10px 10px}#bluesnap-promotion-detail{display:inline-block}#bluesnap-promotion-detail-logo-container{height:15px;vertical-align:middle}#bluesnap-promotion-detail-logo-container img{margin-top:15px}#bluesnap-promotion-detail img{height:inherit}#bluesnap-promotion-detail-text{font-family:'Arial Italic','Arial';font-weight:400;font-style:italic;font-size:10px;color:#369;float:right;height:24px}#process-payment-dialog{text-align:center;width:400px;padding:10px 10px 10px 10px}#process-payment-dialog div{margin-top:15px}#process-payment-dialog button{width:180px;height:28px;vertical-align:middle;margin-top:15px;margin-bottom:10px}.top-50-container{width:1200px}.top-50-container>*{width:100%;width:inherit;padding:10px}.horizontal-container{width:100%;display:-ms-flexbox;-ms-flex-pack:center;display:-moz-box;-moz-box-pack:center;-moz-box-align:center;display:-webkit-box;-webkit-box-pack:center;-webkit-box-align:center;display:box;box-pack:center;box-align:center}.top-50-quickview{margin:10px;width:33%}.top-50-quickview h2{padding-left:10px}.top-50-quickview ul{margin:0;padding:0}.top-50-quickview li:first-of-type{font-size:18px}.top-50-quickview li{background:white;padding:5px}.analytic-report-table-container>*{padding:8px}.analytic-report-table-container h1{font-size:18px}.analytic-report-table-container table{margin:10px}.analytic-report-table-container col{width:10%}.analytic-report-table-container td{text-align:left;vertical-align:middle}.analytic-report-table-container th{text-align:left}.analytic-report-table-container tr:nth-child(even){background:#f2f2f2}.analytic-report-table-container table *{padding:5px}.analytic-report-table-container thead{background:#f0f0f0}.statistics-chart-div.full-width{width:100%;position:relative}.file-list td{vertical-align:middle}.file-list label{margin:3px 3px}#featured-apps #result-list li{padding:10px;height:80px;overflow:visible}#featured-apps #result-list li:nth-child(odd){background:#ededed}#result-list{margin:0;padding:0;background:white;border:1px solid #CCC;border-top:0;width:100%}.admin-table table td,.master-table table td{border:1px solid #e6e6e6;height:40px;vertical-align:middle}#analytics-report a.admin-favorite{display:inline-block;height:7px;width:8px;background:url(../images/icons/star_big.png) no-repeat 2px 1px}#analytics-report a.admin-favorite.added{background:url(../images/icons/star_big.png) no-repeat 2px -16px}.search-type-area{height:25px;background:#fff;margin-right:6px;position:relative;display:none}.search-type{font:12px arial;text-align:center;height:25px;line-height:25px;padding-left:15px;padding-right:15px;margin-right:-4px;display:-moz-inline-box;display:inline-block}.search-type:hover{color:#29abe2!important;background:#e6e6e6!important;cursor:pointer}.search-type-unhightlighted{color:#29abe2!important;background:white}.search-type-hightlighted{color:white!important;background:#29abe2!important}.publisher-result-list{margin-left:-20px}.publisher-result-list li{height:130px;background-color:white;margin-right:6px;margin-bottom:6px}.pubsearch-result-row{height:100%;float:left;position:relative}.pubsearch-result-row-left{width:15%}.pubsearch-result-row-middle{margin-left:5px;width:70%}.pubsearch-result-row-right{width:13.5%}.pubsearch-result-image-link{height:98%;width:98%;background-color:white;display:inline-block;text-align:center;margin-right:2px}.pubsearch-result-image-helper{display:inline-block;height:100%;vertical-align:middle}.pubsearch-result-image{vertical-align:middle;display:inline-block;max-height:96%;max-width:96%;overflow:hidden}.pubsearch-result-name{margin-top:3px;font-size:14px;color:#29abe2;width:100%;overflow:hidden}.pubsearch-result-desc{margin-top:3px;font-size:12px;height:56px;width:100%;overflow:hidden}.publisher-consulting-services-region{position:absolute;bottom:-5px}.publisher-consulting-services-label{margin-bottom:3px;font-size:12px;width:100%}.pubsearch-consulting-service{margin-right:2px;float:left;width:auto;font-size:12px;vertical-align:bottom;margin-bottom:5px}.pubsearch-consulting-service-text{background-color:white;color:#29abe2}.pubsearch-result-row-right button{position:absolute!important;color:white;bottom:0;right:0;margin-bottom:6px;padding:5px}.pubsearch-apps-count{font-size:14px;color:#29abe2;font-weight:bold;position:relative;float:right;margin-top:5px;margin-right:2px}.pubsearch-apps-count-label{margin-top:5px;margin-right:5px;font-size:14px;position:relative;float:right}.ad-hide{display:none}.box-ad-hide{margin-left:189px}
\ No newline at end of file
diff --git a/2024/scripts/rigging_tools/ngskintools2/docs/Resources/linux64.png b/2024/scripts/rigging_tools/ngskintools2/docs/Resources/linux64.png
deleted file mode 100644
index 9e7f5bf..0000000
Binary files a/2024/scripts/rigging_tools/ngskintools2/docs/Resources/linux64.png and /dev/null differ
diff --git a/2024/scripts/rigging_tools/ngskintools2/docs/Resources/macos64.png b/2024/scripts/rigging_tools/ngskintools2/docs/Resources/macos64.png
deleted file mode 100644
index 8053b36..0000000
Binary files a/2024/scripts/rigging_tools/ngskintools2/docs/Resources/macos64.png and /dev/null differ
diff --git a/2024/scripts/rigging_tools/ngskintools2/docs/Resources/original_89910fa8-2c30-4376-a905-12c8a003d16b_.png b/2024/scripts/rigging_tools/ngskintools2/docs/Resources/original_89910fa8-2c30-4376-a905-12c8a003d16b_.png
deleted file mode 100644
index 65887c5..0000000
Binary files a/2024/scripts/rigging_tools/ngskintools2/docs/Resources/original_89910fa8-2c30-4376-a905-12c8a003d16b_.png and /dev/null differ
diff --git a/2024/scripts/rigging_tools/ngskintools2/docs/Resources/resized_5ca803cc-8cd1-4cbe-8825-98efaeef156e_.png b/2024/scripts/rigging_tools/ngskintools2/docs/Resources/resized_5ca803cc-8cd1-4cbe-8825-98efaeef156e_.png
deleted file mode 100644
index 412ca74..0000000
Binary files a/2024/scripts/rigging_tools/ngskintools2/docs/Resources/resized_5ca803cc-8cd1-4cbe-8825-98efaeef156e_.png and /dev/null differ
diff --git a/2024/scripts/rigging_tools/ngskintools2/docs/Resources/win64.png b/2024/scripts/rigging_tools/ngskintools2/docs/Resources/win64.png
deleted file mode 100644
index 3f3ee90..0000000
Binary files a/2024/scripts/rigging_tools/ngskintools2/docs/Resources/win64.png and /dev/null differ
diff --git a/2024/scripts/rigging_tools/ngskintools2/docs/index.html b/2024/scripts/rigging_tools/ngskintools2/docs/index.html
deleted file mode 100644
index a89a39a..0000000
--- a/2024/scripts/rigging_tools/ngskintools2/docs/index.html
+++ /dev/null
@@ -1,353 +0,0 @@
-
-
-
-
-
-
- Autodesk App Store - help file
-
-
-
-
-
-
-
ngSkinTools 2
-
-
-
-
Viktoras Makauskas
-
ngSkinTools is a skinning plugin for Autodesk® Maya®, introducing new concepts to character skinning such as layers, any-pose-mirroring, enhanced paint brushes, true smoothing, and more.
Skinning
-layers are a central feature of ngSkinTools. With them, you break your rig down
-into easier manageable parts and edit them separately, then blend everything
-together through layer transparency.
-
They’re
-not just a simple way to make your work more organized - they also physically
-isolate groups of influences from the rest of the rig, so paint and edit
-operations won’t mix-in influences you were not expecting. This also allows you
-to do things that were impossible before: per-layer mirroring, adjusting
-influence weight up/down through layer transparency, blend transferred weights
-with previous weights, to name a few.
-
-
Viewport
-tools
-
Just
-like in the previous version, ngSkinTools brings its own weight painting tools.
-Improving viewport experience is the main focus of V2, and it's complete revamp
-over the previous implementation.
-
-
Selecting
- influences on screen, a #1 requested feature from users, is nowhere. Just hold
- “S” and drag over the surface to select dominant influence from that part of
- the mesh, or hover over a joint pivot to select precisely the joints you
- want;
-
In
- addition to the usual surface projection mode for the brush, the new “screen”
- brush projection mode is useful when you want to quickly set weights for both
- sides of the mesh;
-
Custom
- shortcuts while in paint mode allow for quick access to intensity
-presets;
-
Color
- feedback is now provided through VP2 APIs, greatly improving the performance
- of displayed meshes.
-
-
Smoothing
-
Keeping
-weights in harmony with each other is not easy. ngSkinTools help you smooth
-weights with the control you need, allowing you to control the intensity, number
-of iterations and effective radius. For very dense meshes, added “iterations”
-argument now allows for the quicker spread of smoothness over larger areas of
-the mesh.
-
The
-“relax” tool from V1 is gone. With major performance rework, you’ll notice that
-simple flood-smoothing is now much faster and should be a near-instant operation
-even with large meshes.
-
The
-opposite “brother” of smooth brush, “sharpen”, is also there - for cases where
-you want to just bring out the dominant influences
-
-
Mirroring
-
Mirroring
-is one of the most frequent automated tasks you might want from your skinning
-tool. With ngSkinTools, you’ll be able to:
-
-
Mirror
- rigs in any pose; no need to switch to T-pose;
-
Have
- granular control over left/right/center influences mapping, matching
- left/right joints by naming convention, joint labels, etc;
-
Easily
- mirror parts of your rig by leveraging layers;
-
Automatic
- mirroring of weights to the opposite side as you paint so that you don’t need
- to get distracted from painting while working on symmetrical layers.
-
-
Layer
-effects
-
With
-the “mirror as a layer effect” feature, ngSkinTools introduce a new concept to
-ngSkinTools - layer effects. This differs from automatic mirroring of weights as
-it’s not directly modifying your layer weights; instead, it’s a post-effect that
-happens in the background buffer. This has multiple benefits, like a much
-cleaner seamline of left/right sides, the ability to tweak mirroring settings
-AFTER weights are painted, etc.
-
-
Compatibility
-
As
-it's predecessor, ngSkinTools2 operates on standard Maya skinCluster (also known
-as “smooth skin”), so no custom nodes will be required to use your rig. The
-plugin has a couple of custom nodes, but they’re only required while you work on
-setting up your skin weights and can be deleted after, so your work should stay
-compatible with most pipelines out there.
-
-
Performance
-
A
-lot of speed improvements have been made since V2, like improving the
-utilization of modern multi-core processors, or eliminating bottlenecks through
-much heavier use of performance profiling. Having a responsive, snappy tool is
-always a pleasure to work with.
-
-
-
-
-
General Usage Instructions
-
The installer from Autodesk App Store loads the application under the Custom shelf.
The installer that ran when you downloaded this plug-in from Autodesk App Store has already installed the plug-in. Windows only: To uninstall this plug-in, simply rerun the installer downloaded, and select the 'Uninstall' button, or you can uninstall it from 'Control Panel\Programs\Programs and Features', just as you would uninstall any other application from your system. The panel on the Plug-ins tab will not be removed until Maya is restarted.
-
-
-
Linux and OSX: To uninstall this plug-in, simply delete the module directory from your system. The panel on the Plug-ins tab will not be removed until Maya is restarted.
-
-
-
Download .msi and run it on your computer. The installation will place files in C:\ProgramData\Autodesk\ApplicationPlugins\ngskintools2 (unless your %ProgramData% the environment variable is different).
-
-
-
Using an autoloader system, nothing needs to be configured additionally. Maya scans autoloader locations for plugins at startup and configures each discovered plugin automatically. The autoloader will create a “ngSkinTools2” shelf with a button to open UI.
-
Now, restart Maya and a new tab ngSkinTools2 should appear on your shelf.
2.0.23 (2021-Mar-12)
-* Fixed: stylus pressure is not updated during the stroke;
-* Fixed: Maya crashes when smoothing an empty layer with "adjust existing influences only";
-* Fixed: (regression) UI is not opening on macOS;
-
-
-
-
-
- 2.0.23
-
-
-
2.0.23 (2021-Mar-10)
-* Added: adjustable brush size: don't reset to zero when changing brush size in the viewport.
-* Added: randomize influence colors in paint/display settings;
-* Added: layers on/off "eye" button in layers tree UI;
-* Fixed: ngSkinTools will not modify skinCluster's `normalizeWeights` value anymore; for performance boost, you still
- can disable skinCluster's normalization by setting `normalizeWeights=None`. In "normalizeWeights:interactive"
- skinCluster mode, Maya will no longer complain that "The weight total would have exceeded 1.0". ngSkinTools will try
- extra hard to normalize each vertex to a perfect 1.0;
-* Fixed: UI is not displayed correctly on high DPI displays when UI scaling is enabled in Maya;
-
-
-
-
-
- 2.0.22
-
-
-
2.0.22 (2021-Feb-06)
- Added: convenience tool for adding influences to existing skin clusters. Select influences, target mesh and select “Tools | Add Influence”;
- Fixed: weights will now display properly when viewport option “use default material” is turned on;
- Added: (v1 feature) Limit max influences per vertex before writing to skin cluster;
- Added: (v1 feature) Prune small weights before writing to skin cluster.
-
-2.0.21 (2021-Jan-11)
- Added: copy/paste vertex weights between different selections (tab “tools” - “copy component weights/paste average component weights”);
- Added: tool “fill transparency” - for all empty vertices in a layer, assign weights from closest non-empty vertex;
- Added: “duplicate layer” operation;
- Added: “Merge layers” operation: combine selected layers into one.
-
-2.0.20 (2020-Dec-02)
- Fixed: Linux: crashing on startup
-
-2.0.19 (2020-Nov-28)
- Added: influences mapping in mirror screen will now allow matching joints by DG connections; if symmetrical joints are linked between themselves with message connections, ngSkinTools will be able to leverage that information when mirroring weights;
- Added: symmetry mesh: an option to provide an alternative mesh for calculating vertex mapping for mirroring;
- Fixed: deleting visibility node can crash Maya sometimes, e.g. switching to component mode (F8) while paint tool is active
-
-2.0.18 (2020-Nov-20)
- Added: “use all joints” option for “weights from closest joint” tool; few internal optimizations to speedup operation;
- Added: “weights from closest joint” option: create a new layer
- Fixed: “weights from closest joint”: the tool is only using joints as spots, but not as segments;
- Fixed: after “weights from closest joint” operation influences list is not refreshed;
- Fixed: “weights from closest joint”: “assign” button sometimes disabled;
-
-2.0.17 (2020-Nov-19)
- Fixed: “resume in workspace” error while opening UI
-
-2.0.16 (2020-Nov-15)
- Added: skin data will be compressed for ngSkinTools data nodes, which should substantially reduce file size for scenes with lots of skinning layers;
- Added: paint mode intensity sliders are now exponential: “smooth”, “add” and “sharpen” sliders will now be more precise for lower values, and “scale” mode will allow for more precision when setting high values.
-
-2.0.15 (2020-Nov-10)
- Added: new “Set Weights” tab contains tools to apply weights to vertex/edge/polygon selection instead of painting.
- Added: a new option for smooth tool - “only adjust existing vertex influences”; when this is turned on, the smooth tool will prevent influences weights spreading across the surface
- Fixed: layer mirror effects correctly saved/loaded in files;
- Fixed: mask mirror effect was not correctly used by layer blending engine
-
-2.0.14 (2020-Oct-04)
- Fixed: occasional crashes when using mirror effect on layers;
- Additional stability fixes.
-
-2.0.13 (2020-Oct-04)
- Fixed: minor bug in 2.0.12 blocks UI from opening;
-
-2.0.12 (2020-Oct-03)
- Added: option to view used influences in influences list;
- Added: hide “DQ weights” channel in influences list if skin cluster skinning method is not set to “Weight Blended”;
-
-2.0.11 (2020-Oct-01)
- Fixed: broken Linux builds
-
-2.0.10 (2020-Sep-26)
- Added: pressing “f” while painting focuses viewport camera to current paint target; for joints and other influences, the current joint pivot is used as camera interest point; when current paint target is a mask, viewport centers around painted values;
- Fixed: influence mapping UI error if some influences are no joints;
-
-2.0.9 (2020-Sep-11)
- Fixed: undo paint crashing Maya;
- Fixed: incorrect brush behavior with multiple viewports open;
- Fixed: incorrect mesh display / VP2 transparency setting sensitive;
- Fixed: clearing selection while painting does not update the display of current mesh;
-
-
-
-
-
-
-
-
diff --git a/2024/scripts/rigging_tools/ngskintools2/launcher.py b/2024/scripts/rigging_tools/ngskintools2/launcher.py
index 06ddd41..7e5e5a1 100644
--- a/2024/scripts/rigging_tools/ngskintools2/launcher.py
+++ b/2024/scripts/rigging_tools/ngskintools2/launcher.py
@@ -1,158 +1,43 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
-
"""
-ngSkinTools2 启动器
-用于从工具架快速启动 ngSkinTools2
+ngSkinTools2 Launcher
+Provides a simple interface to launch ngSkinTools2 from Maya shelf buttons
"""
import sys
-import os
-
-def get_maya_version():
- """
- 获取当前 Maya 版本号
- 返回格式: '2023', '2024' 等
- """
- try:
- from maya import cmds
- maya_version = cmds.about(version=True)
- # Maya 版本格式可能是 "2023" 或 "2023.1" 等,取主版本号
- return maya_version.split('.')[0]
- except Exception as e:
- print(f"Failed to get Maya version: {e}")
- return None
-
-
-def find_compatible_plugin_dir(base_dir, maya_version):
- """
- 查找兼容的插件目录
- 优先使用完全匹配的版本,如果没有则向下查找最接近的版本
-
- Args:
- base_dir: 插件基础目录 (plug-ins/)
- maya_version: Maya 版本号字符串,如 '2023'
-
- Returns:
- 插件目录路径,如果找不到则返回 None
- """
- if not maya_version:
- return None
-
- try:
- maya_ver_int = int(maya_version)
- except ValueError:
- print(f"Invalid Maya version format: {maya_version}")
- return None
-
- # 列出所有可用的插件版本目录
- available_versions = []
- if os.path.exists(base_dir):
- for item in os.listdir(base_dir):
- item_path = os.path.join(base_dir, item)
- if os.path.isdir(item_path):
- try:
- ver_int = int(item)
- available_versions.append((ver_int, item_path))
- except ValueError:
- continue
-
- if not available_versions:
- return None
-
- # 按版本号排序
- available_versions.sort(reverse=True)
-
- # 首先尝试完全匹配
- for ver, path in available_versions:
- if ver == maya_ver_int:
- print(f"Found exact match plugin for Maya {maya_version}: {path}")
- return path
-
- # 如果没有完全匹配,使用小于等于当前版本的最高版本
- for ver, path in available_versions:
- if ver <= maya_ver_int:
- print(f"Using compatible plugin for Maya {maya_version}: {path} (version {ver})")
- return path
-
- # 如果当前版本比所有可用版本都旧,使用最旧的版本
- oldest_ver, oldest_path = available_versions[-1]
- print(f"Warning: Maya {maya_version} is older than available plugins. Using oldest: {oldest_path} (version {oldest_ver})")
- return oldest_path
def LaunchNgSkinTools():
"""
- 启动 ngSkinTools2 主界面
- 自动检测 Maya 版本并加载对应的插件
+ Launch ngSkinTools2 main UI window
+
+ This function handles two scenarios:
+ 1. If module alias exists (ngSkinTools2 -> rigging_tools.ngskintools2), use it
+ 2. If not, create the alias on-the-fly and then launch
"""
try:
- from maya import cmds, mel
-
- # 获取当前 Maya 版本
- maya_version = get_maya_version()
- if not maya_version:
- print("Warning: Could not determine Maya version, will try to continue anyway")
- else:
- print(f"Detected Maya version: {maya_version}")
-
- # 将当前目录添加到 Python 路径,并使用别名
- # 这样 ngSkinTools2 内部的 "from ngSkinTools2.ui" 就能找到模块
- current_dir = os.path.dirname(os.path.abspath(__file__))
- parent_dir = os.path.dirname(current_dir)
-
- # 添加父目录到路径
- if parent_dir not in sys.path:
- sys.path.insert(0, parent_dir)
-
- # 添加当前目录到路径,作为 ngSkinTools2 模块
- if current_dir not in sys.path:
- sys.path.insert(0, current_dir)
-
- # 在 sys.modules 中创建别名,让 ngSkinTools2 指向 ngskintools2
- import rigging_tools.ngskintools2 as ngskintools2_module
- sys.modules['ngSkinTools2'] = ngskintools2_module
-
- # 查找并添加插件路径
- # 根据 Maya 版本自动选择对应的插件目录
- plugin_base_dir = os.path.join(current_dir, 'plug-ins')
- plugin_dir = find_compatible_plugin_dir(plugin_base_dir, maya_version)
-
- if plugin_dir and os.path.exists(plugin_dir):
- # 添加插件路径
- current_plugin_path = os.environ.get('MAYA_PLUG_IN_PATH', '')
- if plugin_dir not in current_plugin_path:
- os.environ['MAYA_PLUG_IN_PATH'] = plugin_dir + os.pathsep + current_plugin_path
-
- # 加载插件
+ # Check if module alias already exists
+ if 'ngSkinTools2' not in sys.modules:
+ # Create the alias on-the-fly
try:
- # 检查插件是否已加载
- if not cmds.pluginInfo('ngSkinTools2', query=True, loaded=True):
- cmds.loadPlugin(os.path.join(plugin_dir, 'ngSkinTools2.mll'))
- print(f"ngSkinTools2 plugin loaded successfully from {plugin_dir}")
- else:
- print(f"ngSkinTools2 plugin already loaded")
- except RuntimeError:
- # 插件不存在,尝试加载
- try:
- cmds.loadPlugin(os.path.join(plugin_dir, 'ngSkinTools2.mll'))
- print(f"ngSkinTools2 plugin loaded successfully from {plugin_dir}")
- except Exception as plugin_error:
- print(f"Warning: Could not load ngSkinTools2 plugin: {plugin_error}")
- except Exception as plugin_error:
- print(f"Warning: Could not load ngSkinTools2 plugin: {plugin_error}")
- else:
- print(f"Warning: Plugin directory not found: {plugin_dir}")
+ import rigging_tools.ngskintools2
+ sys.modules['ngSkinTools2'] = rigging_tools.ngskintools2
+ print("Created ngSkinTools2 module alias")
+ except ImportError as import_err:
+ print(f"Error: Failed to import rigging_tools.ngskintools2 - {import_err}")
+ print("Please ensure the ngskintools2 directory is in the correct location")
+ return
- # 现在可以导入并打开 UI
- from rigging_tools.ngskintools2 import open_ui
+ # Now import and launch
+ from ngSkinTools2 import open_ui
open_ui()
- print("ngSkinTools2 UI opened successfully")
+ print("ngSkinTools2 launched successfully")
+
+ except ImportError as e:
+ print(f"Error: Failed to import ngSkinTools2 - {e}")
+ print("Please ensure ngSkinTools2 is properly installed")
except Exception as e:
- print(f"Failed to open ngSkinTools2: {e}")
+ print(f"Error: Failed to launch ngSkinTools2 - {e}")
import traceback
traceback.print_exc()
-
-
-if __name__ == "__main__":
- LaunchNgSkinTools()
diff --git a/2024/scripts/rigging_tools/ngskintools2/license.txt b/2024/scripts/rigging_tools/ngskintools2/license.txt
deleted file mode 100644
index 69c070d..0000000
--- a/2024/scripts/rigging_tools/ngskintools2/license.txt
+++ /dev/null
@@ -1,32 +0,0 @@
-ngSkinTools Software License Agreement.
-
-
-This is a legal agreement between you and ngSkinTools author (Viktoras Makauskas) covering your use of
-ngSkinTools (the "Software").
-
-1) ngSkinTools is provided as freeware.
-
-2) ngSkinTools Software is owned by Viktoras Makauskas and is protected by copyright laws and international
-treaty provisions. Therefore, you must treat the Software like any other copyrighted material.
-
-3) You may not distribute, rent, sub-license or otherwise make available to others the Software or
-documentation or copies thereof, except as expressly permitted in this License without prior written consent
-from ngSkinTools author (Viktoras Makauskas). In the case of an authorized transfer, the transferee must agree
-to be bound by the terms and conditions of this License Agreement.
-
-4) You may not remove any proprietary notices, labels, trademarks on the Software or documentation. You may not
-modify, de-compile, disassemble or reverse engineer the Software.
-
-5) Limited warranty: ngSkinTools software and documentation are "as is" without any warranty as to their
-performance, merchantability or fitness for any particular purpose. The licensee assumes the entire risk as to
-the quality and performance of the software. In no event shall ngSkinTools author or anyone else who has been
-involved in the creation, development, production, or delivery of this software be liable for any direct,
-incidental or consequential damages, such as, but not limited to, loss of anticipated profits, benefits, use,
-or data resulting from the use of this software, or arising out of any breach of warranty.
-
-Copyright (C) 2009-2020 Viktoras Makauskas
-
-http://www.ngskintools.com
-support@ngskintools.com
-
-All rights reserved.
diff --git a/2024/scripts/rigging_tools/ngskintools2/observableValue.py b/2024/scripts/rigging_tools/ngskintools2/observableValue.py
index f01c198..3410295 100644
--- a/2024/scripts/rigging_tools/ngskintools2/observableValue.py
+++ b/2024/scripts/rigging_tools/ngskintools2/observableValue.py
@@ -22,4 +22,4 @@ class ObservableValue(Object):
if default != Undefined:
return default
- raise Exception("using observable value before setting it")
+ raise Exception("在设置之前使用可观察值")
diff --git a/2024/scripts/rigging_tools/ngskintools2/operations/copy_paste_actions.py b/2024/scripts/rigging_tools/ngskintools2/operations/copy_paste_actions.py
index 916b25b..f362bc0 100644
--- a/2024/scripts/rigging_tools/ngskintools2/operations/copy_paste_actions.py
+++ b/2024/scripts/rigging_tools/ngskintools2/operations/copy_paste_actions.py
@@ -24,7 +24,7 @@ def action_copy_cut(session, parent, cut):
operation(session.state.currentLayer.layer, influences)
operation_name = "Cut" if cut else "Copy"
- result = actions.define_action(parent, operation_name + " weights to clipboard", callback=cut_copy_callback)
+ result = actions.define_action(parent, operation_name + " 将权重复制到剪贴板", callback=cut_copy_callback) # 将权重复制到剪贴板 weights to clipboard
@signal.on(session.events.currentLayerChanged, session.events.currentInfluenceChanged, qtParent=parent)
def on_selection_changed():
@@ -49,13 +49,13 @@ def action_paste(session, parent, operation):
api.paste_weights(session.state.currentLayer.layer, operation, influences=influences)
labels = {
- PasteOperation.add: 'Paste weights (add to existing)',
- PasteOperation.subtract: 'Paste weight (subtract from existing)',
- PasteOperation.replace: 'Paste weights (replace existing)',
+ PasteOperation.add: '粘贴权重(添加到现有)',
+ PasteOperation.subtract: '粘贴权重(从现有值中减去)',
+ PasteOperation.replace: '粘贴权重(替换现有)',
}
result = actions.define_action(parent, labels[operation], callback=paste_callback)
- result.setToolTip("Paste previously copied weights from clipboard")
+ result.setToolTip("从剪贴板粘贴先前复制的权重")
@signal.on(session.events.currentLayerChanged)
def on_selection_changed():
diff --git a/2024/scripts/rigging_tools/ngskintools2/operations/import_export_actions.py b/2024/scripts/rigging_tools/ngskintools2/operations/import_export_actions.py
index 2a64020..17f7d6d 100644
--- a/2024/scripts/rigging_tools/ngskintools2/operations/import_export_actions.py
+++ b/2024/scripts/rigging_tools/ngskintools2/operations/import_export_actions.py
@@ -31,7 +31,7 @@ def buildAction_export(session, parent):
result = actions.define_action(
parent,
- "Export Layers to Json...",
+ "导出图层...",
callback=export_callback,
tooltip="Save layer info to external file, suitable for importing weights to different scene/mesh",
)
@@ -79,7 +79,7 @@ def buildAction_import(session, parent, file_dialog_func=None):
t.customize_callback = transfer_dialog
t.execute()
- result = actions.define_action(parent, "Import Layers from Json...", callback=import_callback, tooltip="Load previously exported weights")
+ result = actions.define_action(parent, "导入图层...", callback=import_callback, tooltip="Load previously exported weights")
@signal.on(session.events.targetChanged, qtParent=parent)
def update():
diff --git a/2024/scripts/rigging_tools/ngskintools2/operations/import_v1_actions.py b/2024/scripts/rigging_tools/ngskintools2/operations/import_v1_actions.py
index 2b19f45..9a74704 100644
--- a/2024/scripts/rigging_tools/ngskintools2/operations/import_v1_actions.py
+++ b/2024/scripts/rigging_tools/ngskintools2/operations/import_v1_actions.py
@@ -28,8 +28,8 @@ def build_action_import_v1(session, parent):
update_state()
session.events.targetChanged.emitIfChanged()
- result = actions.define_action(parent, "Convert From v1.0 Layers", callback=do_convert)
- result.setToolTip("Convert skinning layers from previous version of ngSkinTools; after completing this action, v1 nodes will be deleted.")
+ result = actions.define_action(parent, "从v1.0图层转换", callback=do_convert)
+ result.setToolTip("“转化旧版ngSkinTools的图层;完成此操作后,v1节点将被删除。")
@signal.on(session.events.targetChanged)
def update_state():
diff --git a/2024/scripts/rigging_tools/ngskintools2/operations/layers.py b/2024/scripts/rigging_tools/ngskintools2/operations/layers.py
index 028eb96..b3004ce 100644
--- a/2024/scripts/rigging_tools/ngskintools2/operations/layers.py
+++ b/2024/scripts/rigging_tools/ngskintools2/operations/layers.py
@@ -28,7 +28,7 @@ def initializeLayers(createFirstLayer=True):
layers = ngSkinTools2.api.init_layers(target)
with ngSkinTools2.api.suspend_updates(target):
if createFirstLayer:
- layer = layers.add("Base weights")
+ layer = layers.add("基础权重") #Base weights
layer.set_current()
Mirror(target).set_mirror_config(config.mirrorInfluencesDefaults)
@@ -36,7 +36,7 @@ def initializeLayers(createFirstLayer=True):
if ngSkinTools2.api.is_slow_mode_skin_cluster(target):
dialogs.info(
- "ngSkinTools switched to slow maya API for setting skin cluster weights for this skinCluster, to workaround a Maya bug when skinCluster uses dg nodes as inputs"
+ "切换为设置皮肤集群权重,以解决 Maya皮肤集群使用装点作为输入时的错误。"
)
@@ -73,15 +73,15 @@ def build_action_initialize_layers(session, parent):
def do_initialize():
if import_v1_actions.can_import(session):
q = (
- "Skinning layers from previous version of ngSkinTools are present on this mesh. This operation will initialize "
- "skinning layers from scratch, discarding previous layers information. Do you want to continue?"
+ "来自旧版 ngSkinTools的皮肤层存在于此网格上。此操作将初始化"
+ "从头开始剥离图层,丢弃之前的图层信息。您要继续吗?"
)
if not dialogs.yesNo(q):
return
initializeLayers()
- result = actions.define_action(parent, "Initialize Skinning Layers", callback=do_initialize)
+ result = actions.define_action(parent, "初始化蒙皮层", callback=do_initialize)
@signal.on(session.events.nodeSelectionChanged)
def update():
@@ -95,7 +95,7 @@ def build_action_initialize_layers(session, parent):
def buildAction_createLayer(session, parent):
from ngSkinTools2.ui import actions
- result = actions.define_action(parent, "Create Layer", callback=addLayer, icon=":/newLayerEmpty.png", shortcut=QtCore.Qt.Key_Insert)
+ result = actions.define_action(parent, "创建图层", callback=addLayer, icon=":/newLayerEmpty.png", shortcut=QtCore.Qt.Key_Insert)
@signal.on(session.events.targetChanged)
def update_to_target():
@@ -109,7 +109,7 @@ def buildAction_createLayer(session, parent):
def buildAction_deleteLayer(session, parent):
from ngSkinTools2.ui import actions
- result = actions.define_action(parent, "Delete Layer", callback=deleteSelectedLayers, shortcut=QtCore.Qt.Key_Delete)
+ result = actions.define_action(parent, "删除图层", callback=deleteSelectedLayers, shortcut=QtCore.Qt.Key_Delete)
@signal.on(session.context.selected_layers.changed, session.events.targetChanged, qtParent=parent)
def update_to_target():
@@ -126,12 +126,12 @@ def setCurrentLayer(layer):
:type layer: ngSkinTools2.api.layers.Layer
"""
if not session.active():
- logger.info("didn't set current layer: no session")
+ logger.info("未设置当前图层:没有会话")
if not session.state.layersAvailable:
- logger.info("didn't set current layer: layers not enabled")
+ logger.info("未设置当前图层:图层未启用")
- logger.info("setting current layer to %r on %r", layer, session.state.selectedSkinCluster)
+ logger.info("将当前图层设置为 %r on %r", layer, session.state.selectedSkinCluster)
layer.set_current()
session.events.currentLayerChanged.emitIfChanged()
@@ -158,7 +158,7 @@ def deleteSelectedLayers():
class ToggleEnabledAction(Action):
- name = "Enabled"
+ name = "启用图层" #Enabled
checkable = True
def __init__(self, session):
@@ -192,7 +192,7 @@ class ToggleEnabledAction(Action):
for i in selected_layers:
i.enabled = enabled
- logger.info("layers toggled: %r", selected_layers)
+ logger.info("图层已切换: %r", selected_layers)
session.events.layerListChanged.emitIfChanged()
@@ -209,8 +209,8 @@ def build_action_randomize_influences_colors(session, parent):
:type session: ngSkinTools2.api.session.Session
"""
- result = QAction("Randomize colors", parent)
- result.setToolTip("Choose random colors for each influence, selecting from Maya's pallete of indexed colors")
+ result = QAction("随机颜色", parent)
+ result.setToolTip("为每个影响选择随机颜色,从Maya的索引色板中选择。")
def color_filter(c):
brightness = c[0] * c[0] + c[1] * c[1] + c[2] * c[2]
diff --git a/2024/scripts/rigging_tools/ngskintools2/operations/paint.py b/2024/scripts/rigging_tools/ngskintools2/operations/paint.py
index 41d46d3..f9ec0ea 100644
--- a/2024/scripts/rigging_tools/ngskintools2/operations/paint.py
+++ b/2024/scripts/rigging_tools/ngskintools2/operations/paint.py
@@ -9,8 +9,8 @@ log = getLogger("operations/paint")
class FloodAction(Action):
- name = "Flood"
- tooltip = "Apply current brush to whole selection"
+ name = "填充" # Flood
+ tooltip = "将当前画笔应用于整个选择区域"
def run(self):
session.paint_tool.flood(self.session.state.currentLayer.layer, influences=self.session.state.currentLayer.layer.paint_targets)
@@ -28,8 +28,8 @@ class FloodAction(Action):
class PaintAction(Action):
- name = "Paint"
- tooltip = "Toggle paint tool"
+ name = "绘制" # Paint
+ tooltip = "切换绘制工具"
checkable = True
def run(self):
diff --git a/2024/scripts/rigging_tools/ngskintools2/operations/removeLayerData.py b/2024/scripts/rigging_tools/ngskintools2/operations/removeLayerData.py
index d8e91b7..f8cf0f2 100644
--- a/2024/scripts/rigging_tools/ngskintools2/operations/removeLayerData.py
+++ b/2024/scripts/rigging_tools/ngskintools2/operations/removeLayerData.py
@@ -43,14 +43,14 @@ def list_custom_nodes_for_meshes(meshes):
return list(itertools.chain.from_iterable([list_custom_nodes_for_mesh(i) for i in meshes]))
-message_scene_noCustomNodes = 'Scene does not contain any custom ngSkinTools nodes.'
-message_selection_noCustomNodes = 'Selection does not contain any custom ngSkinTools nodes.'
+message_scene_noCustomNodes = '场景中不包含任何自定义的ngSkinTools节点。'
+message_selection_noCustomNodes = '选择不包含任何自定义ngskinTools节点。'
message_scene_warning = (
- 'This command deletes all custom ngSkinTools nodes. Skin weights ' 'will be preserved, but all layer data will be lost. Do you want to continue?'
+ '此命令删除所有自定义ngSkinTools节点。蒙皮权重“”将被保留,但所有图层数据都将丢失。您想继续吗?'
)
message_selection_warning = (
- 'This command deletes custom ngSkinTools nodes for selection. Skin weights '
- 'will be preserved, but all layer data will be lost. Do you want to continue?'
+ '此命令删除要选择的自定义ngSkinTools节点。皮肤重量'
+ '将被保留,但所有图层数据都将丢失。您想继续吗?'
)
@@ -89,7 +89,7 @@ def remove_custom_nodes(interactive=False, session=None, meshes=None):
if PaintTool.is_painting():
# make sure that painting is canceled to restore mesh display etc
- cmds.setToolTo("Move")
+ cmds.setToolTo("移除") # Move
if session is not None:
session.events.targetChanged.emitIfChanged()
diff --git a/2024/scripts/rigging_tools/ngskintools2/operations/tools.py b/2024/scripts/rigging_tools/ngskintools2/operations/tools.py
index 27e8169..4aee804 100644
--- a/2024/scripts/rigging_tools/ngskintools2/operations/tools.py
+++ b/2024/scripts/rigging_tools/ngskintools2/operations/tools.py
@@ -54,7 +54,7 @@ def create_action__from_closest_joint(parent, session):
if not options.all_influences():
influences = layer.paint_targets
if not influences:
- dialogs.info("Select one or more influences in Influences list")
+ dialogs.info("在影响列表中选择一个或多个影响")
return
if options.create_new_layer():
@@ -77,8 +77,8 @@ def create_action__from_closest_joint(parent, session):
__create_tool_action__(
parent,
session,
- action_name=u"Assign From Closest Joint",
- action_tooltip="Assign 1.0 weight for closest influence per each vertex in selected layer",
+ action_name=u"从最近的关节分配",
+ action_tooltip="为选定层中每个顶点的最近影响分配权重1.0",
exec_handler=exec_handler,
),
options,
@@ -105,8 +105,8 @@ def create_action__unify_weights(parent, session):
__create_tool_action__(
parent,
session,
- action_name=u"Unify Weights",
- action_tooltip="For selected vertices, make verts the same for all verts",
+ action_name=u"统一权重", # Unify Weights
+ action_tooltip="对于选定的顶点,使所有顶点相同。", #对于选定的顶点,使所有顶点相同。
exec_handler=exec_handler,
),
options,
@@ -130,8 +130,8 @@ def create_action__merge_layers(parent, session):
return __create_tool_action__(
parent,
session,
- action_name=u"Merge",
- action_tooltip="Merge contents of this layer into underlying layer. Pre-effects weights will be used for this",
+ action_name=u"合并", # Merge
+ action_tooltip="将本层的元素合并到底层。预效果权重将用于此。",
exec_handler=exec_handler,
enabled_handler=enabled_handler,
)
@@ -155,8 +155,8 @@ def create_action__duplicate_layer(parent, session):
return __create_tool_action__(
parent,
session,
- action_name=u"Duplicate",
- action_tooltip="Duplicate selected layer(s)",
+ action_name=u"复制",
+ action_tooltip="复制选择的图层(多选)",
exec_handler=exec_handler,
)
@@ -176,8 +176,8 @@ def create_action__fill_transparency(parent, session):
return __create_tool_action__(
parent,
session,
- action_name=u"Fill Transparency",
- action_tooltip="All transparent vertices in the selected layer(s) receive weights from their closest non-empty neighbour vertex",
+ action_name=u"填充透明度",
+ action_tooltip="所选图层中的所有透明顶点接收其最近非空邻接顶点的权重,",
exec_handler=exec_handler,
)
@@ -195,8 +195,8 @@ def create_action__copy_component_weights(parent, session):
return __create_tool_action__(
parent,
session,
- action_name=u"Copy Component Weights",
- action_tooltip="Store components weights in memory for further component-based paste actions",
+ action_name=u"复制组件权重",
+ action_tooltip="将组件权重存储在内存中,以便进行进一步的基于组件的粘贴操作",
exec_handler=exec_handler,
)
@@ -214,8 +214,8 @@ def create_action__paste_average_component_weight(parent, session):
return __create_tool_action__(
parent,
session,
- action_name=u"Paste Average Component Weight",
- action_tooltip="Compute average of copied component weights and set that value to currently selected components",
+ action_name=u"粘贴平均组件权重",
+ action_tooltip="计算复制的组件重量的平均值,并将该值设置为当前选定的组件",
exec_handler=exec_handler,
)
@@ -229,7 +229,7 @@ def create_action__add_influences(parent, session):
def exec_handler():
selection = cmds.ls(sl=True, l=True)
if len(selection) < 2:
- logger.info("invalid selection: %s", selection)
+ logger.info("无效选择: %s", selection)
return
api.add_influences(selection[:-1], selection[-1])
cmds.select(selection[-1])
@@ -238,8 +238,8 @@ def create_action__add_influences(parent, session):
return __create_tool_action__(
parent,
session,
- action_name=u"Add Influences",
- action_tooltip="Add selected influences to current skin cluster.",
+ action_name=u"增加影响",
+ action_tooltip="将选定的影响添加到当前皮肤集群。",
exec_handler=exec_handler,
)
@@ -289,7 +289,7 @@ def create_action__select_affected_vertices(parent, session):
return __create_tool_action__(
parent,
session,
- action_name=u"Select Affected Vertices",
- action_tooltip="Select vertices that have non-zero weight for current influence.",
+ action_name=u"选择受影响的顶点",
+ action_tooltip="选择当前影响中权重不为要的顶点。",
exec_handler=exec_handler,
)
diff --git a/2024/scripts/rigging_tools/ngskintools2/operations/website_links.py b/2024/scripts/rigging_tools/ngskintools2/operations/website_links.py
index 3a36476..453e8e5 100644
--- a/2024/scripts/rigging_tools/ngskintools2/operations/website_links.py
+++ b/2024/scripts/rigging_tools/ngskintools2/operations/website_links.py
@@ -12,10 +12,10 @@ def website_base_url():
class WebsiteLinksActions(Object):
def __init__(self, parent):
- self.api_root = make_documentation_action(parent, "API Documentation", "/v2/api")
- self.user_guide = make_documentation_action(parent, "User Guide", "/v2/")
- self.changelog = make_documentation_action(parent, "Change Log", "/v2/changelog", icon=None)
- self.contact = make_documentation_action(parent, "Contact", "/contact/", icon=None)
+ self.api_root = make_documentation_action(parent, "API 文档", "/v2/api")
+ self.user_guide = make_documentation_action(parent, "用户指南", "/v2/")
+ self.changelog = make_documentation_action(parent, "更新日志", "/v2/changelog", icon=None)
+ self.contact = make_documentation_action(parent, "联系", "/contact/", icon=None)
def make_documentation_action(parent, title, url, icon=":/help.png"):
diff --git a/2024/scripts/rigging_tools/ngskintools2/signal.py b/2024/scripts/rigging_tools/ngskintools2/signal.py
index 7961484..ceecb38 100644
--- a/2024/scripts/rigging_tools/ngskintools2/signal.py
+++ b/2024/scripts/rigging_tools/ngskintools2/signal.py
@@ -24,8 +24,8 @@ class SignalQueue(Object):
def emit(self, handler):
if len(self.queue) > self.max_length:
- log.error("queue max length reached: emitting too many events?")
- raise Exception("queue max length reached: emitting too many events?")
+ log.error("队列最大长度已达到:发出的事件过多?")
+ raise Exception("队列最大长度已达到:正在发出太多事件?")
should_start = len(self.queue) == 0
@@ -53,7 +53,7 @@ class SignalQueue(Object):
current_handler += 1
if len(self.queue) > 50:
- log.info("handler queue finished with %d items", len(self.queue))
+ log.info("处理器队列完成,共 %d 项", len(self.queue))
self.queue = []
@@ -77,7 +77,7 @@ class Signal(Object):
def __init__(self, name):
if name is None:
- raise Exception("need name for debug purposes later")
+ raise Exception("需要稍后用于调试目的的名称")
self.name = name
self.handlers = []
self.executing = False
diff --git a/2024/scripts/rigging_tools/ngskintools2/ui/aboutwindow.py b/2024/scripts/rigging_tools/ngskintools2/ui/aboutwindow.py
index e96ffd2..cde00c6 100644
--- a/2024/scripts/rigging_tools/ngskintools2/ui/aboutwindow.py
+++ b/2024/scripts/rigging_tools/ngskintools2/ui/aboutwindow.py
@@ -19,7 +19,7 @@ def show(parent):
layout = QtWidgets.QVBoxLayout()
layout.addStretch()
layout.addWidget(QtWidgets.QLabel("
ngSkinTools
"))
- layout.addWidget(QtWidgets.QLabel("Version {0}".format(version.pluginVersion())))
+ layout.addWidget(QtWidgets.QLabel("当前版本 {0}".format(version.pluginVersion())))
layout.addWidget(QtWidgets.QLabel(version.COPYRIGHT))
url = QtWidgets.QLabel('{0}'.format(version.PRODUCT_URL))
@@ -65,7 +65,7 @@ def show(parent):
def buttonsRow(window):
layout = QtWidgets.QHBoxLayout()
layout.addStretch()
- btnClose = QtWidgets.QPushButton("Close")
+ btnClose = QtWidgets.QPushButton("退出")
btnClose.setMinimumWidth(100 * scale_multiplier)
layout.addWidget(btnClose)
layout.setContentsMargins(20 * scale_multiplier, 15 * scale_multiplier, 20 * scale_multiplier, 15 * scale_multiplier)
@@ -76,7 +76,7 @@ def show(parent):
window = QtWidgets.QWidget(parent, Qt.Window | Qt.WindowTitleHint | Qt.CustomizeWindowHint)
window.resize(600 * scale_multiplier, 500 * scale_multiplier)
window.setAttribute(Qt.WA_DeleteOnClose)
- window.setWindowTitle("About ngSkinTools")
+ window.setWindowTitle("关于 ngSkinTools")
layout = QtWidgets.QVBoxLayout()
window.setLayout(layout)
layout.setContentsMargins(0, 0, 0, 0)
diff --git a/2024/scripts/rigging_tools/ngskintools2/ui/actions.py b/2024/scripts/rigging_tools/ngskintools2/ui/actions.py
index 28b66af..45fac41 100644
--- a/2024/scripts/rigging_tools/ngskintools2/ui/actions.py
+++ b/2024/scripts/rigging_tools/ngskintools2/ui/actions.py
@@ -35,7 +35,7 @@ def build_action_delete_custom_nodes_for_selection(parent, session):
result = define_action(
parent,
- "Delete Custom Nodes For Selection",
+ "删除选中网格的Ng节点",
callback=lambda: removeLayerData.remove_custom_nodes_from_selection(interactive=True, session=session),
)
@@ -86,7 +86,7 @@ class Actions(Object):
self.toolsUnifyWeights, self.toolsUnifyWeightsOptions = tools.create_action__unify_weights(parent, session)
self.toolsDeleteCustomNodes = define_action(
- parent, "Delete All Custom Nodes", callback=lambda: removeLayerData.remove_custom_nodes(interactive=True, session=session)
+ parent, "删除所有网格的Ng节点", callback=lambda: removeLayerData.remove_custom_nodes(interactive=True, session=session)
)
self.toolsDeleteCustomNodesOnSelection = build_action_delete_custom_nodes_for_selection(parent, session)
@@ -135,10 +135,10 @@ class Actions(Object):
context.addAction(self.toggle_layer_enabled)
def addInfluencesActions(self, context):
- context.addAction(self.separator(context, "Actions"))
+ context.addAction(self.separator(context, "动作"))
context.addAction(self.toolsAssignFromClosestJointSelectedInfluences)
context.addAction(self.select_affected_vertices)
- context.addAction(self.separator(context, "Clipboard"))
+ context.addAction(self.separator(context, "剪贴板"))
context.addAction(self.cut_influences)
context.addAction(self.copy_influences)
context.addAction(self.paste_weights)
diff --git a/2024/scripts/rigging_tools/ngskintools2/ui/influenceMappingUI.py b/2024/scripts/rigging_tools/ngskintools2/ui/influenceMappingUI.py
index a77deef..b3991e8 100644
--- a/2024/scripts/rigging_tools/ngskintools2/ui/influenceMappingUI.py
+++ b/2024/scripts/rigging_tools/ngskintools2/ui/influenceMappingUI.py
@@ -36,7 +36,7 @@ def open_as_dialog(parent, matcher, result_callback):
window.close()
def save_defaults():
- if not yesNo("Save current settings as default?"):
+ if not yesNo("将当前设置保存为默认设置?"):
return
config.mirrorInfluencesDefaults = matcher.config.as_json()
@@ -47,18 +47,18 @@ def open_as_dialog(parent, matcher, result_callback):
return widgets.button_row(
[
- ("Apply", apply),
- ("Cancel", window.close),
+ ("应用", apply),
+ ("取消", window.close),
],
side_menu=[
- ("Save As Default", save_defaults),
- ("Load Defaults", load_defaults),
+ ("储存为默认值", save_defaults),
+ ("加载默认值", load_defaults),
],
)
window = QtWidgets.QDialog(parent)
cleanup.registerCleanupHandler(window.close)
- window.setWindowTitle("Influence Mirror Mapping")
+ window.setWindowTitle("影响镜像映射")
window.setAttribute(QtCore.Qt.WA_DeleteOnClose)
window.resize(720 * scale_multiplier, 500 * scale_multiplier)
window.setLayout(QtWidgets.QVBoxLayout())
@@ -102,10 +102,10 @@ def build_ui(parent, matcher):
split_path = path.rsplit("|", 1)
parent_path, name = split_path if len(split_path) == 2 else ["", split_path[0]]
- item = QtWidgets.QTreeWidgetItem([name, '-', '(not in skin cluster)' if is_intermediate else '?'])
+ item = QtWidgets.QTreeWidgetItem([name, '-', '(不在皮肤簇中)' if is_intermediate else '?'])
tree_items[path] = item
- parent_item = None if parent_path == "" else find_item(parent_path, True)
+ parent_item = None if parent_path is "" else find_item(parent_path, True)
if parent_item is not None:
parent_item.addChild(item)
@@ -142,7 +142,7 @@ def build_ui(parent, matcher):
def pattern():
result = QtWidgets.QTableWidget()
result.setColumnCount(2)
- result.setHorizontalHeaderLabels(["Pattern", "Opposite"] if mirror_mode else ["Source", "Destination"])
+ result.setHorizontalHeaderLabels(["左", "右"] if mirror_mode else ["来源", "目标"])
result.setEditTriggers(QtWidgets.QTableWidget.AllEditTriggers)
result.verticalHeader().setVisible(False)
@@ -209,12 +209,12 @@ def build_ui(parent, matcher):
def automaticRules():
form = QtWidgets.QFormLayout()
- use_joint_names = QtWidgets.QCheckBox("Match by joint name")
+ use_joint_names = QtWidgets.QCheckBox("匹配骨骼名称")
naming_patterns = pattern()
- use_position = QtWidgets.QCheckBox("Match by position")
+ use_position = QtWidgets.QCheckBox("匹配位置")
tolerance_scroll = tolerance()
- use_joint_labels = QtWidgets.QCheckBox("Match by joint label")
- use_dg_links = QtWidgets.QCheckBox("Match by dependency graph links")
+ use_joint_labels = QtWidgets.QCheckBox("匹配骨骼标签")
+ use_dg_links = QtWidgets.QCheckBox("匹配依存关系图连接")
def update_enabled_disabled():
def enable_form_row(form_item, e):
@@ -260,27 +260,27 @@ def build_ui(parent, matcher):
use_dg_links.setChecked(matcher.config.use_dg_link_matching)
update_enabled_disabled()
- g = QtWidgets.QGroupBox("Rules")
+ g = QtWidgets.QGroupBox("规则")
g.setLayout(form)
form.addRow(use_dg_links)
- form.addRow("Attribute name:", dg_attribute)
+ form.addRow("属性名称:", dg_attribute)
form.addRow(use_joint_labels)
form.addRow(use_joint_names)
- form.addRow("Naming scheme:", naming_patterns)
+ form.addRow("命名方案:", naming_patterns)
form.addRow(use_position)
- form.addRow("Position tolerance:", tolerance_scroll.layout())
+ form.addRow("位置容差:", tolerance_scroll.layout())
update_values()
return g
def scriptedRules():
- g = QtWidgets.QGroupBox("Scripted rules")
+ g = QtWidgets.QGroupBox("脚本规则")
g.setLayout(QtWidgets.QVBoxLayout())
g.layout().addWidget(QtWidgets.QLabel("TODO"))
return g
def manualRules():
- g = QtWidgets.QGroupBox("Manual overrides")
+ g = QtWidgets.QGroupBox("手动覆盖")
g.setLayout(QtWidgets.QVBoxLayout())
g.layout().addWidget(QtWidgets.QLabel("TODO"))
return g
@@ -302,7 +302,7 @@ def build_ui(parent, matcher):
def createMappingView():
view = QtWidgets.QTreeWidget()
view.setColumnCount(3)
- view.setHeaderLabels(["Source", "Destination", "Matched by rule"])
+ view.setHeaderLabels(["来源", "目标", "按规则匹配"])
view.setIndentation(7)
view.setExpandsOnDoubleClick(False)
@@ -316,14 +316,14 @@ def build_ui(parent, matcher):
:type mapping: dict[InfluenceInfo, InfluenceInfo]
"""
for treeItem in list(usedItems.values()):
- treeItem.setText(1, "(not matched)")
+ treeItem.setText(1, "(不匹配)")
treeItem.setText(2, "")
for k, v in list(mapping.items()):
treeItem = usedItems.get(k.path_name(), None)
if treeItem is None:
continue
- treeItem.setText(1, "(self)" if k == v['infl'] else v["infl"].shortestPath)
+ treeItem.setText(1, "(自己)" if k == v['infl'] else v["infl"].shortestPath)
treeItem.setText(2, v["matchedRule"])
treeItem.setData(1, linkedItemRole, v["infl"].path)
@@ -343,7 +343,7 @@ def build_ui(parent, matcher):
matches = matcher.calculate()
mappingView_updateMatches(matches)
- g = QtWidgets.QGroupBox("Calculated mapping")
+ g = QtWidgets.QGroupBox("计算映射")
g.setLayout(QtWidgets.QVBoxLayout())
mappingView, mappingView_updateMatches = createMappingView()
g.layout().addWidget(mappingView)
diff --git a/2024/scripts/rigging_tools/ngskintools2/ui/influencesview.py b/2024/scripts/rigging_tools/ngskintools2/ui/influencesview.py
index 2f5307b..8c18b93 100644
--- a/2024/scripts/rigging_tools/ngskintools2/ui/influencesview.py
+++ b/2024/scripts/rigging_tools/ngskintools2/ui/influencesview.py
@@ -19,9 +19,9 @@ def build_used_influences_action(parent):
result = actions.define_action(
parent,
- "Used Influences Only",
+ "只显示有权重的影响物",
callback=toggle,
- tooltip="If enabled, influences view will only show influences that have weights on current layer",
+ tooltip="如果启用,影响视图将仅显示当前层上有权重的影响。",
)
@signal.on(config.influences_show_used_influences_only.changed, qtParent=parent)
@@ -46,7 +46,7 @@ def build_set_influences_sorted_action(parent):
parent,
"Show influences sorted",
callback=toggle,
- tooltip="Sort influences by name",
+ tooltip="按名称排序影响",
)
@signal.on(config.influences_show_used_influences_only.changed, qtParent=parent)
@@ -108,7 +108,7 @@ def build_view(parent, actions, session, filter):
targets = (item_id,)
layer.locked_influences = add_or_remove(layer.locked_influences, targets, lock)
- log.info("updated locked influences to %r", layer.locked_influences)
+ log.info("更新锁定的影响为 %r", layer.locked_influences)
session.events.influencesListUpdated.emit()
return handler
@@ -170,14 +170,14 @@ def build_view(parent, actions, session, filter):
view.setSelectionMode(QtWidgets.QAbstractItemView.ExtendedSelection)
view.setContextMenuPolicy(QtCore.Qt.ActionsContextMenu)
actions.addInfluencesActions(view)
- view.addAction(actions.separator(parent, "View Options"))
+ view.addAction(actions.separator(parent, "显示设置"))
view.addAction(actions.show_used_influences_only)
view.addAction(actions.set_influences_sorted)
view.setIndentation(10 * scale_multiplier)
view.header().setStretchLastSection(False)
view.header().setSectionResizeMode(0, QtWidgets.QHeaderView.Stretch)
- view.setHeaderLabels(["Influences", ""])
+ view.setHeaderLabels(["影响物", ""])
view.header().setSectionResizeMode(1, QtWidgets.QHeaderView.Fixed)
view.setColumnWidth(1, 25 * scale_multiplier)
@@ -208,7 +208,7 @@ def build_view(parent, actions, session, filter):
if not session.state.currentLayer.layer:
build_items(view, [], None)
else:
- log.info("current layer changed to %s", session.state.currentLayer.layer)
+ log.info("当前图层更改为 %s", session.state.currentLayer.layer)
refresh_items()
current_influence_changed()
@@ -217,7 +217,7 @@ def build_view(parent, actions, session, filter):
if session.state.currentLayer.layer is None:
return
- log.info("current influence changed - updating item selection")
+ log.info("当前影响已更改-更新项目选择")
with qt.signals_blocked(view):
targets = session.state.currentLayer.layer.paint_targets
first = True
@@ -239,12 +239,12 @@ def build_view(parent, actions, session, filter):
if not session.state.currentLayer.layer:
return
- log.info("focused item changed: %r", get_item_id(curr))
+ log.info("焦点项已更改: %r", get_item_id(curr))
sync_paint_targets_to_selection()
@qt.on(view.itemSelectionChanged)
def sync_paint_targets_to_selection():
- log.info("syncing paint targets")
+ log.info("同步绘画目标")
selected_ids = [get_item_id(item) for item in view.selectedItems()]
selected_ids = [i for i in selected_ids if i is not None]
diff --git a/2024/scripts/rigging_tools/ngskintools2/ui/layersview.py b/2024/scripts/rigging_tools/ngskintools2/ui/layersview.py
index 708450c..a959849 100644
--- a/2024/scripts/rigging_tools/ngskintools2/ui/layersview.py
+++ b/2024/scripts/rigging_tools/ngskintools2/ui/layersview.py
@@ -48,12 +48,12 @@ def build_view(parent, actions):
child_layer = item_to_layer(child)
if child_layer.parent_id != parent_layer_id:
- log.info("changing layer parent: %r->%r (was %r)", parent_layer_id, child_layer, child_layer.parent_id)
+ log.info("更改图层父级: %r->%r (was %r)", parent_layer_id, child_layer, child_layer.parent_id)
child_layer.parent = parent_layer_id
new_index = tree_item.childCount() - i - 1
if child_layer.index != new_index:
- log.info("changing layer index: %r->%r (was %r)", child_layer, new_index, child_layer.index)
+ log.info("更改图层索引: %r->%r (was %r)", child_layer, new_index, child_layer.index)
child_layer.index = new_index
sync_item(child, child_layer.id)
@@ -82,7 +82,7 @@ def build_view(parent, actions):
view.setContextMenuPolicy(QtCore.Qt.ActionsContextMenu)
actions.addLayersActions(view)
- view.setHeaderLabels(["Layers", ""])
+ view.setHeaderLabels(["图层", ""])
# view.setHeaderHidden(True)
view.header().setMinimumSectionSize(1)
view.header().setStretchLastSection(False)
@@ -100,7 +100,7 @@ def build_view(parent, actions):
bar = QtWidgets.QToolBar(parent=parent)
bar.setMovable(False)
bar.setIconSize(QtCore.QSize(visibility_icon_size * scale_multiplier, visibility_icon_size * scale_multiplier))
- a = bar.addAction(icon_visible if layer is None or layer.enabled else icon_hidden, "Toggle enabled/disabled")
+ a = bar.addAction(icon_visible if layer is None or layer.enabled else icon_hidden, "切换 启用/禁用")
@qt.on(a.triggered)
def handler():
@@ -117,11 +117,11 @@ def build_view(parent, actions):
# build map "parent id->list of children "
- log.info("syncing items...")
+ log.info("同步项目q...")
# save selected layers IDs to restore item selection later
selected_layer_ids = {item_to_layer(item).id for item in view.selectedItems()}
- log.info("selected layer IDs: %r", selected_layer_ids)
+ log.info("选择层 IDs: %r", selected_layer_ids)
current_item_id = None if view.currentItem() is None else item_to_layer(view.currentItem()).id
hierarchy = {}
@@ -167,7 +167,7 @@ def build_view(parent, actions):
@signal.on(session.events.layerListChanged, qtParent=view)
def refresh_layer_list():
- log.info("event handler for layer list changed")
+ log.info("图层列表更改的事件处理程序")
if not session.state.layersAvailable:
build_items([])
else:
@@ -177,7 +177,7 @@ def build_view(parent, actions):
@signal.on(session.events.currentLayerChanged, qtParent=view)
def current_layer_changed():
- log.info("event handler for currentLayerChanged")
+ log.info("当前图层更改的事件处理程序")
layer = session.state.currentLayer.layer
current_item = view.currentItem()
if layer is None:
@@ -189,14 +189,14 @@ def build_view(parent, actions):
if prev_layer is None or prev_layer.id != layer.id:
item = tree_items.get(layer.id, None)
if item is not None:
- log.info("setting current item to " + item.text(0))
+ log.info("将当前项目设置为 " + item.text(0))
view.setCurrentItem(item, 0, QtCore.QItemSelectionModel.SelectCurrent | QtCore.QItemSelectionModel.ClearAndSelect)
item.setSelected(True)
@qt.on(view.currentItemChanged)
def current_item_changed(curr, _):
- log.info("current item changed")
+ log.info("当前项目已更改")
if curr is None:
return
@@ -209,7 +209,7 @@ def build_view(parent, actions):
@qt.on(view.itemChanged)
def item_changed(item, column):
- log.info("item changed")
+ log.info("项目已更改")
layers.renameLayer(item_to_layer(item), item.text(column))
@qt.on(view.itemSelectionChanged)
@@ -217,7 +217,7 @@ def build_view(parent, actions):
selection = [item_to_layer(item) for item in view.selectedItems()]
if selection != session.context.selected_layers(default=[]):
- log.info("new selected layers: %r", selection)
+ log.info("新选择图层: %r", selection)
session.context.selected_layers.set(selection)
refresh_layer_list()
diff --git a/2024/scripts/rigging_tools/ngskintools2/ui/mainwindow.py b/2024/scripts/rigging_tools/ngskintools2/ui/mainwindow.py
index e5b2e87..8b12a4f 100644
--- a/2024/scripts/rigging_tools/ngskintools2/ui/mainwindow.py
+++ b/2024/scripts/rigging_tools/ngskintools2/ui/mainwindow.py
@@ -46,20 +46,20 @@ def build_menu(parent, actions):
sub_item.setTearOffEnabled(True)
return sub_item
- sub = top_level_menu("File")
- sub.addSeparator().setText("Import/Export")
+ sub = top_level_menu("文件")
+ sub.addSeparator().setText("导入/导出")
sub.addAction(actions.importFile)
sub.addAction(actions.exportFile)
- sub = top_level_menu("Layers")
- sub.addSeparator().setText("Layer actions")
+ sub = top_level_menu("图层")
+ sub.addSeparator().setText("图层操作")
sub.addAction(actions.initialize)
sub.addAction(actions.import_v1)
actions.addLayersActions(sub)
- sub.addSeparator().setText("Copy")
+ sub.addSeparator().setText("复制")
sub.addAction(actions.transfer)
- sub = top_level_menu("Tools")
+ sub = top_level_menu("工具")
sub.addAction(actions.add_influences)
sub.addAction(actions.toolsAssignFromClosestJoint)
sub.addSeparator()
@@ -68,17 +68,17 @@ def build_menu(parent, actions):
sub.addAction(actions.toolsDeleteCustomNodesOnSelection)
sub.addAction(actions.toolsDeleteCustomNodes)
- sub = top_level_menu("View")
+ sub = top_level_menu("查看")
sub.addAction(actions.show_used_influences_only)
- sub = top_level_menu("Help")
+ sub = top_level_menu("帮助")
sub.addAction(actions.documentation.user_guide)
sub.addAction(actions.documentation.api_root)
sub.addAction(actions.documentation.changelog)
sub.addAction(actions.documentation.contact)
sub.addSeparator()
sub.addAction(actions.check_for_updates)
- sub.addAction("About...").triggered.connect(lambda: aboutwindow.show(parent))
+ sub.addAction("关于...").triggered.connect(lambda: aboutwindow.show(parent))
return menu
@@ -107,11 +107,11 @@ def build_ui(parent):
tabs = QtWidgets.QTabWidget(window)
- tabs.addTab(tabPaint.build_ui(tabs, actions), "Paint")
- tabs.addTab(tabSetWeights.build_ui(tabs), "Set Weights")
- tabs.addTab(tabMirror.build_ui(tabs), "Mirror")
- tabs.addTab(tabLayerEffects.build_ui(), "Effects")
- tabs.addTab(tabTools.build_ui(actions, session), "Tools")
+ tabs.addTab(tabPaint.build_ui(tabs, actions), "绘制")
+ tabs.addTab(tabSetWeights.build_ui(tabs), "设置权重")
+ tabs.addTab(tabMirror.build_ui(tabs), "镜像")
+ tabs.addTab(tabLayerEffects.build_ui(), "样式")
+ tabs.addTab(tabTools.build_ui(actions, session), "工具")
@signal.on(options.current_tab.changed)
def set_current_tab():
diff --git a/2024/scripts/rigging_tools/ngskintools2/ui/model_binds.py b/2024/scripts/rigging_tools/ngskintools2/ui/model_binds.py
index 314313c..da06573 100644
--- a/2024/scripts/rigging_tools/ngskintools2/ui/model_binds.py
+++ b/2024/scripts/rigging_tools/ngskintools2/ui/model_binds.py
@@ -19,4 +19,4 @@ def bind(ui, model):
model.set(ui.value())
else:
- raise Exception("could not bind control to model")
+ raise Exception("无法将控件绑定到模型")
diff --git a/2024/scripts/rigging_tools/ngskintools2/ui/options.py b/2024/scripts/rigging_tools/ngskintools2/ui/options.py
index df7ddca..076510b 100644
--- a/2024/scripts/rigging_tools/ngskintools2/ui/options.py
+++ b/2024/scripts/rigging_tools/ngskintools2/ui/options.py
@@ -99,10 +99,10 @@ def save_option(varName, value):
elif is_string(value):
key = 'sv'
else:
- raise ValueError("could not save option %s: invalid value %r" % (varName, value))
+ raise ValueError("无法保存选项 %s: 无效值 %r" % (varName, value))
kvargs = {key: (varName, value)}
- log.info("saving optionvar: %r", kvargs)
+ log.info("保存选项变量: %r", kvargs)
cmds.optionVar(**kvargs)
@@ -153,11 +153,11 @@ class Config(Object):
def __get_value__(self, name, default_value):
result = self.__state__.get(name, default_value)
- log.info("config: return %s=%r", name, result)
+ log.info("配置: return %s=%r", name, result)
return result
def __set_value__(self, name, value):
- log.info("config: save %s=%r", name, value)
+ log.info("配置: save %s=%r", name, value)
self.__state__[name] = value
self.save()
diff --git a/2024/scripts/rigging_tools/ngskintools2/ui/tabLayerEffects.py b/2024/scripts/rigging_tools/ngskintools2/ui/tabLayerEffects.py
index 56c53f6..4da7beb 100644
--- a/2024/scripts/rigging_tools/ngskintools2/ui/tabLayerEffects.py
+++ b/2024/scripts/rigging_tools/ngskintools2/ui/tabLayerEffects.py
@@ -36,9 +36,9 @@ def build_ui():
def build_properties():
layout = QtWidgets.QVBoxLayout()
- opacity = widgets.NumberSliderGroup(tooltip="multiply layer mask to control overall transparency of the layer.")
+ opacity = widgets.NumberSliderGroup(tooltip="多层蒙版来控制图层的整体透明度.")
opacity.set_value(1.0)
- layout.addLayout(createTitledRow("Opacity:", opacity.layout()))
+ layout.addLayout(createTitledRow("不透明度:", opacity.layout()))
def default_selection_opacity(layers):
if len(layers) > 0:
@@ -65,7 +65,7 @@ def build_ui():
update_values()
- group = QtWidgets.QGroupBox("Layer properties")
+ group = QtWidgets.QGroupBox("图层属性")
group.setLayout(layout)
return group
@@ -76,18 +76,18 @@ def build_ui():
i.effects.configure_mirror(**{option: value})
mirror_direction = QtWidgets.QComboBox()
- mirror_direction.addItem("Positive to negative", MirrorOptions.directionPositiveToNegative)
- mirror_direction.addItem("Negative to positive", MirrorOptions.directionNegativeToPositive)
- mirror_direction.addItem("Flip", MirrorOptions.directionFlip)
+ mirror_direction.addItem("从正到负", MirrorOptions.directionPositiveToNegative)
+ mirror_direction.addItem("从负到正", MirrorOptions.directionNegativeToPositive)
+ mirror_direction.addItem("翻转", MirrorOptions.directionFlip)
mirror_direction.setMinimumWidth(1)
@qt.on(mirror_direction.currentIndexChanged)
def value_changed():
- configure_mirror_all_layers("mirror_direction", mirror_direction.currentData())
+ configure_mirror_all_layers("镜像方向", mirror_direction.currentData())
- influences = QtWidgets.QCheckBox("Influence weights")
- mask = QtWidgets.QCheckBox("Layer mask")
- dq = QtWidgets.QCheckBox("Dual quaternion weights")
+ influences = QtWidgets.QCheckBox("影响物权重")
+ mask = QtWidgets.QCheckBox("图层蒙板")
+ dq = QtWidgets.QCheckBox("双四元数权重")
def configure_checkbox(checkbox, option):
@qt.on(checkbox.stateChanged)
@@ -125,21 +125,21 @@ def build_ui():
return result
layout = QtWidgets.QVBoxLayout()
- layout.addLayout(createTitledRow("Mirror effect on:", elements()))
- layout.addLayout(createTitledRow("Mirror direction:", mirror_direction))
+ layout.addLayout(createTitledRow("镜像效果打开:", elements()))
+ layout.addLayout(createTitledRow("镜像方向:", mirror_direction))
- group = QtWidgets.QGroupBox("Mirror")
+ group = QtWidgets.QGroupBox("镜像")
group.setLayout(layout)
return group
def build_skin_properties():
- use_max_influences = QtWidgets.QCheckBox("Limit max influences per vertex")
+ use_max_influences = QtWidgets.QCheckBox("限制每个顶点的最大影响物")
max_influences = widgets.NumberSliderGroup(min_value=1, max_value=5, tooltip="", value_type=int)
- use_prune_weight = QtWidgets.QCheckBox("Prune small weights before writing to skin cluster")
+ use_prune_weight = QtWidgets.QCheckBox("在写入蒙皮簇之前修剪小权重")
prune_weight = widgets.NumberSliderGroup(decimals=6, min_value=0.000001, max_value=0.05, tooltip="")
prune_weight.set_value(prune_weight.min_value)
- prune_weight.set_expo("start", 3)
+ prune_weight.set_expo("开始", 3)
@signal.on(session.events.targetChanged)
def update_ui():
@@ -164,7 +164,7 @@ def build_ui():
@qt.on(use_max_influences.stateChanged, use_prune_weight.stateChanged)
@signal.on(max_influences.valueChanged, prune_weight.valueChanged)
def update_values():
- log.info("updating effects tab")
+ log.info("更新效果标签页")
if session.state.layersAvailable:
session.state.layers.influence_limit_per_vertex = max_influences.value() if use_max_influences.isChecked() else 0
@@ -174,11 +174,11 @@ def build_ui():
layout = QtWidgets.QVBoxLayout()
layout.addWidget(use_max_influences)
- layout.addLayout(createTitledRow("Max influences:", max_influences.layout()))
+ layout.addLayout(createTitledRow("最大影响物:", max_influences.layout()))
layout.addWidget(use_prune_weight)
- layout.addLayout(createTitledRow("Prune below:", prune_weight.layout()))
+ layout.addLayout(createTitledRow("修剪以下:", prune_weight.layout()))
- group = QtWidgets.QGroupBox("Skin Properties")
+ group = QtWidgets.QGroupBox("蒙皮属性")
group.setLayout(layout)
update_ui()
diff --git a/2024/scripts/rigging_tools/ngskintools2/ui/tabMirror.py b/2024/scripts/rigging_tools/ngskintools2/ui/tabMirror.py
index c8873f8..bae7ec9 100644
--- a/2024/scripts/rigging_tools/ngskintools2/ui/tabMirror.py
+++ b/2024/scripts/rigging_tools/ngskintools2/ui/tabMirror.py
@@ -16,10 +16,10 @@ def build_ui(parent_window):
def build_mirroring_options_group():
def get_mirror_direction():
mirror_direction = QtWidgets.QComboBox()
- mirror_direction.addItem("Guess from stroke", MirrorOptions.directionGuess)
- mirror_direction.addItem("Positive to negative", MirrorOptions.directionPositiveToNegative)
- mirror_direction.addItem("Negative to positive", MirrorOptions.directionNegativeToPositive)
- mirror_direction.addItem("Flip", MirrorOptions.directionFlip)
+ mirror_direction.addItem("从笔划猜测", MirrorOptions.directionGuess)
+ mirror_direction.addItem("从正到负", MirrorOptions.directionPositiveToNegative)
+ mirror_direction.addItem("从负到正", MirrorOptions.directionNegativeToPositive)
+ mirror_direction.addItem("翻转", MirrorOptions.directionFlip)
mirror_direction.setMinimumWidth(1)
qt.select_data(mirror_direction, config.mirror_direction())
@@ -65,19 +65,19 @@ def build_ui(parent_window):
return seam_width_ctrl.layout()
def elements():
- influences = bind_checkbox(QtWidgets.QCheckBox("Influence weights"), config.mirror_weights)
- mask = bind_checkbox(QtWidgets.QCheckBox("Layer mask"), config.mirror_mask)
- dq = bind_checkbox(QtWidgets.QCheckBox("Dual quaternion weights"), config.mirror_dq)
+ influences = bind_checkbox(QtWidgets.QCheckBox("影响物权重"), config.mirror_weights)
+ mask = bind_checkbox(QtWidgets.QCheckBox("图层遮罩"), config.mirror_mask)
+ dq = bind_checkbox(QtWidgets.QCheckBox("双四元权重"), config.mirror_dq)
return influences, mask, dq
- result = QtWidgets.QGroupBox("Mirroring options")
+ result = QtWidgets.QGroupBox("镜像选项")
layout = QtWidgets.QVBoxLayout()
result.setLayout(layout)
- layout.addLayout(createTitledRow("Axis:", axis()))
- layout.addLayout(createTitledRow("Direction:", get_mirror_direction()))
- layout.addLayout(createTitledRow("Seam width:", mirror_seam_width()))
- layout.addLayout(createTitledRow("Elements to mirror:", *elements()))
+ layout.addLayout(createTitledRow("镜像轴:", axis()))
+ layout.addLayout(createTitledRow("方向:", get_mirror_direction()))
+ layout.addLayout(createTitledRow("接缝宽度:", mirror_seam_width()))
+ layout.addLayout(createTitledRow("镜像要素:", *elements()))
return result
@@ -86,10 +86,10 @@ def build_ui(parent_window):
def mirror_mesh_group():
mesh_name_edit = QtWidgets.QLineEdit("mesh1")
mesh_name_edit.setReadOnly(True)
- select_button = QtWidgets.QPushButton("Select")
- create_button = QtWidgets.QPushButton("Create")
+ select_button = QtWidgets.QPushButton("选择")
+ create_button = QtWidgets.QPushButton("创建")
set_button = QtWidgets.QPushButton("Set")
- set_button.setToolTip("Select symmetry mesh and a skinned target first")
+ set_button.setToolTip("首先选择对称网格和蒙皮目标")
layout = QtWidgets.QHBoxLayout()
layout.addWidget(mesh_name_edit)
@@ -144,13 +144,13 @@ def build_ui(parent_window):
return layout
vertex_mapping_mode = QtWidgets.QComboBox()
- vertex_mapping_mode.addItem("Closest point on surface", VertexTransferMode.closestPoint)
- vertex_mapping_mode.addItem("UV space", VertexTransferMode.uvSpace)
+ vertex_mapping_mode.addItem("曲面上最近的点", VertexTransferMode.closestPoint)
+ vertex_mapping_mode.addItem("UV空间", VertexTransferMode.uvSpace)
- result = QtWidgets.QGroupBox("Vertex Mapping")
+ result = QtWidgets.QGroupBox("顶点映射")
layout = QtWidgets.QVBoxLayout()
- layout.addLayout(createTitledRow("Mapping mode:", vertex_mapping_mode))
- layout.addLayout(createTitledRow("Symmetry mesh:", mirror_mesh_group()))
+ layout.addLayout(createTitledRow("映射模式:", vertex_mapping_mode))
+ layout.addLayout(createTitledRow("对称网格:", mirror_mesh_group()))
result.setLayout(layout)
@qt.on(vertex_mapping_mode.currentIndexChanged)
@@ -166,7 +166,7 @@ def build_ui(parent_window):
def influence_mapping_group():
def edit_mapping():
- mapping = QtWidgets.QPushButton("Preview and edit mapping")
+ mapping = QtWidgets.QPushButton("预览和编辑映射")
single_window_policy = qt.SingleWindowPolicy()
@@ -182,7 +182,7 @@ def build_ui(parent_window):
layout = QtWidgets.QVBoxLayout()
layout.addWidget(edit_mapping())
- result = QtWidgets.QGroupBox("Influences mapping")
+ result = QtWidgets.QGroupBox("影响物映射")
result.setLayout(layout)
return result
@@ -192,7 +192,7 @@ def build_ui(parent_window):
tab.innerLayout.addWidget(influence_mapping_group())
tab.innerLayout.addStretch()
- btn_mirror = QtWidgets.QPushButton("Mirror")
+ btn_mirror = QtWidgets.QPushButton("镜像")
tab.lowerButtonsRow.addWidget(btn_mirror)
@qt.on(btn_mirror.clicked)
diff --git a/2024/scripts/rigging_tools/ngskintools2/ui/tabPaint.py b/2024/scripts/rigging_tools/ngskintools2/ui/tabPaint.py
index 9ee6d56..f265d6e 100644
--- a/2024/scripts/rigging_tools/ngskintools2/ui/tabPaint.py
+++ b/2024/scripts/rigging_tools/ngskintools2/ui/tabPaint.py
@@ -50,14 +50,14 @@ def build_ui(parent, global_actions):
t.addAction(a)
t = QtWidgets.QToolBar()
- create_brush_mode_button(t, PaintMode.replace, "Replace", "Whatever")
- create_brush_mode_button(t, PaintMode.add, "Add", "")
- create_brush_mode_button(t, PaintMode.scale, "Scale", "")
+ create_brush_mode_button(t, PaintMode.replace, "替换", "替换")
+ create_brush_mode_button(t, PaintMode.add, "添加", "")
+ create_brush_mode_button(t, PaintMode.scale, "减少", "")
row.addWidget(t)
t = QtWidgets.QToolBar()
- create_brush_mode_button(t, PaintMode.smooth, "Smooth", "")
- create_brush_mode_button(t, PaintMode.sharpen, "Sharpen", "")
+ create_brush_mode_button(t, PaintMode.smooth, "平滑", "")
+ create_brush_mode_button(t, PaintMode.sharpen, "锐化", "")
row.addWidget(t)
@on_signal(et.tool_settings_changed, scope=row)
@@ -96,9 +96,9 @@ def build_ui(parent, global_actions):
update_to_tool()
qt.on(a.toggled)(toggled)
- add_brush_shape_action(':/circleSolid.png', 'Solid', BrushShape.solid, checked=True)
- add_brush_shape_action(':/circlePoly.png', 'Smooth', BrushShape.smooth)
- add_brush_shape_action(':/circleGaus.png', 'Gaus', BrushShape.gaus)
+ add_brush_shape_action(':/circleSolid.png', '硬边圆', BrushShape.solid, checked=True)
+ add_brush_shape_action(':/circlePoly.png', '软边圆', BrushShape.smooth)
+ add_brush_shape_action(':/circleGaus.png', '喷枪', BrushShape.gaus)
return result
@@ -136,23 +136,23 @@ def build_ui(parent, global_actions):
update_to_tool()
add(
- 'Surface',
- 'Using first surface hit under the mouse, update all nearby vertices that are connected by surface to the hit location. '
- + 'Only current shell will be updated.',
+ '表面',
+ '绘制由与曲面相连的模型顶点.'
+ + '仅更新当前shell.',
BrushProjectionMode.surface,
use_volume=False,
checked=True,
)
add(
- 'Volume',
- 'Using first surface hit under the mouse, update all nearby vertices, including those from other shells.',
+ '体积',
+ '绘制附近所有模型顶点,包括没有连接的顶点.',
BrushProjectionMode.surface,
use_volume=True,
checked=False,
)
add(
- 'Screen',
- 'Use screen projection of a brush, updating all vertices on all surfaces that are within the brush radius.',
+ '屏幕',
+ '从屏幕方向投影到笔刷半径内所有曲面上的顶点.',
BrushProjectionMode.screen,
use_volume=False,
checked=False,
@@ -163,53 +163,53 @@ def build_ui(parent, global_actions):
def stylus_pressure_selection():
# noinspection PyShadowingNames
result = QtWidgets.QComboBox()
- result.addItem("Unused")
- result.addItem("Multiply intensity")
- result.addItem("Multiply opacity")
- result.addItem("Multiply radius")
+ result.addItem("未使用")
+ result.addItem("倍增强度")
+ result.addItem("倍增不透明度")
+ result.addItem("倍增半径")
return result
layout = QtWidgets.QVBoxLayout()
- layout.addLayout(createTitledRow("Brush projection:", brush_projection_mode_row()))
- layout.addLayout(createTitledRow("Brush mode:", brush_mode_row3()))
- layout.addLayout(createTitledRow("Brush shape:", brush_shape_row()))
+ layout.addLayout(createTitledRow("笔刷投影:", brush_projection_mode_row()))
+ layout.addLayout(createTitledRow("笔刷模式:", brush_mode_row3()))
+ layout.addLayout(createTitledRow("笔刷形状:", brush_shape_row()))
intensity = widgets.NumberSliderGroup()
radius = widgets.NumberSliderGroup(
- max_value=100, tooltip="You can also set brush radius by just holding B " "and mouse-dragging in the viewport"
+ max_value=100, tooltip="可以通过在视口中按住 B " "并鼠标左键按住拖动来设置笔刷半径"
)
iterations = widgets.NumberSliderGroup(value_type=int, min_value=1, max_value=100)
- layout.addLayout(createTitledRow("Intensity:", intensity.layout()))
- layout.addLayout(createTitledRow("Brush radius:", radius.layout()))
- layout.addLayout(createTitledRow("Brush iterations:", iterations.layout()))
+ layout.addLayout(createTitledRow("强度:", intensity.layout()))
+ layout.addLayout(createTitledRow("笔刷半径:", radius.layout()))
+ layout.addLayout(createTitledRow("笔刷迭代次数:", iterations.layout()))
influences_limit = widgets.NumberSliderGroup(value_type=int, min_value=0, max_value=10)
- layout.addLayout(createTitledRow("Influences limit:", influences_limit.layout()))
+ layout.addLayout(createTitledRow("影响物限制:", influences_limit.layout()))
@signal.on(influences_limit.valueChanged)
def influences_limit_changed():
paint.influences_limit = influences_limit.value()
update_ui()
- fixed_influences = QtWidgets.QCheckBox("Only adjust existing vertex influences")
+ fixed_influences = QtWidgets.QCheckBox("仅调整顶点现有影响物,防止周围权重扩散")
fixed_influences.setToolTip(
- "When this option is enabled, smooth will only adjust existing influences per vertex, "
- "and won't include other influences from nearby vertices"
+ "启用此选项后,平滑-将仅调整每个顶点的现有影响物, "
+ "而不会包含来自附近顶点的影响物,防止周围权重扩散"
)
- layout.addLayout(createTitledRow("Weight bleeding:", fixed_influences))
+ layout.addLayout(createTitledRow("平滑辅助:", fixed_influences))
@qt.on(fixed_influences.stateChanged)
def fixed_influences_changed():
paint.fixed_influences_per_vertex = fixed_influences.isChecked()
- limit_to_component_selection = QtWidgets.QCheckBox("Limit to component selection")
- limit_to_component_selection.setToolTip("When this option is enabled, smoothing will only happen between selected components")
- layout.addLayout(createTitledRow("Isolation:", limit_to_component_selection))
+ limit_to_component_selection = QtWidgets.QCheckBox("限制在选中组件中平滑")
+ limit_to_component_selection.setToolTip("启用此选项后,仅在选定组件之间进行平滑")
+ layout.addLayout(createTitledRow("隔离选中组件:", limit_to_component_selection))
@qt.on(limit_to_component_selection.stateChanged)
def limit_to_component_selection_changed():
paint.limit_to_component_selection = limit_to_component_selection.isChecked()
- interactive_mirror = QtWidgets.QCheckBox("Interactive mirror")
+ interactive_mirror = QtWidgets.QCheckBox("交互式镜像")
layout.addLayout(createTitledRow("", interactive_mirror))
@qt.on(interactive_mirror.stateChanged)
@@ -217,7 +217,7 @@ def build_ui(parent, global_actions):
paint.mirror = interactive_mirror.isChecked()
update_ui()
- sample_joint_on_stroke_start = QtWidgets.QCheckBox("Sample current joint on stroke start")
+ sample_joint_on_stroke_start = QtWidgets.QCheckBox("在笔画开始时取样当前骨骼")
layout.addLayout(createTitledRow("", sample_joint_on_stroke_start))
@qt.on(sample_joint_on_stroke_start.stateChanged)
@@ -225,8 +225,8 @@ def build_ui(parent, global_actions):
paint.sample_joint_on_stroke_start = sample_joint_on_stroke_start.isChecked()
update_ui()
- redistribute_removed_weight = QtWidgets.QCheckBox("Distribute to other influences")
- layout.addLayout(createTitledRow("Removed weight:", redistribute_removed_weight))
+ redistribute_removed_weight = QtWidgets.QCheckBox("分配给其它影响物")
+ layout.addLayout(createTitledRow("移除的权重:", redistribute_removed_weight))
@qt.on(redistribute_removed_weight.stateChanged)
def redistribute_removed_weight_changed():
@@ -234,12 +234,12 @@ def build_ui(parent, global_actions):
update_ui()
stylus = stylus_pressure_selection()
- layout.addLayout(createTitledRow("Stylus pressure:", stylus))
+ layout.addLayout(createTitledRow("手绘板压力:", stylus))
@on_signal(et.tool_settings_changed, scope=layout)
def update_ui():
- log.info("updating paint settings ui")
- log.info("brush mode:%s, brush shape: %s", paint.mode, paint.brush_shape)
+ log.info("更新的绘制设置的ui")
+ log.info("画笔模式:%s, 画笔形状: %s", paint.mode, paint.brush_shape)
paint.update_plugin_brush_radius()
paint.update_plugin_brush_intensity()
@@ -280,7 +280,7 @@ def build_ui(parent, global_actions):
@signal.on(radius.valueChanged, qtParent=layout)
def radius_edited():
- log.info("updated brush radius")
+ log.info("更新笔刷半径")
paint.brush_radius = radius.value()
update_ui()
@@ -301,18 +301,18 @@ def build_ui(parent, global_actions):
update_ui()
- result = QtWidgets.QGroupBox("Brush behavior")
+ result = QtWidgets.QGroupBox("笔刷行为")
result.setLayout(layout)
return result
def build_display_settings():
- result = QtWidgets.QGroupBox("Display settings")
+ result = QtWidgets.QGroupBox("显示设置")
layout = QtWidgets.QVBoxLayout()
influences_display = QtWidgets.QComboBox()
- influences_display.addItem("All influences, multiple colors", WeightsDisplayMode.allInfluences)
- influences_display.addItem("Current influence, grayscale", WeightsDisplayMode.currentInfluence)
- influences_display.addItem("Current influence, colored", WeightsDisplayMode.currentInfluenceColored)
+ influences_display.addItem("所有权重,多种颜色", WeightsDisplayMode.allInfluences)
+ influences_display.addItem("当前权重,灰度", WeightsDisplayMode.currentInfluence)
+ influences_display.addItem("当前权重,彩色", WeightsDisplayMode.currentInfluenceColored)
influences_display.setMinimumWidth(1)
influences_display.setCurrentIndex(paint.display_settings.weights_display_mode)
@@ -327,11 +327,11 @@ def build_ui(parent, global_actions):
display_layout = QtWidgets.QVBoxLayout()
display_layout.addWidget(influences_display)
display_layout.addWidget(display_toolbar)
- layout.addLayout(createTitledRow("Influences display:", display_layout))
+ layout.addLayout(createTitledRow("权重显示:", display_layout))
mask_display = QtWidgets.QComboBox()
- mask_display.addItem("Default", MaskDisplayMode.default_)
- mask_display.addItem("Color ramp", MaskDisplayMode.color_ramp)
+ mask_display.addItem("默认", MaskDisplayMode.default_)
+ mask_display.addItem("彩色渐变", MaskDisplayMode.color_ramp)
mask_display.setMinimumWidth(1)
mask_display.setCurrentIndex(paint.display_settings.weights_display_mode)
@@ -340,14 +340,14 @@ def build_ui(parent, global_actions):
paint.display_settings.mask_display_mode = mask_display.currentData()
update_ui_to_tool()
- layout.addLayout(createTitledRow("Mask display:", mask_display))
+ layout.addLayout(createTitledRow("表面显示:", mask_display))
- show_effects = QtWidgets.QCheckBox("Show layer effects")
+ show_effects = QtWidgets.QCheckBox("显示图层效果")
layout.addLayout(createTitledRow("", show_effects))
- show_masked = QtWidgets.QCheckBox("Show masked weights")
+ show_masked = QtWidgets.QCheckBox("显示蒙皮权重")
layout.addLayout(createTitledRow("", show_masked))
- show_selected_verts_only = QtWidgets.QCheckBox("Hide unselected vertices")
+ show_selected_verts_only = QtWidgets.QCheckBox("隐藏未选择的顶点")
layout.addLayout(createTitledRow("", show_selected_verts_only))
@qt.on(show_effects.stateChanged)
@@ -363,7 +363,7 @@ def build_ui(parent, global_actions):
paint.display_settings.show_selected_verts_only = show_selected_verts_only.isChecked()
mesh_toolbar = QtWidgets.QToolBar()
- toggle_original_mesh = QAction("Show Original Mesh", mesh_toolbar)
+ toggle_original_mesh = QAction("显示原本模型", mesh_toolbar)
toggle_original_mesh.setCheckable(True)
mesh_toolbar.addAction(toggle_original_mesh)
layout.addLayout(createTitledRow("", mesh_toolbar))
@@ -374,7 +374,7 @@ def build_ui(parent, global_actions):
update_ui_to_tool()
wireframe_color_button = widgets.ColorButton()
- layout.addLayout(createTitledRow("Wireframe color:", wireframe_color_button))
+ layout.addLayout(createTitledRow("线框颜色:", wireframe_color_button))
@signal.on(wireframe_color_button.color_changed)
def update_wireframe_color():
diff --git a/2024/scripts/rigging_tools/ngskintools2/ui/tabSetWeights.py b/2024/scripts/rigging_tools/ngskintools2/ui/tabSetWeights.py
index 0e0e67d..34cd91c 100644
--- a/2024/scripts/rigging_tools/ngskintools2/ui/tabSetWeights.py
+++ b/2024/scripts/rigging_tools/ngskintools2/ui/tabSetWeights.py
@@ -1,3 +1,4 @@
+# -*- coding: UTF-8 -*-
from ngSkinTools2 import signal
from ngSkinTools2.api import PaintMode, PaintModeSettings, flood_weights
from ngSkinTools2.api.log import getLogger
@@ -70,14 +71,14 @@ def build_ui(parent):
toolbar.addAction(a)
t = QtWidgets.QToolBar()
- create_mode_button(t, PaintMode.replace, "Replace", "")
- create_mode_button(t, PaintMode.add, "Add", "")
- create_mode_button(t, PaintMode.scale, "Scale", "")
+ create_mode_button(t, PaintMode.replace, "替换", "")
+ create_mode_button(t, PaintMode.add, "添加", "")
+ create_mode_button(t, PaintMode.scale, "减少", "")
row.addWidget(t)
t = QtWidgets.QToolBar()
- create_mode_button(t, PaintMode.smooth, "Smooth", "")
- create_mode_button(t, PaintMode.sharpen, "Sharpen", "")
+ create_mode_button(t, PaintMode.smooth, "平滑", "")
+ create_mode_button(t, PaintMode.sharpen, "锐化", "")
row.addWidget(t)
actions[model.current_settings.mode].setChecked(True)
@@ -109,20 +110,20 @@ def build_ui(parent):
model.current_settings.iterations = iterations.value()
update_ui()
- fixed_influences = QtWidgets.QCheckBox("Only adjust existing vertex influences")
+ fixed_influences = QtWidgets.QCheckBox("仅调整顶点现有影响物,防止周围权重扩散")
fixed_influences.setToolTip(
- "When this option is enabled, smooth will only adjust existing influences per vertex, "
- "and won't include other influences from nearby vertices"
+ "启用此选项后,平滑-将仅调整每个顶点的现有影响物, "
+ "而不会包含来自附近顶点的影响物,防止周围权重扩散"
)
- volume_neighbours = QtWidgets.QCheckBox("Smooth across gaps and thin surfaces")
+ volume_neighbours = QtWidgets.QCheckBox("平滑间隙和薄表面")
volume_neighbours.setToolTip(
- "Use all nearby neighbours, regardless if they belong to same surface. "
- "This will allow for smoothing to happen across gaps and thin surfaces."
+ "使用所有附近相邻的面,无论它们是否属于同一个曲面."
+ "这将允许在间隙和薄曲面之间进行平滑."
)
- limit_to_component_selection = QtWidgets.QCheckBox("Limit to component selection")
- limit_to_component_selection.setToolTip("When this option is enabled, smoothing will only happen between selected components")
+ limit_to_component_selection = QtWidgets.QCheckBox("在选择的组件中平滑")
+ limit_to_component_selection.setToolTip("启用此选项后,仅在选定组件之间进行平滑")
@qt.on(fixed_influences.stateChanged)
@ui_lock.skip_if_updating
@@ -154,16 +155,16 @@ def build_ui(parent):
volume_neighbours.setChecked(model.current_settings.use_volume_neighbours)
volume_neighbours.setEnabled(model.current_settings.mode == PaintMode.smooth)
- settings_group = QtWidgets.QGroupBox("Mode Settings")
+ settings_group = QtWidgets.QGroupBox("模式设置")
layout = QtWidgets.QVBoxLayout()
- layout.addLayout(createTitledRow("Mode:", mode_row()))
- layout.addLayout(createTitledRow("Intensity:", intensity.layout()))
- layout.addLayout(createTitledRow("Iterations:", iterations.layout()))
- layout.addLayout(createTitledRow("Influences limit:", influences_limit.layout()))
- layout.addLayout(createTitledRow("Weight bleeding:", fixed_influences))
- layout.addLayout(createTitledRow("Volume smoothing:", volume_neighbours))
- layout.addLayout(createTitledRow("Isolation:", limit_to_component_selection))
+ layout.addLayout(createTitledRow("模式:", mode_row()))
+ layout.addLayout(createTitledRow("强度:", intensity.layout()))
+ layout.addLayout(createTitledRow("迭代次数:", iterations.layout()))
+ layout.addLayout(createTitledRow("影响物限制:", influences_limit.layout()))
+ layout.addLayout(createTitledRow("平滑辅助:", fixed_influences))
+ layout.addLayout(createTitledRow("体积平滑:", volume_neighbours))
+ layout.addLayout(createTitledRow("隔离选中组件:", limit_to_component_selection))
settings_group.setLayout(layout)
update_ui()
@@ -173,7 +174,7 @@ def build_ui(parent):
def common_settings():
layout = QtWidgets.QVBoxLayout()
- mirror = QtWidgets.QCheckBox("Mirror")
+ mirror = QtWidgets.QCheckBox("镜像")
layout.addLayout(createTitledRow("", mirror))
@qt.on(mirror.stateChanged)
@@ -182,8 +183,8 @@ def build_ui(parent):
for _, v in model.presets.items():
v.mirror = mirror.isChecked()
- redistribute_removed_weight = QtWidgets.QCheckBox("Distribute to other influences")
- layout.addLayout(createTitledRow("Removed weight:", redistribute_removed_weight))
+ redistribute_removed_weight = QtWidgets.QCheckBox("分配给其它影响物")
+ layout.addLayout(createTitledRow("移除的权重:", redistribute_removed_weight))
@qt.on(redistribute_removed_weight.stateChanged)
def redistribute_removed_weight_changed():
@@ -195,7 +196,7 @@ def build_ui(parent):
mirror.setChecked(model.current_settings.mirror)
redistribute_removed_weight.setChecked(model.current_settings.distribute_to_other_influences)
- group = QtWidgets.QGroupBox("Common Settings")
+ group = QtWidgets.QGroupBox("常用设置")
group.setLayout(layout)
update_ui()
@@ -203,8 +204,8 @@ def build_ui(parent):
return group
def apply_button():
- btn = QtWidgets.QPushButton("Apply")
- btn.setToolTip("Apply selected operation to vertex")
+ btn = QtWidgets.QPushButton("应用")
+ btn.setToolTip("将设定操作应用于选中顶点")
@qt.on(btn.clicked)
def clicked():
diff --git a/2024/scripts/rigging_tools/ngskintools2/ui/tabTools.py b/2024/scripts/rigging_tools/ngskintools2/ui/tabTools.py
index 08e6c5c..0b930a7 100644
--- a/2024/scripts/rigging_tools/ngskintools2/ui/tabTools.py
+++ b/2024/scripts/rigging_tools/ngskintools2/ui/tabTools.py
@@ -1,3 +1,4 @@
+# -*- coding: UTF-8 -*-
from ngSkinTools2 import signal
from ngSkinTools2.api.pyside import QtWidgets
from ngSkinTools2.api.session import Session
@@ -20,7 +21,7 @@ def build_ui(actions, session):
def influences_options():
result = QtWidgets.QVBoxLayout()
button_group = QtWidgets.QButtonGroup()
- for index, i in enumerate(["Use all available influences", "Use selected influences"]):
+ for index, i in enumerate(["使用所有可用的影响物", "使用选定的影响物"]):
radio = QtWidgets.QRadioButton(i)
button_group.addButton(radio, index)
result.addWidget(radio)
@@ -38,7 +39,7 @@ def build_ui(actions, session):
return result
- new_layer = QtWidgets.QCheckBox("Create new layer")
+ new_layer = QtWidgets.QCheckBox("创建新图层")
@qt.on(new_layer.toggled)
def update_new_layer():
@@ -53,11 +54,11 @@ def build_ui(actions, session):
update_ui()
- result = QtWidgets.QGroupBox("Assign weights from closest joint")
+ result = QtWidgets.QGroupBox("从最近的关节指定权重")
layout = QtWidgets.QVBoxLayout()
result.setLayout(layout)
- layout.addLayout(createTitledRow("Target layer", new_layer))
- layout.addLayout(createTitledRow("Influences", influences_options()))
+ layout.addLayout(createTitledRow("目标层", new_layer))
+ layout.addLayout(createTitledRow("影响物", influences_options()))
layout.addWidget(btn)
return result
@@ -69,25 +70,25 @@ def build_ui(actions, session):
model_binds.bind(intensity, options.overall_effect)
single_cluster_mode = QtWidgets.QCheckBox(
- "Single group mode",
+ "单组模式",
)
- single_cluster_mode.setToolTip("average weights across whole selection, ignoring separate shells or selection gaps")
+ single_cluster_mode.setToolTip("整个选择的平均权重,忽略单独的壳或选择间隙")
model_binds.bind(single_cluster_mode, options.single_cluster_mode)
btn = QtWidgets.QPushButton()
qt.bind_action_to_button(actions.toolsUnifyWeights, btn)
- result = QtWidgets.QGroupBox("Unify weights")
+ result = QtWidgets.QGroupBox("统一权重")
layout = QtWidgets.QVBoxLayout()
result.setLayout(layout)
- layout.addLayout(createTitledRow("Intensity:", intensity.layout()))
- layout.addLayout(createTitledRow("Clustering:", single_cluster_mode))
+ layout.addLayout(createTitledRow("强度:", intensity.layout()))
+ layout.addLayout(createTitledRow("集群:", single_cluster_mode))
layout.addWidget(btn)
return result
def other_tools_group():
- result = QtWidgets.QGroupBox("Other")
+ result = QtWidgets.QGroupBox("其它")
layout = QtWidgets.QVBoxLayout()
result.setLayout(layout)
layout.addWidget(to_button(actions.fill_layer_transparency))
diff --git a/2024/scripts/rigging_tools/ngskintools2/ui/targetui.py b/2024/scripts/rigging_tools/ngskintools2/ui/targetui.py
index 7b3f975..70ababc 100644
--- a/2024/scripts/rigging_tools/ngskintools2/ui/targetui.py
+++ b/2024/scripts/rigging_tools/ngskintools2/ui/targetui.py
@@ -25,7 +25,7 @@ def build_layers_ui(parent, actions, session):
filter = QtWidgets.QComboBox()
filter.setMinimumHeight(22 * scale_multiplier)
filter.setEditable(True)
- filter.lineEdit().setPlaceholderText("Search...")
+ filter.lineEdit().setPlaceholderText("搜索...")
result.addWidget(filter)
# noinspection PyShadowingNames
clear = QAction(result)
@@ -83,7 +83,7 @@ def build_no_layers_ui(parent, actions, session):
selection_display = QtWidgets.QLabel("pPlane1")
selection_display.setStyleSheet("font-weight: bold")
- selection_note = QtWidgets.QLabel("Skinning Layers cannot be attached to this object")
+ selection_note = QtWidgets.QLabel("蒙皮层无法附加到此对象")
selection_note.setWordWrap(True)
layout.addStretch(1)
@@ -104,11 +104,11 @@ def build_no_layers_ui(parent, actions, session):
selection_display.setText(session.state.selectedSkinCluster)
selection_display.setVisible(is_skinned)
- note = "Select a mesh with a skin cluster attached."
+ note = "选择附着蒙皮节点的网格."
if is_skinned:
- note = "Skinning layers are not yet initialized for this mesh."
+ note = "尚未为此网格初始化蒙皮层."
if import_v1_actions.can_import(session):
- note = "Skinning layers from previous ngSkinTools version are initialized on this mesh."
+ note = "ngSkinTools的旧版本的蒙皮层在此网格上初始化."
selection_note.setText(note)
diff --git a/2024/scripts/rigging_tools/ngskintools2/ui/transferDialog.py b/2024/scripts/rigging_tools/ngskintools2/ui/transferDialog.py
index 7b5d13e..9270010 100644
--- a/2024/scripts/rigging_tools/ngskintools2/ui/transferDialog.py
+++ b/2024/scripts/rigging_tools/ngskintools2/ui/transferDialog.py
@@ -1,3 +1,4 @@
+# -*- coding: UTF-8 -*-
from ngSkinTools2 import api, cleanup, signal
from ngSkinTools2.api import VertexTransferMode
from ngSkinTools2.api.pyside import QtCore, QtWidgets
@@ -43,8 +44,8 @@ def open(parent, model):
return widgets.button_row(
[
- ("Transfer", apply),
- ("Cancel", window.close),
+ ("传递", apply),
+ ("取消", window.close),
]
)
@@ -55,32 +56,32 @@ def open(parent, model):
result = QtWidgets.QVBoxLayout()
vertexMappingMode = QtWidgets.QComboBox()
- vertexMappingMode.addItem("Closest point on surface", VertexTransferMode.closestPoint)
- vertexMappingMode.addItem("UV space", VertexTransferMode.uvSpace)
- vertexMappingMode.addItem("By vertex ID (source and destination vert count must match)", VertexTransferMode.vertexId)
+ vertexMappingMode.addItem("表面上最近的点", VertexTransferMode.closestPoint)
+ vertexMappingMode.addItem("UV空间", VertexTransferMode.uvSpace)
+ vertexMappingMode.addItem("按顶点ID(源和目标顶点数必须匹配)", VertexTransferMode.vertexId)
- g = QtWidgets.QGroupBox("Selection")
+ g = QtWidgets.QGroupBox("选择")
layout = QtWidgets.QVBoxLayout()
g.setLayout(layout)
sourceLabel = QtWidgets.QLabel()
- layout.addLayout(createTitledRow("Source:", sourceLabel))
+ layout.addLayout(createTitledRow("来源:", sourceLabel))
destinationLabel = QtWidgets.QLabel()
- layout.addLayout(createTitledRow("Destination:", destinationLabel))
+ layout.addLayout(createTitledRow("目标:", destinationLabel))
result.addWidget(g)
- g = QtWidgets.QGroupBox("Vertex mapping")
+ g = QtWidgets.QGroupBox("顶点映射")
layout = QtWidgets.QVBoxLayout()
- layout.addLayout(createTitledRow("Mapping mode:", vertexMappingMode))
+ layout.addLayout(createTitledRow("映射模式:", vertexMappingMode))
g.setLayout(layout)
result.addWidget(g)
- g = QtWidgets.QGroupBox("Influences mapping")
+ g = QtWidgets.QGroupBox("影响物映射")
layout = QtWidgets.QVBoxLayout()
g.setLayout(layout)
- edit = QtWidgets.QPushButton("Configure")
+ edit = QtWidgets.QPushButton("配置")
qt.on(edit.clicked)(view_influences_settings)
button_row = QtWidgets.QHBoxLayout()
@@ -90,12 +91,12 @@ def open(parent, model):
result.addWidget(g)
- g = QtWidgets.QGroupBox("Other options")
+ g = QtWidgets.QGroupBox("其他选项")
layout = QtWidgets.QVBoxLayout()
g.setLayout(layout)
- keep_layers = QtWidgets.QCheckBox("Keep existing layers on destination")
- keep_layers_row = qt.wrap_layout_into_widget(createTitledRow("Destination layers:", keep_layers))
+ keep_layers = QtWidgets.QCheckBox("保留目标网格的已有图层")
+ keep_layers_row = qt.wrap_layout_into_widget(createTitledRow("目标图层:", keep_layers))
layout.addWidget(keep_layers_row)
@qt.on(keep_layers.stateChanged)
@@ -137,12 +138,12 @@ def open(parent, model):
tabs = QtWidgets.QTabWidget()
- tabs.addTab(qt.wrap_layout_into_widget(build_settings()), "Settings")
- tabs.addTab(qt.wrap_layout_into_widget(build_influenes_tab()), "Influences mapping")
+ tabs.addTab(qt.wrap_layout_into_widget(build_settings()), "设置")
+ tabs.addTab(qt.wrap_layout_into_widget(build_influenes_tab()), "影响物映射")
window = QtWidgets.QDialog(parent)
cleanup.registerCleanupHandler(window.close)
- window.setWindowTitle("Transfer")
+ window.setWindowTitle("传递")
window.setAttribute(QtCore.Qt.WA_DeleteOnClose)
window.resize(720 * scale_multiplier, 500 * scale_multiplier)
window.setLayout(QtWidgets.QVBoxLayout())
@@ -196,7 +197,7 @@ def build_transfer_action(session, parent):
t.customize_callback = transfer_dialog
t.execute()
- result = define_action(parent, "Transfer layers...", callback=handler)
+ result = define_action(parent, "传递图层...", callback=handler)
@signal.on(session.events.nodeSelectionChanged)
def on_selection_changed():
diff --git a/2024/scripts/rigging_tools/ngskintools2/ui/updatewindow.py b/2024/scripts/rigging_tools/ngskintools2/ui/updatewindow.py
index dfdf7e3..5ac09e1 100644
--- a/2024/scripts/rigging_tools/ngskintools2/ui/updatewindow.py
+++ b/2024/scripts/rigging_tools/ngskintools2/ui/updatewindow.py
@@ -1,3 +1,4 @@
+# -*- coding: UTF-8 -*-
import webbrowser
from ngSkinTools2.api import versioncheck
@@ -27,10 +28,10 @@ def show(parent, silent_mode):
result.setLayout(layout)
layout.setContentsMargins(20, 30, 20, 20)
- header = QtWidgets.QLabel("Checking for update...")
- result1 = QtWidgets.QLabel("Current version: 2.0.0")
- result2 = QtWidgets.QLabel("Update available: 2.0.1")
- download = QtWidgets.QPushButton("Download ngSkinTools v2.0.1")
+ header = QtWidgets.QLabel(u"检查更新中...")
+ result1 = QtWidgets.QLabel(u"当前版本: 2.1.4")
+ result2 = QtWidgets.QLabel("最新版本: 2.1.4")
+ download = QtWidgets.QPushButton("下载 中文ngSkinTools v2.0.1")
# layout.addWidget(QtWidgets.QLabel("Checking for updates..."))
layout.addWidget(header)
layout.addWidget(result1)
@@ -52,16 +53,16 @@ def show(parent, silent_mode):
:type info: ngSkinTools2.api.versioncheck.
"""
- header.setText("{0}".format('Update available!' if info.update_available else 'ngSkinTools is up to date.'))
+ header.setText("{0}".format('更新可用!' if info.update_available else '中文ngSkinTools 已经是最新版.'))
result1.setVisible(True)
- result1.setText("Current version: {0}".format(version.pluginVersion()))
+ result1.setText(u"当前版本: {0}".format(version.pluginVersion()))
if info.update_available:
result2.setVisible(True)
result2.setText(
- "Update available: {0}, released on {1}".format(info.latest_version, info.update_date.strftime("%d %B, %Y"))
+ u"最新版本: {0}, 发布于 {1}".format(info.latest_version, info.update_date.strftime("%d %B, %Y"))
)
download.setVisible(True)
- download.setText("Download ngSkinTools v" + info.latest_version)
+ download.setText(u"下载 中文ngSkinTools v" + info.latest_version)
@qt.on(download.clicked)
def open_link():
@@ -71,10 +72,10 @@ def show(parent, silent_mode):
# noinspection PyShadowingNames
def buttonsRow(window):
- btn_close = QtWidgets.QPushButton("Close")
+ btn_close = QtWidgets.QPushButton("取消")
btn_close.setMinimumWidth(100 * scale_multiplier)
- check_do_on_startup = bind_checkbox(QtWidgets.QCheckBox("Check for updates at startup"), config.checkForUpdatesAtStartup)
+ check_do_on_startup = bind_checkbox(QtWidgets.QCheckBox("启动时检查更新"), config.checkForUpdatesAtStartup)
layout = QtWidgets.QHBoxLayout()
layout.addWidget(check_do_on_startup)
@@ -88,7 +89,7 @@ def show(parent, silent_mode):
window = QtWidgets.QWidget(parent, Qt.Window | Qt.WindowTitleHint | Qt.CustomizeWindowHint)
window.resize(400 * scale_multiplier, 200 * scale_multiplier)
window.setAttribute(Qt.WA_DeleteOnClose)
- window.setWindowTitle("ngSkinTools2 version update")
+ window.setWindowTitle("ngSkinTools2 (中文) 版本更新")
layout = QtWidgets.QVBoxLayout()
window.setLayout(layout)
layout.setContentsMargins(0, 0, 0, 0)
@@ -106,14 +107,14 @@ def show(parent, silent_mode):
if info.update_available:
window.show()
else:
- log.info("not showing the window")
+ log.info("未显示窗口")
window.close()
cleanup.registerCleanupHandler(window.close)
@qt.on(window.destroyed)
def closed():
- log.info("deleting update window")
+ log.info("删除更新窗口")
versioncheck.download_update_info(success_callback=success_signal.emit, failure_callback=error_signal.emit)
@@ -129,4 +130,4 @@ def show_and_start_update(parent):
def build_action_check_for_updates(parent):
from ngSkinTools2.ui import actions
- return actions.define_action(parent, "Check for Updates...", callback=lambda: show_and_start_update(parent))
+ return actions.define_action(parent, "检查更新...", callback=lambda: show_and_start_update(parent))
diff --git a/2024/scripts/rigging_tools/ngskintools2/version.py b/2024/scripts/rigging_tools/ngskintools2/version.py
index 29a258a..d279d88 100644
--- a/2024/scripts/rigging_tools/ngskintools2/version.py
+++ b/2024/scripts/rigging_tools/ngskintools2/version.py
@@ -66,7 +66,7 @@ class SemanticVersion(Object):
result = pattern.match(stringVersion)
if result is None:
- raise Exception("Invalid version string: '{0}'".format(stringVersion))
+ raise Exception("无效的版本字符串: '{0}'".format(stringVersion))
self.major = toInt(result.group(1))
self.minor = toInt(result.group(3))
diff --git a/2024/scripts/userSetup.py b/2024/scripts/userSetup.py
index 701278d..89159b9 100644
--- a/2024/scripts/userSetup.py
+++ b/2024/scripts/userSetup.py
@@ -13,37 +13,20 @@ Features:
- Maya 2018+ compatible
"""
-import maya.cmds as cmds
-import maya.mel as mel
-import maya.utils
+# Standard library imports
import atexit
import os
import sys
import re
-# Set MAYA_MODULE_PATH environment variable for external tools
+# Maya imports with error handling
try:
- _current_file = os.path.abspath(__file__)
- _script_dir = os.path.dirname(_current_file)
- _project_root = os.path.dirname(os.path.dirname(_script_dir))
- _modules_dir = os.path.join(_project_root, 'modules')
-
- if os.path.exists(_modules_dir):
- _modules_dir_normalized = os.path.normpath(_modules_dir)
- _current_module_path = os.environ.get('MAYA_MODULE_PATH', '')
-
- # Check if already in path
- _paths = [p.strip() for p in _current_module_path.split(os.pathsep) if p.strip()]
- _normalized_paths = [os.path.normpath(p) for p in _paths]
-
- if _modules_dir_normalized not in _normalized_paths:
- if _current_module_path:
- os.environ['MAYA_MODULE_PATH'] = f"{_modules_dir_normalized}{os.pathsep}{_current_module_path}"
- else:
- os.environ['MAYA_MODULE_PATH'] = _modules_dir_normalized
- print(f"[Tool] MAYA_MODULE_PATH set to: {_modules_dir_normalized}")
-except Exception as e:
- print(f"[Tool] Warning: Could not set MAYA_MODULE_PATH: {e}")
+ import maya.cmds as cmds
+ import maya.mel as mel
+ import maya.utils
+except ImportError as e:
+ print(f"[Tool] ERROR: Failed to import Maya modules: {e}")
+ raise
# Silently try to open default commandPort to avoid startup error if it's already in use
try:
@@ -51,6 +34,19 @@ try:
except Exception:
pass
+# =============================================================================
+# Constants
+# =============================================================================
+
+# Command port name
+COMMAND_PORT_NAME = "commandportDefault"
+
+# Log levels
+LOG_DEBUG = 0
+LOG_INFO = 1
+LOG_WARNING = 2
+LOG_ERROR = 3
+
# =============================================================================
# Configuration
# =============================================================================
@@ -58,6 +54,9 @@ except Exception:
# Shelves to load
SHELF_NAMES = ["Nexus_Manage", "Nexus_Modeling", "Nexus_Rigging", "Nexus_Animation", "Nexus_DevTools"]
+# User configuration file path (optional override)
+USER_CONFIG_FILE = os.path.join(os.path.expanduser("~"), ".nexus_maya_config.py")
+
# Tool packages configuration
TOOL_CONFIG = {
'scripts': [
@@ -67,12 +66,10 @@ TOOL_CONFIG = {
{'name': 'manage_tools', 'path': 'manage_tools'},
],
'plugins': [
- {'name': 'cv_manip.mll', 'path': 'modeling_tools/gs_curvetools/plugins/2024'},
{'name': 'ngskintools2.mll', 'path': 'rigging_tools/ngskintools2/plug-ins/2024'},
{'name': 'MGPicker_2024x64.mll', 'path': 'animation_tools/mgpicker/MGPicker_Program/Plug-ins'},
],
'icons': [
- {'name': 'gs_curvetools', 'path': 'modeling_tools/gs_curvetools/icons'},
{'name': 'gs_toolbox', 'path': 'modeling_tools/gs_toolbox/icons'},
{'name': 'modit', 'path': 'modeling_tools/ModIt/Icons/Theme_Classic'},
{'name': 'creaseplus', 'path': 'modeling_tools/creaseplus/icons'},
@@ -107,14 +104,41 @@ _ADDED_SCRIPT_PATHS = []
# Utility Functions
# =============================================================================
+def _log(msg, level=LOG_INFO):
+ """
+ Print log message with level control
+
+ Args:
+ msg: Message to print
+ level: LOG_DEBUG, LOG_INFO, LOG_WARNING, or LOG_ERROR
+ """
+ if level == LOG_DEBUG and not TOOL_DEBUG:
+ return
+
+ prefix_map = {
+ LOG_DEBUG: "[Tool:DEBUG]",
+ LOG_INFO: "[Tool]",
+ LOG_WARNING: "[Tool:WARNING]",
+ LOG_ERROR: "[Tool:ERROR]"
+ }
+ prefix = prefix_map.get(level, "[Tool]")
+ print(f"{prefix} {msg}")
+
def _tool_log(msg):
"""Print debug message if TOOL_DEBUG is enabled"""
- if TOOL_DEBUG:
- print(msg)
+ _log(msg, LOG_DEBUG)
def _tool_print(msg):
"""Print info message"""
- print(msg)
+ _log(msg, LOG_INFO)
+
+def _tool_warning(msg):
+ """Print warning message"""
+ _log(msg, LOG_WARNING)
+
+def _tool_error(msg):
+ """Print error message"""
+ _log(msg, LOG_ERROR)
def _get_script_dir():
"""Get the directory containing this script (with fallback)"""
@@ -157,16 +181,25 @@ def _check_maya_version():
try:
maya_version = int(cmds.about(version=True).split()[0])
if maya_version < MAYA_MIN_VERSION:
- _tool_print(f"[Tool] Warning: Maya {maya_version} detected. Minimum supported version is {MAYA_MIN_VERSION}")
+ _tool_warning(f"Maya {maya_version} detected. Minimum supported version is {MAYA_MIN_VERSION}")
return False
- _tool_log(f"[Tool] Maya version: {maya_version}")
+ _tool_log(f"Maya version: {maya_version}")
return True
except Exception as e:
- _tool_print(f"[Tool] Warning: Could not determine Maya version: {e}")
+ _tool_warning(f"Could not determine Maya version: {e}")
return True # Continue anyway
def _find_file_in_paths(filename, search_paths):
- """Find file in a list of search paths"""
+ """
+ Find file in a list of search paths
+
+ Args:
+ filename: Name of file to find
+ search_paths: List of directory paths to search
+
+ Returns:
+ Full path to file if found, None otherwise
+ """
for p in search_paths:
if not p:
continue
@@ -175,6 +208,45 @@ def _find_file_in_paths(filename, search_paths):
return candidate
return None
+def _validate_tool_config():
+ """
+ Validate TOOL_CONFIG structure
+
+ Returns:
+ True if valid, False otherwise
+ """
+ try:
+ required_keys = ['scripts', 'plugins', 'icons']
+ for key in required_keys:
+ if key not in TOOL_CONFIG:
+ _tool_error(f"Missing required key in TOOL_CONFIG: {key}")
+ return False
+
+ if not isinstance(TOOL_CONFIG[key], list):
+ _tool_error(f"TOOL_CONFIG['{key}'] must be a list")
+ return False
+
+ # Validate each item has required fields
+ for idx, item in enumerate(TOOL_CONFIG[key]):
+ if not isinstance(item, dict):
+ _tool_error(f"TOOL_CONFIG['{key}'][{idx}] must be a dict")
+ return False
+
+ if 'name' not in item:
+ _tool_error(f"TOOL_CONFIG['{key}'][{idx}] missing 'name' field")
+ return False
+
+ if 'path' not in item:
+ _tool_error(f"TOOL_CONFIG['{key}'][{idx}] missing 'path' field")
+ return False
+
+ _tool_log("TOOL_CONFIG validation passed")
+ return True
+
+ except Exception as e:
+ _tool_error(f"Error validating TOOL_CONFIG: {e}")
+ return False
+
def _verify_shelf_icon_references(search_paths):
"""Verify that shelf icon references can be resolved"""
if not TOOL_DEBUG:
@@ -198,9 +270,9 @@ def _verify_shelf_icon_references(search_paths):
for img in imgs:
found = any(os.path.exists(os.path.join(p, img).replace('\\', '/')) for p in search_paths)
if not found:
- _tool_log(f"[Tool] Warning: Icon '{img}' not found for shelf '{shelf_name}'")
+ _tool_warning(f"Icon '{img}' not found for shelf '{shelf_name}'")
except Exception as e:
- _tool_log(f"[Tool] Icon verification error: {e}")
+ _tool_log(f"Icon verification error: {e}")
def _remove_shelf_config(shelf_name):
"""Remove shelf config from Maya prefs to force reload"""
@@ -239,7 +311,7 @@ def setup_icon_paths():
if os.path.exists(full_path):
icon_paths[name] = full_path
else:
- _tool_print(f"[Tool] Warning: Icon path not found: {full_path}")
+ _tool_warning(f"Icon path not found: {full_path}")
# Check if already configured
global _ICONS_PATHS
@@ -273,7 +345,7 @@ def setup_icon_paths():
_verify_shelf_icon_references(paths)
except Exception as e:
- _tool_print(f"[Tool] Error setting up icon paths: {e}")
+ _tool_error(f"Error setting up icon paths: {e}")
def load_tool_shelves():
"""Load Nexus shelves into Maya"""
@@ -284,7 +356,7 @@ def load_tool_shelves():
script_dir = _get_script_dir()
shelf_paths = os.path.join(os.path.dirname(script_dir), "shelves")
if not os.path.exists(shelf_paths):
- _tool_print("[Tool] Shelf directory not found, skipping")
+ _tool_warning("Shelf directory not found, skipping")
return
shelf_path_list = [p.strip() for p in shelf_paths.split(os.pathsep) if p.strip()]
@@ -302,7 +374,7 @@ def load_tool_shelves():
break
if not shelf_file_found:
- _tool_print(f"[Tool] Shelf not found: shelf_{shelf_name}.mel")
+ _tool_warning(f"Shelf not found: shelf_{shelf_name}.mel")
continue
# Remove existing shelf
@@ -350,12 +422,12 @@ def load_tool_shelves():
_remove_shelf_config(shelf_name)
except Exception as e:
- _tool_print(f"[Tool] Error loading shelf {shelf_name}: {e}")
+ _tool_error(f"Error loading shelf {shelf_name}: {e}")
_tool_log(f"[Tool] ✓ Shelves: {loaded_count}/{len(SHELF_NAMES)} loaded")
except Exception as e:
- _tool_print(f"[Tool] Error loading shelves: {e}")
+ _tool_error(f"Error loading shelves: {e}")
def load_tool_plugins():
"""Load Nexus plugins"""
@@ -376,7 +448,7 @@ def load_tool_plugins():
_tool_log(f"[Tool] Processing plugin: {plugin_name}")
- # First, check the configured path parameter.
+ # First check the configured path parameter
plugin_path = None
if plugin_rel_path:
# Build full path: script_dir/path/plugin_name
@@ -389,7 +461,7 @@ def load_tool_plugins():
if not plugin_path:
plugin_path = _find_file_in_paths(plugin_name, os.environ.get(env_var, '').split(os.pathsep))
- # Try the script directory and parent plug-ins folder last.
+ # Finally, try the script directory and the parent plug-ins folder.
if not plugin_path:
search_dirs = [
script_dir,
@@ -398,7 +470,7 @@ def load_tool_plugins():
plugin_path = _find_file_in_paths(plugin_name, search_dirs)
if not plugin_path:
- _tool_print(f"[Tool] Plugin not found: {plugin_name}")
+ _tool_warning(f"Plugin not found: {plugin_name}")
continue
# Add plugin directory to environment
@@ -435,12 +507,12 @@ def load_tool_plugins():
loaded_count += 1
_LOADED_PLUGINS[plugin_basename] = plugin_path
except Exception as e:
- _tool_print(f"[Tool] Error loading plugin {plugin_basename}: {e}")
+ _tool_error(f"Error loading plugin {plugin_basename}: {e}")
_tool_log(f"[Tool] ✓ Plugins: {loaded_count}/{len(plugin_configs)} loaded")
except Exception as e:
- _tool_print(f"[Tool] Error loading plugins: {e}")
+ _tool_error(f"Error loading plugins: {e}")
def load_tool_scripts():
"""Add Nexus script paths to sys.path"""
@@ -451,7 +523,6 @@ def load_tool_scripts():
_tool_log("[Tool] No scripts configured")
return
- global _ADDED_SCRIPT_PATHS
loaded = 0
for cfg in script_configs:
name = cfg.get('name', '')
@@ -461,7 +532,7 @@ def load_tool_scripts():
full_path = os.path.normpath(os.path.join(script_dir, path))
if not os.path.exists(full_path):
- _tool_print(f"[Tool] Script path not found: {full_path}")
+ _tool_warning(f"Script path not found: {full_path}")
continue
if full_path not in sys.path:
@@ -473,7 +544,219 @@ def load_tool_scripts():
_tool_log(f"[Tool] ✓ Script paths: {loaded}/{len(script_configs)} added")
except Exception as e:
- _tool_print(f"[Tool] Error loading scripts: {e}")
+ _tool_error(f"Error loading scripts: {e}")
+
+def _parse_mod_file_line(line, maya_version, modules_dir, module_name):
+ """
+ Parse a single line from .mod file
+
+ Args:
+ line: Line to parse
+ maya_version: Current Maya version
+ modules_dir: Modules directory path
+ module_name: Name of the module
+
+ Returns:
+ Tuple of (in_correct_version, current_module_root) or None
+ """
+ parts = line.split()
+
+ if len(parts) < 4:
+ return None
+
+ # Detect current platform
+ current_platform = 'win64' if os.name == 'nt' else ('linux' if sys.platform.startswith('linux') else 'mac')
+
+ # Check for version and platform restrictions
+ has_version_requirement = False
+ version_matches = False
+ platform_matches = True # Assume match if no platform specified
+
+ for part in parts:
+ if part.startswith('MAYAVERSION:'):
+ has_version_requirement = True
+ required_version = int(part.split(':')[1])
+ version_matches = (required_version == maya_version)
+
+ if part.startswith('PLATFORM:'):
+ required_platform = part.split(':')[1].lower()
+ platform_matches = (required_platform == current_platform)
+
+ # Both version and platform must match (or not be specified)
+ if has_version_requirement:
+ if version_matches and platform_matches:
+ # Get the module root path (last parameter)
+ current_module_root = parts[-1]
+ if current_module_root.startswith('..'):
+ current_module_root = _norm_path(os.path.join(modules_dir, current_module_root))
+ _tool_print(f"{module_name}: Maya {maya_version} {current_platform} matched, root: {current_module_root}")
+ return (True, current_module_root)
+ else:
+ return (False, None)
+
+ # If there are no version restrictions, it works for all versions (but still check platform)
+ if platform_matches:
+ current_module_root = parts[-1]
+ if current_module_root.startswith('..'):
+ current_module_root = _norm_path(os.path.join(modules_dir, current_module_root))
+ _tool_print(f"{module_name}: No version restriction, root: {current_module_root}")
+ return (True, current_module_root)
+
+ return (False, None)
+
+def _load_plugins_from_directory(plugins_dir, mod_file):
+ """
+ Load all plugins from a directory
+
+ Args:
+ plugins_dir: Directory containing plugins
+ mod_file: Name of .mod file for logging
+
+ Returns:
+ Number of plugins loaded
+ """
+ plugins_loaded = 0
+
+ if not os.path.exists(plugins_dir):
+ _tool_log(f"Plugin dir not found: {plugins_dir}")
+ return 0
+
+ _tool_log(f"Checking plugin dir: {plugins_dir}")
+
+ for plugin_file in os.listdir(plugins_dir):
+ if not plugin_file.endswith(('.mll', '.so', '.bundle', '.py')):
+ continue
+
+ plugin_name = os.path.splitext(plugin_file)[0]
+ plugin_full_path = _norm_path(os.path.join(plugins_dir, plugin_file))
+
+ # Check if already tracked
+ if plugin_name in _LOADED_PLUGINS:
+ _tool_log(f"Plugin already tracked: {plugin_name}")
+ continue
+
+ # Check if already loaded
+ try:
+ is_loaded = cmds.pluginInfo(plugin_name, query=True, loaded=True)
+ except:
+ is_loaded = False
+
+ if not is_loaded:
+ try:
+ cmds.loadPlugin(plugin_full_path, quiet=False)
+ _tool_print(f"✓ Plugin loaded: {plugin_name} (from {mod_file})")
+ plugins_loaded += 1
+ _LOADED_PLUGINS[plugin_name] = plugin_full_path
+ except Exception as e:
+ _tool_error(f"Failed to load {plugin_name}: {e}")
+ else:
+ _tool_log(f"Plugin already loaded: {plugin_name}")
+ _LOADED_PLUGINS[plugin_name] = plugin_full_path
+
+ return plugins_loaded
+
+def _add_path_to_environment(env_var, path):
+ """
+ Add a path to an environment variable
+
+ Args:
+ env_var: Environment variable name (e.g., 'MAYA_SCRIPT_PATH')
+ path: Path to add
+
+ Returns:
+ True if added, False if already exists
+ """
+ if not os.path.exists(path):
+ _tool_warning(f"Path not found for {env_var}: {path}")
+ return False
+
+ # Get current paths
+ current_value = os.environ.get(env_var, '')
+ current_paths = [p.strip() for p in current_value.split(os.pathsep) if p.strip()]
+
+ # Normalize the new path
+ norm_path = _norm_path(path)
+
+ # Check if already in path
+ if norm_path in [_norm_path(p) for p in current_paths]:
+ _tool_log(f"{env_var} already contains: {norm_path}")
+ return False
+
+ # Add to front of path list
+ current_paths.insert(0, norm_path)
+ new_value = os.pathsep.join(current_paths)
+ os.environ[env_var] = new_value
+
+ # Update MEL environment if needed
+ if env_var in ['XBMLANGPATH', 'MAYA_SCRIPT_PATH', 'MAYA_PLUG_IN_PATH']:
+ try:
+ safe_value = new_value.replace('\\', '/').replace('"', '\\"')
+ mel.eval(f'putenv "{env_var}" "{safe_value}";')
+ except Exception as e:
+ _tool_warning(f"Could not update MEL environment for {env_var}: {e}")
+
+ # Also add PYTHONPATH to sys.path for Python imports
+ if env_var == 'PYTHONPATH':
+ if norm_path not in sys.path:
+ sys.path.insert(0, norm_path)
+ _tool_log(f"Added to sys.path: {norm_path}")
+
+ _tool_print(f"✓ Added to {env_var}: {os.path.basename(norm_path)}")
+ return True
+
+def _load_user_config():
+ """
+ Load user configuration from optional config file
+ Allows users to override default TOOL_CONFIG settings
+ """
+ global TOOL_CONFIG, SHELF_NAMES
+
+ if not os.path.exists(USER_CONFIG_FILE):
+ _tool_log(f"No user config file found at: {USER_CONFIG_FILE}")
+ return
+
+ try:
+ _tool_print(f"Loading user configuration from: {USER_CONFIG_FILE}")
+
+ # Create a namespace for user config
+ user_namespace = {}
+
+ # Execute user config file
+ with open(USER_CONFIG_FILE, 'r', encoding='utf-8') as f:
+ exec(f.read(), user_namespace)
+
+ # Override TOOL_CONFIG if provided
+ if 'TOOL_CONFIG' in user_namespace:
+ user_config = user_namespace['TOOL_CONFIG']
+
+ # Merge configurations
+ for key in ['scripts', 'plugins', 'icons']:
+ if key in user_config:
+ if key in TOOL_CONFIG:
+ # Extend existing config
+ TOOL_CONFIG[key].extend(user_config[key])
+ else:
+ # Add new key
+ TOOL_CONFIG[key] = user_config[key]
+
+ _tool_print("✓ User TOOL_CONFIG loaded and merged")
+
+ # Override SHELF_NAMES if provided
+ if 'SHELF_NAMES' in user_namespace:
+ user_shelves = user_namespace['SHELF_NAMES']
+ if isinstance(user_shelves, list):
+ # Extend shelf list
+ for shelf in user_shelves:
+ if shelf not in SHELF_NAMES:
+ SHELF_NAMES.append(shelf)
+ _tool_print(f"✓ User SHELF_NAMES loaded: {user_shelves}")
+
+ _tool_print("✓ User configuration applied successfully")
+
+ except Exception as e:
+ _tool_error(f"Error loading user config: {e}")
+ import traceback
+ traceback.print_exc()
def load_project_modules():
"""Load plugins defined in .mod files from the modules directory."""
@@ -487,112 +770,155 @@ def load_project_modules():
modules_dir = _norm_path(os.path.join(project_root, "modules"))
if not os.path.exists(modules_dir):
- _tool_log(f"[Tool] Modules directory not found: {modules_dir}")
+ _tool_log(f"Modules directory not found: {modules_dir}")
return
# Find all .mod files
mod_files = [f for f in os.listdir(modules_dir) if f.endswith('.mod')]
if not mod_files:
- _tool_log(f"[Tool] No .mod files found in: {modules_dir}")
+ _tool_log(f"No .mod files found in: {modules_dir}")
return
- _tool_print(f"[Tool] Found {len(mod_files)} module(s): {', '.join(mod_files)}")
+ _tool_print(f"Found {len(mod_files)} module(s): {', '.join(mod_files)}")
+
+ # TWO-PASS APPROACH: First configure all environment variables, then load plugins
+ # This ensures dependencies are available before plugins initialize
+
+ # PASS 1: Configure all environment variables (including MAYA_PLUG_IN_PATH paths)
+ # Track processed modules to avoid duplicates
+ processed_modules = set()
- # Parse .mod files and load plugins.
- plugins_loaded = 0
for mod_file in mod_files:
mod_path = os.path.join(modules_dir, mod_file)
- _tool_log(f"[Tool] Processing: {mod_file}")
+ module_name = os.path.splitext(mod_file)[0]
try:
current_module_root = None
in_correct_version = False
+ module_key = None
with open(mod_path, 'r', encoding='utf-8') as f:
for line in f:
line = line.strip()
- # Skip comments and empty lines.
+ # Skip comments and empty lines
if not line or line.startswith('#') or line.startswith('//'):
continue
# Parse module definition lines (starting with +)
if line.startswith('+'):
- parts = line.split()
- in_correct_version = False
- current_module_root = None
-
- if len(parts) >= 4:
- # Check for version requirements.
- has_version_requirement = False
- for part in parts:
- if part.startswith('MAYAVERSION:'):
- has_version_requirement = True
- required_version = int(part.split(':')[1])
- if required_version == maya_version:
- in_correct_version = True
- # Get the module root path (last parameter)
- current_module_root = parts[-1]
- if current_module_root.startswith('..'):
- current_module_root = _norm_path(os.path.join(modules_dir, current_module_root))
- _tool_log(f"[Tool] Version matched for Maya {maya_version}: {current_module_root}")
- break
+ result = _parse_mod_file_line(line, maya_version, modules_dir, module_name)
+ if result:
+ in_correct_version, current_module_root = result
+ # Create unique key for this module version
+ module_key = f"{module_name}:{maya_version}:{current_module_root}"
- # If there is no version requirement, it applies to all versions.
- if not has_version_requirement:
- in_correct_version = True
- current_module_root = parts[-1]
- if current_module_root.startswith('..'):
- current_module_root = _norm_path(os.path.join(modules_dir, current_module_root))
- _tool_log(f"[Tool] Module without version restriction loaded: {current_module_root}")
+ # Skip if already processed
+ if module_key in processed_modules:
+ _tool_log(f"Skipping duplicate module definition: {module_key}")
+ in_correct_version = False
+ current_module_root = None
+ continue
+
+ processed_modules.add(module_key)
+ else:
+ in_correct_version = False
+ current_module_root = None
+ module_key = None
- # Only process matching version MAYA_PLUG_IN_PATH
+ # Process ALL environment variables in first pass (including MAYA_PLUG_IN_PATH to env, but don't load plugins)
+ elif in_correct_version and current_module_root and ('+:=' in line or '+=' in line):
+ if line.startswith('MAYA_PLUG_IN_PATH'):
+ # Add plugin directory to MAYA_PLUG_IN_PATH environment, but don't load plugins yet
+ plugin_path_relative = line.split('+:=')[-1].strip() if '+:=' in line else line.split('+=')[-1].strip()
+ plugins_dir = _norm_path(os.path.join(current_module_root, plugin_path_relative))
+ _add_path_to_environment('MAYA_PLUG_IN_PATH', plugins_dir)
+
+ elif line.startswith('MAYA_SCRIPT_PATH'):
+ script_path_relative = line.split('+:=')[-1].strip() if '+:=' in line else line.split('+=')[-1].strip()
+ script_path = _norm_path(os.path.join(current_module_root, script_path_relative))
+ _add_path_to_environment('MAYA_SCRIPT_PATH', script_path)
+ if script_path not in sys.path:
+ sys.path.insert(0, script_path)
+
+ elif line.startswith('XBMLANGPATH'):
+ icon_path_relative = line.split('+:=')[-1].strip() if '+:=' in line else line.split('+=')[-1].strip()
+ icon_path = _norm_path(os.path.join(current_module_root, icon_path_relative))
+ _add_path_to_environment('XBMLANGPATH', icon_path)
+
+ else:
+ # Handle PATH, PYTHONPATH, and other environment variables
+ try:
+ env_var = line.split('+')[0].strip()
+ rel_path = line.split('+:=')[-1].strip() if '+:=' in line else line.split('+=')[-1].strip()
+ full_path = _norm_path(os.path.join(current_module_root, rel_path))
+ _add_path_to_environment(env_var, full_path)
+ except Exception as e:
+ _tool_log(f"Could not process environment variable line: {line}, error: {e}")
+
+ except Exception as e:
+ _tool_error(f"Error processing environment variables in {mod_file}: {e}")
+
+ # PASS 2: Now load plugins with all dependencies configured
+ _tool_log("Environment variables configured, now loading plugins...")
+ plugins_loaded = 0
+ processed_modules.clear() # Reset for second pass
+
+ for mod_file in mod_files:
+ mod_path = os.path.join(modules_dir, mod_file)
+ module_name = os.path.splitext(mod_file)[0]
+
+ try:
+ current_module_root = None
+ in_correct_version = False
+ module_key = None
+
+ with open(mod_path, 'r', encoding='utf-8') as f:
+ for line in f:
+ line = line.strip()
+
+ if not line or line.startswith('#') or line.startswith('//'):
+ continue
+
+ if line.startswith('+'):
+ result = _parse_mod_file_line(line, maya_version, modules_dir, module_name)
+ if result:
+ in_correct_version, current_module_root = result
+ module_key = f"{module_name}:{maya_version}:{current_module_root}"
+
+ # Skip if already processed
+ if module_key in processed_modules:
+ _tool_log(f"Skipping duplicate module definition for plugin loading: {module_key}")
+ in_correct_version = False
+ current_module_root = None
+ continue
+
+ processed_modules.add(module_key)
+ else:
+ in_correct_version = False
+ current_module_root = None
+ module_key = None
+
+ # Now load plugins
elif line.startswith('MAYA_PLUG_IN_PATH') and in_correct_version and current_module_root:
if '+:=' in line or '+=' in line:
- plugin_path_relative = line.split('=')[-1].strip()
+ plugin_path_relative = line.split('+:=')[-1].strip() if '+:=' in line else line.split('+=')[-1].strip()
plugins_dir = _norm_path(os.path.join(current_module_root, plugin_path_relative))
-
- if os.path.exists(plugins_dir):
- _tool_log(f"[Tool] Checking plugin dir: {plugins_dir}")
-
- for plugin_file in os.listdir(plugins_dir):
- if plugin_file.endswith(('.mll', '.so', '.bundle', '.py')):
- plugin_name = os.path.splitext(plugin_file)[0]
- plugin_full_path = os.path.join(plugins_dir, plugin_file)
-
- # Check if already loaded.
- if plugin_name in _LOADED_PLUGINS:
- continue
-
- try:
- is_loaded = cmds.pluginInfo(plugin_name, query=True, loaded=True)
- except:
- is_loaded = False
-
- if not is_loaded:
- try:
- cmds.loadPlugin(plugin_full_path, quiet=True)
- _tool_print(f"[Tool] ✓ Plugin loaded: {plugin_name} (from {mod_file})")
- plugins_loaded += 1
- _LOADED_PLUGINS[plugin_name] = plugin_full_path
- except Exception as e:
- _tool_print(f"[Tool] Failed to load {plugin_name}: {e}")
- else:
- _tool_log(f"[Tool] Plugin dir not found: {plugins_dir}")
+ plugins_loaded += _load_plugins_from_directory(plugins_dir, mod_file)
except Exception as e:
- _tool_print(f"[Tool] Error processing {mod_file}: {e}")
+ _tool_error(f"Error processing {mod_file}: {e}")
import traceback
traceback.print_exc()
if plugins_loaded > 0:
- _tool_print(f"[Tool] ✓ Total {plugins_loaded} module plugin(s) loaded")
+ _tool_print(f"✓ Total {plugins_loaded} module plugin(s) loaded")
else:
- _tool_print(f"[Tool] No module plugins loaded")
+ _tool_print("No module plugins loaded")
except Exception as e:
- _tool_print(f"[Tool] Error loading modules: {e}")
+ _tool_error(f"Error loading modules: {e}")
import traceback
traceback.print_exc()
@@ -602,18 +928,18 @@ def setup_command_port():
try:
# Check if already open
try:
- port_exists = bool(mel.eval('commandPort -q -name "commandportDefault"'))
+ port_exists = bool(mel.eval(f'commandPort -q -name "{COMMAND_PORT_NAME}"'))
except Exception:
port_exists = False
if port_exists:
- _tool_log("[Tool] Command port already open")
+ _tool_log("Command port already open")
_COMMAND_PORT_OPENED = True
return
# Open command port
- mel.eval('commandPort -securityWarning -name "commandportDefault";')
- _tool_log("[Tool] ✓ Command port opened")
+ mel.eval(f'commandPort -securityWarning -name "{COMMAND_PORT_NAME}";')
+ _tool_log("✓ Command port opened")
_COMMAND_PORT_OPENED = True
except Exception as e:
@@ -630,15 +956,19 @@ def initialize_tool():
print("[Tool] Nexus Plugin System - Initializing...")
print("=" * 80)
+ # Validate configuration
+ if not _validate_tool_config():
+ _tool_error("Configuration validation failed, continuing with caution...")
+
# Check Maya version compatibility
if not _check_maya_version():
- print("[Tool] Warning: Running on unsupported Maya version")
+ _tool_warning("Running on unsupported Maya version")
- # Set icon paths first, so shelves can find icons
+ # First, set the icon path so that the shelf can find the icon when it loads.
setup_icon_paths()
# Load project modules
- load_project_modules() # Automatic loading using Maya standard module system
+ load_project_modules() # Use Maya standard module systems for automatic loading.
# Setup command port
setup_command_port()
@@ -673,11 +1003,11 @@ def cleanup_on_exit():
global _COMMAND_PORT_OPENED
if _COMMAND_PORT_OPENED:
try:
- if mel.eval('commandPort -q -name "commandportDefault"'):
- mel.eval('commandPort -cl "commandportDefault"')
- _tool_log("[Tool] ✓ Command port closed")
+ if mel.eval(f'commandPort -q -name "{COMMAND_PORT_NAME}"'):
+ mel.eval(f'commandPort -cl "{COMMAND_PORT_NAME}"')
+ _tool_log("✓ Command port closed")
except Exception as e:
- _tool_log(f"[Tool] Could not close command port: {e}")
+ _tool_log(f"Could not close command port: {e}")
# Unload plugins
if _LOADED_PLUGINS:
@@ -725,4 +1055,4 @@ def cleanup_on_exit():
_tool_log(f"[Tool] Cleanup error: {e}")
# Register cleanup function
-atexit.register(cleanup_on_exit)
\ No newline at end of file
+atexit.register(cleanup_on_exit)
diff --git a/2024/shelves/shelf_Nexus_Modeling.mel b/2024/shelves/shelf_Nexus_Modeling.mel
index 51da4c7..f72fdf6 100644
--- a/2024/shelves/shelf_Nexus_Modeling.mel
+++ b/2024/shelves/shelf_Nexus_Modeling.mel
@@ -109,111 +109,6 @@ global proc shelf_Nexus_Modeling () {
-commandRepeatable 1
-flat 1
;
- shelfButton
- -enableCommandRepeat 1
- -flexibleWidthType 3
- -flexibleWidthValue 36
- -enable 1
- -width 39
- -height 34
- -manage 1
- -visible 1
- -preventOverride 0
- -annotation "GS Curvetools - Open UI"
- -enableBackground 0
- -backgroundColor 0 0 0
- -highlightColor 0.321569 0.521569 0.65098
- -align "center"
- -label "GSCurve"
- -labelOffset 0
- -rotation 0
- -flipX 0
- -flipY 0
- -useAlpha 1
- -font "plainLabelFont"
- -imageOverlayLabel "UI"
- -overlayLabelColor 0.8 0.8 0.8
- -overlayLabelBackColor 0 0 0 0.5
- -image "gsCurveToolsIcon_ui.png"
- -image1 "gsCurveToolsIcon_ui.png"
- -style "iconOnly"
- -marginWidth 0
- -marginHeight 1
- -command "import gs_curvetools.main as gs_curvetools_main; gs_curvetools_main.main();"
- -sourceType "python"
- -commandRepeatable 1
- -flat 1
- ;
- shelfButton
- -enableCommandRepeat 1
- -flexibleWidthType 3
- -flexibleWidthValue 36
- -enable 1
- -width 39
- -height 34
- -manage 1
- -visible 1
- -preventOverride 0
- -annotation "GS Curvetools - Reset"
- -enableBackground 0
- -backgroundColor 0 0 0
- -highlightColor 0.321569 0.521569 0.65098
- -align "center"
- -label "GSCReset"
- -labelOffset 0
- -rotation 0
- -flipX 0
- -flipY 0
- -useAlpha 1
- -font "plainLabelFont"
- -imageOverlayLabel "Reset"
- -overlayLabelColor 0.8 0.8 0.8
- -overlayLabelBackColor 0 0 0 0.5
- -image "gsCurveToolsIcon_reset.png"
- -image1 "gsCurveToolsIcon_reset.png"
- -style "iconOnly"
- -marginWidth 0
- -marginHeight 1
- -command "import gs_curvetools.core.utils as gs_curvetools_utils; gs_curvetools_utils.reset_ui(); del gs_curvetools_utils"
- -sourceType "python"
- -commandRepeatable 1
- -flat 1
- ;
- shelfButton
- -enableCommandRepeat 1
- -flexibleWidthType 3
- -flexibleWidthValue 36
- -enable 1
- -width 39
- -height 34
- -manage 1
- -visible 1
- -preventOverride 0
- -annotation "GS Curvetools - Stop/Close"
- -enableBackground 0
- -backgroundColor 0 0 0
- -highlightColor 0.321569 0.521569 0.65098
- -align "center"
- -label "GSCStop"
- -labelOffset 0
- -rotation 0
- -flipX 0
- -flipY 0
- -useAlpha 1
- -font "plainLabelFont"
- -imageOverlayLabel "Stop"
- -overlayLabelColor 0.8 0.8 0.8
- -overlayLabelBackColor 0 0 0 0.5
- -image "gsCurveToolsIcon_stop.png"
- -image1 "gsCurveToolsIcon_stop.png"
- -style "iconOnly"
- -marginWidth 0
- -marginHeight 1
- -command "import gs_curvetools.core.utils as gs_curvetools_utils; gs_curvetools_utils.stop_ui(); del gs_curvetools_utils"
- -sourceType "python"
- -commandRepeatable 1
- -flat 1
- ;
shelfButton
-enableCommandRepeat 1
-flexibleWidthType 3
diff --git a/2025/scripts/animation_tools/mgpicker/MGPicker_Program/Plug-ins/MGPicker_2017x64.mll b/2025/scripts/animation_tools/mgpicker/MGPicker_Program/Plug-ins/MGPicker_2017x64.mll
deleted file mode 100644
index e7657f1..0000000
Binary files a/2025/scripts/animation_tools/mgpicker/MGPicker_Program/Plug-ins/MGPicker_2017x64.mll and /dev/null differ
diff --git a/2025/scripts/animation_tools/mgpicker/MGPicker_Program/Plug-ins/MGPicker_2018x64.mll b/2025/scripts/animation_tools/mgpicker/MGPicker_Program/Plug-ins/MGPicker_2018x64.mll
deleted file mode 100644
index af0b394..0000000
Binary files a/2025/scripts/animation_tools/mgpicker/MGPicker_Program/Plug-ins/MGPicker_2018x64.mll and /dev/null differ
diff --git a/2025/scripts/animation_tools/mgpicker/MGPicker_Program/Plug-ins/MGPicker_2019x64.mll b/2025/scripts/animation_tools/mgpicker/MGPicker_Program/Plug-ins/MGPicker_2019x64.mll
deleted file mode 100644
index 7243098..0000000
Binary files a/2025/scripts/animation_tools/mgpicker/MGPicker_Program/Plug-ins/MGPicker_2019x64.mll and /dev/null differ
diff --git a/2025/scripts/animation_tools/mgpicker/MGPicker_Program/Plug-ins/MGPicker_2020x64.mll b/2025/scripts/animation_tools/mgpicker/MGPicker_Program/Plug-ins/MGPicker_2020x64.mll
deleted file mode 100644
index 896efed..0000000
Binary files a/2025/scripts/animation_tools/mgpicker/MGPicker_Program/Plug-ins/MGPicker_2020x64.mll and /dev/null differ
diff --git a/2025/scripts/animation_tools/mgpicker/MGPicker_Program/Plug-ins/MGPicker_2022x64.mll b/2025/scripts/animation_tools/mgpicker/MGPicker_Program/Plug-ins/MGPicker_2022x64.mll
deleted file mode 100644
index f70eef9..0000000
Binary files a/2025/scripts/animation_tools/mgpicker/MGPicker_Program/Plug-ins/MGPicker_2022x64.mll and /dev/null differ
diff --git a/2025/scripts/animation_tools/mgpicker/MGPicker_Program/Plug-ins/MGPicker_2023x64.mll b/2025/scripts/animation_tools/mgpicker/MGPicker_Program/Plug-ins/MGPicker_2023x64.mll
deleted file mode 100644
index e324793..0000000
Binary files a/2025/scripts/animation_tools/mgpicker/MGPicker_Program/Plug-ins/MGPicker_2023x64.mll and /dev/null differ
diff --git a/2025/scripts/animation_tools/mgpicker/MGPicker_Program/Plug-ins/MGPicker_2024x64.mll b/2025/scripts/animation_tools/mgpicker/MGPicker_Program/Plug-ins/MGPicker_2024x64.mll
deleted file mode 100644
index 401e107..0000000
Binary files a/2025/scripts/animation_tools/mgpicker/MGPicker_Program/Plug-ins/MGPicker_2024x64.mll and /dev/null differ
diff --git a/2025/scripts/animation_tools/mgpicker/MGPicker_Program/Plug-ins/MGPicker_2026x64.mll b/2025/scripts/animation_tools/mgpicker/MGPicker_Program/Plug-ins/MGPicker_2026x64.mll
deleted file mode 100644
index 95c8337..0000000
Binary files a/2025/scripts/animation_tools/mgpicker/MGPicker_Program/Plug-ins/MGPicker_2026x64.mll and /dev/null differ
diff --git a/2025/scripts/modeling_tools/ModIt/Class/Collapsible.py b/2025/scripts/modeling_tools/ModIt/Class/Collapsible.py
index 4b5f2e4..7b0a98d 100644
--- a/2025/scripts/modeling_tools/ModIt/Class/Collapsible.py
+++ b/2025/scripts/modeling_tools/ModIt/Class/Collapsible.py
@@ -1,19 +1,23 @@
##--------------------------------------------------------------------------
-try:
- from PySide6 import QtWidgets, QtCore, QtGui
- from PySide6.QtWidgets import *
- from PySide6.QtGui import *
- from PySide6.QtCore import *
- from shiboken6 import wrapInstance
+# Import Qt from project's unified Qt.py module
+import sys as _sys
+import os as _os
-except ImportError:
- from PySide2 import QtWidgets, QtCore, QtGui
- from shiboken2 import wrapInstance
- from PySide2.QtGui import QIcon
- from PySide2.QtWidgets import QWidget
- import shiboken2
+# Add parent scripts directory to sys.path
+_modit_dir = _os.path.dirname(_os.path.abspath(__file__))
+_scripts_dir = _modit_dir
+while _os.path.basename(_scripts_dir) != 'scripts' and _scripts_dir != _os.path.dirname(_scripts_dir):
+ _scripts_dir = _os.path.dirname(_scripts_dir)
+if _scripts_dir not in _sys.path:
+ _sys.path.insert(0, _scripts_dir)
+from Qt import QtWidgets, QtCore, QtGui, QtCompat
+
+# Use QtCompat for cross-version compatibility
+wrapInstance = QtCompat.wrapInstance
+QIcon = QtGui.QIcon
+QWidget = QtWidgets.QWidget
import json
diff --git a/2025/scripts/modeling_tools/ModIt/ModIt_CSS.py b/2025/scripts/modeling_tools/ModIt/ModIt_CSS.py
index 251860d..0626a66 100644
--- a/2025/scripts/modeling_tools/ModIt/ModIt_CSS.py
+++ b/2025/scripts/modeling_tools/ModIt/ModIt_CSS.py
@@ -1,20 +1,23 @@
##GLOBAL VARIABLEs
-try:
- from PySide6 import QtWidgets, QtCore, QtGui
- from PySide6.QtWidgets import *
- from PySide6.QtGui import *
- from PySide6.QtCore import *
- from shiboken6 import wrapInstance
+# Import Qt from project's unified Qt.py module
+import sys as _sys
+import os as _os
-except ImportError:
- from PySide2 import QtWidgets, QtCore, QtGui
- from shiboken2 import wrapInstance
- from PySide2.QtGui import QIcon
- from PySide2.QtWidgets import QWidget
- import shiboken2
+# Add parent scripts directory to sys.path
+_modit_dir = _os.path.dirname(_os.path.abspath(__file__))
+_scripts_dir = _modit_dir
+while _os.path.basename(_scripts_dir) != 'scripts' and _scripts_dir != _os.path.dirname(_scripts_dir):
+ _scripts_dir = _os.path.dirname(_scripts_dir)
+if _scripts_dir not in _sys.path:
+ _sys.path.insert(0, _scripts_dir)
+from Qt import QtWidgets, QtCore, QtGui, QtCompat
+# Use QtCompat for cross-version compatibility
+wrapInstance = QtCompat.wrapInstance
+QIcon = QtGui.QIcon
+QWidget = QtWidgets.QWidget
from maya import cmds as mc
import os
diff --git a/2025/scripts/modeling_tools/ModIt/ModIt_Global.py b/2025/scripts/modeling_tools/ModIt/ModIt_Global.py
index 46a5b7c..c397f96 100644
--- a/2025/scripts/modeling_tools/ModIt/ModIt_Global.py
+++ b/2025/scripts/modeling_tools/ModIt/ModIt_Global.py
@@ -1,24 +1,29 @@
##GLOBAL VARIABLEs
-from PySide2 import QtWidgets, QtCore, QtGui
from maya import cmds as mc
import maya.mel as mel
import json
-from .Qt import QtWidgets, QtCore, QtCompat
import os
import maya.cmds as cmds
from maya import OpenMayaUI as omui
-# Special cases for different Maya versions
-try:
- from shiboken2 import wrapInstance
-except ImportError:
- from shiboken import wrapInstance
+# Import Qt from project's unified Qt.py module
+import sys
+import os as _os
-try:
- from PySide2.QtGui import QIcon
- from PySide2.QtWidgets import QWidget
-except ImportError:
- from PySide.QtGui import QIcon, QWidget
+# Add parent scripts directory to sys.path to enable absolute import of Qt
+_current_dir = _os.path.dirname(_os.path.abspath(__file__))
+_scripts_dir = _os.path.dirname(_os.path.dirname(_current_dir))
+if _scripts_dir not in sys.path:
+ sys.path.insert(0, _scripts_dir)
+
+from Qt import QtWidgets, QtCore, QtGui, QtCompat
+
+# Import wrapInstance from QtCompat (handles all Qt binding versions)
+wrapInstance = QtCompat.wrapInstance
+
+# Import QIcon and QWidget from Qt module
+QIcon = QtGui.QIcon
+QWidget = QtWidgets.QWidget
from . import ModIt_CSS
diff --git a/2025/scripts/modeling_tools/ModIt/ModIt_UI.py b/2025/scripts/modeling_tools/ModIt/ModIt_UI.py
index fd24805..aeee76c 100644
--- a/2025/scripts/modeling_tools/ModIt/ModIt_UI.py
+++ b/2025/scripts/modeling_tools/ModIt/ModIt_UI.py
@@ -5,21 +5,24 @@
## LastUpdate : 2022/13/09
## Version : 0.0.1
##-------------------------------------------------------------------------- I M P O R T
-try:
- from PySide6 import QtWidgets, QtCore, QtGui
- from PySide6.QtWidgets import *
- from PySide6.QtGui import *
- from PySide6.QtCore import *
- from shiboken6 import wrapInstance
+# Import Qt from project's unified Qt.py module
+import sys as _sys
+import os as _os
-except ImportError:
- from PySide2 import QtWidgets, QtCore, QtGui
- from shiboken2 import wrapInstance
- from PySide2.QtGui import QIcon
- from PySide2.QtWidgets import QWidget
- import shiboken2
+# Add parent scripts directory to sys.path
+_modit_dir = _os.path.dirname(_os.path.abspath(__file__))
+_scripts_dir = _modit_dir
+while _os.path.basename(_scripts_dir) != 'scripts' and _scripts_dir != _os.path.dirname(_scripts_dir):
+ _scripts_dir = _os.path.dirname(_scripts_dir)
+if _scripts_dir not in _sys.path:
+ _sys.path.insert(0, _scripts_dir)
+from Qt import QtWidgets, QtCore, QtGui, QtCompat
+# Use QtCompat for cross-version compatibility
+wrapInstance = QtCompat.wrapInstance
+QIcon = QtGui.QIcon
+QWidget = QtWidgets.QWidget
from maya import cmds as mc
import maya.cmds as cmds
import maya.mel as mel
diff --git a/2025/scripts/modeling_tools/ModIt/Modeling/ModIt_2Bevels_UI.py b/2025/scripts/modeling_tools/ModIt/Modeling/ModIt_2Bevels_UI.py
index 77ec570..6abcc84 100644
--- a/2025/scripts/modeling_tools/ModIt/Modeling/ModIt_2Bevels_UI.py
+++ b/2025/scripts/modeling_tools/ModIt/Modeling/ModIt_2Bevels_UI.py
@@ -8,21 +8,24 @@
from maya import cmds as mc
+# Import Qt from project's unified Qt.py module
+import sys as _sys
+import os as _os
-try:
- from PySide6 import QtWidgets, QtCore, QtGui
- from PySide6.QtWidgets import *
- from PySide6.QtGui import *
- from PySide6.QtCore import *
- from shiboken6 import wrapInstance
+# Add parent scripts directory to sys.path
+_modit_dir = _os.path.dirname(_os.path.abspath(__file__))
+_scripts_dir = _modit_dir
+while _os.path.basename(_scripts_dir) != 'scripts' and _scripts_dir != _os.path.dirname(_scripts_dir):
+ _scripts_dir = _os.path.dirname(_scripts_dir)
+if _scripts_dir not in _sys.path:
+ _sys.path.insert(0, _scripts_dir)
-except ImportError:
- from PySide2 import QtWidgets, QtCore, QtGui
- from shiboken2 import wrapInstance
- from PySide2.QtGui import QIcon
- from PySide2.QtWidgets import QWidget
- import shiboken2
+from Qt import QtWidgets, QtCore, QtGui, QtCompat
+# Use QtCompat for cross-version compatibility
+wrapInstance = QtCompat.wrapInstance
+QIcon = QtGui.QIcon
+QWidget = QtWidgets.QWidget
from maya import OpenMayaUI as omui
##---------------------------------------- Import Modules
diff --git a/2025/scripts/modeling_tools/ModIt/Modeling/Section_COLORS.py b/2025/scripts/modeling_tools/ModIt/Modeling/Section_COLORS.py
index 175136c..41368c0 100644
--- a/2025/scripts/modeling_tools/ModIt/Modeling/Section_COLORS.py
+++ b/2025/scripts/modeling_tools/ModIt/Modeling/Section_COLORS.py
@@ -1,17 +1,22 @@
##--------------------------------------------------------------------------
-try:
- from PySide6 import QtWidgets, QtCore, QtGui
- from PySide6.QtWidgets import *
- from PySide6.QtGui import *
- from PySide6.QtCore import *
- from shiboken6 import wrapInstance
+# Import Qt from project's unified Qt.py module
+import sys as _sys
+import os as _os
-except ImportError:
- from PySide2 import QtWidgets, QtCore, QtGui
- from shiboken2 import wrapInstance
- from PySide2.QtGui import QIcon
- from PySide2.QtWidgets import QWidget
- import shiboken2
+# Add parent scripts directory to sys.path
+_modit_dir = _os.path.dirname(_os.path.abspath(__file__))
+_scripts_dir = _modit_dir
+while _os.path.basename(_scripts_dir) != 'scripts' and _scripts_dir != _os.path.dirname(_scripts_dir):
+ _scripts_dir = _os.path.dirname(_scripts_dir)
+if _scripts_dir not in _sys.path:
+ _sys.path.insert(0, _scripts_dir)
+
+from Qt import QtWidgets, QtCore, QtGui, QtCompat
+
+# Use QtCompat for cross-version compatibility
+wrapInstance = QtCompat.wrapInstance
+QIcon = QtGui.QIcon
+QWidget = QtWidgets.QWidget
from maya import cmds as mc
diff --git a/2025/scripts/modeling_tools/ModIt/Modeling/Section_MESH.py b/2025/scripts/modeling_tools/ModIt/Modeling/Section_MESH.py
index 8aa2a54..a45d10f 100644
--- a/2025/scripts/modeling_tools/ModIt/Modeling/Section_MESH.py
+++ b/2025/scripts/modeling_tools/ModIt/Modeling/Section_MESH.py
@@ -1,19 +1,22 @@
##--------------------------------------------------------------------------
-try:
- from PySide6 import QtWidgets, QtCore, QtGui
- from PySide6.QtWidgets import *
- from PySide6.QtGui import *
- from PySide6.QtCore import *
- from shiboken6 import wrapInstance
+# Import Qt from project's unified Qt.py module
+import sys as _sys
+import os as _os
-except ImportError:
- from PySide2 import QtWidgets, QtCore, QtGui
- from shiboken2 import wrapInstance
- from PySide2.QtGui import QIcon
- from PySide2.QtWidgets import QWidget
- import shiboken2
+# Add parent scripts directory to sys.path
+_modit_dir = _os.path.dirname(_os.path.abspath(__file__))
+_scripts_dir = _modit_dir
+while _os.path.basename(_scripts_dir) != 'scripts' and _scripts_dir != _os.path.dirname(_scripts_dir):
+ _scripts_dir = _os.path.dirname(_scripts_dir)
+if _scripts_dir not in _sys.path:
+ _sys.path.insert(0, _scripts_dir)
+from Qt import QtWidgets, QtCore, QtGui, QtCompat
+# Use QtCompat for cross-version compatibility
+wrapInstance = QtCompat.wrapInstance
+QIcon = QtGui.QIcon
+QWidget = QtWidgets.QWidget
from maya import cmds as mc
import maya.mel as mel
import json
diff --git a/2025/scripts/modeling_tools/ModIt/Modeling/Section_PRIMITIVES.py b/2025/scripts/modeling_tools/ModIt/Modeling/Section_PRIMITIVES.py
index 51c4c24..73f85f7 100644
--- a/2025/scripts/modeling_tools/ModIt/Modeling/Section_PRIMITIVES.py
+++ b/2025/scripts/modeling_tools/ModIt/Modeling/Section_PRIMITIVES.py
@@ -1,19 +1,22 @@
##--------------------------------------------------------------------------
-try:
- from PySide6 import QtWidgets, QtCore, QtGui
- from PySide6.QtWidgets import *
- from PySide6.QtGui import *
- from PySide6.QtCore import *
- from shiboken6 import wrapInstance
+# Import Qt from project's unified Qt.py module
+import sys as _sys
+import os as _os
-except ImportError:
- from PySide2 import QtWidgets, QtCore, QtGui
- from shiboken2 import wrapInstance
- from PySide2.QtGui import QIcon
- from PySide2.QtWidgets import QWidget
- import shiboken2
+# Add parent scripts directory to sys.path
+_modit_dir = _os.path.dirname(_os.path.abspath(__file__))
+_scripts_dir = _modit_dir
+while _os.path.basename(_scripts_dir) != 'scripts' and _scripts_dir != _os.path.dirname(_scripts_dir):
+ _scripts_dir = _os.path.dirname(_scripts_dir)
+if _scripts_dir not in _sys.path:
+ _sys.path.insert(0, _scripts_dir)
+from Qt import QtWidgets, QtCore, QtGui, QtCompat
+# Use QtCompat for cross-version compatibility
+wrapInstance = QtCompat.wrapInstance
+QIcon = QtGui.QIcon
+QWidget = QtWidgets.QWidget
from maya import cmds as mc
import maya.mel as mel
import json
diff --git a/2025/scripts/modeling_tools/ModIt/Modeling/Section_SELECTIONS.py b/2025/scripts/modeling_tools/ModIt/Modeling/Section_SELECTIONS.py
index b08f99d..e74da5e 100644
--- a/2025/scripts/modeling_tools/ModIt/Modeling/Section_SELECTIONS.py
+++ b/2025/scripts/modeling_tools/ModIt/Modeling/Section_SELECTIONS.py
@@ -1,19 +1,22 @@
##--------------------------------------------------------------------------
-try:
- from PySide6 import QtWidgets, QtCore, QtGui
- from PySide6.QtWidgets import *
- from PySide6.QtGui import *
- from PySide6.QtCore import *
- from shiboken6 import wrapInstance
+# Import Qt from project's unified Qt.py module
+import sys as _sys
+import os as _os
-except ImportError:
- from PySide2 import QtWidgets, QtCore, QtGui
- from shiboken2 import wrapInstance
- from PySide2.QtGui import QIcon
- from PySide2.QtWidgets import QWidget
- import shiboken2
+# Add parent scripts directory to sys.path
+_modit_dir = _os.path.dirname(_os.path.abspath(__file__))
+_scripts_dir = _modit_dir
+while _os.path.basename(_scripts_dir) != 'scripts' and _scripts_dir != _os.path.dirname(_scripts_dir):
+ _scripts_dir = _os.path.dirname(_scripts_dir)
+if _scripts_dir not in _sys.path:
+ _sys.path.insert(0, _scripts_dir)
+from Qt import QtWidgets, QtCore, QtGui, QtCompat
+# Use QtCompat for cross-version compatibility
+wrapInstance = QtCompat.wrapInstance
+QIcon = QtGui.QIcon
+QWidget = QtWidgets.QWidget
from maya import cmds as mc
import maya.mel as mel
import json
diff --git a/2025/scripts/modeling_tools/ModIt/Modeling/Section_SETS.py b/2025/scripts/modeling_tools/ModIt/Modeling/Section_SETS.py
index 9608bc2..501905d 100644
--- a/2025/scripts/modeling_tools/ModIt/Modeling/Section_SETS.py
+++ b/2025/scripts/modeling_tools/ModIt/Modeling/Section_SETS.py
@@ -1,19 +1,22 @@
##--------------------------------------------------------------------------
-try:
- from PySide6 import QtWidgets, QtCore, QtGui
- from PySide6.QtWidgets import *
- from PySide6.QtGui import *
- from PySide6.QtCore import *
- from shiboken6 import wrapInstance
+# Import Qt from project's unified Qt.py module
+import sys as _sys
+import os as _os
-except ImportError:
- from PySide2 import QtWidgets, QtCore, QtGui
- from shiboken2 import wrapInstance
- from PySide2.QtGui import QIcon
- from PySide2.QtWidgets import QWidget
- import shiboken2
+# Add parent scripts directory to sys.path
+_modit_dir = _os.path.dirname(_os.path.abspath(__file__))
+_scripts_dir = _modit_dir
+while _os.path.basename(_scripts_dir) != 'scripts' and _scripts_dir != _os.path.dirname(_scripts_dir):
+ _scripts_dir = _os.path.dirname(_scripts_dir)
+if _scripts_dir not in _sys.path:
+ _sys.path.insert(0, _scripts_dir)
+from Qt import QtWidgets, QtCore, QtGui, QtCompat
+# Use QtCompat for cross-version compatibility
+wrapInstance = QtCompat.wrapInstance
+QIcon = QtGui.QIcon
+QWidget = QtWidgets.QWidget
from maya import cmds as mc
import maya.mel as mel
import json
diff --git a/2025/scripts/modeling_tools/ModIt/Modeling/Section_TOOLS.py b/2025/scripts/modeling_tools/ModIt/Modeling/Section_TOOLS.py
index f47bc33..508f0da 100644
--- a/2025/scripts/modeling_tools/ModIt/Modeling/Section_TOOLS.py
+++ b/2025/scripts/modeling_tools/ModIt/Modeling/Section_TOOLS.py
@@ -1,19 +1,22 @@
##--------------------------------------------------------------------------
-try:
- from PySide6 import QtWidgets, QtCore, QtGui
- from PySide6.QtWidgets import *
- from PySide6.QtGui import *
- from PySide6.QtCore import *
- from shiboken6 import wrapInstance
+# Import Qt from project's unified Qt.py module
+import sys as _sys
+import os as _os
-except ImportError:
- from PySide2 import QtWidgets, QtCore, QtGui
- from shiboken2 import wrapInstance
- from PySide2.QtGui import QIcon
- from PySide2.QtWidgets import QWidget
- import shiboken2
+# Add parent scripts directory to sys.path
+_modit_dir = _os.path.dirname(_os.path.abspath(__file__))
+_scripts_dir = _modit_dir
+while _os.path.basename(_scripts_dir) != 'scripts' and _scripts_dir != _os.path.dirname(_scripts_dir):
+ _scripts_dir = _os.path.dirname(_scripts_dir)
+if _scripts_dir not in _sys.path:
+ _sys.path.insert(0, _scripts_dir)
+from Qt import QtWidgets, QtCore, QtGui, QtCompat
+# Use QtCompat for cross-version compatibility
+wrapInstance = QtCompat.wrapInstance
+QIcon = QtGui.QIcon
+QWidget = QtWidgets.QWidget
from maya import cmds as mc
import maya.mel as mel
import json
diff --git a/2025/scripts/modeling_tools/ModIt/Modeling/Section_UTILITIES.py b/2025/scripts/modeling_tools/ModIt/Modeling/Section_UTILITIES.py
index 219b25b..8dc3d10 100644
--- a/2025/scripts/modeling_tools/ModIt/Modeling/Section_UTILITIES.py
+++ b/2025/scripts/modeling_tools/ModIt/Modeling/Section_UTILITIES.py
@@ -1,19 +1,22 @@
##--------------------------------------------------------------------------
-try:
- from PySide6 import QtWidgets, QtCore, QtGui
- from PySide6.QtWidgets import *
- from PySide6.QtGui import *
- from PySide6.QtCore import *
- from shiboken6 import wrapInstance
+# Import Qt from project's unified Qt.py module
+import sys as _sys
+import os as _os
-except ImportError:
- from PySide2 import QtWidgets, QtCore, QtGui
- from shiboken2 import wrapInstance
- from PySide2.QtGui import QIcon
- from PySide2.QtWidgets import QWidget
- import shiboken2
+# Add parent scripts directory to sys.path
+_modit_dir = _os.path.dirname(_os.path.abspath(__file__))
+_scripts_dir = _modit_dir
+while _os.path.basename(_scripts_dir) != 'scripts' and _scripts_dir != _os.path.dirname(_scripts_dir):
+ _scripts_dir = _os.path.dirname(_scripts_dir)
+if _scripts_dir not in _sys.path:
+ _sys.path.insert(0, _scripts_dir)
+from Qt import QtWidgets, QtCore, QtGui, QtCompat
+# Use QtCompat for cross-version compatibility
+wrapInstance = QtCompat.wrapInstance
+QIcon = QtGui.QIcon
+QWidget = QtWidgets.QWidget
from maya import cmds as mc
import maya.mel as mel
import json
diff --git a/2025/scripts/modeling_tools/ModIt/Placement/Layout_PLACEMENT.py b/2025/scripts/modeling_tools/ModIt/Placement/Layout_PLACEMENT.py
index fcf4cdb..3981c12 100644
--- a/2025/scripts/modeling_tools/ModIt/Placement/Layout_PLACEMENT.py
+++ b/2025/scripts/modeling_tools/ModIt/Placement/Layout_PLACEMENT.py
@@ -1,18 +1,22 @@
##--------------------------------------------------------------------------
-try:
- from PySide6 import QtWidgets, QtCore, QtGui
- from PySide6.QtWidgets import *
- from PySide6.QtGui import *
- from PySide6.QtCore import *
- from shiboken6 import wrapInstance
+# Import Qt from project's unified Qt.py module
+import sys as _sys
+import os as _os
-except ImportError:
- from PySide2 import QtWidgets, QtCore, QtGui
- from shiboken2 import wrapInstance
- from PySide2.QtGui import QIcon
- from PySide2.QtWidgets import QWidget
- import shiboken2
+# Add parent scripts directory to sys.path
+_modit_dir = _os.path.dirname(_os.path.abspath(__file__))
+_scripts_dir = _modit_dir
+while _os.path.basename(_scripts_dir) != 'scripts' and _scripts_dir != _os.path.dirname(_scripts_dir):
+ _scripts_dir = _os.path.dirname(_scripts_dir)
+if _scripts_dir not in _sys.path:
+ _sys.path.insert(0, _scripts_dir)
+from Qt import QtWidgets, QtCore, QtGui, QtCompat
+
+# Use QtCompat for cross-version compatibility
+wrapInstance = QtCompat.wrapInstance
+QIcon = QtGui.QIcon
+QWidget = QtWidgets.QWidget
from maya import cmds as mc
import json
diff --git a/2025/scripts/modeling_tools/ModIt/Placement/ModIt_AssetIt.py b/2025/scripts/modeling_tools/ModIt/Placement/ModIt_AssetIt.py
index e1d0e03..3ca348b 100644
--- a/2025/scripts/modeling_tools/ModIt/Placement/ModIt_AssetIt.py
+++ b/2025/scripts/modeling_tools/ModIt/Placement/ModIt_AssetIt.py
@@ -1,19 +1,22 @@
##--------------------------------------------------------------------------
-try:
- from PySide6 import QtWidgets, QtCore, QtGui
- from PySide6.QtWidgets import *
- from PySide6.QtGui import *
- from PySide6.QtCore import *
- from shiboken6 import wrapInstance
+# Import Qt from project's unified Qt.py module
+import sys as _sys
+import os as _os
-except ImportError:
- from PySide2 import QtWidgets, QtCore, QtGui
- from shiboken2 import wrapInstance
- from PySide2.QtGui import QIcon
- from PySide2.QtWidgets import QWidget
- import shiboken2
+# Add parent scripts directory to sys.path
+_modit_dir = _os.path.dirname(_os.path.abspath(__file__))
+_scripts_dir = _modit_dir
+while _os.path.basename(_scripts_dir) != 'scripts' and _scripts_dir != _os.path.dirname(_scripts_dir):
+ _scripts_dir = _os.path.dirname(_scripts_dir)
+if _scripts_dir not in _sys.path:
+ _sys.path.insert(0, _scripts_dir)
+from Qt import QtWidgets, QtCore, QtGui, QtCompat
+# Use QtCompat for cross-version compatibility
+wrapInstance = QtCompat.wrapInstance
+QIcon = QtGui.QIcon
+QWidget = QtWidgets.QWidget
from maya import cmds as mc
import maya.cmds as cmds
from maya import OpenMayaUI as omui
diff --git a/2025/scripts/modeling_tools/ModIt/Preferences/TabOpen.json b/2025/scripts/modeling_tools/ModIt/Preferences/TabOpen.json
index dbf9e29..c9862c0 100644
--- a/2025/scripts/modeling_tools/ModIt/Preferences/TabOpen.json
+++ b/2025/scripts/modeling_tools/ModIt/Preferences/TabOpen.json
@@ -1 +1 @@
-{"TAB_OPEN": 2}
\ No newline at end of file
+{"TAB_OPEN": 0}
\ No newline at end of file
diff --git a/2025/scripts/modeling_tools/ModIt/Preferences/settingsFile.ini b/2025/scripts/modeling_tools/ModIt/Preferences/settingsFile.ini
index 538c2cd..06c4d6d 100644
--- a/2025/scripts/modeling_tools/ModIt/Preferences/settingsFile.ini
+++ b/2025/scripts/modeling_tools/ModIt/Preferences/settingsFile.ini
@@ -1,2 +1,2 @@
[General]
-windowGeometry=@ByteArray(\x1\xd9\xd0\xcb\0\x3\0\0\0\0\x4V\0\0\0q\0\0\x5\xa9\0\0\x3\x37\0\0\x4V\0\0\0\x90\0\0\x5\xa9\0\0\x3\x37\0\0\0\0\0\0\0\0\a\x80\0\0\x4V\0\0\0\x90\0\0\x5\xa9\0\0\x3\x37)
+windowGeometry=@ByteArray(\x1\xd9\xd0\xcb\0\x3\0\0\0\0\x1\x86\0\0\0\x84\0\0\x2\xd9\0\0\x3\x36\0\0\x1\x86\0\0\0\xa3\0\0\x2\xd9\0\0\x3\x36\0\0\0\0\0\0\0\0\a\x80\0\0\x1\x86\0\0\0\xa3\0\0\x2\xd9\0\0\x3\x36)
diff --git a/2025/scripts/modeling_tools/ModIt/Setting/Layout_SETTING.py b/2025/scripts/modeling_tools/ModIt/Setting/Layout_SETTING.py
index fcabdb6..e6de787 100644
--- a/2025/scripts/modeling_tools/ModIt/Setting/Layout_SETTING.py
+++ b/2025/scripts/modeling_tools/ModIt/Setting/Layout_SETTING.py
@@ -1,18 +1,22 @@
##--------------------------------------------------------------------------
-try:
- from PySide6 import QtWidgets, QtCore, QtGui
- from PySide6.QtWidgets import *
- from PySide6.QtGui import *
- from PySide6.QtCore import *
- from shiboken6 import wrapInstance
+# Import Qt from project's unified Qt.py module
+import sys as _sys
+import os as _os
-except ImportError:
- from PySide2 import QtWidgets, QtCore, QtGui
- from shiboken2 import wrapInstance
- from PySide2.QtGui import QIcon
- from PySide2.QtWidgets import QWidget
- import shiboken2
+# Add parent scripts directory to sys.path
+_modit_dir = _os.path.dirname(_os.path.abspath(__file__))
+_scripts_dir = _modit_dir
+while _os.path.basename(_scripts_dir) != 'scripts' and _scripts_dir != _os.path.dirname(_scripts_dir):
+ _scripts_dir = _os.path.dirname(_scripts_dir)
+if _scripts_dir not in _sys.path:
+ _sys.path.insert(0, _scripts_dir)
+from Qt import QtWidgets, QtCore, QtGui, QtCompat
+
+# Use QtCompat for cross-version compatibility
+wrapInstance = QtCompat.wrapInstance
+QIcon = QtGui.QIcon
+QWidget = QtWidgets.QWidget
from maya import cmds as mc
import json
diff --git a/2025/scripts/modeling_tools/ModIt/Shading/Layout_SHADING.py b/2025/scripts/modeling_tools/ModIt/Shading/Layout_SHADING.py
index 2a4da7a..c0a5d19 100644
--- a/2025/scripts/modeling_tools/ModIt/Shading/Layout_SHADING.py
+++ b/2025/scripts/modeling_tools/ModIt/Shading/Layout_SHADING.py
@@ -1,20 +1,22 @@
##--------------------------------------------------------------------------
-try:
- from PySide6 import QtWidgets, QtCore, QtGui
- from PySide6.QtWidgets import *
- from PySide6.QtGui import *
- from PySide6.QtCore import *
- from shiboken6 import wrapInstance
-
-except ImportError:
- from PySide2 import QtWidgets, QtCore, QtGui
- from shiboken2 import wrapInstance
- from PySide2.QtGui import QIcon
- from PySide2.QtWidgets import QWidget
- import shiboken2
+# Import Qt from project's unified Qt.py module
+import sys as _sys
+import os as _os
+# Add parent scripts directory to sys.path
+_modit_dir = _os.path.dirname(_os.path.abspath(__file__))
+_scripts_dir = _modit_dir
+while _os.path.basename(_scripts_dir) != 'scripts' and _scripts_dir != _os.path.dirname(_scripts_dir):
+ _scripts_dir = _os.path.dirname(_scripts_dir)
+if _scripts_dir not in _sys.path:
+ _sys.path.insert(0, _scripts_dir)
+from Qt import QtWidgets, QtCore, QtGui, QtCompat
+# Use QtCompat for cross-version compatibility
+wrapInstance = QtCompat.wrapInstance
+QIcon = QtGui.QIcon
+QWidget = QtWidgets.QWidget
from maya import cmds as mc
import maya.mel as mel
import json
diff --git a/2025/scripts/modeling_tools/ModIt/Tools/ModIt_Bend_UI.py b/2025/scripts/modeling_tools/ModIt/Tools/ModIt_Bend_UI.py
index 30147dd..09fa56f 100644
--- a/2025/scripts/modeling_tools/ModIt/Tools/ModIt_Bend_UI.py
+++ b/2025/scripts/modeling_tools/ModIt/Tools/ModIt_Bend_UI.py
@@ -5,20 +5,24 @@
## LastUpdate : 2022/13/09
## Version : 0.0.1
##-------------------------------------------------------------------------- I M P O R T
-try:
- from PySide6 import QtWidgets, QtCore, QtGui
- from PySide6.QtWidgets import *
- from PySide6.QtGui import *
- from PySide6.QtCore import *
- from shiboken6 import wrapInstance
+# Import Qt from project's unified Qt.py module
+import sys as _sys
+import os as _os
-except ImportError:
- from PySide2 import QtWidgets, QtCore, QtGui
- from shiboken2 import wrapInstance
- from PySide2.QtGui import QIcon
- from PySide2.QtWidgets import QWidget
- import shiboken2
+# Add parent scripts directory to sys.path
+_modit_dir = _os.path.dirname(_os.path.abspath(__file__))
+_scripts_dir = _modit_dir
+while _os.path.basename(_scripts_dir) != 'scripts' and _scripts_dir != _os.path.dirname(_scripts_dir):
+ _scripts_dir = _os.path.dirname(_scripts_dir)
+if _scripts_dir not in _sys.path:
+ _sys.path.insert(0, _scripts_dir)
+from Qt import QtWidgets, QtCore, QtGui, QtCompat
+
+# Use QtCompat for cross-version compatibility
+wrapInstance = QtCompat.wrapInstance
+QIcon = QtGui.QIcon
+QWidget = QtWidgets.QWidget
from maya import cmds as mc
from maya import OpenMayaUI as omui
diff --git a/2025/scripts/modeling_tools/ModIt/Tools/ModIt_DupCurve_UI.py b/2025/scripts/modeling_tools/ModIt/Tools/ModIt_DupCurve_UI.py
index 8cd4997..63416cc 100644
--- a/2025/scripts/modeling_tools/ModIt/Tools/ModIt_DupCurve_UI.py
+++ b/2025/scripts/modeling_tools/ModIt/Tools/ModIt_DupCurve_UI.py
@@ -5,21 +5,24 @@
## LastUpdate : 2022/13/09
## Version : 0.0.1
##-------------------------------------------------------------------------- I M P O R T
-try:
- from PySide6 import QtWidgets, QtCore, QtGui
- from PySide6.QtWidgets import *
- from PySide6.QtGui import *
- from PySide6.QtCore import *
- from shiboken6 import wrapInstance
+# Import Qt from project's unified Qt.py module
+import sys as _sys
+import os as _os
-except ImportError:
- from PySide2 import QtWidgets, QtCore, QtGui
- from shiboken2 import wrapInstance
- from PySide2.QtGui import QIcon
- from PySide2.QtWidgets import QWidget
- import shiboken2
+# Add parent scripts directory to sys.path
+_modit_dir = _os.path.dirname(_os.path.abspath(__file__))
+_scripts_dir = _modit_dir
+while _os.path.basename(_scripts_dir) != 'scripts' and _scripts_dir != _os.path.dirname(_scripts_dir):
+ _scripts_dir = _os.path.dirname(_scripts_dir)
+if _scripts_dir not in _sys.path:
+ _sys.path.insert(0, _scripts_dir)
+from Qt import QtWidgets, QtCore, QtGui, QtCompat
+# Use QtCompat for cross-version compatibility
+wrapInstance = QtCompat.wrapInstance
+QIcon = QtGui.QIcon
+QWidget = QtWidgets.QWidget
from maya import cmds as mc
from maya import OpenMayaUI as omui
##---------------------------------------- Import Modules
diff --git a/2025/scripts/modeling_tools/ModIt/Tools/ModIt_DupLinear_UI.py b/2025/scripts/modeling_tools/ModIt/Tools/ModIt_DupLinear_UI.py
index 63a0f67..ed6549e 100644
--- a/2025/scripts/modeling_tools/ModIt/Tools/ModIt_DupLinear_UI.py
+++ b/2025/scripts/modeling_tools/ModIt/Tools/ModIt_DupLinear_UI.py
@@ -5,21 +5,24 @@
## LastUpdate : 2022/13/09
## Version : 0.0.1
##-------------------------------------------------------------------------- I M P O R T
-try:
- from PySide6 import QtWidgets, QtCore, QtGui
- from PySide6.QtWidgets import *
- from PySide6.QtGui import *
- from PySide6.QtCore import *
- from shiboken6 import wrapInstance
+# Import Qt from project's unified Qt.py module
+import sys as _sys
+import os as _os
-except ImportError:
- from PySide2 import QtWidgets, QtCore, QtGui
- from shiboken2 import wrapInstance
- from PySide2.QtGui import QIcon
- from PySide2.QtWidgets import QWidget
- import shiboken2
+# Add parent scripts directory to sys.path
+_modit_dir = _os.path.dirname(_os.path.abspath(__file__))
+_scripts_dir = _modit_dir
+while _os.path.basename(_scripts_dir) != 'scripts' and _scripts_dir != _os.path.dirname(_scripts_dir):
+ _scripts_dir = _os.path.dirname(_scripts_dir)
+if _scripts_dir not in _sys.path:
+ _sys.path.insert(0, _scripts_dir)
+from Qt import QtWidgets, QtCore, QtGui, QtCompat
+# Use QtCompat for cross-version compatibility
+wrapInstance = QtCompat.wrapInstance
+QIcon = QtGui.QIcon
+QWidget = QtWidgets.QWidget
from maya import cmds as mc
from maya import OpenMayaUI as omui
##---------------------------------------- Import Modules
diff --git a/2025/scripts/modeling_tools/ModIt/Tools/ModIt_DupRadial_UI.py b/2025/scripts/modeling_tools/ModIt/Tools/ModIt_DupRadial_UI.py
index ecc57c4..7137b57 100644
--- a/2025/scripts/modeling_tools/ModIt/Tools/ModIt_DupRadial_UI.py
+++ b/2025/scripts/modeling_tools/ModIt/Tools/ModIt_DupRadial_UI.py
@@ -5,21 +5,24 @@
## LastUpdate : 2022/13/09
## Version : 0.0.1
##-------------------------------------------------------------------------- I M P O R T
-try:
- from PySide6 import QtWidgets, QtCore, QtGui
- from PySide6.QtWidgets import *
- from PySide6.QtGui import *
- from PySide6.QtCore import *
- from shiboken6 import wrapInstance
+# Import Qt from project's unified Qt.py module
+import sys as _sys
+import os as _os
-except ImportError:
- from PySide2 import QtWidgets, QtCore, QtGui
- from shiboken2 import wrapInstance
- from PySide2.QtGui import QIcon
- from PySide2.QtWidgets import QWidget
- import shiboken2
+# Add parent scripts directory to sys.path
+_modit_dir = _os.path.dirname(_os.path.abspath(__file__))
+_scripts_dir = _modit_dir
+while _os.path.basename(_scripts_dir) != 'scripts' and _scripts_dir != _os.path.dirname(_scripts_dir):
+ _scripts_dir = _os.path.dirname(_scripts_dir)
+if _scripts_dir not in _sys.path:
+ _sys.path.insert(0, _scripts_dir)
+from Qt import QtWidgets, QtCore, QtGui, QtCompat
+# Use QtCompat for cross-version compatibility
+wrapInstance = QtCompat.wrapInstance
+QIcon = QtGui.QIcon
+QWidget = QtWidgets.QWidget
from maya import cmds as mc
from maya import OpenMayaUI as omui
diff --git a/2025/scripts/modeling_tools/ModIt/workspace_control.py b/2025/scripts/modeling_tools/ModIt/workspace_control.py
index 5dc8a24..e3ce4b4 100644
--- a/2025/scripts/modeling_tools/ModIt/workspace_control.py
+++ b/2025/scripts/modeling_tools/ModIt/workspace_control.py
@@ -1,19 +1,23 @@
import sys
-try:
- from PySide6 import QtWidgets, QtCore, QtGui
- from PySide6.QtWidgets import *
- from PySide6.QtGui import *
- from PySide6.QtCore import *
- from shiboken6 import wrapInstance
+# Import Qt from project's unified Qt.py module
+import sys as _sys
+import os as _os
-except ImportError:
- from PySide2 import QtWidgets, QtCore, QtGui
- from shiboken2 import wrapInstance
- from PySide2.QtGui import QIcon
- from PySide2.QtWidgets import QWidget
- import shiboken2
+# Add parent scripts directory to sys.path
+_modit_dir = _os.path.dirname(_os.path.abspath(__file__))
+_scripts_dir = _modit_dir
+while _os.path.basename(_scripts_dir) != 'scripts' and _scripts_dir != _os.path.dirname(_scripts_dir):
+ _scripts_dir = _os.path.dirname(_scripts_dir)
+if _scripts_dir not in _sys.path:
+ _sys.path.insert(0, _scripts_dir)
+from Qt import QtWidgets, QtCore, QtGui, QtCompat
+
+# Use QtCompat for cross-version compatibility
+wrapInstance = QtCompat.wrapInstance
+QIcon = QtGui.QIcon
+QWidget = QtWidgets.QWidget
import maya.OpenMayaUI as omui
import maya.cmds as cmds
diff --git a/2025/scripts/modeling_tools/gs_curvetools/LICENSE.txt b/2025/scripts/modeling_tools/gs_curvetools/LICENSE.txt
deleted file mode 100644
index e89f3e5..0000000
--- a/2025/scripts/modeling_tools/gs_curvetools/LICENSE.txt
+++ /dev/null
@@ -1,209 +0,0 @@
-"""
-GS CurveTools License:
-This collection of code named GS CurveTools is a property of George Sladkovsky (Yehor Sladkovskyi)
-and can not be copied or distributed without his written permission.
-
-GS CurveTools v1.3.11 Personal Edition
-Copyright 2025, George Sladkovsky (Yehor Sladkovskyi)
-All Rights Reserved
-
-UI font is Roboto that is licensed under the Apache 2.0 License:
-http://www.apache.org/licenses/LICENSE-2.0
-
-Autodesk Maya is a property of Autodesk, Inc:
-https://www.autodesk.com/
-
-Social Media and Contact Links:
-
-Discord Server: https://discord.gg/f4DH6HQ
-Online Store: https://sladkovsky3d.artstation.com/store
-Online Documentation: https://gs-curvetools.readthedocs.io/
-Twitch Channel: https://www.twitch.tv/videonomad
-YouTube Channel: https://www.youtube.com/c/GeorgeSladkovsky
-ArtStation Portfolio: https://www.artstation.com/sladkovsky3d
-Contact Email: george.sladkovsky@gmail.com
-"""
-
-https://www.artstation.com/marketplace-product-eula
-
-Marketplace Product & Services Agreement
-
-End User Agreement
-
-This Marketplace End User Agreement applies to all downloadable products and professional services (e.g. mentorships, personal training, portfolio reviews) sold via the ArtStation Marketplace, unless a custom agreement or license is provided by the seller.
-
-The EUA is an agreement between the buyer and the seller providing the goods or services.
-
-PLEASE READ THIS DOCUMENT CAREFULLY. IT SIGNIFICANTLY ALTERS YOUR LEGAL RIGHTS AND REMEDIES.
-
-BY CLICKING “I AGREE” OR DOWNLOADING OR USING THE DIGITAL PRODUCT OR RECEIVING THE PROFESSIONAL SERVICES TO WHICH THIS AGREEMENT RELATES YOU ACCEPT ALL OF THIS AGREEMENT’S TERMS, INCLUDING THE DISCLAIMERS OF WARRANTIES AND LIMITATIONS ON DAMAGES, USE AND TRANSFERABILITY. IF YOU DO NOT ACCEPT THIS AGREEMENT’S TERMS, DO NOT DOWNLOAD, INSTALL OR USE THE DIGITAL PRODUCT OR RECEIVE OR USE THE PROFESSIONAL SERVICES.
-
-This end-user agreement (“Agreement”) is a legally binding agreement between you, the licensee and customer (“you” or “your”), and the provider (“we” or “us” or “our”) of the digital products (“Products”) or instructional, training, mentorship or other professional service packages (“Professional Services”) that you purchase through the ArtStation Marketplace, regarding your rights and obligations regarding those Products and Professional Services.
-
-1. Your Status
-In this Agreement, “you” means the person or entity acquiring rights in the Products or purchasing Professional Services. That may be a natural person, or a corporate or business entity or organization.
-
-(a) If you are a natural person then you must be, and you confirm that you are, at least 13 years old. If you are between 13 years and the age of majority in your jurisdiction of residence, you confirm that your parent or legal guardian has reviewed and agrees to this Agreement and is happy for you to access and use the Product or receive the Professional Services.
-
-(b) If you are a corporate entity then: (i) the rights granted under this Agreement are granted to that entity; (ii) you represent and warrant that the individual completing and accepting this Agreement is an authorized your representative and has the authority to legally bind that you to the Agreement; and (iii) to the extent that one or more of your employees are granted any rights in the Product or to receive Professional Services under this Agreement, you will ensure that your employees comply with this Agreement and you will be responsible and liable for any breach of this Agreement by any employee.
-
-2. ArtStation
-ArtStation is a division of Epic Games, Inc., You acknowledge and agree that Epic is a third-party beneficiary of this Agreement and therefore will be entitled to directly enforce and rely upon any provision in this Agreement that confers a benefit on, or rights in favour of, Epic. In addition, you authorize Epic to act as your authorized representative to file a lawsuit or other formal action against a licensor in a court or with any other governmental authority if Epic knows or suspects that a licensor breached any representations or warranties under this Agreement. The foregoing authorization is nonexclusive, and Epic shall be under no obligation to pursue any claim. Epic will not initiate any such action on your behalf without first consulting with and obtaining your approval.
-
-Products
-The following sections 3 through 9 apply to any Products you acquire from us through the ArtStation Marketplace:
-
-3. Product Licence
-Subject to this Agreement’s terms and conditions, we hereby grant you a limited, non-exclusive, worldwide, non-transferable right and licence to (which will be perpetual unless the licence terminates as set out in this Agreement): (a) download the Product; and (b) copy and use the Product. We reserve all rights not expressly granted to you under this Agreement.
-
-4. Licence Scope and Restrictions
-(a) Tutorials
-You are purchasing ONE licence to create ONE copy of the Product for use by you only (or, if you are a corporate entity, for use by a single authorized employee).
-
-If this Product is bundled with a stock digital asset then you receive a limited personal use licence regarding that stock digital asset, and you may use that stock digital asset for your personal use only. You will not use that stock digital asset in any commercial manner unless you purchase a separate commercial licence.
-
-(b) Installable Tools
-You may purchase one or more licences for the Product. A single licence allows you to install the Product on a single computer at a time for use by a single authorized user. If you are a corporate entity and the authorized employee completing the transaction on your behalf purchases multiple licences, you may choose to store the Product on a single server or shared hard drive for use by a single authorized employee at a time for each licence purchased.
-
-Provided that you comply with the restrictions on users set out above, you may use the Product on an unlimited number of projects.
-
-(c) Stock Assets
-Subject to the restrictions set out in this Agreement, you may copy, use, modify, adapt, translate, distribute, publicly display, transmit, broadcast, and create derivative works from the Product in works you create (“Works”), which may include things like films, videos, multi-media projects, computer games, models, images, publications, broadcasts, documents, and presentations.
-
-If you are a corporate entity, you may make the Product available for use by your employees in accordance with this Agreement (for example, by storing the Product on a network server).
-
-You may only share the Product with external people or entities where:
-- You are collaborating with the external parties in the creation of your Work and you need to share the Product for that purpose, provided that any external party that receives the Product may only use it in your Work and must secure and limit access to the Product for that purpose;
-- You are working as a contractor for a client in the creation of a Work and need to share the Product with your client, or any external parties working with your client, provided that your client and any such external parties may use the Product only for your client’s Work, and all parties secure and limit access to the Product for that purpose.
-
-For any other use of the Product by any other party, that party must purchase a licence to the Product.
-
-In addition to any other restrictions in this Agreement, you will not:
-- publish, sell, license, offer or make available for sale or licensing, or otherwise distribute the Product except as part of a Work or through a form of sharing that is authorized in this Agreement; or
-- publish, distribute or make available the Product through any online clearinghouse platform.
-
-FURTHER SPECIFIC TERMS
-In addition to the restrictions set out above, the following terms and conditions apply to the following forms of commercial licences for the Product:
-
-Standard Commercial Licence
-If you have purchased a Standard Commercial licence then you may exercise your rights under that licence:
-- for personal use on an unlimited number of personal projects that are not used or distributed in any commercial manner; and
-- respect to one commercial Work, with up to a maximum of, as applicable, 2,000 sales of the Work or 20,000 monthly views of the Work.
-
-Extended Commercial Licence
-If you have purchased an Extended Commercial licence then you may exercise your rights under that licence:
-- for personal use on an unlimited number of personal projects that are not used or distributed in any commercial manner; and
-- with respect to any number of commercial Works, with no limit on sales or views.
-
-5. Additional Restrictions
-Except as expressly permitted under this Agreement, you will not:
-
-(a) make any copy of the Product except for archival or backup purposes;
-
-(b) circumvent or disable any access control technology, security device, procedure, protocol, or technological protection mechanism that may be included or established in or as part of the Product;
-
-(c) hack, reverse engineer, decompile, disassemble, modify or create derivative works of the Product or any part of the Product;
-
-(d) publish, sell distribute or otherwise make the Product available to others to use, download or copy;
-
-(e) transfer or sub-license the Product or any rights under this Agreement to any third party, whether voluntarily or by operation of law;
-
-(f) use the Product for any purpose that may be defamatory, threatening, abusive, harmful or invasive of anyone’s privacy, or that may otherwise violate any law or give rise to civil or other liability;
-
-(g) misrepresent yourself as the creator or owner of the Property;
-
-(h) remove or modify any proprietary notice, symbol or label in or on the Product;
-
-(i) directly or indirectly assist, facilitate or encourage any third party to carry on any activity prohibited by this Agreement.
-
-6. Proprietary Rights
-The Product is protected by copyright laws and international copyright treaties, as well as other intellectual property laws and treaties. You are licensing the Product and the right to access, install and use the Product in accordance with this Agreement, not buying the Product. As between you and us, we own all right, title and interest in and to the Product, and you are not acquiring any ownership of or rights in the Product except the limited rights granted under this Agreement.
-
-7. No Epic Support
-You acknowledge and agree that you are licensing the Product from us (the Provider), not from Epic, and that Epic has no obligation to support the Product.
-
-8. Interruptions and Errors
-Your use of the Product might be interrupted and might not be free of errors.
-
-9. Updates
-We have no obligation to update the Product.
-
-Professional Services
-The following sections 10 and 11 apply to any Professional Services you purchase from us through the ArtStation Marketplace:
-
-10. Provision of Professional Services
-We will provide the Professional Services directly to you and, subject to this Agreement, will assume all responsibility for all aspects of the Professional Services. We represent and warrant that we have the right to offer and provide the Professional Services and that we have appropriate qualifications and experience to provide the Professional Services.
-
-11. Epic is not Involved
-You acknowledge and agree that:
-
-(a) Epic is only a provider of the online ArtStation Marketplace where you purchased the Professional Services, and does not provide or exercise any control or oversight over us or the Professional Services, and is not responsible for us or the Professional Services or any shortcomings in them, including any damages, losses or legal issues caused by us or the Professional Services;
-
-(b) this Agreement (and any dispute under it) is an agreement between us and you only, and not with Epic, and Epic is not a party to this Agreement;
-
-(c) we are not Epic’s employee, agent or subcontractor;
-
-(d) Epic does not have any obligation to attempt to resolve any dispute between us and you; and
-
-(e) we will provide the Professional Services directly to you, and we (and not Epic) are solely responsible for the Professional Services, and Epic has no obligation or liability to you with respect to the Professional Services.
-
-Both Products and Services
-The following sections 12 through 25 apply to all Products or Services you purchase from us through the ArtStation Marketplace:
-
-12. Disclaimer
-ANY PRODUCTS OR PROFESSIONAL SERVICES ARE PROVIDED ON AN “AS IS” AND “AS AVAILABLE” BASIS, WITHOUT ANY REPRESENTATIONS, WARRANTIES OR CONDITIONS OF ANY KIND.
-
-TO THE FULLEST EXTENT PERMITTED BY APPLICABLE LAW WE DISCLAIM, AND YOU WAIVE (WITH REGARD TO US AND ALSO TO EPIC, ITS AFFILIATES, AND ITS AND THEIR LICENSORS AND SERVICE PROVIDERS (COLLECTIVELY, THE “EPIC PARTIES”), ALL TERMS, CONDITIONS, GUARANTEES, REPRESENTATIONS AND WARRANTIES (EXPRESS, IMPLIED, STATUTORY AND OTHERWISE), IN RESPECT OF THE PRODUCTS AND PROFESSIONAL SERVICES, INCLUDING THOSE OF MERCHANTABILITY, NON-INFRINGEMENT, TITLE, QUALITY AND FITNESS FOR A PARTICULAR PURPOSE.
-
-NEITHER WE NOR ANY OF THE EPIC PARTIES REPRESENT OR WARRANT THAT: (A) ANY PRODUCT OR PROFESSIONAL SERVICE IS ACCURATE, COMPLETE, RELIABLE, CURRENT OR ERROR-FREE; (B) ANY PRODUCT OR PROFESSIONAL SERVICE WILL MEET YOUR REQUIREMENTS OR EXPECTATIONS; (C) ANY PRODUCT OR PROFESSIONAL SERVICES IS FREE OF VIRUSES OR OTHER HARMFUL COMPONENTS; OR (D) ANY DEFECTS IN ANY PRODUCT OR PROFESSIONAL SERVICE WILL BE CORRECTED.
-
-13. Exclusion and Limitation of Liability
-(a) YOU DOWNLOAD, INSTALL AND OTHERWISE USE ALL PRODUCTS, AND RECEIVE AND USE ALL PROFESSIONAL SERVICES, AT YOUR OWN RISK. YOU AGREE TO, AND HEREBY DO:
-
-(i) WAIVE ANY CLAIMS THAT YOU MAY HAVE AGAINST US OR THE EPIC PARTIES OR OUR RESPECTIVE DIRECTORS, OFFICERS, EMPLOYEES, AGENTS, REPRESENTATIVES, LICENSORS, SUCCESSORS AND ASSIGNS (COLLECTIVELY THE “RELEASEES”) ARISING FROM OR RELATING TO ANY PRODUCTS OR PROFESSIONAL SERVICES, AND
-
-(ii) RELEASE THE RELEASEES FROM ANY LIABILITY FOR ANY LOSS, DAMAGE, EXPENSE OR INJURY ARISING FROM OR RELATING TO YOUR USE OF ANY PRODUCT OR PROFESSIONAL SERVICE, WHETHER ARISING IN TORT (INCLUDING NEGLIGENCE), CONTRACT OR OTHERWISE, EVEN IF THE RELEASEES ARE EXPRESSLY ADVISED OF THE POSSIBILITY OF SUCH LOSS, INJURY OR DAMAGE AND EVEN IF THAT LOSS, INJURY OR DAMAGE IS FORESEEABLE.
-
-(b) NEITHER WE NOR THE EPIC PARTIES WILL BE LIABLE FOR ANY LOSSES, DAMAGES, CLAIMS OR EXPENSES THAT CONSTITUTE: (I) LOSS OF INTEREST, PROFIT, BUSINESS, CUSTOMERS OR REVENUE; (II) BUSINESS INTERRUPTIONS; (III) COST OF REPLACEMENT PRODUCTS OR SERVICES; OR (IV) LOSS OF OR DAMAGE TO REPUTATION OR GOODWILL.
-
-(c) NEITHER WE NOR THE EPIC PARTIES WILL BE LIABLE FOR ANY LOSSES, DAMAGES, CLAIMS OR EXPENSES THAT CONSTITUTE INCIDENTAL, CONSEQUENTIAL, SPECIAL, PUNITIVE, EXEMPLARY, MULTIPLE OR INDIRECT DAMAGES, EVEN IF WE HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH LOSSES, DAMAGES, CLAIMS OR EXPENSES.
-
-(d) MAXIMUM LIABILITY: IF, DESPITE THE LIMITATIONS SET OUT ABOVE, WE OR ANY EPIC PARTY BECOME LIABLE TO YOU IN RESPECT OF ANY PRODUCT OR PROFESSIONAL SERVICE OR OTHERWISE UNDER THIS AGREEMENT, THE ENTIRE CUMULATIVE LIABILITY OF US AND THE EPIC PARTIES, AND YOUR EXCLUSIVE AND CUMULATIVE REMEDY, FOR ANY DAMAGES (REGARDLESS OF THE CAUSE OR FORM OR ACTION), WILL BE LIMITED TO CAD$10.
-
-14. Indemnity
-As a condition of your use of any Product or any Professional Services, you agree to hold harmless and indemnify the Releasees from any liability for any loss or damage to any third party resulting from your access to, installation or use of the Product or your receipt and use of the Professional Services.
-
-15. Term and Termination
-This Agreement is effective until terminated. Your rights under this Agreement will terminate automatically without notice if: (a) you breach any terms of this Agreement; or (b) you do not complete payment for the Product or Professional Services, or any payment you make is refunded, reversed or cancelled for any reason. Upon this Agreement’s termination, you will cease all use of the Product and destroy all copies, full or partial, of the Product in your possession. Sections 11 through 25 will survive the termination of this Agreement.
-
-16. Compliance with Laws
-You will comply with all applicable laws when using any Product or Professional Services (including intellectual property and export control laws).
-
-17. Entire Agreement
-This Agreement supersedes all prior agreements of the parties regarding the Product or Professional Services, and constitutes the whole agreement with respect to the Product or Professional Services.
-
-18. Disputes
-If you have any concerns about the Product or Professional Services, please contact us through our ArtStation Marketplace account and we will work with you to try to resolve the issue. You acknowledge and agree that any such dispute is between you and us, and that Epic will not be involved in the dispute and has no obligation to try to resolve the dispute.
-
-19. Persons Bound
-This Agreement will enure to the benefit of and be binding upon the parties and their heirs, executors, administrators, legal representatives, lawful successors and permitted assigns.
-
-20. Assignment
-We may assign this Agreement without notice to you. You may not assign this Agreement or any of your rights under it without our prior written consent, which we will not withhold unreasonably.
-
-21. Waiver
-No waiver, delay, or failure to act by us regarding any particular default or omission will prejudice or impair any of our rights or remedies regarding that or any subsequent default or omission that are not expressly waived in writing.
-
-22. Applicable Law and Jurisdiction
-You agree that this Agreement will be deemed to have been made and executed in the State of North Carolina, U.S.A., and any dispute will be resolved in accordance with the laws of North Carolina, excluding that body of law related to choice of laws, and of the United States of America. Any action or proceeding brought to enforce the terms of this Agreement or to adjudicate any dispute must be brought in the Superior Court of Wake County, State of North Carolina or the United States District Court for the Eastern District of North Carolina. You agree to the exclusive jurisdiction and venue of these courts. You waive any claim of inconvenient forum and any right to a jury trial. The Convention on Contracts for the International Sale of Goods will not apply. Any law or regulation which provides that the language of a contract shall be construed against the drafter will not apply to this Agreement.
-
-23. Legal Effect
-This Agreement describes certain legal rights. You may have other rights under the laws of your country. This Agreement does not change your rights under the laws of your country if the laws of your country do not permit it to do so.
-
-24. Interpretation
-In this Agreement, "we", "us", and "our" refer to the licensor of the Product alone and never refer to the combination of you and that licensor (that combination is referred to as "the parties"), or the combination of you or the licensor with Epic.
-
-25. Artificial Intelligence
-For purposes of this Agreement, “Generative AI Programs” means artificial intelligence, machine learning, deep learning, neural networks, or similar technologies designed to automate the generation of or aid in the creation of new content, including but not limited to audio, visual, or text-based content.
-
-We (the licensor of the Product) represent and warrant that where the Product was created using Generative AI Programs, we have applied the “CreatedWithAI” tag. Under this Agreement, a Product is considered to be created using Generative AI Programs where a material portion of a Product is generated with Generative AI Programs, whether characters, backgrounds, or other material elements. A Product is not considered to be created using Generative AI Programs merely for use of features that solely operate on a Product (e.g., AI-based upscaling or content-aware fill).
diff --git a/2025/scripts/modeling_tools/gs_curvetools/README.txt b/2025/scripts/modeling_tools/gs_curvetools/README.txt
deleted file mode 100644
index 95b782d..0000000
--- a/2025/scripts/modeling_tools/gs_curvetools/README.txt
+++ /dev/null
@@ -1,35 +0,0 @@
-GS CurveTools installation
-
-1. Copy gs_curvetools folder to {Path to Documents}\Documents\Maya\{Maya Version}\scripts\
-
- Example of the final folder structure:
-
- Documents\Maya\2022\scripts\gs_curvetools\fonts
- Documents\Maya\2022\scripts\gs_curvetools\icons
- Documents\Maya\2022\scripts\gs_curvetools\utils
- Documents\Maya\2022\scripts\gs_curvetools\__init__.py
- Documents\Maya\2022\scripts\gs_curvetools\core.py
- Documents\Maya\2022\scripts\gs_curvetools\init.py
- Documents\Maya\2022\scripts\gs_curvetools\LICENSE.txt
- Documents\Maya\2022\scripts\gs_curvetools\main.py
- Documents\Maya\2022\scripts\gs_curvetools\README.txt
-
-2. Run Maya
-
-3. Copy and paste this line to "Python" command box and press "Enter":
-
-import gs_curvetools.init as ct_init;from imp import reload;reload(ct_init);ct_init.Init();
-
-IMPORTANT: There should be no spaces or tabs before this command!
-
-4. Look for GS tab on your Shelf
-
-5. Click CT UI button to run the menu. Click again to hide the menu.
-
-NOTES:
->> To reset to factory defaults click CT with "refresh" arrow button.
->> To stop all scripts and close the menu press CT DEL button.
->> You can use middle-mouse button drag to move the buttons to any tab.
->> All the hotkeys are available in Hotkey Editor > Custom Scripts > GS > GS_CurveTools.
->> Always repeat initialization steps when updating the plug-in to a new version.
->> You can always repeat initialization steps if you lost control buttons or shelf.
diff --git a/2025/scripts/modeling_tools/gs_curvetools/core/tooltips.md b/2025/scripts/modeling_tools/gs_curvetools/core/tooltips.md
deleted file mode 100644
index e1b7897..0000000
--- a/2025/scripts/modeling_tools/gs_curvetools/core/tooltips.md
+++ /dev/null
@@ -1,967 +0,0 @@
-
-
-
-
-
-# importCurves
-Imports Curves that were Exported using the Export Button.
-NOTE: Only import files that were exported using Export Curves button.
-WARNING: This operation is NOT undoable!
-
-# exportCurves
-Exports selected curves into a .curves (or .ma) file. Can then be Imported using Import Curves.
-
-# changeScaleFactor
-Opens a window that controls the Scale Factor and Precision Scale.
-***
-Scale factor determines the initial size of the created curve and adjusts other parameters.
-Scale factor is stored in a global preset, in the scene and on each curve.
-Priority of scale factors Curve>Scene>Global.
-Setting the appropriate scale factor before starting a project can help to have a good initial Width and size of the cards.
-***
-Precision Scale controls the world scale of the curve without changing the curve appearance, CV positions and other parameters.
-Lowering the Precision scale (from 1.0 to 0.05 for example) helps to fix the geometry deformation on very small curves.
-The default value of 0.05 should be sufficient for most cases. Values lower than 0.01 can affect performance.
-***
-Normalize Selected and Normalize Selected to Default will change the Scale Factor and Precision Scale of the selected curves, without changing their appearance or CV positions.
-Normalize Selected to Default will reset the slider values to default (0.5 and 0.05) and Normalize Selected will use the current slider values.
-
-# normalizeSelectedButton
-Normalize selected curves to the chosen slider values.
-Normalization will not change the CV positions or geometry appearance, but the selected objects will have new Scale Factor and Precision Scale applied.
-
-# normalizeSelectedToDefaultButton
-Normalize selected curves to the default slider values (0.5, 0.05).
-Resets the slider values to the default.
-Normalization will not change the CV positions or geometry appearance, but the selected objects will have new Scale Factor and Precision Scale applied.
-
-# saveScaleFactorAndPrecisionScaleButton
-Saves the selected slider values to the global storage and to the current scene.
-New scenes will automatically have these Scale Factor and Precision Scale values.
-NOTE: This will not apply the new values to already existing objects. See Normalize buttons.
-
-# saveScaleFactorAndPrecisionScaleButtonAndClose
-Saves the selected slider values to the global storage and to the current scene.
-New scenes will automatically have these Scale Factor and Precision Scale values.
-Closes the window after save.
-NOTE: This will not apply the new values to already existing objects. See Normalize buttons.
-
-# closePrecisionScaleWindow
-Close this window without save
-
-# globalCurveThickness
-Opens a window that controls the thickness of the curves in the scene as well as the global curve thickness preset across the scenes.
-
-# setAOSettings
-Manually sets the recommended AO settings for older Maya versions.
-These AO settings are needed to use the "See Through" or "Toggle Always on Top" functions.
-Are applied automatically by those functions.
-
-# setTransparencySettings
-Sets recommended transparency settings for Maya viewport.
-***
-Simple Transparency is fast but very inaccurate render mode. Only suitable for simple, one layer hair.
-Object Sorting Transparency has average performance impact and quality. Can have issues on complex multi-layered grooms.
-Depth Transparency - these are the optimal settings for the highest quality of the hair cards preview. Can have performance impact on slower systems.
-
-# convertToWarpCard
-Converts selection to Warp Cards.
-Compatible attributes are retained.
-
-# convertToWarpTube
-Converts selection to Warp Tubes.
-Compatible attributes are retained.
-
-# convertToExtrudeCard
-Converts selection to Extrude Cards.
-Compatible attributes are retained.
-
-# convertToExtrudeTube
-Converts selection to Extrude Tubes.
-Compatible attributes are retained.
-
-# duplicateUnparentCurves
-Duplicates selected NURBS curves and unparents them (parents them to the world).
-Original curves are not deleted.
-Can be used to easily extract and export curves from GS CurveTools objects.
-
-# syncCurveColor
-Toggles the syncing of the curve color to the layer color.
-
-# colorizedRegroup
-Toggles the colorization of the regrouped layers when Regroup by Layer function is used.
-
-# colorOnlyDiffuse
-Colorize only the diffuse component of the card material.
-Alpha will stay the same.
-
-# checkerPattern
-Toggles the use of the checker pattern when the Color mode is enabled.
-
-# ignoreLastLayer
-Toggles the filtering (All, Curve, Geo) and Extraction (Extract All) of the last layer. If enabled, the last layer is ignored.
-NOTE: Last layer is typically used for templates, so it is ignored by default.
-
-# ignoreTemplateCollections
-Ignores the filtering (All, Curve, Geo) and Extraction (Extract All) of all the collections that have "template" in their name. Case insensitive.
-
-# groupTemplateCollections
-Collections that have "template" in their name (case insensitive) will be grouped together into "CT_Templates" group by Regroup By Layer function.
-
-# syncOutlinerLayerVis
-Syncs the outliner and layer visibility. If enabled, hiding the layer will also hide the curve groups in the outliner.
-
-# keepCurveAttributes
-If enabled, the attributes that are stored in the curve will be restored if the curve that was duplicated (on its own, without the geo) is used to create other cards or tubes.
-If disabled, the attributes will be ignored and reset.
-Example:
-1. Create a card and change its twist value.
-2. Ctrl+D and Shift+P the curve (not the curve group).
-3. Click Curve Card and the twist value will be restored on a newly created card.
-
-# boundCurvesFollowParent
-Will ensure that moving a parent curve in a Bound Object (Bound Group) will also move all the child curves along with it to a new layer. Recommended to keep this enabled.
-
-# massBindOption
-Will bind selected hair clump (or geometry) to all selected "empty" curves.
-
-# bindDuplicatesCurves
-Will automatically duplicate the curves before binding them to the curve, leaving old curves behind with no edits.
-
-# bindFlipUVs
-Enabling this option will flip the UVs of the original cards before binding them to the curve.
-This option will also flip the UVs back when using Unbind for better workflow.
-Disabling this option will result in an old Bind/Unbind behaviour.
-
-# unpackDeleteOriginalObject
-Unpack (Shift + Click on Unbind) will delete the original Bind object.
-
-# unpackCVMatch
-Unpack (Shift + Click on Unbind) will match the CVs of the original Bind object.
-
-# addBetweenBlendAttributes
-Enables blending of the attributes when using Add Cards/Tubes or Fill functions.
-
-# fillCreateCurvesOnly
-When enabled Fill function will only create curves (not the geo).
-
-# convertInstances
-Will automatically convert instanced curves to normal curves before any other function is applied.
-
-# replacingCurveLayerSelection
-Will disable additive selection for the layers. When holding Ctrl and clicking on a new layer, old layer will be deselected automatically.
-
-# useAutoRefineOnNewCurves
-Automatically enables auto-refine on the new curves.
-
-# flipUVsAfterMirror
-Enabling this option will flip the UVs horizontally after mirroring the cards to achieve exact mirroring.
-
-# enableTooltips
-Will toggle the visibility of these tooltips you are reading right now.
-
-# showLayerCollectionsMenu
-Shows layer collections menu widget.
-
-# importIntoANewCollection
-If enabled, all the imported curves will be placed into a new "Imported Curves" layer collection.
-If disabled, all the imported curves will be placed into the "Main" layer collection
-
-# layerNumbersOnly
-Layers will use only numbers if enabled.
-
-# convertToNewLayerSystem
-Converts all the layers in the scene to a new layer system that is hidden from the Channel Box Display Layers window.
-Layers can still be accessed from Window->Relationship Editors->Display Layer window.
-
-# updateLayers
-Utility function that will manually update all layers. Used for if layers are correct for some reason.
-
-# resetToDefaults
-Resets every option and the GS CurveTools to the default "factory" state.
-
-# maya2020UVFix
-This function will fix any broken UVs when trying to open old scenes in Maya 2020 or 2022 or when opening scenes in 2020 and 2022 when using Maya Binary file type. This will have no effect on older versions of Maya (<2020). This bug is native to Maya and thus can’t be fixed in GS CurveTools plug-in.
-
-# mayaFixBrokenGraphs
-This function will attempt to fix all the broken graphs in the scene.
-Use if one of the graphs (Width, Twist or Profile) is in a broken state.
-
-# convertBezierToNurbs
-Converts the selected Bezier curves to NURBS curves.
-Bezier curves are not supported by the GS CurveTools.
-
-# maya2020TwistAttribute
-This function will fix any broken cards created in Maya 2020.4 before v1.2.2 update.
-
-# maya2020UnbindFix
-This function will fix any cards that are not unbinding properly and were created before v1.2.3 update in Maya 2020.4.
-
-# deleteAllAnimationKeys
-This function will delete all the animation keys on all the curves present in the scene.
-This can fix deformation issues when using duplicate or other GS CurveTools functions.
-Some functions (like duplicate) will delete the keys automatically, however the keys can still cause issues.
-
-
-
-# warpSwitch
-Advanced cards and tubes suitable for longer hair.
-Additional options and controls.
-Slower than Extrude (viewport performance).
-Can have issues on very small scales.
-
-# extrudeSwitch
-Simple cards and tubes suitable for shorter hair and brows.
-Has limited controls.
-Much faster than Warp (viewport performance).
-Better for small scales.
-
-# newCard
-Creates a new Card in the middle of the world. Used at the beginning of the project to create templates.
-
-# newTube
-Creates a new Tube in the middle of the world. Used at the beginning of the project to create templates.
-
-# curveCard
-Converts selected Maya curve to CurveTools Card.
-
-# curveTube
-Converts selected Maya curve to CurveTools Tube.
-
-# gsBind
-Binds selection to a single curve. Creates a Bind Group. Selection options:
-1. Single "empty" curve (default Maya curve) and single combined geometry.
-2. Single "empty" curve (default Maya curve) and any number of Curve Cards and Curve Tubes.
-***
-Shift + Click will duplicate the original curves/geo before binding it to the empty curve.
-Same option is available in the Options menu (Duplicate Curves Before Bind).
-
-# gsUnbind
-Normal Click:
-UnBinds geometry or Cards/Tubes from selected Bound object.
-Geometry and Cards/Tubes will be placed at the origin.
-***
-Shift + Click:
-Will UNPACK the selected Bind object in-place.
-Unpack will attempt to create an in-place approximation of the cards and tubes that Bind object consists of.
-Basically it will extract the geometry and create cards (or tubes) based on that geometry.
-The original Bind object will be deleted in the process. Optionally, you can keep it (toggle in the options menu).
-This operation is not procedural, so you will not be able to return back to the Bind object after (unlike regular UnBind).
-WARNING: Unpack is not a 1 to 1 conversion. It will try its best to approximate the shape, but complex twists and bends will not be captured.
-
-# addCards
-Creates Cards in-between selected Cards based on the Add slider value.
-Shift + Click: creates objects but does not blend the attributes.
-Bound objects are NOT supported.
-
-NOTE: Selection order defines the direction of added Cards if more than 2 initial Cards are selected.
-
-# addTubes
-Creates Tubes in-between selected Tubes based on the Add slider value.
-Shift + Click: creates objects but does not blend the attributes.
-Bound objects are NOT supported.
-
-NOTE: Selection order defines the direction of added Tubes if more than 2 initial Tubes are selected.
-
-# gsFill
-Creates Cards/Tubes or Bound Groups in between selected Cards/Tubes or Bound Groups based on the Add slider value.
-Shift + Click: creates objects but does not blend the attributes.
-
-NOTE 1: Selection order defines the direction of added curves if more than 2 initial curves are selected.
-NOTE 2: The type of Card or Tube or Bound Group is defined by the previous curve in the selection chain.
-NOTE 3: Options -> Fill Creates Only Curves option will make the Fill function create only NURBS curves, but not the geo.
-
-# gsSubdivide
-Subdivides selected curve into multiple curves based on the Add slider value
-Shift + Click subdivides selected curve but does not delete the original curve
-
-# gsEdgeToCurve
-Converts selected geometry edges to curves.
-Multiple unconnected edge groups can be selected at the same time.
-***
-Key Combinations:
-Shift + Click will create a curve without the curvature (first degree curve or simply a line)
-
-# gsGeoToCurve
-Opens the Geo-to-Curve UI
-Geo to Curve algorithm will attempt to generate GS CurveTools cards and tubes from selected geometry.
-Selected geometry should be either one-sided cards or regular tubes without caps (or both).
-Multi-selection compatible, but selected geometries should be separate objects and not one combined object.
-
-# layerCollectionsComboBox
-Layer collections drop-down menu.
-Allows to separate the project into different layer collections, up to 80 layers in each collection.
-Has additional functionality in marking menu (Hold RMB):
-***
-Marking menu:
-1. Clear - will delete all the cards from the current layer. Undoable operation.
-2. Merge Up, Merge Down - merge all the cards from the current layer to the layer above or below it.
-3. Copy, Paste - will copy all the cards from the current layer and paste them to the layer that user selects.
-4. Move Up, Move Down - will rearrange the current layer collections by moving the currently selected collection up or down in the list.
-5. Rename - will rename the current layer collection
-
-# layerCollectionsPlus
-Add additional layer collection after the current one.
-
-# layerCollectionsMinus
-Remove current layer collection. All the cards from the removed collection will be merged one layer UP.
-
-# gsAllFilter
-Layer filter. Controls the visibility of all objects in all layers:
-Normal click will show all curves and geometry in all layers.
-Shift + Click will hide all curves and geometry in all layers
-Ctrl + Click will show all the curves and geometry in all layers and all collections.
-Ctrl + Shift + Click will hide all curves and geometry in all layers and all collections.
-
-# gsCurveFilter
-Layer filter. Hides all geometry and shows all the curves in all layers.
-Ctrl + Click will do the same thing, but for all layers and all collections.
-NOTE: Holding RMB will open a marking menu with Toggle Always on Top function as well as "Auto-Hide Inactive Curves" function.
-Toggle Always on Top function will toggle the Always on Top feature that will show the curve component always on top. The effect is different in different Maya versions
-Auto-Hide Inactive Curves will hide all the curve components on all inactive layer collections when switching between collections.
-
-# gsGeoFilter
-Layer filter. Hides all curves and shows only geometry.
-Ctrl + Click will do the same thing, but for all layers and all collections.
-
-# colorMode
-Color mode toggle. Enables colors for each layer and (optionally) UV checker material.
-NOTE: Checker pattern can be disabled in the Options menu
-
-# curveGrp0
-Curve Layers that are used for organization of the cards and tubes in the scene.
-Selected layer (white outline) will be used to store newly created cards.
-Holding RMB will open a marking menu with all the functions of current layer.
-***
-Key Combinations:
-Shift + Click: additively select the contents of the layers.
-Ctrl + Click: exclusively select the contents of the layer.
-Alt + Click: show/hide selected layer.
-Ctrl + Shift: show/hide curve component on selected layer.
-Ctrl + Alt: show/hide geo component for the selected layer.
-Shift + Alt + Click: isolate select the layer.
-Shift + Ctrl + Alt + Click: enable Always on Top for each layer (only for Maya 2022+).
-***
-Layer MMB Dragging:
-MMB + Drag: move the contents of one layer to another layer. Combine if target layer has contents.
-MMB + Shift + Drag: copy the contents of one layer to another layer. Copy and Add if target layer has contents.
-
-# gsExtractSelected
-Extracts (Duplicates) the geometry component from the selected curves:
-***
-Key Combinations:
-Normal click will extract geometry and combine it.
-Shift + Click will extract geometry as individual cards.
-Ctrl + Click will extract geometry, combine it, open export menu and delete the extracted geo after export.
-Shift + Ctrl click will extract geometry, open export menu and delete the extracted geo after export.
-
-# gsExtractAll
-Extracts (Duplicates) the geometry component from all layers and collections. Original layers are HIDDEN, NOT deleted:
-Last Layer in the current Collection is ignored by default. Can be changed in the options.
-Collections with "template" in their name (case insensitive) will be ignored by default. Can be changed in the options.
-***
-Key Combinations:
-Normal click will extract geometry and combine it.
-Shift + Click will extract geometry as individual cards grouped by layers.
-Ctrl + Click will extract geometry, combine it, open export menu and delete the extracted geo after export.
-Shift + Ctrl click will extract geometry, open export menu and delete the extracted geo after export.
-
-# gsSelectCurve
-Selects the curve components of the selected Curve Cards/Tubes.
-NOTE: Useful during the selection in the outliner.
-
-# gsSelectGeo
-Selects the geometry component of the selected Curve Cards/Tubes.
-NOTE: Useful for quick assignment of the materials.
-
-# gsSelectGroup
-Selects the group component of the selected Curve Cards/Tubes.
-NOTE: Useful when you are deleting curves from viewport selection.
-
-# gsGroupCurves
-Groups the selected curves and assigns the name from Group Name input field (or default name if empty).
-
-# gsRegroupByLayer
-Regroups all the curves based on their layer number, group names and collection names.
-Group names can be changed in the Layer Names & Colors menu.
-Groups can be colorized if the "Colorize Regrouped Layers" is enabled in the Options menu.
-Collections with "template" in their name will be grouped under "CT_Templates". Can be changed in the options.
-
-# gsGroupNameTextField
-The name used by the Group Curves function.
-If empty, uses the default name.
-
-# gsCustomLayerNamesAndColors
-Opens a menu where group names and colors can be changed and stored in a global preset.
-
-# gsTransferAttributes
-Transfers attributes from the FIRST selected curve to ALL the other curves in the selection.
-NOTE: Shift + Click transfers the attributes from the LAST selected curve to ALL others.
-NOTE2: Holding RMB on this button opens a marking menu with Copy-Paste and Filter functionality
-
-# gsTransferUVs
-Transfers UVs from the FIRST selected curve to ALL the other curves in the selection.
-NOTE: Shift + Click transfers the UVs from the LAST selected curve to ALL others.
-NOTE2: Holding RMB on this button opens a marking menu with Copy-Paste and Filter functionality
-
-# gsResetPivot
-Resets the pivot on all selected curves to the default position (root CV).
-
-# gsRebuildWithCurrentValue
-Rebuild selected curves using current rebuild slider value
-
-# gsResetRebuildSliderRange
-Reset rebuild slider range (1 to 50)
-
-# gsDuplicateCurve
-Duplicates all the selected curves and selects them.
-NOTE: You can select either NURBS curve component, geometry component or group to duplicate.
-
-# gsRandomizeCurve
-Opens a window where different attributes of the selected curves can be randomized:
-1. Enable the sections of interest and change the parameters.
-2. Dragging the sliders in each section enables a PREVIEW of the randomization. Releasing the slider will reset the curves.
-3. Click Randomize if you wish to apply the current randomization.
-
-# gsExtendCurve
-Lengthens a selected curves based on the Factor slider.
-
-# gsReduceCurve
-Shortens the selected curves based on the Factor slider.
-
-# gsSmooth
-Smoothes selected curves or curve CVs based on the Factor slider.
-NOTE 1: At least 3 CVs should be selected for component smoothing.
-NOTE 2: Holding RMB will open a marking menu where you can select a stronger smoothing algorithm.
-
-# mirrorX
-Mirrors or Flips all the selected curves on the World X axis.
-
-# mirrorY
-Mirrors or Flips all the selected curves on the World Y axis.
-
-# mirrorZ
-Mirrors or Flips all the selected curves on the World Z axis.
-
-# gsControlCurve
-Adds a Control Curve Deformer to the selected curves. Can be used to adjust groups of curves.
-NOTE 1: Should NOT be used to permanently control clumps of cards. Use Bind instead.
-
-# gsApplyControlCurve
-Applies the Control Curve Deformer.
-Either the Control Curve or any controlled Curves can be selected for this to work.
-
-# gsCurveControlWindow
-Opens a Curve Control Window. Contains all the available controls for curves.
-
-# gsUVEditorMain
-Opens a UV editor that can be used to setup and adjust UVs on multiple cards.
-NOTE 1: Lambert material with PNG, JPG/JPEG or TIF/TIFF (LZW or No Compression) texture file is recommended. TGA (24bit and no RLE) is also supported.
-NOTE 2: Make sure to select the curves or the group, not the geo, to adjust the UVs.
-NOTE 3: Using default Maya UV editor will break GS CurveTools Cards, Tubes and Bound Groups.
-NOTE 4: Default UV editor can be used when custom geometry is used in a Bound Groups.
-
-
-
-
-# gsLayerSelector
-Shows the Layer of the selected curve.
-Selecting different layer will change the layer of all the selected curves.
-
-# gsColorPicker
-Layer/Card Color Picker.
-
-# gsCurveColorPicker
-Curve Color Picker.
-
-# selectedObjectName
-Selected object name. Editing this field will rename all the selected objects.
-
-# lineWidth
-Controls the thickness of the selected curves.
-
-# gsBindAxisAuto
-Automatic selection of the bind Axis (recommended).
-NOTE: Change to manual X, Y, Z axis if bind operation result is not acceptable.
-
-# AxisFlip
-Flips the direction of the bound geometry.
-
-# editOrigObj
-Temporarily disables curve bind and shows the original objects.
-Used to adjust the objects after the bind.
-To add or remove from the Bound group use Unbind.
-
-# selectOriginalCurves
-Selects the original curves that were attached to a bind curve.
-Allows to edit their attributes without using Unbind or Edit Original Objects
-
-# twistCurveFrame
-Advanced twist control graph. Allows for precise twisting of the geometry along the curve. Click to expand.
-
-# Magnitude
-Twist multiplier. The larger the values, the more the twist. Default is 0.5.
-
-# gsTwistGraphResetButton
-Resets the graph to the default state.
-
-# gsTwistGraphPopOut
-Opens a larger graph in a separate window that is synced to the main graph.
-
-# widthLockSwitch
-Links/Unlinks the X and Z width sliders.
-If linked, the sliders will move as one.
-
-# LengthLock
-Locks/Unlocks the length slider.
-When Locked the geometry is stretched to the length of the curve and the slider is ignored.
-
-# widthCurveFrame
-Advanced width control graph. Allows for precise scaling of the geometry along the curve. Click to expand.
-
-# gsWidthGraphResetButton
-Resets the graph to the default state.
-
-# gsWidthGraphPopOut
-Opens a larger graph in a separate window that is synced to the main graph.
-
-# profileCurveGraph
-Advanced control over the profile of the card. Modifies the profile applied by the Profile slider. Click to expand.
-Add or remove points and change them to increase or decrease the Profile value along the curve.
-
-# autoEqualizeSwitchOn
-Locks the points horizontally to equal intervals to avoid geometry deformation.
-
-# autoEqualizeSwitchOff
-Unlocks the points and allows for the full control.
-
-# equalizeCurveButton
-Snaps the points to the equal horizontal intervals.
-
-# gsResetProfileGraphButton
-Resets the curve to the default state.
-
-# gsProfileGraphPopOut
-Opens a larger graph in a separate window that is synced to the main graph.
-
-# reverseNormals
-Reverses the normals on the selected cards/tubes.
-
-# orientToNormalsFrame
-Orient selected cards/tubes to the normals of the selected geo.
-
-# gsOrientToNormalsSelectTarget
-Set selected mesh as a target for the algorithm.
-
-# orientRefreshViewport
-Toggles the viewport update during the alignment process.
-Disabling can speed up the process.
-
-# gsOrientToNormals
-Starts the alignment process.
-Will align the selected cards to the normals of the selected geometry.
-
-# flipUV
-Flips the UVs of the card/tube horizontally.
-
-# resetControlSliders
-Resets the range of the sliders to the default state.
-
-# UVFrame
-Legacy controls for the UVs. Just use the new UV Editor.
-
-# solidifyFrame
-Expands controls that control the thickness of the cards/tubes.
-
-# solidify
-Toggles the thickness of the geometry.
-
-
-
-# lengthDivisions
-Change the length divisions of the selected cards/tubes.
-
-# dynamicDivisions
-Toggles the dynamic divisions mode.
-Dynamic divisions will change the divisions of the cards/tubes based on the length of the curves.
-In dynamic divisions mode, L-Div slider will control the density of the divisions, not the fixed divisions count.
-
-# widthDivisions
-Change the width divisions of the selected cards/tubes.
-
-# Orientation
-Change the orientation of the card/tube around the curve.
-
-# Twist
-Smoothly twist the entire geometry card/tube. Twists the tip of the card.
-
-# invTwist
-Smoothly twist the entire geometry card. Twists the root of the card.
-
-# Width
-Change the width of the selected card.
-
-# Taper
-Linearly changes the width of the card/tube along the length of the curve.
-
-# WidthX
-Change the width of the tube along the X axis.
-
-# WidthZ
-Change the width of the tube along the Z axis.
-
-# Length
-Change the length of the attached geometry. Works only when Length Unlock button is checked.
-
-# Offset
-Offset the geometry along the curve.
-
-# Profile
-Change the profile of the card along the length of the curve uniformly.
-
-# profileSmoothing
-Smoothing will smooth the profile transition.
-
-# otherFrame
-Other less used options
-
-# curveRefine
-Controls the number of "virtual" vertices on the curve. These are the vertices that are used to calculate the geometry deformation.
-Zero (0) value will disable the refinement and the geometry will be attached directly to the curve. The fastest option.
-Larger refine values means smoother geometry that is a closer fit to the curve.
-Only increase past 20 if you need additional precision or if there are any visual glitches with the geometry.
-Large refine values can cause significant performance drop, lag and other issues on smaller curve sizes.
-Recommended values are:
-20 for curves with less than 20 CVs.
-0 (disabled) or same as the number of CVs for curves with more than 20 CVs.
-
-# autoRefine
-Enables auto-refine for selected curves. Recommended to keep this on.
-Manual refinement can be helpful if the geometry deformation is wrong or not precise enough.
-
-# samplingAccuracy
-Increases the sampling accuracy of the deformer that attaches the geometry to a curve.
-Larger values = more precise geometry fit to a curve and more lag.
-
-# surfaceNormals
-Changes the smoothing angle of the normals of the geometry.
-
-# gsIterationsSlider
-Controls the number of iterations per card.
-
-# gsMinimumAngle
-Controls the target angle difference between the normal of the mesh and the card.
-
-# solidifyThickness
-Controls the amount of thickness on the geometry.
-
-# solidifyDivisions
-Controls the number of divisions on the solidify extrusion.
-
-# solidifyScaleX
-Changes the scale on the X axis.
-
-# solidifyScaleY
-Changes the scale on the Y axis.
-
-# solidifyOffset
-Controls the offset of the solidify extrusion.
-
-# solidifyNormals
-Controls the smoothing angle for normals of the solidify extrusion.
-
-# geometryHighlight
-If enabled, selecting the curve will also highlight the geometry component that is attached to that curve.
-Works only on GS CurveTools curves and geo.
-
-# curveHighlight
-If enabled, selected curves and their components will be additionally highlighted for better visibility.
-The curves and components will be in X-Ray mode by default.
-Colors and transparency values can be changes in the menu below.
-
-# gsSelectedCVColor
-Selected CV highlight color
-
-# gsSelectedCVAlpha
-Selected CV highlight transparency (alpha)
-
-# gsDeselectedCVColor
-Deselected CV highlight color
-
-# gsDeselectedCVAlpha
-Deselected CV highlight transparency (alpha)
-
-# curveVisibility
-Toggle selected curves highlight
-
-# gsCurveHighlightColor
-Selected curve highlight color
-
-# gsCurveHighlightAlpha
-Selected curve highlight transparency (alpha)
-
-# hullVisibility
-Toggle hull visibility.
-Hull is a line that connects all the CVs on the curve.
-
-# gsHullHighlightColor
-Hull highlight color
-
-# gsHullHighlightAlpha
-Hull highlight transparency (alpha)
-
-# advancedVisibilityFrame
-Better highlights for selected curves and components.
-
-# lazyUpdate
-Enables lazy update for selected curves.
-Lazy update can slightly increase the performance of the highlight,
-however it has some visual drawbacks (curve highlight can fail to update when switching curves in component selection mode)
-
-# alwaysOnTop
-Toggles X-Ray (always on top) drawing for highlighted components.
-Disabling this defeats the purpose of the advanced visibility, but hey, it's your choice.
-
-# curveDistanceColor
-Toggles the distance color effect on the curve highlight.
-Distance color darkens the curve color the further it is from the camera.
-
-# cvDistanceColor
-Toggles the distance color effect on the CV highlight.
-Distance color darkens the CVs color the further it is from the camera.
-
-# hullDistanceColor
-Toggles the distance color effect on the hull highlight.
-Distance color darkens the hull color the further it is from the camera.
-
-# gsDistanceColorMinValue
-Distance color minimum.
-This value is the minimum allowed color multiplier for the Distance Color effect.
-The lower this value, the darker further parts of the curve will be.
-Black at 0.0
-Original color at 1.0
-
-# gsDistanceColorMaxValue
-Distance color maximum.
-This value is the maximum allowed color multiplier for the Distance Color effect.
-The higher this value, the brighter closest parts of the curve will be.
-Black at 0.0
-Original color at 1.0
-
-# CVocclusion
-Toggles the experimental CV occlusion mode (hull is affected as well)
-When the appropriate mesh name is added to Occluder Mesh input field,
-this function will automatically hide CVs and hull lines that are behind this mesh (even in X-Ray mode).
-Warning: enabling this mode can negatively impart viewport performance.
-
-# gsSelectOccluderButton
-This button adds the selected mesh name to the Occluder Mesh input field.
-
-# gsOccluderMeshName
-Type the full path for the occluder mesh here, or use the "Select Occluder" button on the left <-
-
-
-
-
-# gsGenerateLayerColorGradient
-Generate a color gradient for the layer colors.
-Rows control the number of Rows to generate.
-Left color picker sets the initial color.
-Right color picker sets the final color.
-
-# gsRandomizeLayerColors
-Generate random colors for the layers.
-SatMin controls the minimum allowed saturation.
-SatMax controls the maximum allowed saturation.
-
-# gsResetAllLayerColors
-Resets all the color swatches to the default color.
-
-# gsGetCurrentSceneLayers
-Populates the menu with the names and colors stored in the scene.
-
-# gsSetAsCurrentSceneLayers
-Applies the names and colors from the menu to the scene.
-
-# gsLoadGlobalLayerPreset
-Load the global names and colors preset to the menu.
-NOTE: Don't forget to Set to Scene before closing the menu.
-
-# gsSaveGlobalLayerPreset
-Saves the current names and colors from the menu to the global preset.
-
-
-
-# gsUVSelect
-Enables the selection of the UVs.
-Drag to draw a box selection.
-
-# gsUVMove
-Enables the Move tool.
-Move the selected UVs or move individual UVs if nothing is selected.
-
-# gsUVRotate
-Enables the Rotation of the selected UVs.
-Hold LMB and drag anywhere in the viewport to rotate the selected UVs.
-Rotation pivot is the center of the individual unscaled UV.
-
-# gsUVScale
-Enables the Scaling of the selected UVs.
-Hold LMB and drag in the viewport to scale the card Horizontally of Vertically.
-Repeated hotkey click will toggle between Horizontal and Vertical scaling.
-
-# gsUVHorizontalScale
-Horizontal scaling mode selector.
-
-# gsUVVerticalScale
-Vertical scaling mode selector.
-
-# gsDrawUVs
-Enables the UVs Drawing Tool:
-1. Select UVs using Selection Mode.
-2. Enable the UV Drawing Tool.
-3. Draw a UV Rectangle anywhere in the viewport to create/move the UVs there.
-
-# gsHorizontalFlipUV
-Flips the selected UVs horizontally.
-Flipped UVs have the blue circle indicator inside the root rectangle.
-
-# gsVerticalFlipUV
-Flips the selected UVs vertically.
-
-# gsResetUVs
-Resets the selected UVs to the default 0,1 rectangle.
-
-# gsSyncSelectionUVs
-Syncs selection between UV editor and Maya Viewport.
-
-# gsRandomizeUVs
-Randomize selected UV positions between already existing UV positions.
-***
-Normal click will keep the overall density distribution of the UVs.
-This means that if there is one card in one position and twenty cards in the other,
-it will keep this distribution of 1 to 20.
-***
-Shift+Click will ignore the original density distribution
-and simply randomize the UVs between the original positions.
-
-# gsFocusUVs
-Focuses on the selected UVs or on all the UVs if nothing is selected.
-
-# gsUVIsolateSelect
-Hides all the unselected UVs and shows only the selected ones.
-
-# gsUVShowAll
-Shows all the hidden UVs.
-
-# UVEditorUseTransforms
-Use "Coverage" and "Translate Frame" parameters from place2dTexture node for texture.
-Offset is not supported.
-Diffuse and Alpha channel MUST have the same coverage and translate frame values.
-
-# UVEditorTransparencyToggle
-Enable texture map transparency using Alpha map from Transparency plug in the material node
-
-# UVEditorBGColorPicker
-Background Color
-
-# UVEditorGridColorPicker
-Grid Color
-
-# UVEditorFrameColorPicker
-Frame Color
-
-# UVEditorUVFrameSelectedColorPicker
-Selected UV frame color
-
-# UVEditorUVFrameDeselectedColorPicker
-Deselected UV frame color
-
-# UVEditorUVCardFillColorPicker
-UV frame background color
-
-
-
-# gsGeoToCurve_outputTypeSwitch
-Controls the output of Geo-to-Curve algorithm
-
-# gsGeoToCurve_generateAuto
-Automatically determine the final object type (card or tube) based on the selected geometry.
-
-# gsGeoToCurve_generateCards
-Generate cards from selected geometry (one-sided cards or tubes)
-
-# gsGeoToCurve_generateTubes
-Generate tubes from selected geometry (one-sided cards or tubes)
-
-# gsGeoToCurve_generateCurves
-Generate curves from selected geometry (one-sided cards or tubes)
-
-# gsGeoToCurve_cardType
-Controls the type of generated objects (Warp or Extrude)
-
-# gsGeoToCurve_warp
-Generate Warp cards or tubes
-
-# gsGeoToCurve_extrude
-Generate Extrude cards or tubes
-
-# gsGeoToCurve_matchAttributes
-Controls which attributes on the new cards/tubes should be approximated from the original geometry.
-NOTE: This process is not perfect and final result can be inaccurate.
-
-# gsGeoToCurve_orientation
-Match orientation attribute during the generation process
-
-# gsGeoToCurve_width
-Match orientation attribute during the generation process
-
-# gsGeoToCurve_taper
-Match taper attribute during the generation process
-
-# gsGeoToCurve_twist
-Match twist attribute during the generation process
-
-# gsGeoToCurve_profile
-Match profile attribute during the generation process
-
-# gsGeoToCurve_material
-Copy material (shader) from the original geometry
-
-# gsGeoToCurve_UVs
-Tries to approximate the UVs from the original geometry
-NOTE: Matches the bounding box of the UVs. Rotated and deformed UVs are not matched precisely.
-
-# gsGeoToCurve_UVMatchOptions
-Controls UV matching behaviour
-
-# gsGeoToCurve_verticalFlip
-Vertically flip matched UVs
-
-# gsGeoToCurve_horizontalFlip
-Horizontally flip matched UVs
-
-# gsGeoToCurve_reverseCurve
-Reverse generated curve direction
-Root CV should be generated near the scalp of the model.
-Enable or disable if resulting card direction and taper are reversed.
-
-# gsGeoToCurve_convertSelected
-Convert selected geometry to cards, tubes or curves based on the selected options.
-Newly created procedural objects will be placed in the currently selected layer.
-NOTE: if the currently selected layer is hidden (grayed out), the newly created objects will be hidden as well.
-
-# gsGeoToCurve_deleteOriginalObject
-Delete the original geometry after converting it to cards, tubes or curves.
-
-# gsGeoToCurve_useAimMesh
-Use the aim mesh (selected below) to place the root CV of the generated cards, tubes or curves close to the target mesh.
-Placing CVs close to the target mesh will help with the alignment process and general adjustments later on.
-The aim mesh should be a polygonal mesh.
-
-# gsGeoToCurve_selectAimMesh
-Select the aim mesh in the scene and click this button to add its name to the input field.
diff --git a/2025/scripts/modeling_tools/gs_curvetools/fonts/Roboto-Bold.ttf b/2025/scripts/modeling_tools/gs_curvetools/fonts/Roboto-Bold.ttf
deleted file mode 100644
index 3742457..0000000
Binary files a/2025/scripts/modeling_tools/gs_curvetools/fonts/Roboto-Bold.ttf and /dev/null differ
diff --git a/2025/scripts/modeling_tools/gs_curvetools/fonts/Roboto-Italic.ttf b/2025/scripts/modeling_tools/gs_curvetools/fonts/Roboto-Italic.ttf
deleted file mode 100644
index c9df607..0000000
Binary files a/2025/scripts/modeling_tools/gs_curvetools/fonts/Roboto-Italic.ttf and /dev/null differ
diff --git a/2025/scripts/modeling_tools/gs_curvetools/fonts/Roboto-Regular.ttf b/2025/scripts/modeling_tools/gs_curvetools/fonts/Roboto-Regular.ttf
deleted file mode 100644
index 2b6392f..0000000
Binary files a/2025/scripts/modeling_tools/gs_curvetools/fonts/Roboto-Regular.ttf and /dev/null differ
diff --git a/2025/scripts/modeling_tools/gs_curvetools/icons/drop-down-arrow.png b/2025/scripts/modeling_tools/gs_curvetools/icons/drop-down-arrow.png
deleted file mode 100644
index 4452f34..0000000
Binary files a/2025/scripts/modeling_tools/gs_curvetools/icons/drop-down-arrow.png and /dev/null differ
diff --git a/2025/scripts/modeling_tools/gs_curvetools/icons/gsCurveToolsIcon_logo.png b/2025/scripts/modeling_tools/gs_curvetools/icons/gsCurveToolsIcon_logo.png
deleted file mode 100644
index 2dda8c9..0000000
Binary files a/2025/scripts/modeling_tools/gs_curvetools/icons/gsCurveToolsIcon_logo.png and /dev/null differ
diff --git a/2025/scripts/modeling_tools/gs_curvetools/icons/gsCurveToolsIcon_reset.png b/2025/scripts/modeling_tools/gs_curvetools/icons/gsCurveToolsIcon_reset.png
deleted file mode 100644
index a72f685..0000000
Binary files a/2025/scripts/modeling_tools/gs_curvetools/icons/gsCurveToolsIcon_reset.png and /dev/null differ
diff --git a/2025/scripts/modeling_tools/gs_curvetools/icons/gsCurveToolsIcon_reset_legacy.png b/2025/scripts/modeling_tools/gs_curvetools/icons/gsCurveToolsIcon_reset_legacy.png
deleted file mode 100644
index d40254d..0000000
Binary files a/2025/scripts/modeling_tools/gs_curvetools/icons/gsCurveToolsIcon_reset_legacy.png and /dev/null differ
diff --git a/2025/scripts/modeling_tools/gs_curvetools/icons/gsCurveToolsIcon_stop.png b/2025/scripts/modeling_tools/gs_curvetools/icons/gsCurveToolsIcon_stop.png
deleted file mode 100644
index 14be446..0000000
Binary files a/2025/scripts/modeling_tools/gs_curvetools/icons/gsCurveToolsIcon_stop.png and /dev/null differ
diff --git a/2025/scripts/modeling_tools/gs_curvetools/icons/gsCurveToolsIcon_stop_legacy.png b/2025/scripts/modeling_tools/gs_curvetools/icons/gsCurveToolsIcon_stop_legacy.png
deleted file mode 100644
index df5a67e..0000000
Binary files a/2025/scripts/modeling_tools/gs_curvetools/icons/gsCurveToolsIcon_stop_legacy.png and /dev/null differ
diff --git a/2025/scripts/modeling_tools/gs_curvetools/icons/gsCurveToolsIcon_ui.png b/2025/scripts/modeling_tools/gs_curvetools/icons/gsCurveToolsIcon_ui.png
deleted file mode 100644
index 5e0b410..0000000
Binary files a/2025/scripts/modeling_tools/gs_curvetools/icons/gsCurveToolsIcon_ui.png and /dev/null differ
diff --git a/2025/scripts/modeling_tools/gs_curvetools/icons/gsCurveToolsIcon_ui_legacy.png b/2025/scripts/modeling_tools/gs_curvetools/icons/gsCurveToolsIcon_ui_legacy.png
deleted file mode 100644
index e5bc3dc..0000000
Binary files a/2025/scripts/modeling_tools/gs_curvetools/icons/gsCurveToolsIcon_ui_legacy.png and /dev/null differ
diff --git a/2025/scripts/modeling_tools/gs_curvetools/icons/marking.png b/2025/scripts/modeling_tools/gs_curvetools/icons/marking.png
deleted file mode 100644
index 2835c8b..0000000
Binary files a/2025/scripts/modeling_tools/gs_curvetools/icons/marking.png and /dev/null differ
diff --git a/2025/scripts/modeling_tools/gs_curvetools/icons/mod.png b/2025/scripts/modeling_tools/gs_curvetools/icons/mod.png
deleted file mode 100644
index deb0c16..0000000
Binary files a/2025/scripts/modeling_tools/gs_curvetools/icons/mod.png and /dev/null differ
diff --git a/2025/scripts/modeling_tools/gs_curvetools/icons/reset.png b/2025/scripts/modeling_tools/gs_curvetools/icons/reset.png
deleted file mode 100644
index 4cba961..0000000
Binary files a/2025/scripts/modeling_tools/gs_curvetools/icons/reset.png and /dev/null differ
diff --git a/2025/scripts/modeling_tools/gs_curvetools/icons/sliderLock_en_reversed.png b/2025/scripts/modeling_tools/gs_curvetools/icons/sliderLock_en_reversed.png
deleted file mode 100644
index 8c2813c..0000000
Binary files a/2025/scripts/modeling_tools/gs_curvetools/icons/sliderLock_en_reversed.png and /dev/null differ
diff --git a/2025/scripts/modeling_tools/gs_curvetools/icons/sliderLock_reversed.png b/2025/scripts/modeling_tools/gs_curvetools/icons/sliderLock_reversed.png
deleted file mode 100644
index 638a116..0000000
Binary files a/2025/scripts/modeling_tools/gs_curvetools/icons/sliderLock_reversed.png and /dev/null differ
diff --git a/2025/scripts/modeling_tools/gs_curvetools/plugins/2018/cv_manip.mll b/2025/scripts/modeling_tools/gs_curvetools/plugins/2018/cv_manip.mll
deleted file mode 100644
index 0078219..0000000
Binary files a/2025/scripts/modeling_tools/gs_curvetools/plugins/2018/cv_manip.mll and /dev/null differ
diff --git a/2025/scripts/modeling_tools/gs_curvetools/plugins/2019/cv_manip.mll b/2025/scripts/modeling_tools/gs_curvetools/plugins/2019/cv_manip.mll
deleted file mode 100644
index 93736ce..0000000
Binary files a/2025/scripts/modeling_tools/gs_curvetools/plugins/2019/cv_manip.mll and /dev/null differ
diff --git a/2025/scripts/modeling_tools/gs_curvetools/plugins/2020/cv_manip.mll b/2025/scripts/modeling_tools/gs_curvetools/plugins/2020/cv_manip.mll
deleted file mode 100644
index 8e34d98..0000000
Binary files a/2025/scripts/modeling_tools/gs_curvetools/plugins/2020/cv_manip.mll and /dev/null differ
diff --git a/2025/scripts/modeling_tools/gs_curvetools/plugins/2022/cv_manip.mll b/2025/scripts/modeling_tools/gs_curvetools/plugins/2022/cv_manip.mll
deleted file mode 100644
index eff0140..0000000
Binary files a/2025/scripts/modeling_tools/gs_curvetools/plugins/2022/cv_manip.mll and /dev/null differ
diff --git a/2025/scripts/modeling_tools/gs_curvetools/plugins/2023/cv_manip.mll b/2025/scripts/modeling_tools/gs_curvetools/plugins/2023/cv_manip.mll
deleted file mode 100644
index 047dc3c..0000000
Binary files a/2025/scripts/modeling_tools/gs_curvetools/plugins/2023/cv_manip.mll and /dev/null differ
diff --git a/2025/scripts/modeling_tools/gs_curvetools/plugins/2024/cv_manip.mll b/2025/scripts/modeling_tools/gs_curvetools/plugins/2024/cv_manip.mll
deleted file mode 100644
index 2a1dd2a..0000000
Binary files a/2025/scripts/modeling_tools/gs_curvetools/plugins/2024/cv_manip.mll and /dev/null differ
diff --git a/2025/scripts/modeling_tools/gs_curvetools/plugins/2025/cv_manip.mll b/2025/scripts/modeling_tools/gs_curvetools/plugins/2025/cv_manip.mll
deleted file mode 100644
index dff851b..0000000
Binary files a/2025/scripts/modeling_tools/gs_curvetools/plugins/2025/cv_manip.mll and /dev/null differ
diff --git a/2025/scripts/modeling_tools/gs_curvetools/plugins/cv_manip.py b/2025/scripts/modeling_tools/gs_curvetools/plugins/cv_manip.py
deleted file mode 100644
index 8647705..0000000
--- a/2025/scripts/modeling_tools/gs_curvetools/plugins/cv_manip.py
+++ /dev/null
@@ -1,93 +0,0 @@
-"""
-CV Manipulator (highlighting) plug-in entry point for Mac
----
-GS CurveTools License:
-This collection of code named GS CurveTools is a property of George Sladkovsky (Yehor Sladkovskyi)
-and can not be copied or distributed without his written permission.
-
-GS CurveTools v1.3.11 Personal Edition
-Copyright 2025, George Sladkovsky (Yehor Sladkovskyi)
-All Rights Reserved
-
-UI font is Roboto that is licensed under the Apache 2.0 License:
-http://www.apache.org/licenses/LICENSE-2.0
-
-Autodesk Maya is a property of Autodesk, Inc:
-https://www.autodesk.com/
-
-Social Media and Contact Links:
-
-Discord Server: https://discord.gg/f4DH6HQ
-Online Store: https://sladkovsky3d.artstation.com/store
-Online Documentation: https://gs-curvetools.readthedocs.io/
-Twitch Channel: https://www.twitch.tv/videonomad
-YouTube Channel: https://www.youtube.com/c/GeorgeSladkovsky
-ArtStation Portfolio: https://www.artstation.com/sladkovsky3d
-Contact Email: george.sladkovsky@gmail.com
-"""
-
-# pylint: disable-all
-
-import sys
-
-try:
- from importlib import reload
-except ImportError:
- from imp import reload
-
-import maya.api.OpenMaya as om
-import maya.api.OpenMayaRender as omr
-
-from gs_curvetools.config.constants import NODES
-from gs_curvetools.plugins import cv_manip_src
-
-reload(cv_manip_src)
-
-# API parameters
-maya_useNewAPI = True
-
-
-# ------------ Init & UnInit Plugin ------------
-def initializePlugin(obj):
- plugin = om.MFnPlugin(obj, "GeorgeSladkovsky", "1.3", "Any")
- try:
- plugin.registerNode(
- NODES.DrawManager.node,
- cv_manip_src.DrawManagerNode.id,
- cv_manip_src.DrawManagerNode.creator,
- cv_manip_src.DrawManagerNode.initialize,
- om.MPxNode.kLocatorNode,
- cv_manip_src.DrawManagerNode.drawDbClassification,
- )
- except BaseException:
- sys.stderr.write("Failed to register node\n")
- raise
-
- try:
- omr.MDrawRegistry.registerDrawOverrideCreator(
- cv_manip_src.DrawManagerNode.drawDbClassification,
- cv_manip_src.DrawManagerNode.drawRegistrantId,
- cv_manip_src.DrawOverride.creator,
- )
- except BaseException:
- sys.stderr.write("Failed to register override\n")
- raise
-
-
-def uninitializePlugin(obj):
- om.MMessage.removeCallbacks(cv_manip_src.CALLBACK_IDS)
- cv_manip_src.CALLBACK_IDS = []
- plugin = om.MFnPlugin(obj)
- try:
- plugin.deregisterNode(cv_manip_src.DrawManagerNode.id)
- except BaseException:
- sys.stderr.write("Failed to deregister node\n")
- raise
-
- try:
- omr.MDrawRegistry.deregisterGeometryOverrideCreator(
- cv_manip_src.DrawManagerNode.drawDbClassification, cv_manip_src.DrawManagerNode.drawRegistrantId
- )
- except BaseException:
- sys.stderr.write("Failed to deregister override\n")
- raise
diff --git a/2025/scripts/modeling_tools/gs_curvetools/ui/components/curve_control.py b/2025/scripts/modeling_tools/gs_curvetools/ui/components/curve_control.py
deleted file mode 100644
index 5b04b8e..0000000
--- a/2025/scripts/modeling_tools/gs_curvetools/ui/components/curve_control.py
+++ /dev/null
@@ -1,949 +0,0 @@
-"""
-Curve control window
----
-GS CurveTools License:
-This collection of code named GS CurveTools is a property of George Sladkovsky (Yehor Sladkovskyi)
-and can not be copied or distributed without his written permission.
-
-GS CurveTools v1.3.10 Personal Edition
-Copyright 2025, George Sladkovsky (Yehor Sladkovskyi)
-All Rights Reserved
-
-UI font is Roboto that is licensed under the Apache 2.0 License:
-http://www.apache.org/licenses/LICENSE-2.0
-
-Autodesk Maya is a property of Autodesk, Inc:
-https://www.autodesk.com/
-
-Social Media and Contact Links:
-
-Discord Server: https://discord.gg/f4DH6HQ
-Online Store: https://sladkovsky3d.artstation.com/store
-Online Documentation: https://gs-curvetools.readthedocs.io/
-Twitch Channel: https://www.twitch.tv/videonomad
-YouTube Channel: https://www.youtube.com/c/GeorgeSladkovsky
-ArtStation Portfolio: https://www.artstation.com/sladkovsky3d
-Contact Email: george.sladkovsky@gmail.com
-"""
-from functools import partial
-import maya.cmds as mc
-from gs_curvetools.api.maya_tools import deferred, no_undo, undo
-from gs_curvetools.api.qt_compat import *
-from gs_curvetools.api.utils import open_link
-from gs_curvetools.config.constants import *
-from gs_curvetools.config.folders import GetFolder
-from gs_curvetools.core.core import Core
-from gs_curvetools.debug.logger import logger
-from gs_curvetools.managers.options_manager import OptionsManager
-from gs_curvetools.managers.script_jobs import ScriptJobs
-from gs_curvetools.managers.widget_manager import WidgetManager
-from gs_curvetools.ui import style
-from gs_curvetools.ui.tooltips import Tooltips
-from gs_curvetools.ui.utils import maya_dockable_window
-from gs_curvetools.ui.widgets import Button, ColorPicker, Column, ControlSlider, FallOffCurve, FloatField, Frame, IconCheckButton, Label, LayerSelector, LineEdit, PopOutWindow, Row, maya_slider, separator
-
-class CurveControlWindow(QWidget):
- """曲线控制用户界面"""
- update_curve_control_ui = Signal()
- update_main_ui = Signal()
-
- def __init__(self, parent):
- super(CurveControlWindow, self).__init__(parent)
- self.core = Core.singleton()
- self.widget_manager = WidgetManager()
- self.options_manager = OptionsManager()
- self.script_jobs = ScriptJobs.singleton()
- self.tooltips = Tooltips()
-
- def open_ui(self):
- """创建曲线控制工作区"""
- if mc.workspaceControl(WINDOWS.CurveControl.name, q=1, ex=1):
- if not mc.workspaceControl(WINDOWS.CurveControl.name, q=1, vis=1):
- mc.workspaceControl(WINDOWS.CurveControl.name, e=1, rs=1)
- deferred(self.update_main_ui.emit)()
- else:
- mc.workspaceControl(WINDOWS.CurveControl.name, e=1, vis=0)
- return
- else:
- dockable_window = maya_dockable_window(name=WINDOWS.CurveControl.name, label="曲线控制", i_w=350, i_h=750, width_property='free')
- layout = dockable_window.layout()
- assert layout is not None, '未找到布局'
- layout.addWidget(self)
- self.create_ui()
- self.update_curve_control_ui.emit()
- self.script_jobs.check_script_jobs(WINDOWS.CurveControl.name)
-
- def create_ui(self):
- """创建曲线控制用户界面"""
- main_layout = QtWidgets.QVBoxLayout(self)
- main_layout.setContentsMargins(*style.scale([2, 0, 2, 0]))
- scroll_widget = QtWidgets.QWidget()
- layout = QtWidgets.QVBoxLayout(scroll_widget)
- scroll_area = QtWidgets.QScrollArea()
- scroll_area.setWidget(scroll_widget)
- main_layout.addWidget(scroll_area)
- layout.setContentsMargins(0, 0, 0, 0)
- layout.setSpacing(style.scale(2))
- layout.setAlignment(QtCore.Qt.AlignmentFlag.AlignTop)
- scroll_area.setFrameShape(QtWidgets.QFrame.Shape.NoFrame)
- scroll_area.setWidgetResizable(True)
- layout.addWidget(separator())
- with Row(layout, 'gsCurveControlHeader') as row:
- row_layout = row.layout()
- if not row_layout:
- raise RuntimeError('未找到行布局')
- layer_selector = LayerSelector('gsLayerSelector', row_layout)
- layer_selector.setFixedWidth(style.scale(40))
- layer_selector.currentIndexChanged.connect(self.core.layer_manager.change_layer_via_option_menu)
- layer_color_picker = ColorPicker('gsColorPicker', row_layout)
- layer_color_picker.setContentsMargins(*style.scale([3, 3, 1, 3]))
- layer_color_picker.setFixedWidth(style.scale(20))
- layer_color_picker.connect_command(self.core.color_mode.change_layer_color_via_picker)
- curve_color_picker = ColorPicker('gsCurveColorPicker', row_layout)
- curve_color_picker.setContentsMargins(*style.scale([1, 3, 2, 3]))
- curve_color_picker.setFixedWidth(style.scale(20))
- curve_color_picker.connect_command(self.core.color_mode.change_curve_color_via_picker)
- selected_object_name = LineEdit('selectedObjectName', row_layout)
- selected_object_name.setPlaceholderText('选择曲线')
- selected_object_name.returnPressed.connect(undo(self.core.functions.rename_selected))
- line_thickness = FloatField('lineWidth', row_layout)
- line_thickness.setFixedWidth(style.scale(35))
- line_thickness.set_range(-1, 10)
- line_thickness.set_value(-1)
- line_thickness.set_drag_command(partial(self.core.sliders.curve_control_slider_drag, line_thickness))
- line_thickness.set_release_command(self.core.sliders.release)
- layout.addWidget(separator())
- label = Label(layout, 'selectCurvesPrompt')
- label.set_label('选择兼容的曲线')
- label.set_font_size(14)
- label.setVisible(False)
- with Column(layout, 'axisFrame') as column:
- column_layout = column.layout()
- if not column_layout:
- raise RuntimeError('未找到列布局')
- label = Label(column_layout)
- label.set_label('轴控制')
- label.set_font_size(14)
- with Row(column.layout()) as row:
- axis_button_grp = QtWidgets.QButtonGroup(row)
- self.widget_manager.add('Axis', axis_button_grp)
- axis_auto = Button(row.layout(), 'gsBindAxisAuto')
- axis_auto.set_label('自动', line_height=100)
- axis_auto.setCheckable(True)
- axis_auto.set_button_style('small')
- axis_auto.setChecked(True)
- axis_auto.clicked.connect(partial(undo(self.core.functions.apply_axis), 0))
- axis_x = Button(row.layout(), 'gsBindAxisX')
- axis_x.set_label('X', line_height=100)
- axis_x.setCheckable(True)
- axis_x.set_button_style('small')
- axis_x.clicked.connect(partial(undo(self.core.functions.apply_axis), 1))
- axis_y = Button(row.layout(), 'gsBindAxisY')
- axis_y.set_label('Y', line_height=100)
- axis_y.setCheckable(True)
- axis_y.set_button_style('small')
- axis_y.clicked.connect(partial(undo(self.core.functions.apply_axis), 2))
- axis_z = Button(row.layout(), 'gsBindAxisZ')
- axis_z.set_label('Z', line_height=100)
- axis_z.setCheckable(True)
- axis_z.set_button_style('small')
- axis_z.clicked.connect(partial(undo(self.core.functions.apply_axis), 3))
- axis_button_grp.addButton(axis_auto, 0)
- axis_button_grp.addButton(axis_x, 1)
- axis_button_grp.addButton(axis_y, 2)
- axis_button_grp.addButton(axis_z, 3)
- axis_flip = Button(row.layout(), 'AxisFlip')
- axis_flip.set_label('翻转', line_height=100)
- axis_flip.setCheckable(True)
- axis_flip.set_button_style('small')
- axis_flip.clicked.connect(partial(undo(self.core.functions.apply_axis), -1))
- column_layout.addWidget(separator())
- with Row(column.layout(), margins=style.scale([0, 0, 0, 0]), obj_name='originalCurvesRow') as original_curves_row:
- select_original_curves = Button(original_curves_row.layout(), 'selectOriginalCurves')
- select_original_curves.set_label('选择原始曲线', line_height=100)
- select_original_curves.set_button_style('small-filled')
- select_original_curves.clicked.connect(undo(self.core.curve_control.select_original_objects))
- edit_orig_obj = Button(original_curves_row.layout(), 'editOrigObj')
- edit_orig_obj.set_label('编辑原始对象', line_height=100)
- edit_orig_obj.setCheckable(True)
- edit_orig_obj.set_button_style('small')
- edit_orig_obj.clicked.connect(undo(self.core.curve_control.edit_original_objects))
- column_layout.addWidget(separator())
- with Row(layout, margins=style.scale([0, 0, 3, 0])) as length_divisions_row:
- length_division = ControlSlider(obj_name='lengthDivisions', typ='int')
- length_division.set_label('长度分段')
- length_division.set_min_max(2, 100)
- length_division.set_field_min_max(2, 10000)
- length_division.set_value(2)
- length_division.set_drag_command(partial(self.core.sliders.curve_control_slider_drag, length_division))
- length_division.set_release_command(self.core.sliders.release)
- dynamic_divisions_toggle = Button(obj_name='dynamicDivisions')
- dynamic_divisions_toggle.set_label('自动')
- dynamic_divisions_toggle.setFixedWidth(style.scale(35))
- dynamic_divisions_toggle.set_button_style('small')
- dynamic_divisions_toggle.setCheckable(True)
- dynamic_divisions_toggle.clicked.connect(undo(self.core.functions.toggle_dynamic_divisions))
- length_division_layout = length_divisions_row.layout()
- if not isinstance(length_division_layout, QHBoxLayout):
- raise RuntimeError('未找到长度分段布局')
- length_division_layout.addWidget(length_division, 4)
- length_division_layout.addWidget(dynamic_divisions_toggle, 1)
- width_division = ControlSlider(layout, 'widthDivisions', 'int')
- width_division.set_label('宽度分段')
- width_division.set_min_max(2, 31)
- width_division.set_field_min_max(2, 10000)
- width_division.set_value(2)
- width_division.set_drag_command(partial(self.core.sliders.curve_control_slider_drag, width_division))
- width_division.set_release_command(self.core.sliders.release)
- orientation = ControlSlider(layout, 'Orientation', 'float')
- orientation.set_label('方向')
- orientation.set_min_max(-180, 180)
- orientation.set_field_min_max(-36000, 36000)
- orientation.set_precision(1)
- orientation.set_step(0.5)
- orientation.set_drag_command(partial(self.core.sliders.curve_control_slider_drag, orientation))
- orientation.set_release_command(self.core.sliders.release)
- twist = ControlSlider(layout, 'Twist', 'float')
- twist.set_label('扭曲')
- twist.set_min_max(-180, 180)
- twist.set_field_min_max(-36000, 36000)
- twist.set_precision(1)
- twist.set_step(0.5)
- twist.set_drag_command(partial(self.core.sliders.curve_control_slider_drag, twist))
- twist.set_release_command(self.core.sliders.release)
- inv_twist = ControlSlider(layout, 'invTwist', 'float')
- inv_twist.set_label('反向扭曲')
- inv_twist.set_min_max(-180, 180)
- inv_twist.set_field_min_max(-36000, 36000)
- inv_twist.set_precision(1)
- inv_twist.set_step(0.5)
- inv_twist.set_drag_command(partial(self.core.sliders.curve_control_slider_drag, inv_twist))
- inv_twist.set_release_command(self.core.sliders.release)
- with Frame(layout, 'twistCurveFrame', margins=[0, 1, 0, 2]) as twist_curve_frame:
- twist_curve_frame.get_frame_button().set_label('扭曲曲线图表')
- twist_graph = FallOffCurve(twist_curve_frame.get_frame_layout(), 'twistCurve')
-
- def twist_graph_command(_):
- self.core.attributes.propagate_graphs(twist_graph)
- self.core.attributes.store_graphs(twist_graph)
- twist_graph.change_command(twist_graph_command)
- with Row(twist_curve_frame.get_frame_layout(), margins=style.scale([5, 0, 5, 2])) as row:
- row.setFixedHeight(int(style.BUTTON_HEIGHT))
- magnitude = FloatField('Magnitude', row.layout())
- magnitude.setFixedWidth(style.scale(45))
- magnitude.set_range(-99, 99)
- magnitude.set_step(0.01)
- magnitude.set_precision(2)
- magnitude.set_drag_command(partial(self.core.sliders.curve_control_slider_drag, magnitude))
- magnitude.set_release_command(self.core.sliders.release)
- reset_button = Button(row.layout(), 'gsTwistGraphResetButton')
- reset_button.set_label('重置曲线')
-
- def reset_twist_cmd():
- self.core.utils.reset_single_graph('twist')
- self.core.attributes.store_graphs(twist_graph)
- reset_button.clicked.connect(undo(reset_twist_cmd))
- pop_out_button = Button(row.layout(), 'gsTwistGraphPopOut')
- pop_out_button.setFixedWidth(style.scale(56))
- pop_out_button.set_label('^')
- pop_out_button.clicked.connect(self.twist_graph_pop_out)
- width = ControlSlider(layout, 'Width', 'float')
- width.set_label('宽度')
- width.set_min_max(0.001, 2)
- width.set_field_min_max(0.001, 1000)
- width.set_precision(3)
- width.set_step(0.001)
- width.set_value(1)
- width.set_drag_command(partial(self.core.sliders.curve_control_slider_drag, width))
- width.set_release_command(self.core.sliders.release)
- taper = ControlSlider(layout, 'Taper', 'float')
- taper.set_label('锥度')
- taper.set_min_max(0.001, 3)
- taper.set_field_min_max(0.001, 1000)
- taper.set_precision(3)
- taper.set_step(0.001)
- taper.set_value(1)
- taper.set_drag_command(partial(self.core.sliders.curve_control_slider_drag, taper))
- taper.set_release_command(self.core.sliders.release)
- with Row(layout, obj_name='widthComboSlider', spacing=0) as row:
- row_layout = row.layout()
- if not row_layout:
- raise RuntimeError('未找到行布局')
- with Column(row.layout()) as column:
- column_layout = column.layout()
- if not column_layout:
- raise RuntimeError('未找到列布局')
- width_x = ControlSlider(column_layout, 'WidthX', 'float')
- width_x.set_label('宽度 X')
- width_x.set_min_max(0.001, 2)
- width_x.set_field_min_max(0.001, 1000)
- width_x.set_precision(3)
- width_x.set_step(0.001)
- width_x.set_value(1)
- width_x.set_drag_command(partial(self.core.sliders.curve_control_slider_drag, width_x))
- width_x.set_release_command(self.core.sliders.release)
- width_z = ControlSlider(column.layout(), 'WidthZ', 'float')
- width_z.set_label('宽度 Z')
- width_z.set_min_max(0.001, 2)
- width_z.set_field_min_max(0.001, 1000)
- width_z.set_precision(3)
- width_z.set_step(0.001)
- width_z.set_value(1)
- width_z.set_drag_command(partial(self.core.sliders.curve_control_slider_drag, width_z))
- width_z.set_release_command(self.core.sliders.release)
- lock_button = IconCheckButton(row_layout, 'widthLockSwitch')
- lock_button.set_icons(GetFolder.icons() + 'sliderLock_en_reversed.png', GetFolder.icons() + 'sliderLock_reversed.png')
- lock_button.set_icon_width_height(10, 30)
- lock_button.setChecked(True)
- with Frame(layout, 'widthCurveFrame', margins=[0, 1, 0, 2]) as width_curve_frame:
- width_curve_frame.get_frame_button().set_label('宽度曲线图表')
- width_graph = FallOffCurve(width_curve_frame.get_frame_layout(), 'scaleCurve')
-
- def width_graph_command(_):
- self.core.attributes.propagate_graphs(width_graph)
- self.core.attributes.store_graphs(width_graph)
- width_graph.change_command(width_graph_command)
- with Row(width_curve_frame.get_frame_layout(), margins=style.scale([5, 0, 5, 2])) as row:
- row.setFixedHeight(int(style.BUTTON_HEIGHT))
- reset_button = Button(row.layout(), 'gsWidthGraphResetButton')
- reset_button.set_label('重置曲线')
-
- def reset_width_cmd():
- self.core.utils.reset_single_graph('scale')
- self.core.attributes.store_graphs(width_graph)
- reset_button.clicked.connect(undo(reset_width_cmd))
- pop_out_button = Button(row.layout(), 'gsWidthGraphPopOut')
- pop_out_button.setFixedWidth(style.scale(56))
- pop_out_button.set_label('^')
- pop_out_button.clicked.connect(self.width_graph_pop_out)
- length_unlock = Button(layout, 'LengthLock')
- length_unlock.set_label('长度解锁', line_height=100)
- length_unlock.setCheckable(True)
- length_unlock.set_button_style('small')
- length_unlock.setFixedWidth(style.scale(106))
- length_unlock.clicked.connect(partial(self.core.updates.curve_control_check_boxes, 2))
- length = ControlSlider(layout, 'Length', 'float')
- length.set_label('长度')
- length.set_min_max(0.001, 40)
- length.set_field_min_max(-1000, 1000)
- length.set_precision(3)
- length.set_step(0.001)
- length.set_value(20)
- length.set_drag_command(partial(self.core.sliders.curve_control_slider_drag, length))
- length.set_release_command(self.core.sliders.release)
- offset = ControlSlider(layout, 'Offset', 'float')
- offset.set_label('偏移')
- offset.set_min_max(-1, 1)
- offset.set_field_min_max(-30, 30)
- offset.set_step(0.001)
- offset.set_value(1)
- offset.set_drag_command(partial(self.core.sliders.curve_control_slider_drag, offset))
- offset.set_release_command(self.core.sliders.release)
- profile = ControlSlider(layout, 'Profile', 'float')
- profile.set_label('轮廓')
- profile.set_min_max(-2, 2)
- profile.set_field_min_max(-1000, 1000)
- profile.set_step(0.001)
- profile.set_drag_command(partial(self.core.sliders.curve_control_slider_drag, profile))
- profile.set_release_command(self.core.sliders.release)
- with Frame(layout, 'profileCurveGraph', margins=[0, 1, 0, 2]) as profile_curve_frame:
- profile_curve_frame.get_frame_button().set_label('轮廓曲线图表')
- profile_graph = FallOffCurve(profile_curve_frame.get_frame_layout(), 'profileCurve', attr=False)
-
- def change_command(value):
- self.core.attributes.update_lattice(value)
- self.core.attributes.equalize_profile_curve()
- self.core.attributes.store_graphs(profile_graph)
- profile_graph.change_command(change_command)
- profile_smoothing_slider = ControlSlider(profile_curve_frame.get_frame_layout(), 'profileSmoothing', 'int')
- profile_smoothing_slider.set_label('平滑度')
- profile_smoothing_slider.set_min_max(2, 30)
- profile_smoothing_slider.set_value(2)
- profile_smoothing_slider.set_drag_command(partial(self.core.sliders.curve_control_slider_drag, profile_smoothing_slider))
- profile_smoothing_slider.set_release_command(self.core.sliders.release)
- with Row(profile_curve_frame.get_frame_layout(), margins=style.scale([5, 0, 5, 2])) as row:
- row.setFixedHeight(int(style.BUTTON_HEIGHT))
- with Column(row.layout(), spacing=0) as eq_column:
- eq_column.setFixedHeight(style.scale(24))
- with Row(eq_column.layout(), spacing=0) as eq_row:
-
- def toggle_eq():
- self.widget_manager.get('equalizeCurveButton').setDisabled(self.widget_manager.get('autoEqualizeSwitchOn').isChecked())
- auto_equalize_group = QtWidgets.QButtonGroup(eq_row)
- auto_equalize_group.buttonClicked.connect(toggle_eq)
- auto_equalize_group.buttonClicked.connect(undo(self.core.attributes.equalize_profile_curve))
- auto_equalize = Button(eq_row.layout(), 'autoEqualizeSwitchOn')
- auto_equalize.set_label('自动', line_height=100)
- auto_equalize.set_label_style('small')
- auto_equalize.set_button_style('small-compound-top-left')
- auto_equalize.setCheckable(True)
- auto_equalize.setChecked(True)
- auto_equalize_off = Button(eq_row.layout(), 'autoEqualizeSwitchOff')
- auto_equalize_off.set_label('手动', line_height=100)
- auto_equalize_off.set_label_style('small')
- auto_equalize_off.set_button_style('small-compound-top-right')
- auto_equalize_off.setCheckable(True)
- auto_equalize_group.addButton(auto_equalize)
- auto_equalize_group.addButton(auto_equalize_off)
- equalize_profile_curve = Button(eq_column.layout(), 'equalizeCurveButton')
- equalize_profile_curve.set_label('均衡曲线', line_height=100)
- equalize_profile_curve.set_label_style('small')
- equalize_profile_curve.set_button_style('small-filled-compound-bottom')
- equalize_profile_curve.setDisabled(True)
- equalize_profile_curve.clicked.connect(partial(undo(self.core.attributes.equalize_profile_curve), True))
- reset_button = Button(obj_name='gsResetProfileGraphButton')
- reset_button.set_label('重置曲线')
-
- def reset_button_clicked(*_):
- self.core.attributes.reset_profile_curve()
- self.core.attributes.store_graphs(profile_graph)
- reset_button.clicked.connect(undo(reset_button_clicked))
- pop_out_button = Button(obj_name='gsProfileGraphPopOut')
- pop_out_button.set_label('^')
- pop_out_button.clicked.connect(self.profile_graph_pop_out)
- row_layout = row.layout()
- if not isinstance(row_layout, QHBoxLayout):
- raise RuntimeError('未找到行布局')
- row_layout.addWidget(eq_column, 2)
- row_layout.addWidget(reset_button, 3)
- row_layout.addWidget(pop_out_button, 1)
- normals = ControlSlider(layout, 'surfaceNormals', 'float')
- normals.set_label('法线')
- normals.set_min_max(0, 180)
- normals.set_precision(1)
- normals.set_value(180)
- normals.set_drag_command(partial(self.core.sliders.curve_control_slider_drag, normals))
- normals.set_release_command(self.core.sliders.release)
- reverse_normals = Button(layout, 'reverseNormals')
- reverse_normals.set_label('反转法线', line_height=100)
- reverse_normals.setCheckable(True)
- reverse_normals.set_button_style('small')
- reverse_normals.setFixedWidth(style.scale(106))
- reverse_normals.clicked.connect(partial(self.core.updates.curve_control_check_boxes, 0))
- with Frame(layout, 'otherFrame', label='其他', margins=[2, 2, 2, 2]) as refine_frame, Row(refine_frame.get_frame_layout(), margins=style.scale([0, 0, 3, 0])) as curve_sampling_row:
- sampling_accuracy = ControlSlider(layout, 'samplingAccuracy', 'float')
- sampling_accuracy.set_label('采样精度')
- sampling_accuracy.set_min_max(0.001, 2)
- sampling_accuracy.set_step(0.01)
- sampling_accuracy.set_value(0.33)
- sampling_accuracy.set_drag_command(partial(self.core.sliders.curve_control_slider_drag, sampling_accuracy))
- sampling_accuracy.set_release_command(self.core.sliders.release)
- auto_sampling = Button(obj_name='autoSampling')
- auto_sampling.set_label('自动')
- auto_sampling.setFixedWidth(style.scale(35))
- auto_sampling.set_button_style('small')
- auto_sampling.setCheckable(True)
- auto_sampling.clicked.connect(undo(self.core.functions.toggle_auto_sampling))
- curve_sampling_row_layout = curve_sampling_row.layout()
- if not isinstance(curve_sampling_row_layout, QHBoxLayout):
- raise RuntimeError('未找到曲线采样行布局')
- curve_sampling_row_layout.addWidget(sampling_accuracy, 4)
- curve_sampling_row_layout.addWidget(auto_sampling, 1)
- with Row(refine_frame.get_frame_layout(), margins=style.scale([0, 0, 3, 0])) as curve_refine_row:
- refine = ControlSlider(layout, 'curveRefine', 'int')
- refine.set_label('细化')
- refine.set_min_max(0, 100)
- refine.set_field_min_max(0, 10000)
- refine.set_value(20)
- refine.set_drag_command(partial(self.core.sliders.curve_control_slider_drag, refine))
- refine.set_release_command(self.core.sliders.release)
- auto_refine_toggle = Button(obj_name='autoRefine')
- auto_refine_toggle.set_label('自动')
- auto_refine_toggle.setFixedWidth(style.scale(35))
- auto_refine_toggle.set_button_style('small')
- auto_refine_toggle.setCheckable(True)
- auto_refine_toggle.clicked.connect(undo(self.core.functions.toggle_auto_refine))
- curve_refine_row_layout = curve_refine_row.layout()
- if not isinstance(curve_refine_row_layout, QHBoxLayout):
- raise RuntimeError('未找到曲线细化行布局')
- curve_refine_row_layout.addWidget(refine, 4)
- curve_refine_row_layout.addWidget(auto_refine_toggle, 1)
- smooth = ControlSlider(refine_frame.get_frame_layout(), 'curveSmooth', 'float')
- smooth.setVisible(False)
- smooth.set_label('平滑')
- smooth.set_min_max(0, 10)
- smooth.set_drag_command(partial(self.core.sliders.curve_control_slider_drag, smooth))
- smooth.set_release_command(self.core.sliders.release)
- with Frame(layout, 'orientToNormalsFrame', label='朝向法线', margins=[2, 2, 2, 2]) as orient_frame:
- orient_frame.setVisible(False)
-
- def select_mesh():
- sel = mc.filterExpand(mc.ls(sl=1, l=1), sm=12)
- if not sel:
- sel = mc.ls(hl=1, o=1, l=1)
- if not sel:
- logger.warning('选择兼容的网格。', in_view=True)
- else:
- self.mesh_name.setText(sel[0])
- with Row(orient_frame.get_frame_layout()) as row:
- select_mesh_btn = Button(row.layout(), 'gsOrientToNormalsSelectTarget')
- select_mesh_btn.setFixedWidth(style.scale(100))
- select_mesh_btn.set_label('选择目标')
- select_mesh_btn.clicked.connect(select_mesh)
- self.mesh_name = LineEdit('gsOrientMeshName', row.layout())
- self.mesh_name.setPlaceholderText('选择或输入目标网格')
- self.mesh_name.setClearButtonEnabled(True)
- orient_frame.get_frame_layout().addWidget(separator())
- with Row(orient_frame.get_frame_layout()) as row:
- iterations_slider = ControlSlider(row.layout(), 'gsIterationsSlider', 'int')
- iterations_slider.set_min_max(1, 100)
- iterations_slider.set_value(10)
- iterations_slider.set_label('迭代次数')
- auto_refresh_button = Button(row.layout(), 'orientRefreshViewport')
- auto_refresh_button.set_button_style('small')
- auto_refresh_button.setCheckable(True)
- auto_refresh_button.setChecked(True)
- auto_refresh_button.set_width_height(width=style.scale(60))
- auto_refresh_button.set_label('刷新视图', line_height=100)
- with Row(orient_frame.get_frame_layout()) as row:
- min_angle_slider = ControlSlider(row.layout(), 'gsMinimumAngle', 'float')
- min_angle_slider.set_min_max(0.1, 90)
- min_angle_slider.set_value(1)
- min_angle_slider.set_label('最小角度')
- orient_frame.get_frame_layout().addWidget(separator())
- with Row(orient_frame.get_frame_layout()) as row:
- orient = Button(row.layout(), 'gsOrientToNormals')
- orient.set_label('朝向')
- orient.clicked.connect(undo(self.core.functions.orient_to_face_normals))
- with Frame(layout, 'solidifyFrame', label='实体化控制', margins=[2, 2, 2, 2]) as solidify_frame:
- solidify = Button(solidify_frame.get_frame_layout(), 'solidify')
- solidify.set_label('实体化', line_height=100)
- solidify.setCheckable(True)
- solidify.set_button_style('small')
- solidify.setFixedWidth(style.scale(106))
- solidify.clicked.connect(partial(self.core.updates.curve_control_check_boxes, 1))
- thickness = ControlSlider(solidify_frame.get_frame_layout(), 'solidifyThickness', 'float')
- thickness.set_label('厚度')
- thickness.set_min_max(0.001, 5)
- thickness.set_field_min_max(-100, 100)
- thickness.set_value(0.25)
- thickness.set_step(0.001)
- thickness.set_drag_command(partial(self.core.sliders.curve_control_slider_drag, thickness))
- thickness.set_release_command(self.core.sliders.release)
- divisions = ControlSlider(solidify_frame.get_frame_layout(), 'solidifyDivisions', 'int')
- divisions.set_label('分段数')
- divisions.set_min_max(0, 10)
- divisions.set_field_min_max(0, 100)
- divisions.set_drag_command(partial(self.core.sliders.curve_control_slider_drag, divisions))
- divisions.set_release_command(self.core.sliders.release)
- solidify_scale_x = ControlSlider(solidify_frame.get_frame_layout(), 'solidifyScaleX', 'float')
- solidify_scale_x.set_label('缩放 X')
- solidify_scale_x.set_min_max(-10, 10)
- solidify_scale_x.set_field_min_max(-100, 100)
- solidify_scale_x.set_step(0.001)
- solidify_scale_x.set_drag_command(partial(self.core.sliders.curve_control_slider_drag, solidify_scale_x))
- solidify_scale_x.set_release_command(self.core.sliders.release)
- solidify_scale_y = ControlSlider(solidify_frame.get_frame_layout(), 'solidifyScaleY', 'float')
- solidify_scale_y.set_label('缩放 Y')
- solidify_scale_y.set_min_max(-10, 10)
- solidify_scale_y.set_field_min_max(-100, 100)
- solidify_scale_y.set_step(0.001)
- solidify_scale_y.set_drag_command(partial(self.core.sliders.curve_control_slider_drag, solidify_scale_y))
- solidify_scale_y.set_release_command(self.core.sliders.release)
- offset = ControlSlider(solidify_frame.get_frame_layout(), 'solidifyOffset', 'float')
- offset.set_label('偏移')
- offset.set_min_max(-1, 1)
- offset.set_field_min_max(-100, 100)
- offset.set_step(0.001)
- offset.set_drag_command(partial(self.core.sliders.curve_control_slider_drag, offset))
- offset.set_release_command(self.core.sliders.release)
- solidify_normals = ControlSlider(solidify_frame.get_frame_layout(), 'solidifyNormals', 'float')
- solidify_normals.set_label('实体化法线')
- solidify_normals.set_min_max(0, 180)
- solidify_normals.set_precision(1)
- solidify_normals.set_value(180)
- solidify_normals.set_drag_command(partial(self.core.sliders.curve_control_slider_drag, solidify_normals))
- solidify_normals.set_release_command(self.core.sliders.release)
- with Frame(layout, 'UVFrame', label='UV 控制', margins=[2, 2, 2, 2]) as uv_frame:
- flip_uv = Button(uv_frame.get_frame_layout(), 'flipUV')
- flip_uv.set_label('水平翻转 UV', line_height=100)
- flip_uv.setCheckable(True)
- flip_uv.set_button_style('small')
- flip_uv.setFixedWidth(style.scale(106))
- flip_uv.clicked.connect(partial(undo(self.core.updates.curve_control_check_boxes), 3))
- move_u = ControlSlider(uv_frame.get_frame_layout(), 'moveU', 'float')
- move_u.set_label('移动 U')
- move_u.set_min_max(-0.5, 0.5)
- move_u.set_step(0.001)
- move_u.set_field_min_max(-100, 100)
- move_u.set_drag_command(partial(self.core.sliders.curve_control_slider_drag, move_u))
- move_u.set_release_command(self.core.sliders.release)
- move_v = ControlSlider(uv_frame.get_frame_layout(), 'moveV', 'float')
- move_v.set_label('移动 V')
- move_v.set_min_max(-0.5, 0.5)
- move_v.set_step(0.001)
- move_v.set_field_min_max(-100, 100)
- move_v.set_drag_command(partial(self.core.sliders.curve_control_slider_drag, move_v))
- move_v.set_release_command(self.core.sliders.release)
- scale_u = ControlSlider(uv_frame.get_frame_layout(), 'scaleU', 'float')
- scale_u.set_label('缩放 U')
- scale_u.set_min_max(0.001, 1.999)
- scale_u.set_field_min_max(0, 100)
- scale_u.set_step(0.001)
- scale_u.set_value(1)
- scale_u.set_drag_command(partial(self.core.sliders.curve_control_slider_drag, scale_u))
- scale_u.set_release_command(self.core.sliders.release)
- scale_v = ControlSlider(uv_frame.get_frame_layout(), 'scaleV', 'float')
- scale_v.set_label('缩放 V')
- scale_v.set_min_max(0.001, 1.999)
- scale_v.set_field_min_max(0, 100)
- scale_v.set_step(0.001)
- scale_v.set_value(1)
- scale_v.set_drag_command(partial(self.core.sliders.curve_control_slider_drag, scale_v))
- scale_v.set_release_command(self.core.sliders.release)
- rotate_uv = ControlSlider(uv_frame.get_frame_layout(), 'rotateUV', 'float')
- rotate_uv.set_label('旋转 UV')
- rotate_uv.set_min_max(-180, 180)
- rotate_uv.set_field_min_max(-3600, 3600)
- rotate_uv.set_precision(2)
- rotate_uv.set_drag_command(partial(self.core.sliders.curve_control_slider_drag, rotate_uv))
- rotate_uv.set_release_command(self.core.sliders.release)
- rotate_uv_root = ControlSlider(uv_frame.get_frame_layout(), 'rotateRootUV', 'float')
- rotate_uv_root.set_label('旋转根部 UV')
- rotate_uv_root.set_min_max(-180, 180)
- rotate_uv_root.set_field_min_max(-3600, 3600)
- rotate_uv_root.set_precision(2)
- rotate_uv_root.set_drag_command(partial(self.core.sliders.curve_control_slider_drag, rotate_uv_root))
- rotate_uv_root.set_release_command(self.core.sliders.release)
- rotate_uv_root.setVisible(False)
- rotate_uv_tip = ControlSlider(uv_frame.get_frame_layout(), 'rotateTipUV', 'float')
- rotate_uv_tip.set_label('旋转尖端 UV')
- rotate_uv_tip.set_min_max(-180, 180)
- rotate_uv_tip.set_field_min_max(-3600, 3600)
- rotate_uv_tip.set_precision(2)
- rotate_uv_tip.set_drag_command(partial(self.core.sliders.curve_control_slider_drag, rotate_uv_tip))
- rotate_uv_tip.set_release_command(self.core.sliders.release)
- rotate_uv_tip.setVisible(False)
- if MAYA_VER in (2020, 2022) and (not self.options_manager.get('UVBugMessageDismissed')):
- with Row(uv_frame.get_frame_layout()) as row:
- label = Label(row.layout())
- label.set_label('
')
- link_button = Button(row.layout())
- link_button.set_label('打开修复方法')
- link_button.set_button_style('small-filled')
- link_button.clicked.connect(lambda: open_link('https://gs-curvetools.readthedocs.io/en/latest/faq.html#maya-2020-2022-and-broken-uvs'))
- dismiss_message = Button(row.layout())
- dismiss_message.set_label('忽略提示')
- dismiss_message.set_button_style('small-filled')
- dismiss_message.clicked.connect(lambda: row.setHidden(True))
- dismiss_message.clicked.connect(lambda: self.options_manager.set('UVBugMessageDismissed', 1))
-
- def update_colors(self, *_):
- """更新 UV 编辑器的颜色"""
- if self.editor:
- self.options_manager.save()
- try:
- self.editor.change_color(literal_eval(self.options_manager.get('UVEditorBGColor')), literal_eval(self.options_manager.get('UVEditorGridColor')), literal_eval(self.options_manager.get('UVEditorFrameColor')), literal_eval(self.options_manager.get('UVEditorUVCardFillColor')), literal_eval(self.options_manager.get('UVEditorUVFrameSelectedColor')))
- except BaseException as exc:
- self.editor.change_color()
- logger.exception(exc)
- self.editor.update()
-
- @no_undo
- def update_editor(self):
- """更新 UV 编辑器"""
- self.update_item_list()
- self.update_uvs()
- self.update_texture()
-
- def show_all(self):
- """显示所有 UV"""
- self.uv_list.expandAll()
- self.uv_list.selectAll()
- self.update_visibility()
- self.isolate_mode = False
-
- @no_undo
- def update_uvs(self, keep_selection=False):
- """更新 UV"""
- sel = mc.filterExpand(mc.ls(sl=1, fl=1, l=1), sm=9)
- old_uvs = self.editor.uv_dict
- self.editor.purge_uvs()
- if not sel:
- return
- sel = self.check_for_legacy_uvs(sel)
- assert sel is not None
- for item in sel:
- if mc.attributeQuery('Orientation', n=item, ex=1) and mc.connectionInfo(item + '.Orientation', isSource=1):
- if mc.attributeQuery('gsmessage', n=item, ex=1) and mc.listConnections(item + '.gsmessage'):
- curves = self.core.utils.get_all_connected_curves(item)
- else:
- curves = [item]
- for curve in curves:
- attrs = self.core.attributes.get_uvs(curve)
- checkbox = self.core.attributes.get_checkboxes(curve)
- if attrs:
- uv_item = self.editor.create_uv(curve)
- if 'flipUV' in checkbox:
- uv_item.flip = not checkbox['flipUV']
- uv_item.move_uv(x=attrs['moveU'], y=attrs['moveV'], rot=attrs['rotateUV'] * -1, s_x=attrs['scaleU'], s_y=attrs['scaleV'])
- if keep_selection:
- new_uvs = self.editor.uv_dict
- for key, val in new_uvs.items():
- if key in old_uvs:
- val.setSelected(True)
-
- def check_for_legacy_uvs(self, curves):
- """检查是否存在旧版 UV"""
- legacy_curves = []
- for curve in curves:
- root = mc.attributeQuery('rotateRootUV', n=curve, ex=1)
- tip = mc.attributeQuery('rotateTipUV', n=curve, ex=1)
- if root or tip:
- root_value = mc.getAttr(curve + '.rotateRootUV')
- tip_value = mc.getAttr(curve + '.rotateTipUV')
- if root_value or tip_value:
- legacy_curves.append(curve)
- if not legacy_curves:
- return curves
- logger.warning('检测到非零旧版 UV 属性', in_view=True)
- dialog = mc.confirmDialog(title='旧版 UV', message='检测到非零旧版 UV。\nUV 编辑器与此不兼容。\n是否将其归零以继续?', icon='warning', button=['是', '取消'], cancelButton='取消', dismissString='取消')
- if dialog == '是':
- for curve in legacy_curves:
- mc.setAttr(curve + '.rotateRootUV', 0)
- mc.setAttr(curve + '.rotateTipUV', 0)
- return curves
- elif dialog == '取消':
- dialog = mc.confirmDialog(title='旧版 UV', message='UV 编辑器与旧版 UV 不兼容。\n部分卡片将被忽略。', icon='信息', button='确定', cancelButton='确定', dismissString='确定')
- return list(set(curves) - set(legacy_curves))
-
- @no_undo
- def update_texture(self):
- """更新纹理"""
- sel = self.core.utils.select_part(2, just_return=True)
- if not sel:
- self.editor.remove_texture()
- self.editor.diffuse_path = ''
- return
- geo = mc.filterExpand(sel, sm=12)
- if not geo:
- return
- dag = mc.ls(geo[-1], dag=1, s=1)
- shader = mc.listConnections(dag, d=1, s=1, t='shadingEngine')
- if not shader:
- return
- diffuse_file_node, alpha_file_node = self.core.utils.find_diffuse_alpha(shader[0])
- if not diffuse_file_node and (not alpha_file_node):
- return
- texture_path = None
- alpha_path = None
- if diffuse_file_node:
- texture_path = mc.getAttr(diffuse_file_node + '.fileTextureName')
- if alpha_file_node:
- alpha_path = mc.getAttr(alpha_file_node + '.fileTextureName') if alpha_file_node else None
- if not texture_path and alpha_path:
- texture_path = alpha_path
- diffuse_file_node = alpha_file_node
- place_2d_texture = None
- if mc.attributeQuery('coverage', n=diffuse_file_node, ex=1):
- info = mc.connectionInfo(diffuse_file_node + '.coverage', sfd=1)
- if info:
- place_2d_texture = info.split('.')
- if place_2d_texture:
- place_2d_texture = place_2d_texture[0]
- cov, trans = (None, None)
- if place_2d_texture and mc.objExists(place_2d_texture) and self.widget_manager.get('UVEditorUseTransforms').isChecked() and mc.attributeQuery('coverage', ex=1, n=place_2d_texture) and mc.attributeQuery('translateFrame', ex=1, n=place_2d_texture):
- try:
- cov = mc.getAttr(place_2d_texture + '.coverage')[0]
- trans = mc.getAttr(place_2d_texture + '.translateFrame')[0]
- except BaseException as exc:
- logger.exception(exc)
- coverage = cov if cov else (1.0, 1.0)
- translation = (trans[0], trans[1]) if trans and trans else (0, 0)
- if not self.widget_manager.get('UVEditorTransparencyToggle').isChecked() and (not self.widget_manager.get('UVEditorAlphaOnlyToggle').isChecked()):
- alpha_path = None
- if texture_path:
- _, ext = os.path.splitext(texture_path)
- try:
- supported_formats = [str(x, encoding='ASCII').lower() for x in QtGui.QImageReader.supportedImageFormats()]
- except TypeError:
- supported_formats = [str(x).decode('ASCII').lower() for x in QtGui.QImageReader.supportedImageFormats()]
- if ext and ext[1:].lower() not in supported_formats:
- logger.warning('{} 格式不受支持。请使用 JPG/JPEG、PNG、TIF/TIFF(LZW 或无压缩)、TGA(24 位,无 RLE)'.format(ext[1:].upper()))
- return
- err = self.editor.set_texture('%s' % texture_path, alpha_path, coverage, translation)
- if err == 'SamePath':
- return
- if err == 'NoTexture':
- logger.warning('无法加载纹理文件。')
- elif err == 'ZeroTexture':
- logger.warning('无效路径或零纹理。请检查导出的纹理位深度和压缩方式。TIF/TIFF(LZW 或无压缩)、TGA(24 位,无 RLE)。')
-
- def manual_curve_update(self):
- """手动更新 UV 曲线"""
- try:
- self._update_curves()
- except BaseException as exc:
- logger.exception(exc)
- finally:
- self._stop_curves_update()
-
- def _update_curves(self):
- if self.uv_update_check == 0:
- mc.undoInfo(ock=1, cn='gsUVUpdate')
- self.uv_update_check = 1
- sel = mc.filterExpand(mc.ls(sl=1), sm=9)
- uvs = self.editor.get_uvs()
- self.current_selection *= 0
- if not sel:
- return
- for curve in sel:
- if curve in uvs:
- self.current_selection.append(curve)
- elif mc.attributeQuery('gsmessage', n=curve, ex=1) and mc.listConnections(curve + '.gsmessage'):
- bound_curves = self.core.utils.get_all_connected_curves(curve)
- if bound_curves:
- self.current_selection += bound_curves
- if not self.timer.increment(0.016666666666666666):
- return
- if not self.current_selection:
- return
- uvs = self.editor.get_uvs()
- for curve in self.current_selection:
- if curve in uvs:
- self.core.attributes.set_attributes(curve, uvs[curve])
-
- def _stop_curves_update(self):
- if self.uv_update_check == 1:
- mc.undoInfo(cck=1)
- self.uv_update_check = 0
- self.current_selection *= 0
- self.core.curve_control.update_ui()
-
- def update_buttons(self, controller_mode, scale_mode):
- """更新按钮状态"""
- assert self.controller_group is not None
- assert self.direction_switch is not None
- buttons = self.controller_group.buttons()
- direction = self.direction_switch.buttons()
- if controller_mode == 'SELECT':
- buttons[0].setChecked(True)
- elif controller_mode == 'MOVE':
- buttons[1].setChecked(True)
- elif controller_mode == 'ROTATE':
- buttons[2].setChecked(True)
- elif controller_mode == 'SCALE':
- buttons[3].setChecked(True)
- if scale_mode == 'H':
- direction[0].setChecked(True)
- else:
- direction[1].setChecked(True)
- elif controller_mode == 'DRAW':
- buttons[4].setChecked(True)
-
- def update_controller_mode(self):
- """更新控制模式"""
- assert self.controller_group is not None
- assert self.direction_switch is not None
- button_id = self.controller_group.checkedId()
- scale_id = self.direction_switch.checkedId()
- scale = 'H'
- if button_id == 0:
- mode = 'SELECT'
- elif button_id == 1:
- mode = 'MOVE'
- elif button_id == 2:
- mode = 'ROTATE'
- elif button_id == 3:
- mode = 'SCALE'
- if scale_id == 0:
- scale = 'H'
- else:
- scale = 'V'
- else:
- mode = 'DRAW'
- self.editor.controller_mode_change(mode, scale)
-
- def update_item_list(self):
- """更新项目列表"""
- sel = mc.filterExpand(mc.ls(sl=1), sm=9)
- if not sel:
- self.uv_list.clear_item_list()
- return
- final_dict = {}
- for curve in sel:
- if mc.attributeQuery('Orientation', n=curve, ex=1) and mc.connectionInfo(curve + '.Orientation', isSource=1):
- if mc.attributeQuery('gsmessage', n=curve, ex=1) and mc.listConnections(curve + '.gsmessage'):
- bound_curves = self.core.utils.get_all_connected_curves(curve)
- final_dict[curve] = bound_curves
- else:
- final_dict[curve] = []
- self.uv_list.update_item_list(final_dict)
-
- def update_visibility(self):
- """更新 UV 的可见性"""
- item_list = self.uv_list.get_selection()
- items = self.editor.get_all_uvs()
- for item in items:
- if item.name in item_list:
- item.setVisible(True)
- else:
- item.setVisible(False)
- self.editor.update()
-
- def hide(self):
- """隐藏选中的 UV 项目"""
- sel_uvs = self.editor.get_all_uvs(selected=True)
- sel_uvs_list = [i.name for i in sel_uvs]
- for uv_item in sel_uvs:
- uv_item.setVisible(False)
- item_list = self.uv_list.get_item_list()
- select_list = []
- for item in item_list:
- if item.curve_name in sel_uvs_list:
- select_list.append(item)
- self.uv_list.select_items(select_list)
-
- def isolate_select(self):
- """隔离选中的 UV 项目"""
- all_uvs = self.editor.get_all_uvs()
- sel_uvs = self.editor.get_all_uvs(selected=True)
- if not sel_uvs:
- return
- if self.isolate_mode:
- self.show_all()
- self.isolate_mode = False
- return
- self.isolate_mode = True
- sel_uvs_list = [i.name for i in sel_uvs]
- for uv_item in all_uvs:
- if uv_item.name not in sel_uvs_list:
- uv_item.setVisible(False)
- item_list = self.uv_list.get_item_list()
- deselect_list = []
- for item in item_list:
- if item.curve_name not in sel_uvs_list:
- deselect_list.append(item)
- self.uv_list.select_items(deselect_list)
-
- def horizontal_flip_uv(self):
- """水平翻转 UV"""
- items = self.editor.get_all_uvs(selected=True)
- for item in items:
- if item.name and mc.attributeQuery('flipUV', n=item.name, ex=1):
- flip = mc.getAttr(item.name + '.flipUV')
- mc.setAttr(item.name + '.flipUV', not flip)
- item.flip = flip
- item.update()
- if items:
- self.editor.update()
-
- def vertical_flip_uv(self):
- """垂直翻转 UV"""
- self.editor.vertical_flip_uvs()
- self.manual_curve_update()
-
- def function_switch(self, key):
- """功能切换"""
- if key == 'H':
- self.horizontal_flip_uv()
- elif key == 'V':
- self.vertical_flip_uv()
- elif key == 'X':
- self.reset_uvs()
- elif key == 'I':
- self.isolate_select()
- elif key == 'O':
- self.hide()
- elif key == 'A':
- self.show_all()
- elif key == 'S':
- self.sync_selection()
-
- def reset_uvs(self):
- """重置 UV"""
- self.editor.reset_uvs()
- self.manual_curve_update()
-
- def randomize_uvs(self):
- """随机化 UV"""
- if get_mod() == 'Shift':
- self.editor.randomize_uvs(True)
- else:
- self.editor.randomize_uvs(False)
- self.manual_curve_update()
-
- def sync_selection(self):
- """根据 UV 编辑器的选择在 Maya 视口中选择曲线"""
- sel = mc.filterExpand(mc.ls(sl=1), sm=9)
- if not sel:
- return
- sel_uvs = [x.name for x in self.editor.get_all_uvs(selected=True)]
- new_sel = [x for x in sel if x in sel_uvs]
- if new_sel:
- mc.select(new_sel, r=1)
-
- @deferred_lp
- def x():
- uvs = self.editor.get_all_uvs()
- for uv_item in uvs:
- uv_item.setSelected(True)
- self.editor.scene().update()
- x()
\ No newline at end of file
diff --git a/2025/scripts/modeling_tools/gs_curvetools/ui/main_window.py b/2025/scripts/modeling_tools/gs_curvetools/ui/main_window.py
deleted file mode 100644
index fc4851b..0000000
--- a/2025/scripts/modeling_tools/gs_curvetools/ui/main_window.py
+++ /dev/null
@@ -1,651 +0,0 @@
-# 字节码版本: 3.11a7e (3495)
-# 源代码时间戳: 2025-04-22 11:47:05 UTC (1745322425)
-
-"""
-GS曲线工具主窗口
----
-GS曲线工具许可协议:
-名为GS曲线工具的此代码集合归乔治·斯拉德科夫斯基(叶戈尔·斯拉德科夫斯基)所有,
-未经他的书面许可,不得复制或分发。
-
-GS曲线工具 v1.3.10 个人版
-版权所有 2025,乔治·斯拉德科夫斯基(叶戈尔·斯拉德科夫斯基)
-保留所有权利
-
-用户界面字体为Roboto,该字体根据Apache 2.0许可协议授权:
-http://www.apache.org/licenses/LICENSE-2.0
-
-Autodesk Maya是Autodesk公司的产品:
-https://www.autodesk.com/
-
-社交媒体和联系方式:
-
-Discord服务器: https://discord.gg/f4DH6HQ
-在线商店: https://sladkovsky3d.artstation.com/store
-在线文档: https://gs-curvetools.readthedocs.io/
-Twitch频道: https://www.twitch.tv/videonomad
-YouTube频道: https://www.youtube.com/c/GeorgeSladkovsky
-ArtStation作品集: https://www.artstation.com/sladkovsky3d
-联系邮箱: george.sladkovsky@gmail.com
-"""
-import os
-from functools import partial
-import maya.cmds as mc
-from gs_curvetools.api.maya_tools import deferred, get_mod, no_undo, undo
-from gs_curvetools.api.qt_compat import *
-from gs_curvetools.api.typing import *
-from gs_curvetools.api.utils import open_link
-from gs_curvetools.config.constants import *
-from gs_curvetools.config.folders import GetFolder
-from gs_curvetools.debug.logger import logger
-from gs_curvetools.managers.options_manager import OptionsManager
-from gs_curvetools.managers.script_jobs import ScriptJobs
-from gs_curvetools.ui import style
-from gs_curvetools.ui.components import AboutWindow, AttributesFilterWindow, CurveControlWindow, CurveThicknessWindow, CustomLayerColorsWindow, GeoToCurveWindow, RandomizeCurveWindow, ScaleFactorWindow, UVEditorWindow
-from gs_curvetools.ui.tooltips import Tooltips
-from gs_curvetools.ui.utils import maya_dockable_window
-from gs_curvetools.ui.widgets import ActionGroup, Button, Frame, Layer, LayerCollectionWidget, Layout, LineEdit, Menu, MenuItem, Row, get_unique_name, maya_slider, separator, wrap_control
-if TYPE_CHECKING:
- from gs_curvetools.core.core import Core
- from gs_curvetools.managers.widget_manager import WidgetManager
-
-class MainWindow(QWidget):
- """Main GS CurveTools window"""
-
- def __init__(self, manager, core):
- menu_height = 786 if MAYA_VER <= 2024 else 810
- dockable_window = maya_dockable_window(name=WINDOWS.MainWindow.name, label=WINDOWS.MainWindow.label, i_h=menu_height)
- mc.workspaceControl(WINDOWS.MainWindow.name, e=1, ui=UI_SCRIPT)
- super(MainWindow, self).__init__(dockable_window)
- self.setParent(dockable_window)
- dockable_layout = dockable_window.layout()
- assert dockable_layout is not None
- dockable_layout.addWidget(self)
- self.widget_manager = manager
- self.core = core
- self.script_jobs = ScriptJobs.singleton()
- self.script_jobs.check_script_jobs(WINDOWS.MainWindow.name)
- self.options_manager = OptionsManager()
- self.tooltips = Tooltips()
- QtGui.QFontDatabase.removeAllApplicationFonts()
- fonts = os.listdir(GetFolder.fonts())
- for font in fonts:
- QtGui.QFontDatabase.addApplicationFont(os.path.join(GetFolder.fonts(), font))
- self.about_window = AboutWindow()
- self.attributes_filter_window = AttributesFilterWindow(self)
- self.curve_control_window = CurveControlWindow(self)
- self.curve_thickness_window = CurveThicknessWindow(self)
- self.custom_layer_colors_window = CustomLayerColorsWindow(self)
- self.geo_to_curve_window = GeoToCurveWindow(self)
- self.randomize_curve_window = RandomizeCurveWindow(self)
- self.scale_factor_window = ScaleFactorWindow(self)
- self.uv_editor = UVEditorWindow(self)
- self.widget_manager.add(WINDOWS.MainWindow.name, dockable_window)
- self._connect_signals()
-
- def _connect_signals(self):
- """Sets up the signals"""
- self.curve_control_window.update_curve_control_ui.connect(self.core.curve_control.update_ui)
- self.curve_control_window.update_main_ui.connect(self.core.updates.update_main_ui)
-
- def create_ui(self):
- """Creates the UI"""
- main_layout = QVBoxLayout(self)
- main_layout.setContentsMargins(*style.scale([2, 0, 2, 0]))
- scroll_area = QScrollArea(self)
- scroll_widget = QWidget()
- scroll_widget.setFocus()
- scroll_layout = QVBoxLayout(scroll_widget)
- scroll_area.setWidget(scroll_widget)
- main_layout.addWidget(scroll_area)
- scroll_layout.setContentsMargins(0, 0, 0, 0)
- scroll_layout.setSpacing(style.scale(2))
- scroll_layout.setAlignment(QtCore.Qt.AlignmentFlag.AlignTop)
- scroll_area.setFrameShape(QtWidgets.QFrame.Shape.NoFrame)
- scroll_area.setWidgetResizable(True)
- menu_bar_widget = QWidget(scroll_area)
- menu_bar_layout = QHBoxLayout(menu_bar_widget)
- menu_bar_layout.setContentsMargins(0, 0, 0, 0)
- menu_bar_layout.setAlignment(QtCore.Qt.AlignmentFlag.AlignCenter)
- menu_bar = QMenuBar(menu_bar_widget)
- menu_bar.setSizePolicy(QtWidgets.QSizePolicy.Policy.Preferred, QtWidgets.QSizePolicy.Policy.Preferred)
- menu_bar_layout.addWidget(menu_bar)
- scroll_layout.addWidget(menu_bar_widget)
- with Menu('选项', menu_bar) as menu:
- menu.triggered.connect(self.options_manager.save)
- menu.addSection('导入 / 导出')
- import_curves = MenuItem('importCurves', '导入曲线', menu)
- import_curves.triggered.connect(no_undo(self.core.import_export.import_curves))
- export_curves = MenuItem('exportCurves', '导出曲线', menu)
- export_curves.triggered.connect(self.core.import_export.export_curves)
- menu.addSection('全局修改器')
- change_scale_factor = MenuItem('changeScaleFactor', '更改比例因子和精度', menu)
- change_scale_factor.triggered.connect(self.scale_factor_window.show_window)
- global_curve_thickness = MenuItem('globalCurveThickness', '全局曲线厚度', menu)
- global_curve_thickness.triggered.connect(self.curve_thickness_window.show_window)
- menu.addSection('视图端口命令')
- ao_settings = MenuItem('setAOSettings', '设置AO设置', menu)
- ao_settings.triggered.connect(self.options_manager.set_ao_settings)
- with Menu('透明度设置', menu) as transparency_settings_menu:
- simple_transparency = MenuItem('setSimpleTransparency', '简单透明度(快速,不准确)', transparency_settings_menu)
- simple_transparency.triggered.connect(partial(no_undo(self.options_manager.set_transparency_settings), 0))
- object_sorting_transparency = MenuItem('setObjectSortingTransparency', '对象排序透明度(中等)', transparency_settings_menu)
- object_sorting_transparency.triggered.connect(partial(no_undo(self.options_manager.set_transparency_settings), 1))
- set_depth_transparency = MenuItem('setDepthTransparency', '深度透明度(准确,缓慢,推荐)', transparency_settings_menu)
- set_depth_transparency.triggered.connect(partial(no_undo(self.options_manager.set_transparency_settings), 2))
- menu.addSection('转换曲线')
- with Menu('转换曲线', menu) as convert_curves_submenu:
- convert_to_warp_card = MenuItem('convertToWarpCard', '转换为变形面片', convert_curves_submenu)
- convert_to_warp_card.triggered.connect(partial(undo(self.core.functions.convert_selection_to), 0))
- convert_to_warp_tube = MenuItem('convertToWarpTube', '转换为变形管', convert_curves_submenu)
- convert_to_warp_tube.triggered.connect(partial(undo(self.core.functions.convert_selection_to), 1))
- convert_to_extrude_card = MenuItem('convertToExtrudeCard', '转换为挤压面片', convert_curves_submenu)
- convert_to_extrude_card.triggered.connect(partial(undo(self.core.functions.convert_selection_to), 2))
- convert_to_extrude_tube = MenuItem('convertToExtrudeTube', '转换为挤压管', convert_curves_submenu)
- convert_to_extrude_tube.triggered.connect(partial(undo(self.core.functions.convert_selection_to), 3))
- menu.addSection('实用功能')
- duplicate_unparent = MenuItem('duplicateUnparentCurves', '复制并取消父级关联曲线', menu)
- duplicate_unparent.triggered.connect(undo(self.core.functions.duplicate_unparent))
- menu.addSection('常规选项')
- MenuItem('keepCurveAttributes', '保留曲线属性', menu, True, self.options_manager.get('keepCurveAttributes'))
- MenuItem('addBetweenBlendAttributes', '添加面片/管混合属性', menu, True, self.options_manager.get('addBetweenBlendAttributes'))
- MenuItem('fillCreateCurvesOnly', '填充仅创建曲线', menu, True, self.options_manager.get('fillCreateCurvesOnly'))
- MenuItem('convertInstances', '自动转换实例', menu, True, self.options_manager.get('convertInstances'))
- MenuItem('useAutoSamplingOnNewCurves', '对新曲线使用自动采样', menu, True, self.options_manager.get('useAutoSamplingOnNewCurves'))
- MenuItem('useAutoRefineOnNewCurves', '对新曲线使用自动细化', menu, True, self.options_manager.get('useAutoRefineOnNewCurves'))
- MenuItem('flipUVsAfterMirror', '镜像后翻转UV', menu, True, self.options_manager.get('flipUVsAfterMirror'))
- enable_tooltips_menu = MenuItem('enableTooltips', '启用工具提示', menu, True, self.options_manager.get('enableTooltips'))
- enable_tooltips_menu.triggered.connect(self.toggle_tooltips)
- menu.addSection('颜色选项')
- sync_color = MenuItem('syncCurveColor', '同步曲线颜色到图层颜色', menu, True, self.options_manager.get('syncCurveColor'))
- sync_color.triggered.connect(self.core.color_mode.sync_curve_colors)
- MenuItem('colorizedRegroup', '对重新分组的图层进行颜色化', menu, True, self.options_manager.get('colorizedRegroup'))
- color_only_diffuse = MenuItem('colorOnlyDiffuse', '颜色仅影响漫反射', menu, True, self.options_manager.get('colorOnlyDiffuse'))
- color_only_diffuse.triggered.connect(self.core.color_mode.update_color_options)
- checker_pattern = MenuItem('checkerPattern', '颜色模式使用棋盘格图案', menu, True, self.options_manager.get('checkerPattern'))
- checker_pattern.triggered.connect(self.core.color_mode.update_color_options)
- menu.addSection('绑定选项')
- MenuItem('boundCurvesFollowParent', '绑定曲线跟随父级', menu, True, self.options_manager.get('boundCurvesFollowParent'))
- MenuItem('massBindOption', '绑定到所有可用的空曲线', menu, True, self.options_manager.get('massBindOption'))
- MenuItem('bindDuplicatesCurves', '绑定前复制曲线', menu, True, self.options_manager.get('bindDuplicatesCurves'))
- MenuItem('bindFlipUVs', '绑定前翻转UV', menu, True, self.options_manager.get('bindFlipUVs'))
- menu.addSection('解绑/解包选项')
- MenuItem('unpackDeleteOriginalObject', '解包时删除原始对象', menu, True, self.options_manager.get('unpackDeleteOriginalObject'))
- MenuItem('unpackCVMatch', '解包匹配原始CV数量', menu, True, self.options_manager.get('unpackCVMatch'))
- menu.addSection('图层选项')
- MenuItem('ignoreLastLayer', '忽略最后一个图层', menu, True, self.options_manager.get('ignoreLastLayer'))
- MenuItem('syncOutlinerLayerVis', '同步大纲/图层可见性', menu, True, self.options_manager.get('syncOutlinerLayerVis'))
- MenuItem('replacingCurveLayerSelection', '替换曲线图层选择', menu, True, self.options_manager.get('replacingCurveLayerSelection'))
- only_numbers_in_layers = MenuItem('layerNumbersOnly', '图层仅使用数字', menu, True, self.options_manager.get('layerNumbersOnly'))
- only_numbers_in_layers.triggered.connect(self.core.layer_manager.change_layers_to_numbers)
- only_numbers_in_layers.triggered.connect(self.update_layer_list)
- with Menu('活动图层数量', menu) as layer_number_menu, ActionGroup('layerRowsActionGroup', layer_number_menu) as action_group:
- MenuItem('2layerRows', '20个图层', layer_number_menu, True, self.options_manager.get('2layerRows'), collection=action_group)
- MenuItem('3layerRows', '30个图层', layer_number_menu, True, self.options_manager.get('3layerRows'), collection=action_group)
- MenuItem('4layerRows', '40个图层', layer_number_menu, True, self.options_manager.get('4layerRows'), collection=action_group)
- MenuItem('6layerRows', '60个图层', layer_number_menu, True, self.options_manager.get('6layerRows'), collection=action_group)
- MenuItem('8layerRows', '80个图层', layer_number_menu, True, self.options_manager.get('8layerRows'), collection=action_group)
- action_group.triggered.connect(self.core.updates.update_main_ui)
- menu.addSection('图层集合选项')
- MenuItem('ignoreTemplateCollections', '忽略“模板”集合名称', menu, True, self.options_manager.get('ignoreTemplateCollections'))
- MenuItem('groupTemplateCollections', '将“模板”集合分组在一起', menu, True, self.options_manager.get('groupTemplateCollections'))
- layer_collections_toggle = MenuItem('showLayerCollectionsMenu', '显示图层集合菜单', menu, True, self.options_manager.get('showLayerCollectionsMenu'))
- layer_collections_toggle.triggered.connect(self.core.layer_manager.layer_collections.toggle_widget)
- MenuItem('importIntoANewCollection', '导入到新集合中', menu, True, self.options_manager.get('importIntoANewCollection'))
- menu.addSection('其他选项')
- with Menu('其他选项', menu) as other_options_menu:
- other_options_menu.addSection('更新功能')
- convert_to_new_layer_system = MenuItem('convertToNewLayerSystem', '转换为新图层系统', other_options_menu)
- convert_to_new_layer_system.triggered.connect(undo(self.core.utils.convert_to_new_layer_system))
- update_layers = MenuItem('updateLayers', '更新图层', other_options_menu)
- update_layers.triggered.connect(undo(self.core.layer_manager.delete_unused_layers))
- from gs_curvetools.main import reset as reset_gs_curvetools
- reset_to_defaults = MenuItem('resetToDefaults', '恢复默认设置', other_options_menu)
- reset_to_defaults.triggered.connect(reset_gs_curvetools)
- other_options_menu.addSection('修复')
- maya_2020_uv_fix = MenuItem('maya2020UVFix', '修复Maya 2020 - 2022 UV错误', other_options_menu)
- maya_2020_uv_fix.triggered.connect(undo(self.core.fixes.fix_maya_2020_uvs))
- fix_broken_graphs = MenuItem('mayaFixBrokenGraphs', '修复损坏的图表', other_options_menu)
- fix_broken_graphs.triggered.connect(undo(self.core.fixes.fix_broken_graphs))
- convert_bezier_to_nurbs = MenuItem('convertBezierToNurbs', '将所选贝塞尔曲线转换为NURBS曲线', other_options_menu)
- convert_bezier_to_nurbs.triggered.connect(undo(self.core.fixes.convert_bezier_to_nurbs))
- maya_2020_twist_fix = MenuItem('maya2020TwistAttribute', '修复Maya 2020.4扭曲属性', other_options_menu)
- maya_2020_twist_fix.triggered.connect(undo(self.core.fixes.fix_maya_2020_twist))
- maya_2020_unbind_fix = MenuItem('maya2020UnbindFix', '修复Maya 2020.4解绑功能', other_options_menu)
- maya_2020_unbind_fix.triggered.connect(undo(self.core.fixes.fix_maya_2020_unbind))
- delete_all_animation_keys = MenuItem('deleteAllAnimationKeys', '删除所有动画关键帧', other_options_menu)
- delete_all_animation_keys.triggered.connect(undo(self.core.fixes.delete_keys_on_all_objects))
- disable_curve_smooth = MenuItem('disableCurveSmooth', '重置旧版曲线平滑属性', other_options_menu)
- disable_curve_smooth.triggered.connect(self.core.fixes.reset_curve_smooth)
- reset_legacy_magnitude = MenuItem('resetLegacyMagnitude', '重置旧版轮廓幅度属性', other_options_menu)
- reset_legacy_magnitude.triggered.connect(self.core.fixes.reset_legacy_profile_magnitude)
- with Menu('帮助', menu_bar) as menu:
- open_log_file = MenuItem('openLogFile', '打开日志文件', menu)
- open_log_file.triggered.connect(logger.open_log_file)
- open_online_documentation = MenuItem('openOnlineDocumentation', '打开在线文档', menu)
- open_online_documentation.triggered.connect(lambda: open_link(USER_DOCS))
- useful_links = MenuItem('usefulLinks', '有用的链接和联系方式', menu)
- useful_links.triggered.connect(self.about_window.social_window)
- with Menu('关于', menu_bar) as menu:
- about_action = MenuItem('gsAbout', '关于', menu)
- about_action.triggered.connect(self.about_window.about_window)
- menu.addSeparator()
- menu.addAction('Made by George Sladkovsky (%s)' % YEAR).setEnabled(False)
- scroll_layout.addWidget(separator())
- with Row(scroll_layout) as row:
- extrude_warp_switch_group = QtWidgets.QButtonGroup(scroll_layout.widget())
- self.widget_manager.add('gsExtrudeWarpSwitchGroup', extrude_warp_switch_group)
- extrude_warp_switch_group.buttonToggled.connect(self.extrude_warp_toggle)
- extrude_warp_switch_group.buttonClicked.connect(self.options_manager.save)
- warp_switch = Button(row.layout(), 'warpSwitch')
- warp_switch.set_label('变形', line_height=100)
- warp_switch.set_button_style('small')
- warp_switch.setCheckable(True)
- extrude_switch = Button(row.layout(), 'extrudeSwitch')
- extrude_switch.set_label('挤压', line_height=100)
- extrude_switch.set_button_style('small')
- extrude_switch.setCheckable(True)
- extrude_warp_switch_group.addButton(warp_switch, 0)
- extrude_warp_switch_group.addButton(extrude_switch, 1)
- with Row(scroll_layout) as row:
- new_card = Button(row.layout(), 'newCard')
- new_card.set_label('新面片')
- new_card.clicked.connect(partial(undo(self.core.create.new), 0))
- new_tube = Button(row.layout(), 'newTube')
- new_tube.set_label('新管')
- new_tube.clicked.connect(partial(undo(self.core.create.new), 1))
- with Row(scroll_layout) as row:
- curve_card = Button(row.layout(), 'curveCard')
- curve_card.set_label('曲线面片')
- curve_card.clicked.connect(partial(undo(self.core.create.from_curves), 0))
- curve_tube = Button(row.layout(), 'curveTube')
- curve_tube.set_label('曲线管')
- curve_tube.clicked.connect(partial(undo(self.core.create.from_curves), 1))
- with Row(scroll_layout) as row:
- bind = Button(row.layout(), 'gsBind')
- bind.set_label('绑定')
- bind.set_icon('mod-top')
- bind.clicked.connect(undo(self.core.create.bind))
- unbind = Button(row.layout(), 'gsUnbind')
- unbind.set_label('解绑')
- unbind.set_icon('mod-top')
- unbind.clicked.connect(undo(lambda: self.core.create.unpack() if get_mod() == 'Shift' else self.core.create.unbind()))
- scroll_layout.addWidget(separator())
- with Row(scroll_layout) as row:
- add_cards = Button(row.layout(), 'addCards')
- add_cards.set_label('添加面片')
- add_cards.set_icon('mod-top')
- add_cards.clicked.connect(partial(undo(self.core.create.add_between), 0))
- add_tubes = Button(row.layout(), 'addTubes')
- add_tubes.set_label('添加管')
- add_tubes.set_icon('mod-top')
- add_tubes.clicked.connect(partial(undo(self.core.create.add_between), 1))
- with Row(scroll_layout) as row:
- fill = Button(row.layout(), 'gsFill')
- fill.set_label('填充')
- fill.set_icon('mod-top')
- fill.clicked.connect(undo(self.core.create.fill))
- subdivide = Button(row.layout(), 'gsSubdivide')
- subdivide.set_label('细分')
- subdivide.set_icon('mod-top')
- subdivide.clicked.connect(undo(self.core.functions.subdivide_curve))
- with Row(scroll_layout) as row:
- m_add_cards_slider = mc.intSliderGrp('gsCurvesSlider', l='添加', f=1, adj=3, cw=[(1, 20), (2, 25), (3, 1)], min=1, max=10, v=3)
- add_cards_slider = maya_slider(m_add_cards_slider, layout=row.layout())
- self.widget_manager.add('gsCurvesSlider', add_cards_slider)
- add_cards_slider.setContentsMargins(0, 0, 0, 0)
- c = add_cards_slider.children()[2]
- if isinstance(c, QWidget):
- c.setFocusPolicy(QtCore.Qt.FocusPolicy.NoFocus)
- scroll_layout.addWidget(separator())
- with Row(scroll_layout) as row:
- edge_to_curve = Button(row.layout(), 'gsEdgeToCurve')
- edge_to_curve.set_label('边转曲线')
- edge_to_curve.set_icon('mod-top')
- edge_to_curve.clicked.connect(undo(self.core.conversion.edge_to_curve))
- geo_to_curve = Button(row.layout(), 'gsGeoToCurve')
- geo_to_curve.set_label('几何体转曲线')
- geo_to_curve.clicked.connect(self.geo_to_curve_window.open_ui)
- scroll_layout.addWidget(separator())
- with Row(scroll_layout, obj_name='LayerCollectionsLayout', spacing=1) as layer_collections_layout:
- layer_combo_box = LayerCollectionWidget('layerCollectionsComboBox')
- layer_combo_box.setStyleSheet(style.SMALL_COMBO_BOX)
-
- def collection_changed():
- self.core.updates.update_visibility_based_on_active_collection()
- self.core.updates.update_main_ui()
- layer_combo_box.currentIndexChanged.connect(lambda *_: deferred(collection_changed)())
- layer_combo_box.setSizeAdjustPolicy(QtWidgets.QComboBox.SizeAdjustPolicy.AdjustToMinimumContentsLengthWithIcon)
- layer_combo_box.setDuplicatesEnabled(False)
- layer_combo_box.setMinimumWidth(0)
- layer_combo_box.setFixedHeight(style.scale(16))
- mc.popupMenu(mm=1, p=layer_combo_box.objectName())
- mc.menuItem(rp='N', l='清除', c=lambda *_: undo(self.core.layer_manager.layer_collections.clear)())
- mc.menuItem(rp='E', l='复制', c=lambda *_: no_undo(self.core.layer_manager.layer_collections.copy)())
- mc.menuItem(rp='NE', l='上移', c=lambda *_: no_undo(self.core.layer_manager.layer_collections.move_up)())
- mc.menuItem(rp='NW', l='合并上移', c=lambda *_: no_undo(self.core.layer_manager.layer_collections.merge_up)())
- mc.menuItem(rp='W', l='粘贴', c=lambda *_: undo(self.core.layer_manager.layer_collections.paste)())
- mc.menuItem(rp='SW', l='合并下移', c=lambda *_: no_undo(self.core.layer_manager.layer_collections.merge_down)())
- mc.menuItem(rp='SE', l='下移', c=lambda *_: no_undo(self.core.layer_manager.layer_collections.move_down)())
- mc.menuItem(rp='S', l='重命名', c=lambda *_: no_undo(self.core.layer_manager.layer_collections.rename)())
- with Row(layer_collections_layout.layout(), margins=style.scale([1, 0, 0, 0])) as plus_minus_buttons_layout:
- layer_combo_plus = Button(obj_name='layerCollectionsPlus', layout=plus_minus_buttons_layout.layout())
- layer_combo_plus.setFixedHeight(style.scale(16))
- layer_combo_plus.set_label('+', line_height=100)
- layer_combo_plus.setMinimumWidth(1)
- layer_combo_plus.set_button_style('small-filled')
- layer_combo_plus.clicked.connect(self.core.layer_manager.layer_collections.create)
- layer_combo_minus = Button(obj_name='layerCollectionsMinus', layout=plus_minus_buttons_layout.layout())
- layer_combo_minus.setEnabled(False)
- layer_combo_minus.setFixedHeight(style.scale(16))
- layer_combo_minus.setMinimumWidth(1)
- layer_combo_minus.set_label('-', line_height=100)
- layer_combo_minus.set_button_style('small-filled')
- layer_combo_minus.clicked.connect(undo(self.core.layer_manager.layer_collections.delete))
- lcl = layer_collections_layout.layout()
- if isinstance(lcl, QHBoxLayout):
- lcl.addWidget(layer_combo_box, 3)
- lcl.addWidget(plus_minus_buttons_layout, 1)
- layer_combo_box.insertItem(0, '主集合')
- with Row(scroll_layout) as row:
- all_filter = Button(row.layout(), 'gsAllFilter')
- all_filter.set_button_style('small-filled')
- all_filter.set_label('全部', line_height=100)
- all_filter.set_icon('mod-top')
- all_filter.clicked.connect(partial(undo(self.core.layer_manager.layers_filter_toggle), True, True))
- curve_filter = Button(row.layout(), 'gsCurveFilter')
- curve_filter.set_button_style('small-filled')
- curve_filter.set_label('曲线', line_height=100)
- curve_filter.clicked.connect(partial(undo(self.core.layer_manager.layers_filter_toggle), True, False, ignore=['Shift+Ctrl']))
- mc.popupMenu(mm=1, p=curve_filter.objectName())
- mc.menuItem(rp='N', l='切换始终置顶', c=lambda *_: undo(self.core.functions.always_on_top_toggle)())
- mc.menuItem(rp='S', l='在非活动集合上自动隐藏曲线', cb=self.options_manager.get('AutoHideCurvesOnInactiveCollections'), c=undo(self.core.layer_manager.collection_visibility_toggle))
- geo_filter = Button(row.layout(), 'gsGeoFilter')
- geo_filter.set_button_style('small-filled')
- geo_filter.set_label('几何体', line_height=100)
- geo_filter.clicked.connect(partial(undo(self.core.layer_manager.layers_filter_toggle), False, True, ignore=['Shift+Ctrl']))
- color_mode = Button(row.layout(), 'colorMode')
- color_mode.set_button_style('small-filled')
- color_mode.setCheckable(True)
- color_mode.setChecked(False)
- color_mode.set_label('颜色', line_height=100)
- color_mode.clicked.connect(undo(self.core.color_mode.toggle_color_vis))
- mc.popupMenu(mm=1, p=color_mode.objectName())
- mc.menuItem(rp='N', l='随机化颜色', c=lambda *_: undo(self.core.color_mode.randomize_colors)())
- mc.menuItem(rp='E', l='重置曲线颜色', c=lambda *_: self.core.color_mode.reset_curve_colors())
- mc.menuItem(rp='W', l='应用曲线颜色', c=lambda *_: self.core.color_mode.sync_curve_colors(True))
- mc.menuItem(rp='S', l='自定义颜色窗口', c=lambda *_: self.custom_layer_colors_window.window())
- with Layout(scroll_layout, obj_name='LayerLayout') as layer_layout:
- layer_button_grp = QtWidgets.QButtonGroup(layer_layout)
- layer_button_grp.setObjectName(get_unique_name('LayerGroup'))
- layer_button_grp.setExclusive(True)
- self.widget_manager.add('LayerGroup', layer_button_grp)
- with Row(layer_layout.layout(), 'layerRow0', spacing=0) as row:
- for i in range(10):
- layer_button_grp.addButton(self.selection_sets(i, row.layout(), str(i)))
- with Row(layer_layout.layout(), 'layerRow1', spacing=0) as row:
- letter = ord('A')
- letters = [chr(i) for i in range(letter, letter + 10)]
- if self.widget_manager.get('layerNumbersOnly').isChecked():
- letters = list(range(10, 20))
- for i in range(10):
- layer_button_grp.addButton(self.selection_sets(i + 10, row.layout(), str(letters[i])))
- with Row(layer_layout.layout(), 'layerRow2', spacing=0) as row:
- for i in range(10):
- layer_button_grp.addButton(self.selection_sets(i + 20, row.layout(), str(i + 20)))
- self.widget_manager.get('layerRow2').setHidden(True)
- with Row(layer_layout.layout(), 'layerRow3', spacing=0) as row:
- for i in range(10):
- layer_button_grp.addButton(self.selection_sets(i + 30, row.layout(), str(i + 30)))
- self.widget_manager.get('layerRow3').setHidden(True)
- with Row(layer_layout.layout(), 'layerRow4', spacing=0) as row:
- for i in range(10):
- layer_button_grp.addButton(self.selection_sets(i + 40, row.layout(), str(i + 40)))
- self.widget_manager.get('layerRow4').setHidden(True)
- with Row(layer_layout.layout(), 'layerRow5', spacing=0) as row:
- for i in range(10):
- layer_button_grp.addButton(self.selection_sets(i + 50, row.layout(), str(i + 50)))
- self.widget_manager.get('layerRow5').setHidden(True)
- with Row(layer_layout.layout(), 'layerRow6', spacing=0) as row:
- for i in range(10):
- layer_button_grp.addButton(self.selection_sets(i + 60, row.layout(), str(i + 60)))
- self.widget_manager.get('layerRow6').setHidden(True)
- with Row(layer_layout.layout(), 'layerRow7', spacing=0) as row:
- for i in range(10):
- layer_button_grp.addButton(self.selection_sets(i + 70, row.layout(), str(i + 70)))
- self.widget_manager.get('layerRow7').setHidden(True)
- self.widget_manager.get('curveGrp0').setChecked(True)
- with Row(scroll_layout) as row:
- extract_selected = Button(row.layout(), 'gsExtractSelected')
- extract_selected.set_label('提取 所选')
- extract_selected.set_icon('mod-bottom')
- extract_selected.clicked.connect(undo(self.core.functions.extract_selected_curves))
- extract_all = Button(row.layout(), 'gsExtractAll')
- extract_all.set_label('提取 全部')
- extract_all.set_icon('mod-bottom')
- extract_all.clicked.connect(undo(self.core.functions.extract_all_curves))
- scroll_layout.addWidget(separator())
- with Row(scroll_layout) as row:
- select_curve = Button(row.layout(), 'gsSelectCurve')
- select_curve.set_label('选择 曲线')
- select_curve.clicked.connect(partial(undo(self.core.utils.select_part), 1))
- select_geo = Button(row.layout(), 'gsSelectGeo')
- select_geo.set_label('选择 几何体')
- select_geo.clicked.connect(partial(undo(self.core.utils.select_part), 2))
- select_group = Button(row.layout(), 'gsSelectGroup')
- select_group.set_label('选择 组')
- select_group.clicked.connect(partial(undo(self.core.utils.select_part), 0))
- with Row(scroll_layout) as row:
- group_curves = Button(row.layout(), 'gsGroupCurves')
- group_curves.set_label('分组 曲线')
- group_curves.clicked.connect(undo(self.core.functions.group_curves))
- regroup_by_layer = Button(row.layout(), 'gsRegroupByLayer')
- regroup_by_layer.set_label('按图层 重新分组')
- regroup_by_layer.clicked.connect(undo(self.core.functions.regroup_by_layer))
- group_name = LineEdit('gsGroupNameTextField', scroll_layout)
- group_name.setAlignment(QtCore.Qt.AlignmentFlag.AlignCenter)
- group_name.set_auto_format(True)
- group_name.setClearButtonEnabled(True)
- group_name.setPlaceholderText('组名称')
- custom_layer_names_colors = Button(scroll_layout, 'gsCustomLayerNamesAndColors')
- custom_layer_names_colors.set_button_style('small-filled')
- custom_layer_names_colors.set_label('图层名称和颜色')
- custom_layer_names_colors.clicked.connect(self.custom_layer_colors_window.window)
- scroll_layout.addWidget(separator())
- scroll_layout.addWidget(wrap_control(mc.text(l='选择控制点')))
- slider_widget = wrap_control(mc.floatSliderGrp('gsSelectCVSlider', w=1, min=0, max=1, step=0.05, dc=self.core.sliders.select_cv_slider, cc=self.core.sliders.release))
- self.widget_manager.add('gsSelectCVSlider', slider_widget)
- scroll_layout.addWidget(slider_widget)
- with Row(scroll_layout) as row:
- transfer_attributes = Button(row.layout(), 'gsTransferAttributes')
- transfer_attributes.set_label('转移 属性.')
-
- transfer_attributes.set_icon('mod-bottom')
- transfer_attributes.clicked.connect(undo(self.core.attributes.transfer_attributes))
- mc.popupMenu(mm=1, p=transfer_attributes.objectName())
- mc.menuItem('gsCopyAttributes', rp='N', l='复制属性', aob=1, c=lambda _: self.core.attributes.copy_attributes())
- mc.menuItem(ob=1, c=lambda _: self.attributes_filter_window.open_ui())
- mc.menuItem('gsPasteAttributes', rp='S', l='粘贴属性', aob=1, c=lambda _: self.core.attributes.paste_attributes())
- mc.menuItem(ob=1, c=lambda _: self.attributes_filter_window.open_ui())
- transfer_uvs = Button(row.layout(), 'gsTransferUVs')
- transfer_uvs.set_label('转移\nUV')
- transfer_uvs.set_icon('mod-bottom')
- transfer_uvs.clicked.connect(undo(self.core.attributes.transfer_uvs))
- mc.popupMenu(mm=1, p=transfer_uvs.objectName())
- mc.menuItem('gsCopyUVs', aob=1, rp='N', l='复制UV', c=lambda _: self.core.attributes.copy_uvs())
- mc.menuItem(ob=1, c=lambda _: self.attributes_filter_window.open_ui())
- mc.menuItem('gsPasteUVs', aob=1, rp='S', l='粘贴UV', c=lambda _: self.core.attributes.paste_uvs())
- mc.menuItem(ob=1, c=lambda _: self.attributes_filter_window.open_ui())
- reset_pivot = Button(row.layout(), 'gsResetPivot')
- reset_pivot.set_label('重置\n轴心点')
- reset_pivot.clicked.connect(undo(self.core.functions.reset_curve_pivot_point))
- reset_pivot.set_icon('mod-bottom')
- mc.popupMenu(mm=1, p=reset_pivot.objectName())
- mc.menuItem('gsResetPivotToRoot', rp='N', l='重置到根部', c=lambda _: self.core.functions.reset_curve_pivot_point())
- mc.menuItem('gsResetPivotToTip', rp='S', l='重置到尖端', c=lambda _: self.core.functions.reset_curve_pivot_point(2))
- scroll_layout.addWidget(separator())
-
- def rebuild_slider_release():
- self.core.sliders.rebuild_slider_release()
- self.core.sliders.release()
-
- def rebuild_button_clicked():
- self.core.sliders.rebuild_slider_drag()
- rebuild_slider_release()
- with Row(scroll_layout, margins=style.scale([1.5, 0, 1.5, 0])) as rebuild_reset_row:
- rebuild_button = Button(obj_name='gsRebuildWithCurrentValue')
- rebuild_button.set_button_style('small-filled')
- rebuild_button.set_label('R', line_height=100)
- rebuild_button.setMinimumWidth(1)
- rebuild_button.setMaximumSize(*style.scale([16, 16]))
- rebuild_button.clicked.connect(rebuild_button_clicked)
- reset_button = Button(obj_name='gsResetRebuildSliderRange')
- reset_button.set_button_style('small-filled')
- reset_button.set_icon('reset')
- reset_button.setMinimumWidth(1)
- reset_button.setMaximumSize(*style.scale([16, 16]))
- reset_button.clicked.connect(lambda: mc.intSliderGrp('gsRebuildSlider', e=1, min=1, max=50))
- rrr = rebuild_reset_row.layout()
- if isinstance(rrr, QHBoxLayout):
- rrr.addWidget(rebuild_button, 1)
- rrr.addWidget(wrap_control(mc.text(l='重建曲线')), 3)
- rrr.addWidget(reset_button, 1)
- rebuild_curve_slider = wrap_control(mc.intSliderGrp('gsRebuildSlider', f=1, cw=[(1, 32), (2, 28)], min=1, max=50, fmx=999, v=1, dc=self.core.sliders.rebuild_slider_drag, cc=lambda *_: rebuild_slider_release()))
- self.widget_manager.add('gsRebuildSlider', rebuild_curve_slider)
- scroll_layout.addWidget(rebuild_curve_slider)
- with Row(scroll_layout) as row:
- duplicate_curve = Button(row.layout(), 'gsDuplicateCurve')
- duplicate_curve.set_label('复制')
- duplicate_curve.clicked.connect(undo(self.core.functions.duplicate_curve))
- randomize_curve = Button(row.layout(), 'gsRandomizeCurve')
- randomize_curve.set_label('随机化')
- randomize_curve.clicked.connect(self.randomize_curve_window.open_ui)
- with Row(scroll_layout) as row:
- extend_curve = Button(row.layout(), 'gsExtendCurve')
- extend_curve.set_label('延伸')
- extend_curve.clicked.connect(undo(self.core.functions.extend_curve))
- reduce_curve = Button(row.layout(), 'gsReduceCurve')
- reduce_curve.set_label('缩减')
- reduce_curve.clicked.connect(undo(self.core.functions.reduce_curve))
- with Row(scroll_layout) as row:
- smooth = Button(row.layout(), 'gsSmooth')
- smooth.set_label('平滑')
- smooth.clicked.connect(undo(self.core.functions.smooth_curve))
- smooth.set_icon('marking-top')
- mc.popupMenu(mm=1, p=smooth.objectName())
- mc.radioMenuItemCollection()
- mc.menuItem('gsSmoothMult1', rp='N', rb=1, l='x1')
- mc.menuItem('gsSmoothMult3', rp='E', rb=0, l='x3')
- mc.menuItem('gsSmoothMult5', rp='S', rb=0, l='x5')
- mc.menuItem('gsSmoothMult10', rp='W', rb=0, l='x10')
- factor_slider = wrap_control(mc.floatSliderGrp('gsFactorSlider', l='因子', adj=3, w=1, cw=[(1, 32), (2, 28)], min=1, max=100))
- self.widget_manager.add('gsFactorSlider', factor_slider)
- scroll_layout.addWidget(factor_slider)
- scroll_layout.addWidget(separator())
- with Frame(scroll_layout, obj_name='MirrorFrame', label='镜像', margins=[1, 1, 1, 1]) as frame:
- with Row(frame.get_frame_layout()) as row:
- mirror_x = Button(row.layout(), 'mirrorX')
- mirror_x.set_label('X')
- mirror_x.set_font_size(16)
- mirror_x.clicked.connect(partial(undo(self.core.functions.mirror_hair), 0))
- mirror_y = Button(row.layout(), 'mirrorY')
- mirror_y.set_label('Y')
- mirror_y.set_font_size(16)
- mirror_y.clicked.connect(partial(undo(self.core.functions.mirror_hair), 1))
- mirror_z = Button(row.layout(), 'mirrorZ')
- mirror_z.set_label('Z')
- mirror_z.set_font_size(16)
- mirror_z.clicked.connect(partial(undo(self.core.functions.mirror_hair), 2))
- with Row(frame.get_frame_layout()) as row:
- mirror_flip_grp = QtWidgets.QButtonGroup(row)
- mirror = Button(row.layout(), 'mirrorRadio')
- mirror.set_label('镜像')
- mirror.set_button_style('small')
- mirror.setCheckable(True)
- mirror.setChecked(True)
- flip = Button(row.layout(), 'flipRadio')
- flip.set_label('翻转')
- flip.set_button_style('small')
- flip.setCheckable(True)
- mirror_flip_grp.addButton(mirror)
- mirror_flip_grp.addButton(flip)
- scroll_layout.addWidget(separator())
- with Row(scroll_layout) as row:
- control_curve = Button(row.layout(), 'gsControlCurve')
- control_curve.set_label('控制曲线')
- control_curve.clicked.connect(undo(self.core.functions.control_curve_create))
- apply_control_curve = Button(row.layout(), 'gsApplyControlCurve')
- apply_control_curve.set_label('应用')
- apply_control_curve.setFixedWidth(style.scale(48))
- apply_control_curve.clicked.connect(undo(self.core.functions.control_curve_apply))
- scroll_layout.addWidget(separator())
- with Row(scroll_layout) as row:
- curve_control_window = Button(row.layout(), 'gsCurveControlWindow')
- curve_control_window.set_label('曲线控制窗口')
- curve_control_window.pressed.connect(self.curve_control_window.open_ui)
- scroll_layout.addWidget(separator())
- with Row(scroll_layout) as row:
- uv_editor = Button(row.layout(), 'gsUVEditorMain')
- uv_editor.set_label('UV编辑器窗口')
- uv_editor.pressed.connect(self.uv_editor.open_ui)
- scroll_layout.addWidget(separator())
- scroll_layout.addWidget(wrap_control(mc.text(l=VERSION)))
- warp_switch.setChecked(self.options_manager.get('warpSwitch'))
- extrude_switch.setChecked(not self.options_manager.get('warpSwitch'))
- self.core.layer_manager.layer_collections.toggle_widget()
- self.tooltips.toggle_custom_tooltips_main(self.options_manager.get('enableTooltips'))
-
- def selection_sets(self, i, layout, label):
- def toggle_geometry_edit(*_):
- self.core.layer_manager.curve_geometry_edit_toggle(i)
- self.core.updates.update_main_ui()
-
- def toggle_curve_visibility(*_):
- self.core.layer_manager.toggle_obj_visibility(i, 0)
- self.core.updates.update_main_ui()
-
- def toggle_geo_visibility(*_):
- self.core.layer_manager.toggle_obj_visibility(i, 1)
- self.core.updates.update_main_ui()
-
- def toggle_layer_visibility(*_):
- self.core.layer_manager.toggle_layer_visibility(i)
- self.core.updates.update_main_ui()
- sel_set = Layer(layout=layout, obj_name='curveGrp%s' % i)
- sel_set.setStyleSheet(style.layer())
- sel_set.set_label(str(label))
- mc.popupMenu(mm=1, p=sel_set.objectName())
- mc.menuItem(rp='N', l='将所选内容添加到图层', c=lambda _: self.core.layer_manager.curve_add_to_layer(i))
- mc.menuItem(rp='NW', l='提取几何体', c=lambda _: self.core.functions.extract_curve_geo(i))
- mc.menuItem(rp='NE', l='切换几何体编辑', c=toggle_geometry_edit)
- mc.menuItem(rp='W', l='选择曲线', c=lambda _: self.core.layer_manager.curve_layer_select_obj(i, 0))
- mc.menuItem(rp='E', l='选择几何体', c=lambda _: self.core.layer_manager.curve_layer_select_obj(i, 1))
- mc.menuItem(rp='SW', l='切换曲线可见性', c=toggle_curve_visibility)
- mc.menuItem(rp='SE', l='切换几何体可见性', c=toggle_geo_visibility)
- mc.menuItem(rp='S', l='切换图层可见性', c=toggle_layer_visibility)
- sel_set.clicked.connect(partial(undo(self.core.layer_manager.layer_clicked), i))
- return sel_set
-
- def extrude_warp_toggle(self):
- """Toggle the extrude/warp switch"""
- buttons = ['newCard', 'newTube', 'curveCard', 'curveTube', 'addCards', 'addTubes']
- button_style = style.BUTTON_NORMAL
- if self.widget_manager.get('extrudeSwitch').isChecked():
- button_style = style.BUTTON_NORMAL_BLUE_BORDER
- for button in buttons:
- self.widget_manager.get(button).setStyleSheet(button_style)
-
- def update_layer_list(self):
- """Update the layer list"""
- if self.widget_manager.exists('gsLayerSelector'):
- self.widget_manager.get('gsLayerSelector').updateLayerList()
- self.core.curve_control.update_ui()
-
- def toggle_tooltips(self):
- """Toggle the custom tooltips"""
- for widget in self.widget_manager.get_widgets():
- if hasattr(widget, 'enable_tooltip') and callable(getattr(widget, 'enable_tooltip')):
- widget.enable_tooltip(self.options_manager.get('enableTooltips'))
- self.tooltips.toggle_custom_tooltips_main(self.options_manager.get('enableTooltips'))
- self.tooltips.toggle_custom_tooltips_curve_control(self.options_manager.get('enableTooltips'))
- self.tooltips.toggle_custom_tooltips_scale_factor(self.options_manager.get('enableTooltips'))
\ No newline at end of file
diff --git a/2025/scripts/modeling_tools/gs_curvetools/ui/tooltips.md b/2025/scripts/modeling_tools/gs_curvetools/ui/tooltips.md
deleted file mode 100644
index e1b7897..0000000
--- a/2025/scripts/modeling_tools/gs_curvetools/ui/tooltips.md
+++ /dev/null
@@ -1,967 +0,0 @@
-
-
-
-
-
-# importCurves
-Imports Curves that were Exported using the Export Button.
-NOTE: Only import files that were exported using Export Curves button.
-WARNING: This operation is NOT undoable!
-
-# exportCurves
-Exports selected curves into a .curves (or .ma) file. Can then be Imported using Import Curves.
-
-# changeScaleFactor
-Opens a window that controls the Scale Factor and Precision Scale.
-***
-Scale factor determines the initial size of the created curve and adjusts other parameters.
-Scale factor is stored in a global preset, in the scene and on each curve.
-Priority of scale factors Curve>Scene>Global.
-Setting the appropriate scale factor before starting a project can help to have a good initial Width and size of the cards.
-***
-Precision Scale controls the world scale of the curve without changing the curve appearance, CV positions and other parameters.
-Lowering the Precision scale (from 1.0 to 0.05 for example) helps to fix the geometry deformation on very small curves.
-The default value of 0.05 should be sufficient for most cases. Values lower than 0.01 can affect performance.
-***
-Normalize Selected and Normalize Selected to Default will change the Scale Factor and Precision Scale of the selected curves, without changing their appearance or CV positions.
-Normalize Selected to Default will reset the slider values to default (0.5 and 0.05) and Normalize Selected will use the current slider values.
-
-# normalizeSelectedButton
-Normalize selected curves to the chosen slider values.
-Normalization will not change the CV positions or geometry appearance, but the selected objects will have new Scale Factor and Precision Scale applied.
-
-# normalizeSelectedToDefaultButton
-Normalize selected curves to the default slider values (0.5, 0.05).
-Resets the slider values to the default.
-Normalization will not change the CV positions or geometry appearance, but the selected objects will have new Scale Factor and Precision Scale applied.
-
-# saveScaleFactorAndPrecisionScaleButton
-Saves the selected slider values to the global storage and to the current scene.
-New scenes will automatically have these Scale Factor and Precision Scale values.
-NOTE: This will not apply the new values to already existing objects. See Normalize buttons.
-
-# saveScaleFactorAndPrecisionScaleButtonAndClose
-Saves the selected slider values to the global storage and to the current scene.
-New scenes will automatically have these Scale Factor and Precision Scale values.
-Closes the window after save.
-NOTE: This will not apply the new values to already existing objects. See Normalize buttons.
-
-# closePrecisionScaleWindow
-Close this window without save
-
-# globalCurveThickness
-Opens a window that controls the thickness of the curves in the scene as well as the global curve thickness preset across the scenes.
-
-# setAOSettings
-Manually sets the recommended AO settings for older Maya versions.
-These AO settings are needed to use the "See Through" or "Toggle Always on Top" functions.
-Are applied automatically by those functions.
-
-# setTransparencySettings
-Sets recommended transparency settings for Maya viewport.
-***
-Simple Transparency is fast but very inaccurate render mode. Only suitable for simple, one layer hair.
-Object Sorting Transparency has average performance impact and quality. Can have issues on complex multi-layered grooms.
-Depth Transparency - these are the optimal settings for the highest quality of the hair cards preview. Can have performance impact on slower systems.
-
-# convertToWarpCard
-Converts selection to Warp Cards.
-Compatible attributes are retained.
-
-# convertToWarpTube
-Converts selection to Warp Tubes.
-Compatible attributes are retained.
-
-# convertToExtrudeCard
-Converts selection to Extrude Cards.
-Compatible attributes are retained.
-
-# convertToExtrudeTube
-Converts selection to Extrude Tubes.
-Compatible attributes are retained.
-
-# duplicateUnparentCurves
-Duplicates selected NURBS curves and unparents them (parents them to the world).
-Original curves are not deleted.
-Can be used to easily extract and export curves from GS CurveTools objects.
-
-# syncCurveColor
-Toggles the syncing of the curve color to the layer color.
-
-# colorizedRegroup
-Toggles the colorization of the regrouped layers when Regroup by Layer function is used.
-
-# colorOnlyDiffuse
-Colorize only the diffuse component of the card material.
-Alpha will stay the same.
-
-# checkerPattern
-Toggles the use of the checker pattern when the Color mode is enabled.
-
-# ignoreLastLayer
-Toggles the filtering (All, Curve, Geo) and Extraction (Extract All) of the last layer. If enabled, the last layer is ignored.
-NOTE: Last layer is typically used for templates, so it is ignored by default.
-
-# ignoreTemplateCollections
-Ignores the filtering (All, Curve, Geo) and Extraction (Extract All) of all the collections that have "template" in their name. Case insensitive.
-
-# groupTemplateCollections
-Collections that have "template" in their name (case insensitive) will be grouped together into "CT_Templates" group by Regroup By Layer function.
-
-# syncOutlinerLayerVis
-Syncs the outliner and layer visibility. If enabled, hiding the layer will also hide the curve groups in the outliner.
-
-# keepCurveAttributes
-If enabled, the attributes that are stored in the curve will be restored if the curve that was duplicated (on its own, without the geo) is used to create other cards or tubes.
-If disabled, the attributes will be ignored and reset.
-Example:
-1. Create a card and change its twist value.
-2. Ctrl+D and Shift+P the curve (not the curve group).
-3. Click Curve Card and the twist value will be restored on a newly created card.
-
-# boundCurvesFollowParent
-Will ensure that moving a parent curve in a Bound Object (Bound Group) will also move all the child curves along with it to a new layer. Recommended to keep this enabled.
-
-# massBindOption
-Will bind selected hair clump (or geometry) to all selected "empty" curves.
-
-# bindDuplicatesCurves
-Will automatically duplicate the curves before binding them to the curve, leaving old curves behind with no edits.
-
-# bindFlipUVs
-Enabling this option will flip the UVs of the original cards before binding them to the curve.
-This option will also flip the UVs back when using Unbind for better workflow.
-Disabling this option will result in an old Bind/Unbind behaviour.
-
-# unpackDeleteOriginalObject
-Unpack (Shift + Click on Unbind) will delete the original Bind object.
-
-# unpackCVMatch
-Unpack (Shift + Click on Unbind) will match the CVs of the original Bind object.
-
-# addBetweenBlendAttributes
-Enables blending of the attributes when using Add Cards/Tubes or Fill functions.
-
-# fillCreateCurvesOnly
-When enabled Fill function will only create curves (not the geo).
-
-# convertInstances
-Will automatically convert instanced curves to normal curves before any other function is applied.
-
-# replacingCurveLayerSelection
-Will disable additive selection for the layers. When holding Ctrl and clicking on a new layer, old layer will be deselected automatically.
-
-# useAutoRefineOnNewCurves
-Automatically enables auto-refine on the new curves.
-
-# flipUVsAfterMirror
-Enabling this option will flip the UVs horizontally after mirroring the cards to achieve exact mirroring.
-
-# enableTooltips
-Will toggle the visibility of these tooltips you are reading right now.
-
-# showLayerCollectionsMenu
-Shows layer collections menu widget.
-
-# importIntoANewCollection
-If enabled, all the imported curves will be placed into a new "Imported Curves" layer collection.
-If disabled, all the imported curves will be placed into the "Main" layer collection
-
-# layerNumbersOnly
-Layers will use only numbers if enabled.
-
-# convertToNewLayerSystem
-Converts all the layers in the scene to a new layer system that is hidden from the Channel Box Display Layers window.
-Layers can still be accessed from Window->Relationship Editors->Display Layer window.
-
-# updateLayers
-Utility function that will manually update all layers. Used for if layers are correct for some reason.
-
-# resetToDefaults
-Resets every option and the GS CurveTools to the default "factory" state.
-
-# maya2020UVFix
-This function will fix any broken UVs when trying to open old scenes in Maya 2020 or 2022 or when opening scenes in 2020 and 2022 when using Maya Binary file type. This will have no effect on older versions of Maya (<2020). This bug is native to Maya and thus can’t be fixed in GS CurveTools plug-in.
-
-# mayaFixBrokenGraphs
-This function will attempt to fix all the broken graphs in the scene.
-Use if one of the graphs (Width, Twist or Profile) is in a broken state.
-
-# convertBezierToNurbs
-Converts the selected Bezier curves to NURBS curves.
-Bezier curves are not supported by the GS CurveTools.
-
-# maya2020TwistAttribute
-This function will fix any broken cards created in Maya 2020.4 before v1.2.2 update.
-
-# maya2020UnbindFix
-This function will fix any cards that are not unbinding properly and were created before v1.2.3 update in Maya 2020.4.
-
-# deleteAllAnimationKeys
-This function will delete all the animation keys on all the curves present in the scene.
-This can fix deformation issues when using duplicate or other GS CurveTools functions.
-Some functions (like duplicate) will delete the keys automatically, however the keys can still cause issues.
-
-
-
-# warpSwitch
-Advanced cards and tubes suitable for longer hair.
-Additional options and controls.
-Slower than Extrude (viewport performance).
-Can have issues on very small scales.
-
-# extrudeSwitch
-Simple cards and tubes suitable for shorter hair and brows.
-Has limited controls.
-Much faster than Warp (viewport performance).
-Better for small scales.
-
-# newCard
-Creates a new Card in the middle of the world. Used at the beginning of the project to create templates.
-
-# newTube
-Creates a new Tube in the middle of the world. Used at the beginning of the project to create templates.
-
-# curveCard
-Converts selected Maya curve to CurveTools Card.
-
-# curveTube
-Converts selected Maya curve to CurveTools Tube.
-
-# gsBind
-Binds selection to a single curve. Creates a Bind Group. Selection options:
-1. Single "empty" curve (default Maya curve) and single combined geometry.
-2. Single "empty" curve (default Maya curve) and any number of Curve Cards and Curve Tubes.
-***
-Shift + Click will duplicate the original curves/geo before binding it to the empty curve.
-Same option is available in the Options menu (Duplicate Curves Before Bind).
-
-# gsUnbind
-Normal Click:
-UnBinds geometry or Cards/Tubes from selected Bound object.
-Geometry and Cards/Tubes will be placed at the origin.
-***
-Shift + Click:
-Will UNPACK the selected Bind object in-place.
-Unpack will attempt to create an in-place approximation of the cards and tubes that Bind object consists of.
-Basically it will extract the geometry and create cards (or tubes) based on that geometry.
-The original Bind object will be deleted in the process. Optionally, you can keep it (toggle in the options menu).
-This operation is not procedural, so you will not be able to return back to the Bind object after (unlike regular UnBind).
-WARNING: Unpack is not a 1 to 1 conversion. It will try its best to approximate the shape, but complex twists and bends will not be captured.
-
-# addCards
-Creates Cards in-between selected Cards based on the Add slider value.
-Shift + Click: creates objects but does not blend the attributes.
-Bound objects are NOT supported.
-
-NOTE: Selection order defines the direction of added Cards if more than 2 initial Cards are selected.
-
-# addTubes
-Creates Tubes in-between selected Tubes based on the Add slider value.
-Shift + Click: creates objects but does not blend the attributes.
-Bound objects are NOT supported.
-
-NOTE: Selection order defines the direction of added Tubes if more than 2 initial Tubes are selected.
-
-# gsFill
-Creates Cards/Tubes or Bound Groups in between selected Cards/Tubes or Bound Groups based on the Add slider value.
-Shift + Click: creates objects but does not blend the attributes.
-
-NOTE 1: Selection order defines the direction of added curves if more than 2 initial curves are selected.
-NOTE 2: The type of Card or Tube or Bound Group is defined by the previous curve in the selection chain.
-NOTE 3: Options -> Fill Creates Only Curves option will make the Fill function create only NURBS curves, but not the geo.
-
-# gsSubdivide
-Subdivides selected curve into multiple curves based on the Add slider value
-Shift + Click subdivides selected curve but does not delete the original curve
-
-# gsEdgeToCurve
-Converts selected geometry edges to curves.
-Multiple unconnected edge groups can be selected at the same time.
-***
-Key Combinations:
-Shift + Click will create a curve without the curvature (first degree curve or simply a line)
-
-# gsGeoToCurve
-Opens the Geo-to-Curve UI
-Geo to Curve algorithm will attempt to generate GS CurveTools cards and tubes from selected geometry.
-Selected geometry should be either one-sided cards or regular tubes without caps (or both).
-Multi-selection compatible, but selected geometries should be separate objects and not one combined object.
-
-# layerCollectionsComboBox
-Layer collections drop-down menu.
-Allows to separate the project into different layer collections, up to 80 layers in each collection.
-Has additional functionality in marking menu (Hold RMB):
-***
-Marking menu:
-1. Clear - will delete all the cards from the current layer. Undoable operation.
-2. Merge Up, Merge Down - merge all the cards from the current layer to the layer above or below it.
-3. Copy, Paste - will copy all the cards from the current layer and paste them to the layer that user selects.
-4. Move Up, Move Down - will rearrange the current layer collections by moving the currently selected collection up or down in the list.
-5. Rename - will rename the current layer collection
-
-# layerCollectionsPlus
-Add additional layer collection after the current one.
-
-# layerCollectionsMinus
-Remove current layer collection. All the cards from the removed collection will be merged one layer UP.
-
-# gsAllFilter
-Layer filter. Controls the visibility of all objects in all layers:
-Normal click will show all curves and geometry in all layers.
-Shift + Click will hide all curves and geometry in all layers
-Ctrl + Click will show all the curves and geometry in all layers and all collections.
-Ctrl + Shift + Click will hide all curves and geometry in all layers and all collections.
-
-# gsCurveFilter
-Layer filter. Hides all geometry and shows all the curves in all layers.
-Ctrl + Click will do the same thing, but for all layers and all collections.
-NOTE: Holding RMB will open a marking menu with Toggle Always on Top function as well as "Auto-Hide Inactive Curves" function.
-Toggle Always on Top function will toggle the Always on Top feature that will show the curve component always on top. The effect is different in different Maya versions
-Auto-Hide Inactive Curves will hide all the curve components on all inactive layer collections when switching between collections.
-
-# gsGeoFilter
-Layer filter. Hides all curves and shows only geometry.
-Ctrl + Click will do the same thing, but for all layers and all collections.
-
-# colorMode
-Color mode toggle. Enables colors for each layer and (optionally) UV checker material.
-NOTE: Checker pattern can be disabled in the Options menu
-
-# curveGrp0
-Curve Layers that are used for organization of the cards and tubes in the scene.
-Selected layer (white outline) will be used to store newly created cards.
-Holding RMB will open a marking menu with all the functions of current layer.
-***
-Key Combinations:
-Shift + Click: additively select the contents of the layers.
-Ctrl + Click: exclusively select the contents of the layer.
-Alt + Click: show/hide selected layer.
-Ctrl + Shift: show/hide curve component on selected layer.
-Ctrl + Alt: show/hide geo component for the selected layer.
-Shift + Alt + Click: isolate select the layer.
-Shift + Ctrl + Alt + Click: enable Always on Top for each layer (only for Maya 2022+).
-***
-Layer MMB Dragging:
-MMB + Drag: move the contents of one layer to another layer. Combine if target layer has contents.
-MMB + Shift + Drag: copy the contents of one layer to another layer. Copy and Add if target layer has contents.
-
-# gsExtractSelected
-Extracts (Duplicates) the geometry component from the selected curves:
-***
-Key Combinations:
-Normal click will extract geometry and combine it.
-Shift + Click will extract geometry as individual cards.
-Ctrl + Click will extract geometry, combine it, open export menu and delete the extracted geo after export.
-Shift + Ctrl click will extract geometry, open export menu and delete the extracted geo after export.
-
-# gsExtractAll
-Extracts (Duplicates) the geometry component from all layers and collections. Original layers are HIDDEN, NOT deleted:
-Last Layer in the current Collection is ignored by default. Can be changed in the options.
-Collections with "template" in their name (case insensitive) will be ignored by default. Can be changed in the options.
-***
-Key Combinations:
-Normal click will extract geometry and combine it.
-Shift + Click will extract geometry as individual cards grouped by layers.
-Ctrl + Click will extract geometry, combine it, open export menu and delete the extracted geo after export.
-Shift + Ctrl click will extract geometry, open export menu and delete the extracted geo after export.
-
-# gsSelectCurve
-Selects the curve components of the selected Curve Cards/Tubes.
-NOTE: Useful during the selection in the outliner.
-
-# gsSelectGeo
-Selects the geometry component of the selected Curve Cards/Tubes.
-NOTE: Useful for quick assignment of the materials.
-
-# gsSelectGroup
-Selects the group component of the selected Curve Cards/Tubes.
-NOTE: Useful when you are deleting curves from viewport selection.
-
-# gsGroupCurves
-Groups the selected curves and assigns the name from Group Name input field (or default name if empty).
-
-# gsRegroupByLayer
-Regroups all the curves based on their layer number, group names and collection names.
-Group names can be changed in the Layer Names & Colors menu.
-Groups can be colorized if the "Colorize Regrouped Layers" is enabled in the Options menu.
-Collections with "template" in their name will be grouped under "CT_Templates". Can be changed in the options.
-
-# gsGroupNameTextField
-The name used by the Group Curves function.
-If empty, uses the default name.
-
-# gsCustomLayerNamesAndColors
-Opens a menu where group names and colors can be changed and stored in a global preset.
-
-# gsTransferAttributes
-Transfers attributes from the FIRST selected curve to ALL the other curves in the selection.
-NOTE: Shift + Click transfers the attributes from the LAST selected curve to ALL others.
-NOTE2: Holding RMB on this button opens a marking menu with Copy-Paste and Filter functionality
-
-# gsTransferUVs
-Transfers UVs from the FIRST selected curve to ALL the other curves in the selection.
-NOTE: Shift + Click transfers the UVs from the LAST selected curve to ALL others.
-NOTE2: Holding RMB on this button opens a marking menu with Copy-Paste and Filter functionality
-
-# gsResetPivot
-Resets the pivot on all selected curves to the default position (root CV).
-
-# gsRebuildWithCurrentValue
-Rebuild selected curves using current rebuild slider value
-
-# gsResetRebuildSliderRange
-Reset rebuild slider range (1 to 50)
-
-# gsDuplicateCurve
-Duplicates all the selected curves and selects them.
-NOTE: You can select either NURBS curve component, geometry component or group to duplicate.
-
-# gsRandomizeCurve
-Opens a window where different attributes of the selected curves can be randomized:
-1. Enable the sections of interest and change the parameters.
-2. Dragging the sliders in each section enables a PREVIEW of the randomization. Releasing the slider will reset the curves.
-3. Click Randomize if you wish to apply the current randomization.
-
-# gsExtendCurve
-Lengthens a selected curves based on the Factor slider.
-
-# gsReduceCurve
-Shortens the selected curves based on the Factor slider.
-
-# gsSmooth
-Smoothes selected curves or curve CVs based on the Factor slider.
-NOTE 1: At least 3 CVs should be selected for component smoothing.
-NOTE 2: Holding RMB will open a marking menu where you can select a stronger smoothing algorithm.
-
-# mirrorX
-Mirrors or Flips all the selected curves on the World X axis.
-
-# mirrorY
-Mirrors or Flips all the selected curves on the World Y axis.
-
-# mirrorZ
-Mirrors or Flips all the selected curves on the World Z axis.
-
-# gsControlCurve
-Adds a Control Curve Deformer to the selected curves. Can be used to adjust groups of curves.
-NOTE 1: Should NOT be used to permanently control clumps of cards. Use Bind instead.
-
-# gsApplyControlCurve
-Applies the Control Curve Deformer.
-Either the Control Curve or any controlled Curves can be selected for this to work.
-
-# gsCurveControlWindow
-Opens a Curve Control Window. Contains all the available controls for curves.
-
-# gsUVEditorMain
-Opens a UV editor that can be used to setup and adjust UVs on multiple cards.
-NOTE 1: Lambert material with PNG, JPG/JPEG or TIF/TIFF (LZW or No Compression) texture file is recommended. TGA (24bit and no RLE) is also supported.
-NOTE 2: Make sure to select the curves or the group, not the geo, to adjust the UVs.
-NOTE 3: Using default Maya UV editor will break GS CurveTools Cards, Tubes and Bound Groups.
-NOTE 4: Default UV editor can be used when custom geometry is used in a Bound Groups.
-
-
-
-
-# gsLayerSelector
-Shows the Layer of the selected curve.
-Selecting different layer will change the layer of all the selected curves.
-
-# gsColorPicker
-Layer/Card Color Picker.
-
-# gsCurveColorPicker
-Curve Color Picker.
-
-# selectedObjectName
-Selected object name. Editing this field will rename all the selected objects.
-
-# lineWidth
-Controls the thickness of the selected curves.
-
-# gsBindAxisAuto
-Automatic selection of the bind Axis (recommended).
-NOTE: Change to manual X, Y, Z axis if bind operation result is not acceptable.
-
-# AxisFlip
-Flips the direction of the bound geometry.
-
-# editOrigObj
-Temporarily disables curve bind and shows the original objects.
-Used to adjust the objects after the bind.
-To add or remove from the Bound group use Unbind.
-
-# selectOriginalCurves
-Selects the original curves that were attached to a bind curve.
-Allows to edit their attributes without using Unbind or Edit Original Objects
-
-# twistCurveFrame
-Advanced twist control graph. Allows for precise twisting of the geometry along the curve. Click to expand.
-
-# Magnitude
-Twist multiplier. The larger the values, the more the twist. Default is 0.5.
-
-# gsTwistGraphResetButton
-Resets the graph to the default state.
-
-# gsTwistGraphPopOut
-Opens a larger graph in a separate window that is synced to the main graph.
-
-# widthLockSwitch
-Links/Unlinks the X and Z width sliders.
-If linked, the sliders will move as one.
-
-# LengthLock
-Locks/Unlocks the length slider.
-When Locked the geometry is stretched to the length of the curve and the slider is ignored.
-
-# widthCurveFrame
-Advanced width control graph. Allows for precise scaling of the geometry along the curve. Click to expand.
-
-# gsWidthGraphResetButton
-Resets the graph to the default state.
-
-# gsWidthGraphPopOut
-Opens a larger graph in a separate window that is synced to the main graph.
-
-# profileCurveGraph
-Advanced control over the profile of the card. Modifies the profile applied by the Profile slider. Click to expand.
-Add or remove points and change them to increase or decrease the Profile value along the curve.
-
-# autoEqualizeSwitchOn
-Locks the points horizontally to equal intervals to avoid geometry deformation.
-
-# autoEqualizeSwitchOff
-Unlocks the points and allows for the full control.
-
-# equalizeCurveButton
-Snaps the points to the equal horizontal intervals.
-
-# gsResetProfileGraphButton
-Resets the curve to the default state.
-
-# gsProfileGraphPopOut
-Opens a larger graph in a separate window that is synced to the main graph.
-
-# reverseNormals
-Reverses the normals on the selected cards/tubes.
-
-# orientToNormalsFrame
-Orient selected cards/tubes to the normals of the selected geo.
-
-# gsOrientToNormalsSelectTarget
-Set selected mesh as a target for the algorithm.
-
-# orientRefreshViewport
-Toggles the viewport update during the alignment process.
-Disabling can speed up the process.
-
-# gsOrientToNormals
-Starts the alignment process.
-Will align the selected cards to the normals of the selected geometry.
-
-# flipUV
-Flips the UVs of the card/tube horizontally.
-
-# resetControlSliders
-Resets the range of the sliders to the default state.
-
-# UVFrame
-Legacy controls for the UVs. Just use the new UV Editor.
-
-# solidifyFrame
-Expands controls that control the thickness of the cards/tubes.
-
-# solidify
-Toggles the thickness of the geometry.
-
-
-
-# lengthDivisions
-Change the length divisions of the selected cards/tubes.
-
-# dynamicDivisions
-Toggles the dynamic divisions mode.
-Dynamic divisions will change the divisions of the cards/tubes based on the length of the curves.
-In dynamic divisions mode, L-Div slider will control the density of the divisions, not the fixed divisions count.
-
-# widthDivisions
-Change the width divisions of the selected cards/tubes.
-
-# Orientation
-Change the orientation of the card/tube around the curve.
-
-# Twist
-Smoothly twist the entire geometry card/tube. Twists the tip of the card.
-
-# invTwist
-Smoothly twist the entire geometry card. Twists the root of the card.
-
-# Width
-Change the width of the selected card.
-
-# Taper
-Linearly changes the width of the card/tube along the length of the curve.
-
-# WidthX
-Change the width of the tube along the X axis.
-
-# WidthZ
-Change the width of the tube along the Z axis.
-
-# Length
-Change the length of the attached geometry. Works only when Length Unlock button is checked.
-
-# Offset
-Offset the geometry along the curve.
-
-# Profile
-Change the profile of the card along the length of the curve uniformly.
-
-# profileSmoothing
-Smoothing will smooth the profile transition.
-
-# otherFrame
-Other less used options
-
-# curveRefine
-Controls the number of "virtual" vertices on the curve. These are the vertices that are used to calculate the geometry deformation.
-Zero (0) value will disable the refinement and the geometry will be attached directly to the curve. The fastest option.
-Larger refine values means smoother geometry that is a closer fit to the curve.
-Only increase past 20 if you need additional precision or if there are any visual glitches with the geometry.
-Large refine values can cause significant performance drop, lag and other issues on smaller curve sizes.
-Recommended values are:
-20 for curves with less than 20 CVs.
-0 (disabled) or same as the number of CVs for curves with more than 20 CVs.
-
-# autoRefine
-Enables auto-refine for selected curves. Recommended to keep this on.
-Manual refinement can be helpful if the geometry deformation is wrong or not precise enough.
-
-# samplingAccuracy
-Increases the sampling accuracy of the deformer that attaches the geometry to a curve.
-Larger values = more precise geometry fit to a curve and more lag.
-
-# surfaceNormals
-Changes the smoothing angle of the normals of the geometry.
-
-# gsIterationsSlider
-Controls the number of iterations per card.
-
-# gsMinimumAngle
-Controls the target angle difference between the normal of the mesh and the card.
-
-# solidifyThickness
-Controls the amount of thickness on the geometry.
-
-# solidifyDivisions
-Controls the number of divisions on the solidify extrusion.
-
-# solidifyScaleX
-Changes the scale on the X axis.
-
-# solidifyScaleY
-Changes the scale on the Y axis.
-
-# solidifyOffset
-Controls the offset of the solidify extrusion.
-
-# solidifyNormals
-Controls the smoothing angle for normals of the solidify extrusion.
-
-# geometryHighlight
-If enabled, selecting the curve will also highlight the geometry component that is attached to that curve.
-Works only on GS CurveTools curves and geo.
-
-# curveHighlight
-If enabled, selected curves and their components will be additionally highlighted for better visibility.
-The curves and components will be in X-Ray mode by default.
-Colors and transparency values can be changes in the menu below.
-
-# gsSelectedCVColor
-Selected CV highlight color
-
-# gsSelectedCVAlpha
-Selected CV highlight transparency (alpha)
-
-# gsDeselectedCVColor
-Deselected CV highlight color
-
-# gsDeselectedCVAlpha
-Deselected CV highlight transparency (alpha)
-
-# curveVisibility
-Toggle selected curves highlight
-
-# gsCurveHighlightColor
-Selected curve highlight color
-
-# gsCurveHighlightAlpha
-Selected curve highlight transparency (alpha)
-
-# hullVisibility
-Toggle hull visibility.
-Hull is a line that connects all the CVs on the curve.
-
-# gsHullHighlightColor
-Hull highlight color
-
-# gsHullHighlightAlpha
-Hull highlight transparency (alpha)
-
-# advancedVisibilityFrame
-Better highlights for selected curves and components.
-
-# lazyUpdate
-Enables lazy update for selected curves.
-Lazy update can slightly increase the performance of the highlight,
-however it has some visual drawbacks (curve highlight can fail to update when switching curves in component selection mode)
-
-# alwaysOnTop
-Toggles X-Ray (always on top) drawing for highlighted components.
-Disabling this defeats the purpose of the advanced visibility, but hey, it's your choice.
-
-# curveDistanceColor
-Toggles the distance color effect on the curve highlight.
-Distance color darkens the curve color the further it is from the camera.
-
-# cvDistanceColor
-Toggles the distance color effect on the CV highlight.
-Distance color darkens the CVs color the further it is from the camera.
-
-# hullDistanceColor
-Toggles the distance color effect on the hull highlight.
-Distance color darkens the hull color the further it is from the camera.
-
-# gsDistanceColorMinValue
-Distance color minimum.
-This value is the minimum allowed color multiplier for the Distance Color effect.
-The lower this value, the darker further parts of the curve will be.
-Black at 0.0
-Original color at 1.0
-
-# gsDistanceColorMaxValue
-Distance color maximum.
-This value is the maximum allowed color multiplier for the Distance Color effect.
-The higher this value, the brighter closest parts of the curve will be.
-Black at 0.0
-Original color at 1.0
-
-# CVocclusion
-Toggles the experimental CV occlusion mode (hull is affected as well)
-When the appropriate mesh name is added to Occluder Mesh input field,
-this function will automatically hide CVs and hull lines that are behind this mesh (even in X-Ray mode).
-Warning: enabling this mode can negatively impart viewport performance.
-
-# gsSelectOccluderButton
-This button adds the selected mesh name to the Occluder Mesh input field.
-
-# gsOccluderMeshName
-Type the full path for the occluder mesh here, or use the "Select Occluder" button on the left <-
-
-
-
-
-# gsGenerateLayerColorGradient
-Generate a color gradient for the layer colors.
-Rows control the number of Rows to generate.
-Left color picker sets the initial color.
-Right color picker sets the final color.
-
-# gsRandomizeLayerColors
-Generate random colors for the layers.
-SatMin controls the minimum allowed saturation.
-SatMax controls the maximum allowed saturation.
-
-# gsResetAllLayerColors
-Resets all the color swatches to the default color.
-
-# gsGetCurrentSceneLayers
-Populates the menu with the names and colors stored in the scene.
-
-# gsSetAsCurrentSceneLayers
-Applies the names and colors from the menu to the scene.
-
-# gsLoadGlobalLayerPreset
-Load the global names and colors preset to the menu.
-NOTE: Don't forget to Set to Scene before closing the menu.
-
-# gsSaveGlobalLayerPreset
-Saves the current names and colors from the menu to the global preset.
-
-
-
-# gsUVSelect
-Enables the selection of the UVs.
-Drag to draw a box selection.
-
-# gsUVMove
-Enables the Move tool.
-Move the selected UVs or move individual UVs if nothing is selected.
-
-# gsUVRotate
-Enables the Rotation of the selected UVs.
-Hold LMB and drag anywhere in the viewport to rotate the selected UVs.
-Rotation pivot is the center of the individual unscaled UV.
-
-# gsUVScale
-Enables the Scaling of the selected UVs.
-Hold LMB and drag in the viewport to scale the card Horizontally of Vertically.
-Repeated hotkey click will toggle between Horizontal and Vertical scaling.
-
-# gsUVHorizontalScale
-Horizontal scaling mode selector.
-
-# gsUVVerticalScale
-Vertical scaling mode selector.
-
-# gsDrawUVs
-Enables the UVs Drawing Tool:
-1. Select UVs using Selection Mode.
-2. Enable the UV Drawing Tool.
-3. Draw a UV Rectangle anywhere in the viewport to create/move the UVs there.
-
-# gsHorizontalFlipUV
-Flips the selected UVs horizontally.
-Flipped UVs have the blue circle indicator inside the root rectangle.
-
-# gsVerticalFlipUV
-Flips the selected UVs vertically.
-
-# gsResetUVs
-Resets the selected UVs to the default 0,1 rectangle.
-
-# gsSyncSelectionUVs
-Syncs selection between UV editor and Maya Viewport.
-
-# gsRandomizeUVs
-Randomize selected UV positions between already existing UV positions.
-***
-Normal click will keep the overall density distribution of the UVs.
-This means that if there is one card in one position and twenty cards in the other,
-it will keep this distribution of 1 to 20.
-***
-Shift+Click will ignore the original density distribution
-and simply randomize the UVs between the original positions.
-
-# gsFocusUVs
-Focuses on the selected UVs or on all the UVs if nothing is selected.
-
-# gsUVIsolateSelect
-Hides all the unselected UVs and shows only the selected ones.
-
-# gsUVShowAll
-Shows all the hidden UVs.
-
-# UVEditorUseTransforms
-Use "Coverage" and "Translate Frame" parameters from place2dTexture node for texture.
-Offset is not supported.
-Diffuse and Alpha channel MUST have the same coverage and translate frame values.
-
-# UVEditorTransparencyToggle
-Enable texture map transparency using Alpha map from Transparency plug in the material node
-
-# UVEditorBGColorPicker
-Background Color
-
-# UVEditorGridColorPicker
-Grid Color
-
-# UVEditorFrameColorPicker
-Frame Color
-
-# UVEditorUVFrameSelectedColorPicker
-Selected UV frame color
-
-# UVEditorUVFrameDeselectedColorPicker
-Deselected UV frame color
-
-# UVEditorUVCardFillColorPicker
-UV frame background color
-
-
-
-# gsGeoToCurve_outputTypeSwitch
-Controls the output of Geo-to-Curve algorithm
-
-# gsGeoToCurve_generateAuto
-Automatically determine the final object type (card or tube) based on the selected geometry.
-
-# gsGeoToCurve_generateCards
-Generate cards from selected geometry (one-sided cards or tubes)
-
-# gsGeoToCurve_generateTubes
-Generate tubes from selected geometry (one-sided cards or tubes)
-
-# gsGeoToCurve_generateCurves
-Generate curves from selected geometry (one-sided cards or tubes)
-
-# gsGeoToCurve_cardType
-Controls the type of generated objects (Warp or Extrude)
-
-# gsGeoToCurve_warp
-Generate Warp cards or tubes
-
-# gsGeoToCurve_extrude
-Generate Extrude cards or tubes
-
-# gsGeoToCurve_matchAttributes
-Controls which attributes on the new cards/tubes should be approximated from the original geometry.
-NOTE: This process is not perfect and final result can be inaccurate.
-
-# gsGeoToCurve_orientation
-Match orientation attribute during the generation process
-
-# gsGeoToCurve_width
-Match orientation attribute during the generation process
-
-# gsGeoToCurve_taper
-Match taper attribute during the generation process
-
-# gsGeoToCurve_twist
-Match twist attribute during the generation process
-
-# gsGeoToCurve_profile
-Match profile attribute during the generation process
-
-# gsGeoToCurve_material
-Copy material (shader) from the original geometry
-
-# gsGeoToCurve_UVs
-Tries to approximate the UVs from the original geometry
-NOTE: Matches the bounding box of the UVs. Rotated and deformed UVs are not matched precisely.
-
-# gsGeoToCurve_UVMatchOptions
-Controls UV matching behaviour
-
-# gsGeoToCurve_verticalFlip
-Vertically flip matched UVs
-
-# gsGeoToCurve_horizontalFlip
-Horizontally flip matched UVs
-
-# gsGeoToCurve_reverseCurve
-Reverse generated curve direction
-Root CV should be generated near the scalp of the model.
-Enable or disable if resulting card direction and taper are reversed.
-
-# gsGeoToCurve_convertSelected
-Convert selected geometry to cards, tubes or curves based on the selected options.
-Newly created procedural objects will be placed in the currently selected layer.
-NOTE: if the currently selected layer is hidden (grayed out), the newly created objects will be hidden as well.
-
-# gsGeoToCurve_deleteOriginalObject
-Delete the original geometry after converting it to cards, tubes or curves.
-
-# gsGeoToCurve_useAimMesh
-Use the aim mesh (selected below) to place the root CV of the generated cards, tubes or curves close to the target mesh.
-Placing CVs close to the target mesh will help with the alignment process and general adjustments later on.
-The aim mesh should be a polygonal mesh.
-
-# gsGeoToCurve_selectAimMesh
-Select the aim mesh in the scene and click this button to add its name to the input field.
diff --git a/2025/scripts/rigging_tools/PickUpWeightedBones.py b/2025/scripts/rigging_tools/PickUpWeightedBones.py
new file mode 100644
index 0000000..9169460
--- /dev/null
+++ b/2025/scripts/rigging_tools/PickUpWeightedBones.py
@@ -0,0 +1,1394 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+"""
+PickUpWeightedBones.py
+从选中对象中筛选出几何体,获取这些几何体蒙皮权重对应的骨骼,并整理到一个集合里
+带有完整的UI界面
+"""
+
+import maya.cmds as cmds
+import maya.mel as mel
+from functools import partial
+
+# 全局变量
+WINDOW_NAME = "pickUpWeightedBonesWindow"
+WINDOW_TITLE = "骨骼拾取工具"
+WINDOW_WIDTH = 450
+WINDOW_HEIGHT = 700
+
+
+class PickUpWeightedBonesUI(object):
+ """骨骼拾取工具UI类"""
+
+ def __init__(self):
+ self.window = WINDOW_NAME
+ self.geometry_list = []
+ self.bone_list = []
+ self.selected_bones = []
+
+ # UI控件引用
+ self.geometry_text_scroll = None
+ self.bone_text_scroll = None
+ self.info_text_scroll = None
+ self.constraint_checkboxes = {}
+
+ # 约束类型
+ self.constraint_types = {
+ 'parentConstraint': True,
+ 'pointConstraint': True,
+ 'orientConstraint': True,
+ 'scaleConstraint': True,
+ 'aimConstraint': True,
+ 'poleVectorConstraint': True,
+ 'geometryConstraint': True,
+ 'normalConstraint': True,
+ 'tangentConstraint': True
+ }
+
+ def create_ui(self):
+ """创建UI界面"""
+ # 如果窗口已存在,删除它
+ if cmds.window(self.window, exists=True):
+ cmds.deleteUI(self.window)
+
+ # 创建窗口
+ self.window = cmds.window(
+ self.window,
+ title=WINDOW_TITLE,
+ widthHeight=(WINDOW_WIDTH, WINDOW_HEIGHT),
+ sizeable=True
+ )
+
+ # 主布局
+ main_layout = cmds.columnLayout(adjustableColumn=True, rowSpacing=5)
+
+ # 标题
+ cmds.text(
+ label="从Maya场景中筛选带权重的骨骼",
+ font="boldLabelFont",
+ height=30,
+ backgroundColor=[0.3, 0.3, 0.3]
+ )
+
+ cmds.separator(height=10, style='none')
+
+ # 使用说明
+ cmds.frameLayout(label="使用说明", collapsable=True, collapse=False, borderStyle='etchedIn')
+ cmds.columnLayout(adjustableColumn=True, rowSpacing=3)
+ cmds.text(label="1. 选择场景中的对象或几何体", align='left')
+ cmds.text(label="2. 点击'拾取几何体'按钮(会自动筛选出几何体)", align='left')
+ cmds.text(label="3. 点击'分析骨骼'查看带权重的骨骼列表", align='left')
+ cmds.text(label="4. 选择要清理的约束类型", align='left')
+ cmds.text(label="5. 点击'清理约束'或'整理骨骼'按钮", align='left')
+ cmds.setParent('..')
+ cmds.setParent('..')
+
+ cmds.separator(height=10, style='in')
+
+ # 几何体拾取区域
+ cmds.frameLayout(label="几何体拾取器", collapsable=True, collapse=False, borderStyle='etchedIn')
+ cmds.columnLayout(adjustableColumn=True, rowSpacing=5)
+
+ cmds.rowLayout(numberOfColumns=3, columnWidth3=(150, 150, 100), adjustableColumn=3)
+ cmds.button(label="拾取几何体", command=self.pick_geometry, backgroundColor=[0.4, 0.6, 0.4])
+ cmds.button(label="选择模型", command=self.select_geometry_in_scene, backgroundColor=[0.5, 0.5, 0.6])
+ cmds.button(label="清空", command=self.clear_geometry, width=70)
+ cmds.setParent('..')
+
+ cmds.text(label="已拾取的几何体:", align='left', font='smallBoldLabelFont')
+ self.geometry_text_scroll = cmds.scrollField(
+ editable=False,
+ wordWrap=False,
+ height=80,
+ backgroundColor=[0.2, 0.2, 0.2],
+ font='smallFixedWidthFont'
+ )
+
+ cmds.setParent('..')
+ cmds.setParent('..')
+
+ cmds.separator(height=5, style='in')
+
+ # 骨骼列表区域
+ cmds.frameLayout(label="骨骼列表", collapsable=True, collapse=False, borderStyle='etchedIn')
+ cmds.columnLayout(adjustableColumn=True, rowSpacing=5)
+
+ cmds.rowLayout(numberOfColumns=3, columnWidth3=(150, 150, 100), adjustableColumn=3)
+ cmds.button(label="分析骨骼", command=self.analyze_bones, backgroundColor=[0.4, 0.5, 0.6])
+ cmds.button(label="选择骨骼", command=self.select_bones_in_scene)
+ cmds.button(label="清空", command=self.clear_bones)
+ cmds.setParent('..')
+
+ cmds.text(label="带权重的骨骼:", align='left', font='smallBoldLabelFont')
+ self.bone_text_scroll = cmds.scrollField(
+ editable=False,
+ wordWrap=False,
+ height=120,
+ backgroundColor=[0.2, 0.2, 0.2],
+ font='smallFixedWidthFont'
+ )
+
+ cmds.setParent('..')
+ cmds.setParent('..')
+
+ cmds.separator(height=5, style='in')
+
+ # 约束清理器
+ cmds.frameLayout(label="约束清理器", collapsable=True, collapse=False, borderStyle='etchedIn')
+ cmds.columnLayout(adjustableColumn=True, rowSpacing=5)
+
+ # 快速选择按钮
+ cmds.rowLayout(numberOfColumns=2, columnWidth2=(WINDOW_WIDTH/2-20, WINDOW_WIDTH/2-20))
+ cmds.button(label="全选", command=self.select_all_constraints, backgroundColor=[0.3, 0.4, 0.3])
+ cmds.button(label="全不选", command=self.deselect_all_constraints, backgroundColor=[0.4, 0.3, 0.3])
+ cmds.setParent('..')
+
+ cmds.separator(height=5, style='none')
+
+ # 约束类型复选框 - 两列布局
+ cmds.rowLayout(numberOfColumns=2, columnWidth2=(WINDOW_WIDTH/2-20, WINDOW_WIDTH/2-20))
+
+ # 左列
+ left_column = cmds.columnLayout(adjustableColumn=True)
+ self.constraint_checkboxes['parentConstraint'] = cmds.checkBox(
+ label='parentConstraint', value=True
+ )
+ self.constraint_checkboxes['orientConstraint'] = cmds.checkBox(
+ label='orientConstraint', value=True
+ )
+ self.constraint_checkboxes['aimConstraint'] = cmds.checkBox(
+ label='aimConstraint', value=True
+ )
+ self.constraint_checkboxes['geometryConstraint'] = cmds.checkBox(
+ label='geometryConstraint', value=True
+ )
+ self.constraint_checkboxes['tangentConstraint'] = cmds.checkBox(
+ label='tangentConstraint', value=True
+ )
+ cmds.setParent('..')
+
+ # 右列
+ right_column = cmds.columnLayout(adjustableColumn=True)
+ self.constraint_checkboxes['pointConstraint'] = cmds.checkBox(
+ label='pointConstraint', value=True
+ )
+ self.constraint_checkboxes['scaleConstraint'] = cmds.checkBox(
+ label='scaleConstraint', value=True
+ )
+ self.constraint_checkboxes['poleVectorConstraint'] = cmds.checkBox(
+ label='poleVectorConstraint', value=True
+ )
+ self.constraint_checkboxes['normalConstraint'] = cmds.checkBox(
+ label='normalConstraint', value=True
+ )
+ cmds.setParent('..')
+
+ cmds.setParent('..')
+
+ cmds.separator(height=5, style='in')
+
+ # 约束操作按钮区域
+ cmds.rowLayout(numberOfColumns=2, columnWidth2=(WINDOW_WIDTH/2-10, WINDOW_WIDTH/2-10), height=40)
+ cmds.button(
+ label="扫描模型约束",
+ command=self.scan_geometry_constraints,
+ backgroundColor=[0.4, 0.5, 0.6],
+ height=35
+ )
+ cmds.button(
+ label="扫描骨骼约束",
+ command=self.scan_bone_constraints,
+ backgroundColor=[0.5, 0.4, 0.6],
+ height=35
+ )
+ cmds.setParent('..')
+
+ cmds.rowLayout(numberOfColumns=2, columnWidth2=(WINDOW_WIDTH/2-10, WINDOW_WIDTH/2-10), height=40)
+ cmds.button(
+ label="扫描模型和骨骼约束",
+ command=self.scan_all_constraints,
+ backgroundColor=[0.6, 0.5, 0.4],
+ height=35
+ )
+ cmds.button(
+ label="清理约束",
+ command=self.clean_constraints,
+ backgroundColor=[0.6, 0.4, 0.3],
+ height=35
+ )
+ cmds.setParent('..')
+
+ cmds.setParent('..')
+ cmds.setParent('..')
+
+ cmds.separator(height=5, style='in')
+
+ # 矩阵节点清理器
+ cmds.frameLayout(label="矩阵节点清理器", collapsable=True, collapse=False, borderStyle='etchedIn')
+ cmds.columnLayout(adjustableColumn=True, rowSpacing=5)
+
+ # 安全模式警告
+ cmds.text(
+ label="警告: 矩阵节点是绑定系统的核心组件,删除可能导致绑定失效!",
+ align='left',
+ font='smallBoldLabelFont',
+ backgroundColor=[0.6, 0.3, 0.3]
+ )
+
+ # 安全模式复选框
+ self.safe_mode_checkbox = cmds.checkBox(
+ label='启用安全模式 (推荐)',
+ value=True,
+ annotation='安全模式下会保护绑定系统的核心节点,只删除控制约束相关的矩阵节点'
+ )
+ cmds.separator(height=5, style='none')
+
+ # 快速选择按钮
+ cmds.rowLayout(numberOfColumns=2, columnWidth2=(WINDOW_WIDTH/2-20, WINDOW_WIDTH/2-20))
+ cmds.button(label="全选", command=self.select_all_matrix_nodes, backgroundColor=[0.3, 0.4, 0.3])
+ cmds.button(label="全不选", command=self.deselect_all_matrix_nodes, backgroundColor=[0.4, 0.3, 0.3])
+ cmds.setParent('..')
+
+ cmds.separator(height=5, style='none')
+
+ # 矩阵节点类型复选框 - 两列布局
+ cmds.rowLayout(numberOfColumns=2, columnWidth2=(WINDOW_WIDTH/2-20, WINDOW_WIDTH/2-20))
+
+ # 左列
+ left_column = cmds.columnLayout(adjustableColumn=True)
+ self.matrix_checkboxes = {}
+ self.matrix_checkboxes['multMatrix'] = cmds.checkBox(
+ label='multMatrix', value=True
+ )
+ self.matrix_checkboxes['decomposeMatrix'] = cmds.checkBox(
+ label='decomposeMatrix', value=True
+ )
+ self.matrix_checkboxes['multiplyDivide'] = cmds.checkBox(
+ label='multiplyDivide', value=True
+ )
+ self.matrix_checkboxes['plusMinusAverage'] = cmds.checkBox(
+ label='plusMinusAverage', value=True
+ )
+ self.matrix_checkboxes['blendMatrix'] = cmds.checkBox(
+ label='blendMatrix', value=True
+ )
+ cmds.setParent('..')
+
+ # 右列
+ right_column = cmds.columnLayout(adjustableColumn=True)
+ self.matrix_checkboxes['pickMatrix'] = cmds.checkBox(
+ label='pickMatrix', value=True
+ )
+ self.matrix_checkboxes['composeMatrix'] = cmds.checkBox(
+ label='composeMatrix', value=True
+ )
+ self.matrix_checkboxes['inverseMatrix'] = cmds.checkBox(
+ label='inverseMatrix', value=True
+ )
+ self.matrix_checkboxes['transposeMatrix'] = cmds.checkBox(
+ label='transposeMatrix', value=True
+ )
+ self.matrix_checkboxes['blendColors'] = cmds.checkBox(
+ label='blendColors', value=True
+ )
+ cmds.setParent('..')
+
+ cmds.setParent('..')
+
+ cmds.separator(height=5, style='in')
+
+ # 矩阵节点操作按钮区域
+ cmds.rowLayout(numberOfColumns=2, columnWidth2=(WINDOW_WIDTH/2-10, WINDOW_WIDTH/2-10), height=40)
+ cmds.button(
+ label="扫描模型矩阵节点",
+ command=self.scan_geometry_matrix_nodes,
+ backgroundColor=[0.4, 0.5, 0.6],
+ height=35
+ )
+ cmds.button(
+ label="扫描骨骼矩阵节点",
+ command=self.scan_bone_matrix_nodes,
+ backgroundColor=[0.5, 0.4, 0.6],
+ height=35
+ )
+ cmds.setParent('..')
+
+ cmds.rowLayout(numberOfColumns=2, columnWidth2=(WINDOW_WIDTH/2-10, WINDOW_WIDTH/2-10), height=40)
+ cmds.button(
+ label="扫描模型和骨骼矩阵节点",
+ command=self.scan_all_matrix_nodes,
+ backgroundColor=[0.6, 0.5, 0.4],
+ height=35
+ )
+ cmds.button(
+ label="清理矩阵节点",
+ command=self.clean_matrix_nodes,
+ backgroundColor=[0.6, 0.4, 0.3],
+ height=35
+ )
+ cmds.setParent('..')
+
+ cmds.setParent('..')
+ cmds.setParent('..')
+
+ cmds.separator(height=5, style='none')
+
+ # 骨骼集合操作按钮
+ cmds.rowLayout(numberOfColumns=2, columnWidth2=(WINDOW_WIDTH/2-10, WINDOW_WIDTH/2-10), height=40)
+ cmds.button(
+ label="创建骨骼选择集",
+ command=self.create_bone_set_only,
+ backgroundColor=[0.5, 0.6, 0.4],
+ height=35
+ )
+ cmds.button(
+ label="整理骨骼",
+ command=self.organize_bones,
+ backgroundColor=[0.5, 0.6, 0.4],
+ height=35
+ )
+ cmds.setParent('..')
+
+ cmds.separator(height=10, style='in')
+
+ # 信息输出区域
+ cmds.text(label="信息", align='left', font='smallBoldLabelFont')
+ self.info_text_scroll = cmds.scrollField(
+ editable=False,
+ wordWrap=True,
+ height=100,
+ backgroundColor=[0.15, 0.15, 0.15],
+ font='smallFixedWidthFont'
+ )
+
+ # 显示窗口
+ cmds.showWindow(self.window)
+
+ # 初始化信息
+ self.log_info("工具已就绪,请选择对象后点击'拾取几何体'")
+
+ def log_info(self, message):
+ """输出信息到信息框"""
+ if self.info_text_scroll:
+ current_text = cmds.scrollField(self.info_text_scroll, query=True, text=True)
+ new_text = current_text + "\n" + message if current_text else message
+ cmds.scrollField(self.info_text_scroll, edit=True, text=new_text)
+ print(message)
+
+ def clear_info(self):
+ """清空信息框"""
+ if self.info_text_scroll:
+ cmds.scrollField(self.info_text_scroll, edit=True, text="")
+
+ def pick_geometry(self, *args):
+ """拾取几何体 - 自动扫描子层级"""
+ self.geometry_list = []
+ selection = cmds.ls(selection=True, long=True)
+
+ if not selection:
+ self.log_info("警告: 请先选择对象")
+ cmds.warning("请先选择对象")
+ return
+
+ for obj in selection:
+ # 检查是否是transform节点
+ if cmds.nodeType(obj) == 'transform':
+ # 获取所有子层级中的transform节点(递归扫描)
+ all_descendants = cmds.listRelatives(obj, allDescendents=True, fullPath=True, type='transform') or []
+ # 包含自身和所有子层级
+ all_transforms = [obj] + all_descendants
+
+ for transform in all_transforms:
+ # 获取shape节点
+ shapes = cmds.listRelatives(transform, shapes=True, fullPath=True, noIntermediate=True)
+ if shapes:
+ for shape in shapes:
+ shape_type = cmds.nodeType(shape)
+ # 只拾取mesh类型几何体,剔除曲线和Nurbs
+ if shape_type == 'mesh':
+ self.geometry_list.append(transform)
+ break
+ # 如果直接选择的是shape节点
+ elif cmds.nodeType(obj) == 'mesh':
+ parent = cmds.listRelatives(obj, parent=True, fullPath=True)
+ if parent:
+ self.geometry_list.append(parent[0])
+
+ # 去重
+ self.geometry_list = list(set(self.geometry_list))
+
+ # 更新UI
+ if self.geometry_list:
+ geo_names = [geo.split('|')[-1] for geo in self.geometry_list]
+ cmds.scrollField(self.geometry_text_scroll, edit=True, text='\n'.join(geo_names))
+ self.log_info(f"成功拾取 {len(self.geometry_list)} 个几何体")
+ else:
+ cmds.scrollField(self.geometry_text_scroll, edit=True, text="")
+ self.log_info("警告: 选择中没有找到几何体对象")
+ cmds.warning("选择中没有找到几何体对象")
+
+ def clear_geometry(self, *args):
+ """清空几何体列表"""
+ self.geometry_list = []
+ cmds.scrollField(self.geometry_text_scroll, edit=True, text="")
+ self.log_info("已清空几何体列表")
+
+ def analyze_bones(self, *args):
+ """分析骨骼"""
+ if not self.geometry_list:
+ self.log_info("警告: 请先拾取几何体")
+ cmds.warning("请先拾取几何体")
+ return
+
+ self.bone_list = []
+ geometry_with_skin = []
+
+ for geo in self.geometry_list:
+ skin_cluster = self.get_skincluster_from_geometry(geo)
+ if skin_cluster:
+ bones = self.get_weighted_bones_from_skincluster(skin_cluster)
+ if bones:
+ self.bone_list.extend(bones)
+ geometry_with_skin.append(geo)
+ self.log_info(f"从 {geo.split('|')[-1]} 找到 {len(bones)} 个影响骨骼")
+ else:
+ self.log_info(f"几何体 {geo.split('|')[-1]} 没有skinCluster")
+
+ # 去重
+ self.bone_list = list(set(self.bone_list))
+
+ # 更新UI
+ if self.bone_list:
+ bone_names = [bone.split('|')[-1] for bone in self.bone_list]
+ cmds.scrollField(self.bone_text_scroll, edit=True, text='\n'.join(bone_names))
+ self.log_info(f"总共找到 {len(self.bone_list)} 个唯一骨骼")
+ else:
+ cmds.scrollField(self.bone_text_scroll, edit=True, text="")
+ self.log_info("警告: 没有找到任何带权重的骨骼")
+ cmds.warning("没有找到任何带权重的骨骼")
+
+ def clear_bones(self, *args):
+ """清空骨骼列表"""
+ self.bone_list = []
+ cmds.scrollField(self.bone_text_scroll, edit=True, text="")
+ self.log_info("已清空骨骼列表")
+
+ def select_bones_in_scene(self, *args):
+ """在场景中选择骨骼"""
+ if not self.bone_list:
+ self.log_info("警告: 骨骼列表为空")
+ cmds.warning("骨骼列表为空")
+ return
+
+ existing_bones = [bone for bone in self.bone_list if cmds.objExists(bone)]
+ if existing_bones:
+ cmds.select(existing_bones, replace=True)
+ self.log_info(f"已选择 {len(existing_bones)} 个骨骼")
+ else:
+ self.log_info("警告: 没有找到可选择的骨骼")
+
+ def select_geometry_in_scene(self, *args):
+ """在场景中选择几何体"""
+ if not self.geometry_list:
+ self.log_info("警告: 几何体列表为空")
+ cmds.warning("几何体列表为空")
+ return
+
+ existing_geos = [geo for geo in self.geometry_list if cmds.objExists(geo)]
+ if existing_geos:
+ cmds.select(existing_geos, replace=True)
+ self.log_info(f"已选择 {len(existing_geos)} 个几何体")
+ else:
+ self.log_info("警告: 没有找到可选择的几何体")
+
+ def select_all_constraints(self, *args):
+ """全选约束类型"""
+ for checkbox in self.constraint_checkboxes.values():
+ cmds.checkBox(checkbox, edit=True, value=True)
+ self.log_info("已全选所有约束类型")
+
+ def deselect_all_constraints(self, *args):
+ """全不选约束类型"""
+ for checkbox in self.constraint_checkboxes.values():
+ cmds.checkBox(checkbox, edit=True, value=False)
+ self.log_info("已取消选择所有约束类型")
+
+ def get_selected_constraint_types(self):
+ """获取选中的约束类型"""
+ selected_types = []
+ for constraint_type, checkbox in self.constraint_checkboxes.items():
+ if cmds.checkBox(checkbox, query=True, value=True):
+ selected_types.append(constraint_type)
+ return selected_types
+
+ def scan_geometry_constraints(self, *args):
+ """扫描模型约束 - 扫描几何体上的约束"""
+ if not self.geometry_list:
+ self.log_info("警告: 请先拾取几何体")
+ cmds.warning("请先拾取几何体")
+ return
+
+ self._scan_constraints_on_objects(self.geometry_list, "几何体")
+
+ def scan_bone_constraints(self, *args):
+ """扫描骨骼约束 - 扫描骨骼上的约束"""
+ if not self.bone_list:
+ self.log_info("警告: 请先分析骨骼")
+ cmds.warning("请先分析骨骼")
+ return
+
+ self._scan_constraints_on_objects(self.bone_list, "骨骼")
+
+ def scan_all_constraints(self, *args):
+ """扫描模型和骨骼约束 - 扫描所有对象的约束"""
+ if not self.geometry_list and not self.bone_list:
+ self.log_info("警告: 请先拾取几何体或分析骨骼")
+ cmds.warning("请先拾取几何体或分析骨骼")
+ return
+
+ all_objects = list(set(self.geometry_list + self.bone_list))
+ self._scan_constraints_on_objects(all_objects, "模型和骨骼")
+
+ def _scan_constraints_on_objects(self, objects, object_type_name):
+ """扫描对象上的约束 - 通用方法"""
+ # 所有约束类型
+ all_constraint_types = [
+ 'parentConstraint',
+ 'pointConstraint',
+ 'orientConstraint',
+ 'scaleConstraint',
+ 'aimConstraint',
+ 'poleVectorConstraint',
+ 'geometryConstraint',
+ 'normalConstraint',
+ 'tangentConstraint'
+ ]
+
+ self.log_info(f"\n开始扫描{object_type_name}约束...")
+
+ # 首先检查场景中是否有约束节点
+ scene_constraints = {}
+ for constraint_type in all_constraint_types:
+ constraints = cmds.ls(type=constraint_type)
+ if constraints:
+ scene_constraints[constraint_type] = len(constraints)
+
+ if not scene_constraints:
+ self.log_info("\n场景中没有找到任何约束节点!")
+ self.log_info("可能原因:")
+ self.log_info(" 1. 此绑定没有使用约束系统")
+ self.log_info(" 2. 约束已经被烘焙或删除")
+ self.log_info(" 3. 使用了其他控制方式(表达式、脚本等)")
+ return
+
+ self.log_info("场景中找到约束节点:")
+ for constraint_type, count in sorted(scene_constraints.items()):
+ self.log_info(f" {constraint_type}: {count} 个")
+
+ # 扫描对象上的约束
+ total_constraints = 0
+ constraint_summary = {}
+ found_any = False
+
+ for obj in objects:
+ if not cmds.objExists(obj):
+ continue
+
+ obj_constraints = []
+
+ for constraint_type in all_constraint_types:
+ # 查找连接到对象的约束节点(作为被约束对象)
+ constraints = cmds.listConnections(obj, type=constraint_type, source=True, destination=False)
+ if constraints:
+ constraints = list(set(constraints))
+ obj_constraints.extend(constraints)
+
+ if constraint_type not in constraint_summary:
+ constraint_summary[constraint_type] = 0
+ constraint_summary[constraint_type] += len(constraints)
+
+ # 也查找对象作为约束目标的情况
+ target_constraints = cmds.listConnections(obj, type=constraint_type, source=False, destination=True)
+ if target_constraints:
+ target_constraints = list(set(target_constraints))
+ for tc in target_constraints:
+ if tc not in obj_constraints:
+ obj_constraints.append(tc)
+ if constraint_type not in constraint_summary:
+ constraint_summary[constraint_type] = 0
+ constraint_summary[constraint_type] += 1
+
+ # 去重
+ unique_constraints = list(set(obj_constraints))
+
+ if unique_constraints:
+ found_any = True
+ total_constraints += len(unique_constraints)
+ constraint_names = [c.split('|')[-1] for c in unique_constraints]
+ self.log_info(f" {obj.split('|')[-1]} 有 {len(unique_constraints)} 个约束: {', '.join(constraint_names)}")
+
+ # 输出统计信息
+ self.log_info("\n扫描完成!")
+ self.log_info(f"总{object_type_name}数: {len(objects)}")
+ self.log_info(f"{object_type_name}上的约束数: {total_constraints}")
+
+ if constraint_summary:
+ self.log_info(f"\n{object_type_name}约束类型统计:")
+ for constraint_type, count in sorted(constraint_summary.items()):
+ self.log_info(f" {constraint_type}: {count} 个")
+ else:
+ self.log_info(f"\n这些{object_type_name}上没有找到约束")
+ self.log_info("提示: 场景中有约束,但不在选中的对象上")
+
+ def clean_constraints(self, *args):
+ """清理约束"""
+ if not self.bone_list:
+ self.log_info("警告: 请先分析骨骼")
+ cmds.warning("请先分析骨骼")
+ return
+
+ selected_types = self.get_selected_constraint_types()
+ if not selected_types:
+ self.log_info("警告: 请至少选择一种约束类型")
+ cmds.warning("请至少选择一种约束类型")
+ return
+
+ # 确认对话框
+ result = cmds.confirmDialog(
+ title='确认清理',
+ message='确定要删除选中骨骼上的约束吗?\n这个操作不可撤销!',
+ button=['确定', '取消'],
+ defaultButton='确定',
+ cancelButton='取消',
+ dismissString='取消'
+ )
+
+ if result != '确定':
+ self.log_info("操作已取消")
+ return
+
+ removed_count = self.remove_constraints_from_bones(self.bone_list, selected_types)
+
+ if removed_count > 0:
+ self.log_info(f"成功清理了 {removed_count} 个约束")
+ else:
+ self.log_info("没有找到需要清理的约束")
+
+ def create_bone_set_only(self, *args):
+ """创建骨骼选择集 - 只创建选择集"""
+ if not self.bone_list:
+ self.log_info("警告: 请先分析骨骼")
+ cmds.warning("请先分析骨骼")
+ return
+
+ self.log_info("\n开始创建骨骼选择集...")
+
+ # 创建选择集
+ set_name = "weighted_bones_set"
+ bone_set = self.create_bone_set(self.bone_list, set_name)
+
+ if not bone_set:
+ self.log_info("操作已取消")
+ return
+
+ self.log_info(f"\n成功!")
+ self.log_info(f"- 骨骼选择集已创建: {bone_set}")
+ self.log_info(f"- 添加的骨骼数量: {len(self.bone_list)}")
+
+ def organize_bones(self, *args):
+ """整理骨骼 - 复制骨骼层级结构到新的root骨骼下"""
+ if not self.bone_list:
+ self.log_info("警告: 请先分析骨骼")
+ cmds.warning("请先分析骨骼")
+ return
+
+ # 确认对话框
+ result = cmds.confirmDialog(
+ title='确认整理骨骼',
+ message='将复制骨骼层级结构到新的root骨骼下。\n\n这将:\n1. 创建新的root骨骼\n2. 复制骨骼及其层级关系\n3. 保持原始骨骼的位置和旋转\n4. 原始骨骼不会被删除\n\n确定要继续吗?',
+ button=['确定', '取消'],
+ defaultButton='确定',
+ cancelButton='取消',
+ dismissString='取消'
+ )
+
+ if result != '确定':
+ self.log_info("操作已取消")
+ return
+
+ self.log_info("\n开始整理骨骼...")
+
+ try:
+ # 1. 分析骨骼层级关系
+ bone_hierarchy = self._analyze_bone_hierarchy(self.bone_list)
+
+ if not bone_hierarchy:
+ self.log_info("警告: 无法分析骨骼层级关系")
+ return
+
+ self.log_info(f"分析了 {len(bone_hierarchy)} 个根骨骼")
+
+ # 2. 创建新的root骨骼
+ cmds.select(clear=True)
+ root_name = "organized_root"
+ # 生成唯一名称
+ i = 1
+ while cmds.objExists(root_name):
+ root_name = f"organized_root_{i}"
+ i += 1
+
+ root_bone = cmds.joint(name=root_name, position=[0, 0, 0])
+ self.log_info(f"创建了根骨骼: {root_name}")
+
+ # 3. 复制骨骼层级
+ created_count = self._copy_bone_hierarchy(bone_hierarchy, root_bone)
+
+ self.log_info(f"\n成功!")
+ self.log_info(f"- 骨骼已整理到新的root骨骼下")
+ self.log_info(f"- 创建的骨骼数量: {created_count}")
+ self.log_info(f"- 新的root骨骼: {root_name}")
+
+ # 4. 选择新的root骨骼
+ cmds.select(root_bone, replace=True, hierarchy=True)
+
+ except Exception as e:
+ import traceback
+ error_msg = traceback.format_exc()
+ self.log_info(f"错误: 整理骨骼时发生异常:\n{error_msg}")
+ cmds.warning(f"整理骨骼时发生异常: {str(e)}")
+
+ def _analyze_bone_hierarchy(self, bone_list):
+ """分析骨骼层级关系
+
+ 返回根骨骼列表,每个根骨骼包含其子骨骼的层级结构
+ 考虑组的层级结构,保持原始的层级关系
+ """
+ # 过滤出存在的骨骼 - 移除 | 前缀后检查
+ existing_bones = []
+ for bone in bone_list:
+ # 移除 | 前缀
+ clean_bone = bone[1:] if bone.startswith('|') else bone
+ if cmds.objExists(clean_bone):
+ existing_bones.append(clean_bone)
+
+ if not existing_bones:
+ return None
+
+ # 构建骨骼映射表:骨骼名 -> 完整路径列表(处理同名骨骼)
+ bone_map = {}
+ for bone in existing_bones:
+ bone_name = bone.split('|')[-1]
+ if bone_name not in bone_map:
+ bone_map[bone_name] = []
+ bone_map[bone_name].append(bone)
+
+ # 构建完整的父子关系(包括通过组连接的骨骼)
+ parent_map = {} # 子骨骼 -> 父骨骼(完整路径)
+ children_map = {} # 父骨骼 -> 子骨骼列表(完整路径列表)
+
+ for bone in existing_bones:
+ bone_name = bone.split('|')[-1]
+
+ # 向上遍历父对象链,找到最近的骨骼父对象
+ current_parent = bone
+ found_bone_parent = False
+
+ while True:
+ parents = cmds.listRelatives(current_parent, parent=True, fullPath=True)
+ if not parents:
+ break
+
+ current_parent = parents[0]
+ parent_name = current_parent.split('|')[-1]
+
+ # 检查父对象是否是骨骼
+ if parent_name in bone_map:
+ # 找到骨骼父对象
+ parent_map[bone] = current_parent
+
+ # 添加到子骨骼列表
+ if current_parent not in children_map:
+ children_map[current_parent] = []
+ children_map[current_parent].append(bone)
+ found_bone_parent = True
+ break
+ # 如果父对象不是骨骼,继续向上查找
+ # 这样可以保持组的层级关系
+
+ # 找出根骨骼(没有在bone_list中的父骨骼)
+ root_bones = []
+ for bone in existing_bones:
+ if bone not in parent_map:
+ root_bones.append(bone)
+
+ # 构建层级结构
+ hierarchy = []
+ for root_bone in root_bones:
+ root_name = root_bone.split('|')[-1]
+ hierarchy.append({
+ 'name': root_name,
+ 'path': root_bone,
+ 'children': self._build_hierarchy_tree(root_bone, children_map, bone_map)
+ })
+
+ return hierarchy
+
+ def _build_hierarchy_tree(self, bone_path, children_map, bone_map):
+ """递归构建层级树
+
+ Args:
+ bone_path: 骨骼完整路径
+ children_map: 子骨骼映射表(完整路径 -> 完整路径列表)
+ bone_map: 骨骼名到完整路径列表的映射表
+ """
+ if bone_path not in children_map:
+ return []
+
+ bone_name = bone_path.split('|')[-1]
+ tree = []
+ for child_path in children_map[bone_path]:
+ child_name = child_path.split('|')[-1]
+ tree.append({
+ 'name': child_name,
+ 'path': child_path, # 使用完整路径
+ 'children': self._build_hierarchy_tree(child_path, children_map, bone_map)
+ })
+
+ return tree
+
+ def _rebuild_bone_hierarchy(self, hierarchy, root_parent):
+ """重建骨骼层级结构
+
+ Args:
+ hierarchy: 层级结构列表
+ root_parent: 根父骨骼(新的root骨骼)
+ """
+ for root_node in hierarchy:
+ self._create_bone_hierarchy_node(root_node, root_parent)
+
+ def _create_bone_hierarchy_node(self, node, parent):
+ """递归创建骨骼层级节点
+
+ Args:
+ node: 骨骼节点字典 {'name': str, 'path': str, 'children': list}
+ parent: 父骨骼对象
+ """
+ # 获取原始骨骼的完整路径
+ original_bone_path = node.get('path', node['name'])
+
+ # 移除路径前导的 | 符号,确保 Maya 能正确识别对象
+ if original_bone_path and original_bone_path.startswith('|'):
+ original_bone_path = original_bone_path[1:]
+
+ # 检查骨骼是否存在
+ if not original_bone_path or not cmds.objExists(original_bone_path):
+ self.log_info(f" 警告: 原始骨骼不存在: {original_bone_path}")
+ return
+
+ # 获取变换属性 - 使用相对空间(local space)
+ try:
+ translation = cmds.xform(original_bone_path, query=True, translation=True, worldSpace=False)
+ rotation = cmds.xform(original_bone_path, query=True, rotation=True, worldSpace=False)
+ scale = cmds.xform(original_bone_path, query=True, scale=True, worldSpace=False)
+ except Exception as e:
+ self.log_info(f" 警告: 无法获取 {original_bone_path} 的变换信息: {str(e)}")
+ # 设置默认值,避免后续错误
+ translation = [0, 0, 0]
+ rotation = [0, 0, 0]
+ scale = [1, 1, 1]
+
+ # 清除选择状态,避免创建冲突
+ cmds.select(clear=True)
+
+ # 创建新的骨骼 - 如果有父对象,在父对象下创建
+ if parent and cmds.objExists(parent):
+ # 选择父对象,确保新骨骼在父对象下创建
+ cmds.select(parent, replace=True)
+ new_bone = cmds.joint(name=node['name'])
+ else:
+ # 没有父对象,直接创建
+ new_bone = cmds.joint(name=node['name'])
+
+ # 应用变换
+ try:
+ cmds.xform(new_bone, translation=translation, rotation=rotation, scale=scale, worldSpace=False)
+ except Exception as e:
+ self.log_info(f" 警告: 无法应用变换到 {new_bone}: {str(e)}")
+
+ # 递归创建子骨骼
+ for child_node in node['children']:
+ self._create_bone_hierarchy_node(child_node, new_bone)
+
+ def _copy_bone_hierarchy(self, hierarchy, root_parent):
+ """复制骨骼层级结构
+
+ Args:
+ hierarchy: 层级结构列表
+ root_parent: 根父骨骼(新的root骨骼)
+
+ Returns:
+ int: 创建的骨骼数量
+ """
+ created_count = 0
+ for root_node in hierarchy:
+ created_count += self._copy_bone_node(root_node, root_parent)
+ return created_count
+
+ def _copy_bone_node(self, node, parent):
+ """递归复制骨骼节点
+
+ Args:
+ node: 骨骼节点字典 {'name': str, 'path': str, 'children': list}
+ parent: 父骨骼对象
+
+ Returns:
+ int: 创建的骨骼数量
+ """
+ # 获取原始骨骼的完整路径
+ original_bone = node['path']
+
+ # 移除路径前导的 | 符号
+ if original_bone and original_bone.startswith('|'):
+ original_bone = original_bone[1:]
+
+ # 检查骨骼是否存在
+ if not original_bone or not cmds.objExists(original_bone):
+ self.log_info(f" 警告: 原始骨骼不存在: {original_bone}")
+ return 0
+
+ # 获取世界空间的变换信息
+ try:
+ world_pos = cmds.xform(original_bone, query=True, translation=True, worldSpace=True)
+ world_rot = cmds.xform(original_bone, query=True, rotation=True, worldSpace=True)
+ except Exception as e:
+ self.log_info(f" 警告: 无法获取 {original_bone} 的世界空间变换: {str(e)}")
+ world_pos = [0, 0, 0]
+ world_rot = [0, 0, 0]
+
+ # 获取相对缩放
+ try:
+ scale = cmds.getAttr(f"{original_bone}.scale")
+ except:
+ scale = [1, 1, 1]
+
+ # 清除选择
+ cmds.select(clear=True)
+
+ # 选择父骨骼(如果有)
+ if parent and cmds.objExists(parent):
+ cmds.select(parent, replace=True)
+
+ # 创建新骨骼
+ new_bone_name = f"copy_{node['name']}"
+ new_bone = cmds.joint(name=new_bone_name)
+
+ # 设置世界空间位置和旋转
+ try:
+ cmds.xform(new_bone, translation=world_pos, worldSpace=True)
+ cmds.xform(new_bone, rotation=world_rot, worldSpace=True)
+ except Exception as e:
+ self.log_info(f" 警告: 无法设置 {new_bone} 的世界空间变换: {str(e)}")
+
+ # 设置缩放
+ try:
+ cmds.setAttr(f"{new_bone}.scale", *scale)
+ except:
+ pass
+
+ created_count = 1
+
+ # 递归复制子骨骼
+ for child_node in node['children']:
+ created_count += self._copy_bone_node(child_node, new_bone)
+
+ return created_count
+
+ # ========== 矩阵节点清理器功能 ==========
+
+ def select_all_matrix_nodes(self, *args):
+ """全选矩阵节点类型"""
+ for checkbox in self.matrix_checkboxes.values():
+ cmds.checkBox(checkbox, edit=True, value=True)
+ self.log_info("已全选所有矩阵节点类型")
+
+ def deselect_all_matrix_nodes(self, *args):
+ """全不选矩阵节点类型"""
+ for checkbox in self.matrix_checkboxes.values():
+ cmds.checkBox(checkbox, edit=True, value=False)
+ self.log_info("已取消选择所有矩阵节点类型")
+
+ def get_selected_matrix_node_types(self):
+ """获取选中的矩阵节点类型"""
+ selected_types = []
+ for node_type, checkbox in self.matrix_checkboxes.items():
+ if cmds.checkBox(checkbox, query=True, value=True):
+ selected_types.append(node_type)
+ return selected_types
+
+ def scan_geometry_matrix_nodes(self, *args):
+ """扫描模型矩阵节点 - 扫描几何体上的矩阵节点"""
+ if not self.geometry_list:
+ self.log_info("警告: 请先拾取几何体")
+ cmds.warning("请先拾取几何体")
+ return
+
+ self._scan_matrix_nodes_on_objects(self.geometry_list, "几何体")
+
+ def scan_bone_matrix_nodes(self, *args):
+ """扫描骨骼矩阵节点 - 扫描骨骼上的矩阵节点"""
+ if not self.bone_list:
+ self.log_info("警告: 请先分析骨骼")
+ cmds.warning("请先分析骨骼")
+ return
+
+ self._scan_matrix_nodes_on_objects(self.bone_list, "骨骼")
+
+ def scan_all_matrix_nodes(self, *args):
+ """扫描模型和骨骼矩阵节点 - 扫描所有对象的矩阵节点"""
+ if not self.geometry_list and not self.bone_list:
+ self.log_info("警告: 请先拾取几何体或分析骨骼")
+ cmds.warning("请先拾取几何体或分析骨骼")
+ return
+
+ all_objects = list(set(self.geometry_list + self.bone_list))
+ self._scan_matrix_nodes_on_objects(all_objects, "模型和骨骼")
+
+ def _scan_matrix_nodes_on_objects(self, objects, object_type_name):
+ """扫描对象上的矩阵节点 - 通用方法"""
+ # 所有矩阵节点类型
+ all_matrix_types = [
+ 'multMatrix',
+ 'decomposeMatrix',
+ 'multiplyDivide',
+ 'plusMinusAverage',
+ 'blendMatrix',
+ 'pickMatrix',
+ 'composeMatrix',
+ 'inverseMatrix',
+ 'transposeMatrix',
+ 'blendColors'
+ ]
+
+ self.log_info(f"\n开始扫描{object_type_name}矩阵节点...")
+
+ # 首先检查场景中是否有矩阵节点
+ scene_matrix_nodes = {}
+ for matrix_type in all_matrix_types:
+ nodes = cmds.ls(type=matrix_type)
+ if nodes:
+ scene_matrix_nodes[matrix_type] = len(nodes)
+
+ if not scene_matrix_nodes:
+ self.log_info("\n场景中没有找到任何矩阵节点!")
+ return
+
+ self.log_info("场景中找到矩阵节点:")
+ for matrix_type, count in sorted(scene_matrix_nodes.items()):
+ self.log_info(f" {matrix_type}: {count} 个")
+
+ # 扫描对象上的矩阵节点
+ total_matrix_nodes = 0
+ matrix_summary = {}
+ found_any = False
+
+ for obj in objects:
+ if not cmds.objExists(obj):
+ continue
+
+ obj_matrix_nodes = []
+
+ for matrix_type in all_matrix_types:
+ # 查找连接到对象的矩阵节点(作为源)
+ matrix_nodes = cmds.listConnections(obj, type=matrix_type, source=True, destination=False)
+ if matrix_nodes:
+ matrix_nodes = list(set(matrix_nodes))
+ obj_matrix_nodes.extend(matrix_nodes)
+
+ if matrix_type not in matrix_summary:
+ matrix_summary[matrix_type] = 0
+ matrix_summary[matrix_type] += len(matrix_nodes)
+
+ # 也查找对象作为矩阵节点目标的情况
+ target_matrix_nodes = cmds.listConnections(obj, type=matrix_type, source=False, destination=True)
+ if target_matrix_nodes:
+ target_matrix_nodes = list(set(target_matrix_nodes))
+ for tm in target_matrix_nodes:
+ if tm not in obj_matrix_nodes:
+ obj_matrix_nodes.append(tm)
+ if matrix_type not in matrix_summary:
+ matrix_summary[matrix_type] = 0
+ matrix_summary[matrix_type] += 1
+
+ # 去重
+ unique_matrix_nodes = list(set(obj_matrix_nodes))
+
+ if unique_matrix_nodes:
+ found_any = True
+ total_matrix_nodes += len(unique_matrix_nodes)
+ node_names = [n.split('|')[-1] for n in unique_matrix_nodes]
+ self.log_info(f" {obj.split('|')[-1]} 有 {len(unique_matrix_nodes)} 个矩阵节点: {', '.join(node_names)}")
+
+ # 输出统计信息
+ self.log_info("\n扫描完成!")
+ self.log_info(f"总{object_type_name}数: {len(objects)}")
+ self.log_info(f"{object_type_name}上的矩阵节点数: {total_matrix_nodes}")
+
+ if matrix_summary:
+ self.log_info(f"\n{object_type_name}矩阵节点类型统计:")
+ for matrix_type, count in sorted(matrix_summary.items()):
+ self.log_info(f" {matrix_type}: {count} 个")
+ else:
+ self.log_info(f"\n这些{object_type_name}上没有找到矩阵节点")
+ self.log_info("提示: 场景中有矩阵节点,但不在选中的对象上")
+
+ def clean_matrix_nodes(self, *args):
+ """清理矩阵节点"""
+ if not self.bone_list:
+ self.log_info("警告: 请先分析骨骼")
+ cmds.warning("请先分析骨骼")
+ return
+
+ selected_types = self.get_selected_matrix_node_types()
+ if not selected_types:
+ self.log_info("警告: 请至少选择一种矩阵节点类型")
+ cmds.warning("请至少选择一种矩阵节点类型")
+ return
+
+ # 检查安全模式
+ safe_mode = cmds.checkBox(self.safe_mode_checkbox, query=True, value=True)
+
+ if safe_mode:
+ warning_msg = (
+ '安全模式已启用!\n'
+ '只删除控制约束相关的矩阵节点,保护绑定系统的核心节点。\n'
+ '如果需要删除所有矩阵节点,请先禁用安全模式。\n\n'
+ '确定要继续吗?'
+ )
+ else:
+ warning_msg = (
+ '危险操作!\n'
+ '安全模式已禁用,将删除所有选中的矩阵节点!\n'
+ '这可能会完全破坏绑定系统的连接关系!\n\n'
+ '确定要继续吗?'
+ )
+
+ # 确认对话框
+ result = cmds.confirmDialog(
+ title='确认清理',
+ message=warning_msg,
+ button=['确定', '取消'],
+ defaultButton='取消',
+ cancelButton='取消',
+ dismissString='取消'
+ )
+
+ if result != '确定':
+ self.log_info("操作已取消")
+ return
+
+ removed_count = self.remove_matrix_nodes_from_bones(self.bone_list, selected_types, safe_mode)
+
+ if removed_count > 0:
+ self.log_info(f"成功清理了 {removed_count} 个矩阵节点")
+ else:
+ self.log_info("没有找到需要清理的矩阵节点")
+
+ # ========== 核心功能函数 ==========
+
+ def get_skincluster_from_geometry(self, geometry):
+ """获取几何体的skinCluster节点"""
+ shapes = cmds.listRelatives(geometry, shapes=True, fullPath=True, noIntermediate=True)
+ if not shapes:
+ return None
+
+ for shape in shapes:
+ history = cmds.listHistory(shape, pruneDagObjects=True)
+ if history:
+ skin_clusters = cmds.ls(history, type='skinCluster')
+ if skin_clusters:
+ return skin_clusters[0]
+
+ return None
+
+ def get_weighted_bones_from_skincluster(self, skin_cluster):
+ """从skinCluster获取所有有权重的骨骼"""
+ if not skin_cluster:
+ return []
+
+ influences = cmds.skinCluster(skin_cluster, query=True, influence=True)
+ return influences if influences else []
+
+ def remove_constraints_from_bones(self, bones, constraint_types):
+ """移除骨骼上的指定约束"""
+ if not bones:
+ return 0
+
+ removed_count = 0
+ self.log_info("\n开始移除骨骼约束...")
+
+ for bone in bones:
+ if not cmds.objExists(bone):
+ continue
+
+ # 查找骨骼上的所有约束
+ constraints = []
+ for constraint_type in constraint_types:
+ # 查找连接到骨骼的约束节点
+ bone_constraints = cmds.listConnections(bone, type=constraint_type)
+ if bone_constraints:
+ constraints.extend(bone_constraints)
+
+ # 去重
+ constraints = list(set(constraints))
+
+ # 删除约束
+ for constraint in constraints:
+ if cmds.objExists(constraint):
+ try:
+ cmds.delete(constraint)
+ removed_count += 1
+ self.log_info(f" 移除约束: {constraint.split('|')[-1]} (来自 {bone.split('|')[-1]})")
+ except Exception as e:
+ self.log_info(f" 警告: 无法删除约束 {constraint}: {str(e)}")
+
+ return removed_count
+
+ def remove_matrix_nodes_from_bones(self, bones, matrix_types, safe_mode=True):
+ """移除骨骼上的指定矩阵节点
+
+ Args:
+ bones: 骨骼列表
+ matrix_types: 矩阵节点类型列表
+ safe_mode: 安全模式,True时保护绑定系统的核心节点
+ """
+ if not bones:
+ return 0
+
+ removed_count = 0
+ skipped_count = 0
+ self.log_info("\n开始移除骨骼矩阵节点...")
+
+ if safe_mode:
+ self.log_info("安全模式已启用,将保护绑定系统的核心节点")
+
+ # 定义保护模式列表(绑定系统的核心节点)
+ protected_patterns = [
+ '*_parent_multMatrix', # 父子关系矩阵
+ '*_child_decomposeMatrix', # 子节点解压矩阵
+ '*_child_decomposeMatrix1', # 子节点解压矩阵变体
+ '*_worldparent_multMatrix', # 世界父矩阵
+ '*_scale_parent_multMatrix', # 缩放父矩阵
+ '*_psd_*_multMatrix', # PSD相关矩阵
+ '*_psd_*_pickMatrix', # PSD pick矩阵
+ '*_psd_*_composeMatrix', # PSD组合矩阵
+ '*_tb_*_multMatrix', # Twist Bone相关矩阵
+ '*_tb_*_child_decomposeMatrix', # Twist Bone解压矩阵
+ '*_skin_joint_multMatrix', # 蒙皮骨骼矩阵
+ '*_skin_child_decomposeMatrix', # 蒙皮骨骼解压矩阵
+ '*_scale_child_decomposeMatrix', # 缩放子节点解压矩阵
+ '*_parent_multMatrix1', # 父子关系矩阵变体
+ '*_parent_multMatrix2', # 父子关系矩阵变体
+ '*_parent_multMatrix3', # 父子关系矩阵变体
+ ]
+
+ # 导入fnmatch模块用于通配符匹配
+ import fnmatch
+
+ for bone in bones:
+ if not cmds.objExists(bone):
+ continue
+
+ # 查找骨骼上的所有矩阵节点
+ matrix_nodes = []
+ for matrix_type in matrix_types:
+ # 查找连接到骨骼的矩阵节点
+ bone_matrix_nodes = cmds.listConnections(bone, type=matrix_type)
+ if bone_matrix_nodes:
+ matrix_nodes.extend(bone_matrix_nodes)
+
+ # 去重
+ matrix_nodes = list(set(matrix_nodes))
+
+ # 删除矩阵节点
+ for matrix_node in matrix_nodes:
+ if not cmds.objExists(matrix_node):
+ continue
+
+ # 检查是否在保护列表中
+ node_name = matrix_node.split('|')[-1]
+ should_skip = False
+
+ if safe_mode:
+ for pattern in protected_patterns:
+ if fnmatch.fnmatch(node_name, pattern):
+ should_skip = True
+ break
+
+ if should_skip:
+ skipped_count += 1
+ if skipped_count <= 5: # 只显示前5个跳过的节点
+ self.log_info(f" [保护] 跳过核心节点: {node_name}")
+ continue
+
+ try:
+ cmds.delete(matrix_node)
+ removed_count += 1
+ self.log_info(f" 移除矩阵节点: {node_name} (来自 {bone.split('|')[-1]})")
+ except Exception as e:
+ self.log_info(f" 警告: 无法删除矩阵节点 {matrix_node}: {str(e)}")
+
+ if safe_mode and skipped_count > 5:
+ self.log_info(f" ... 还有 {skipped_count - 5} 个核心节点被保护")
+
+ return removed_count
+
+ def create_bone_set(self, bones, set_name):
+ """创建集合并添加骨骼"""
+ if not bones:
+ return None
+
+ # 检查集合是否已存在
+ if cmds.objExists(set_name):
+ result = cmds.confirmDialog(
+ title='集合已存在',
+ message=f'集合 "{set_name}" 已存在,是否要添加到现有集合中?',
+ button=['添加到现有集合', '创建新集合', '取消'],
+ defaultButton='添加到现有集合',
+ cancelButton='取消',
+ dismissString='取消'
+ )
+
+ if result == '取消':
+ return None
+ elif result == '创建新集合':
+ i = 1
+ while cmds.objExists(f"{set_name}{i}"):
+ i += 1
+ set_name = f"{set_name}{i}"
+ bone_set = cmds.sets(name=set_name, empty=True)
+ else:
+ bone_set = set_name
+ else:
+ bone_set = cmds.sets(name=set_name, empty=True)
+
+ # 将骨骼添加到集合中
+ for bone in bones:
+ if cmds.objExists(bone):
+ try:
+ cmds.sets(bone, addElement=bone_set)
+ except Exception as e:
+ self.log_info(f"警告: 无法将 {bone} 添加到集合中: {str(e)}")
+
+ return bone_set
+
+
+def show_ui():
+ """显示UI"""
+ ui = PickUpWeightedBonesUI()
+ ui.create_ui()
+
+
+# 执行函数
+if __name__ == "__main__":
+ show_ui()
diff --git a/2025/scripts/rigging_tools/StandardizeSkeleton.py b/2025/scripts/rigging_tools/StandardizeSkeleton.py
new file mode 100644
index 0000000..93c2628
--- /dev/null
+++ b/2025/scripts/rigging_tools/StandardizeSkeleton.py
@@ -0,0 +1,737 @@
+# -*- coding: utf-8 -*-
+"""
+StandardizeSkeleton.py
+标准化骨骼工具 - 用于从绑定文件中提取干净的骨骼层级
+
+功能:
+1. 识别所有有蒙皮权重的骨骼
+2. 复制这些骨骼并保持原有层级关系
+3. 移除控制器和其他非骨骼节点
+4. 批量添加/剔除骨骼前缀后缀
+5. 创建干净的骨骼树,便于导出到游戏引擎
+
+作者: Kilo Code
+日期: 2025
+"""
+
+import maya.cmds as cmds
+import maya.mel as mel
+from functools import partial
+
+try:
+ from PySide2 import QtWidgets, QtCore, QtGui
+ from shiboken2 import wrapInstance
+except ImportError:
+ from PySide6 import QtWidgets, QtCore, QtGui
+ from shiboken6 import wrapInstance
+
+import maya.OpenMayaUI as omui
+
+
+def get_maya_main_window():
+ """获取Maya主窗口"""
+ main_window_ptr = omui.MQtUtil.mainWindow()
+ return wrapInstance(int(main_window_ptr), QtWidgets.QWidget)
+
+
+class StandardizeSkeletonUI(QtWidgets.QDialog):
+ """标准化骨骼工具UI"""
+
+ def __init__(self, parent=get_maya_main_window()):
+ super(StandardizeSkeletonUI, self).__init__(parent)
+
+ self.setWindowTitle("标准化骨骼工具")
+ self.setMinimumWidth(500)
+ self.setMinimumHeight(600)
+ self.setWindowFlags(self.windowFlags() ^ QtCore.Qt.WindowContextHelpButtonHint)
+
+ self.geometry_list = [] # 存储几何体列表
+
+ self.create_widgets()
+ self.create_layouts()
+ self.create_connections()
+
+ def create_widgets(self):
+ """创建UI控件"""
+ # 几何体列表区域
+ self.geo_group = QtWidgets.QGroupBox("几何体列表")
+ self.geo_list_widget = QtWidgets.QListWidget()
+ self.geo_list_widget.setSelectionMode(QtWidgets.QAbstractItemView.ExtendedSelection)
+
+ self.add_selected_btn = QtWidgets.QPushButton("添加选中对象")
+ self.add_selected_btn.setToolTip("选择对象后点击,会自动过滤出几何体")
+
+ self.remove_selected_btn = QtWidgets.QPushButton("移除选中项")
+ self.clear_list_btn = QtWidgets.QPushButton("清空列表")
+
+ # 骨骼信息区域
+ self.info_group = QtWidgets.QGroupBox("骨骼信息")
+ self.info_text = QtWidgets.QTextEdit()
+ self.info_text.setReadOnly(True)
+ self.info_text.setMaximumHeight(150)
+
+ self.analyze_btn = QtWidgets.QPushButton("分析权重骨骼")
+ self.analyze_btn.setStyleSheet("background-color: #4a90e2; color: white; font-weight: bold;")
+
+ # 导出选项区域
+ self.export_group = QtWidgets.QGroupBox("导出选项")
+
+ self.export_name_label = QtWidgets.QLabel("导出组名称:")
+ self.export_name_edit = QtWidgets.QLineEdit("export_skeleton_grp")
+
+ self.prefix_label = QtWidgets.QLabel("添加前缀:")
+ self.prefix_edit = QtWidgets.QLineEdit()
+ self.prefix_edit.setPlaceholderText("例如: SK_")
+
+ self.suffix_label = QtWidgets.QLabel("添加后缀:")
+ self.suffix_edit = QtWidgets.QLineEdit()
+ self.suffix_edit.setPlaceholderText("例如: _jnt")
+
+ self.remove_prefix_label = QtWidgets.QLabel("移除前缀:")
+ self.remove_prefix_edit = QtWidgets.QLineEdit()
+ self.remove_prefix_edit.setPlaceholderText("例如: L_, R_, M_")
+
+ self.remove_suffix_label = QtWidgets.QLabel("移除后缀:")
+ self.remove_suffix_edit = QtWidgets.QLineEdit()
+ self.remove_suffix_edit.setPlaceholderText("例如: _joint, _jnt")
+
+ self.exclude_keywords_label = QtWidgets.QLabel("排除关键词:")
+ self.exclude_keywords_edit = QtWidgets.QLineEdit()
+ self.exclude_keywords_edit.setPlaceholderText("例如: hair, lashe, zip, wrinkle")
+ self.exclude_keywords_edit.setToolTip("包含这些关键词的骨骼将被排除(逗号分隔,不区分大小写)")
+
+ self.root_joint_label = QtWidgets.QLabel("根骨骼限制:")
+ self.root_joint_edit = QtWidgets.QLineEdit()
+ self.root_joint_edit.setPlaceholderText("例如: rig|root_joint (留空=不限制)")
+ self.root_joint_edit.setToolTip("只导出此骨骼下的子骨骼(留空则导出所有有权重的骨骼)")
+
+ self.keep_hierarchy_cb = QtWidgets.QCheckBox("保持原始层级关系")
+ self.keep_hierarchy_cb.setChecked(True)
+ self.keep_hierarchy_cb.setToolTip("保持骨骼的父子层级关系")
+
+ self.freeze_transforms_cb = QtWidgets.QCheckBox("冻结变换")
+ self.freeze_transforms_cb.setChecked(False)
+ self.freeze_transforms_cb.setToolTip("冻结导出骨骼的变换属性")
+
+ self.delete_constraints_cb = QtWidgets.QCheckBox("删除所有约束")
+ self.delete_constraints_cb.setChecked(True)
+ self.delete_constraints_cb.setToolTip("删除复制骨骼上的所有约束节点")
+
+ # 执行按钮
+ self.create_skeleton_btn = QtWidgets.QPushButton("创建导出骨骼")
+ self.create_skeleton_btn.setStyleSheet("background-color: #5cb85c; color: white; font-weight: bold; padding: 10px;")
+ self.create_skeleton_btn.setMinimumHeight(40)
+
+ self.select_export_btn = QtWidgets.QPushButton("选择导出组")
+ self.delete_export_btn = QtWidgets.QPushButton("删除导出组")
+
+ # 帮助文本
+ self.help_text = QtWidgets.QLabel(
+ "使用说明:\n"
+ "1. 点击'添加选中对象'添加包含几何体的对象\n"
+ "2. 点击'分析权重骨骼'查看将要导出的骨骼信息\n"
+ "3. 设置导出选项(可选)\n"
+ "4. 点击'创建导出骨骼'生成干净的骨骼层级"
+ )
+ self.help_text.setStyleSheet("color: #666; padding: 10px; background-color: #f5f5f5; border-radius: 5px;")
+ self.help_text.setWordWrap(True)
+
+ def create_layouts(self):
+ """创建布局"""
+ main_layout = QtWidgets.QVBoxLayout(self)
+
+ # 帮助文本
+ main_layout.addWidget(self.help_text)
+
+ # 几何体列表区域
+ geo_layout = QtWidgets.QVBoxLayout()
+ geo_layout.addWidget(self.geo_list_widget)
+
+ geo_btn_layout = QtWidgets.QHBoxLayout()
+ geo_btn_layout.addWidget(self.add_selected_btn)
+ geo_btn_layout.addWidget(self.remove_selected_btn)
+ geo_btn_layout.addWidget(self.clear_list_btn)
+ geo_layout.addLayout(geo_btn_layout)
+
+ self.geo_group.setLayout(geo_layout)
+ main_layout.addWidget(self.geo_group)
+
+ # 分析按钮
+ main_layout.addWidget(self.analyze_btn)
+
+ # 骨骼信息区域
+ info_layout = QtWidgets.QVBoxLayout()
+ info_layout.addWidget(self.info_text)
+ self.info_group.setLayout(info_layout)
+ main_layout.addWidget(self.info_group)
+
+ # 导出选项区域
+ export_layout = QtWidgets.QGridLayout()
+
+ row = 0
+ export_layout.addWidget(self.export_name_label, row, 0)
+ export_layout.addWidget(self.export_name_edit, row, 1)
+
+ row += 1
+ export_layout.addWidget(self.prefix_label, row, 0)
+ export_layout.addWidget(self.prefix_edit, row, 1)
+
+ row += 1
+ export_layout.addWidget(self.suffix_label, row, 0)
+ export_layout.addWidget(self.suffix_edit, row, 1)
+
+ row += 1
+ export_layout.addWidget(self.remove_prefix_label, row, 0)
+ export_layout.addWidget(self.remove_prefix_edit, row, 1)
+
+ row += 1
+ export_layout.addWidget(self.remove_suffix_label, row, 0)
+ export_layout.addWidget(self.remove_suffix_edit, row, 1)
+
+ row += 1
+ export_layout.addWidget(self.exclude_keywords_label, row, 0)
+ export_layout.addWidget(self.exclude_keywords_edit, row, 1)
+
+ row += 1
+ export_layout.addWidget(self.root_joint_label, row, 0)
+ export_layout.addWidget(self.root_joint_edit, row, 1)
+
+ row += 1
+ export_layout.addWidget(self.keep_hierarchy_cb, row, 0, 1, 2)
+
+ row += 1
+ export_layout.addWidget(self.freeze_transforms_cb, row, 0, 1, 2)
+
+ row += 1
+ export_layout.addWidget(self.delete_constraints_cb, row, 0, 1, 2)
+
+ self.export_group.setLayout(export_layout)
+ main_layout.addWidget(self.export_group)
+
+ # 执行按钮
+ main_layout.addWidget(self.create_skeleton_btn)
+
+ # 底部按钮
+ bottom_btn_layout = QtWidgets.QHBoxLayout()
+ bottom_btn_layout.addWidget(self.select_export_btn)
+ bottom_btn_layout.addWidget(self.delete_export_btn)
+ main_layout.addLayout(bottom_btn_layout)
+
+ def create_connections(self):
+ """创建信号连接"""
+ self.add_selected_btn.clicked.connect(self.add_selected_geometry)
+ self.remove_selected_btn.clicked.connect(self.remove_selected_items)
+ self.clear_list_btn.clicked.connect(self.clear_geometry_list)
+ self.analyze_btn.clicked.connect(self.analyze_weighted_joints)
+ self.create_skeleton_btn.clicked.connect(self.create_export_skeleton)
+ self.select_export_btn.clicked.connect(self.select_export_group)
+ self.delete_export_btn.clicked.connect(self.delete_export_group)
+
+ def add_selected_geometry(self):
+ """添加选中的几何体"""
+ selection = cmds.ls(selection=True, long=True)
+
+ if not selection:
+ QtWidgets.QMessageBox.warning(self, "警告", "请先选择对象!")
+ return
+
+ added_count = 0
+ for obj in selection:
+ # 获取所有子节点中的mesh
+ meshes = self.get_meshes_from_object(obj)
+
+ for mesh in meshes:
+ # 获取transform节点
+ transform = cmds.listRelatives(mesh, parent=True, fullPath=True)[0]
+
+ if transform not in self.geometry_list:
+ self.geometry_list.append(transform)
+ # 显示短名称
+ short_name = transform.split('|')[-1]
+ self.geo_list_widget.addItem(short_name)
+ added_count += 1
+
+ if added_count > 0:
+ self.info_text.append(f"添加了 {added_count} 个几何体")
+ else:
+ QtWidgets.QMessageBox.information(self, "提示", "没有找到新的几何体或几何体已存在")
+
+ def get_meshes_from_object(self, obj):
+ """从对象中获取所有mesh"""
+ meshes = []
+
+ # 检查对象本身是否是mesh
+ shapes = cmds.listRelatives(obj, shapes=True, fullPath=True, type="mesh") or []
+ meshes.extend(shapes)
+
+ # 检查所有子节点
+ descendants = cmds.listRelatives(obj, allDescendents=True, fullPath=True, type="mesh") or []
+ meshes.extend(descendants)
+
+ return list(set(meshes)) # 去重
+
+ def remove_selected_items(self):
+ """移除选中的列表项"""
+ selected_items = self.geo_list_widget.selectedItems()
+
+ if not selected_items:
+ QtWidgets.QMessageBox.warning(self, "警告", "请先选择要移除的项!")
+ return
+
+ for item in selected_items:
+ row = self.geo_list_widget.row(item)
+ self.geo_list_widget.takeItem(row)
+ if row < len(self.geometry_list):
+ self.geometry_list.pop(row)
+
+ def clear_geometry_list(self):
+ """清空几何体列表"""
+ self.geo_list_widget.clear()
+ self.geometry_list = []
+ self.info_text.append("已清空几何体列表")
+
+ def analyze_weighted_joints(self):
+ """分析有权重的骨骼"""
+ if not self.geometry_list:
+ QtWidgets.QMessageBox.warning(self, "警告", "请先添加几何体!")
+ return
+
+ self.info_text.clear()
+ self.info_text.append("正在分析权重骨骼...\n")
+
+ try:
+ # 获取排除关键词
+ exclude_keywords_text = self.exclude_keywords_edit.text().strip()
+ exclude_keywords = [k.strip() for k in exclude_keywords_text.split(',') if k.strip()] if exclude_keywords_text else None
+
+ # 获取根骨骼限制
+ root_joint = self.root_joint_edit.text().strip() or None
+
+ if exclude_keywords:
+ self.info_text.append(f"排除关键词: {', '.join(exclude_keywords)}")
+
+ if root_joint:
+ if cmds.objExists(root_joint):
+ self.info_text.append(f"根骨骼限制: {root_joint}\n")
+ else:
+ self.info_text.append(f"警告: 根骨骼 '{root_joint}' 不存在,将忽略此限制\n")
+ root_joint = None
+
+ weighted_joints = self.get_weighted_joints(self.geometry_list, exclude_keywords, root_joint)
+
+ if not weighted_joints:
+ self.info_text.append("未找到有权重的骨骼!")
+ return
+
+ # 分析骨骼层级
+ root_joints = self.get_root_joints(weighted_joints)
+
+ self.info_text.append(f"找到 {len(weighted_joints)} 个有权重的骨骼")
+ self.info_text.append(f"根骨骼数量: {len(root_joints)}")
+ self.info_text.append(f"\n根骨骼列表:")
+ for root in root_joints:
+ short_name = root.split('|')[-1]
+ self.info_text.append(f" - {short_name}")
+
+ # 显示前20个骨骼
+ self.info_text.append(f"\n前20个权重骨骼:")
+ for i, joint in enumerate(weighted_joints[:20]):
+ short_name = joint.split('|')[-1]
+ self.info_text.append(f" {i+1}. {short_name}")
+
+ if len(weighted_joints) > 20:
+ self.info_text.append(f" ... 还有 {len(weighted_joints) - 20} 个骨骼")
+
+ except Exception as e:
+ self.info_text.append(f"\n错误: {str(e)}")
+ import traceback
+ self.info_text.append(traceback.format_exc())
+
+ def get_weighted_joints(self, geometry_list, exclude_keywords=None, root_joint=None):
+ """获取所有有权重的骨骼"""
+ weighted_joints = set()
+
+ # 如果指定了根骨骼,获取其所有子骨骼
+ root_joint_children = None
+ if root_joint and cmds.objExists(root_joint):
+ root_joint_children = set()
+ all_joints = cmds.listRelatives(root_joint, allDescendents=True, type="joint", fullPath=True) or []
+ root_joint_children = set(all_joints)
+ root_joint_children.add(cmds.ls(root_joint, long=True)[0])
+
+ for geo in geometry_list:
+ # 获取mesh shape
+ shapes = cmds.listRelatives(geo, shapes=True, fullPath=True, type="mesh") or []
+
+ for shape in shapes:
+ # 查找skinCluster
+ history = cmds.listHistory(shape, pruneDagObjects=True) or []
+
+ # 过滤出skinCluster节点
+ skin_clusters = [node for node in history if cmds.nodeType(node) == "skinCluster"]
+
+ for skin_cluster in skin_clusters:
+ # 获取影响的骨骼
+ influences = cmds.skinCluster(skin_cluster, query=True, influence=True) or []
+
+ # 转换为长名称
+ for influence in influences:
+ long_name = cmds.ls(influence, long=True)[0]
+ if cmds.nodeType(long_name) == "joint":
+ # 检查是否在根骨骼下
+ if root_joint_children is not None and long_name not in root_joint_children:
+ continue
+
+ # 检查是否需要排除
+ if exclude_keywords:
+ short_name = long_name.split('|')[-1].lower()
+ should_exclude = False
+ for keyword in exclude_keywords:
+ if keyword.lower() in short_name:
+ should_exclude = True
+ break
+ if not should_exclude:
+ weighted_joints.add(long_name)
+ else:
+ weighted_joints.add(long_name)
+
+ return list(weighted_joints)
+
+ def get_root_joints(self, joint_list):
+ """获取根骨骼(在joint_list中没有父骨骼的骨骼)"""
+ root_joints = []
+
+ for joint in joint_list:
+ # 获取父节点
+ parent = cmds.listRelatives(joint, parent=True, fullPath=True)
+
+ # 如果没有父节点,或者父节点不是joint,或者父节点不在列表中
+ if not parent:
+ root_joints.append(joint)
+ else:
+ parent_joint = parent[0]
+ if cmds.nodeType(parent_joint) != "joint" or parent_joint not in joint_list:
+ root_joints.append(joint)
+
+ return root_joints
+
+ def create_export_skeleton(self):
+ """创建导出骨骼"""
+ if not self.geometry_list:
+ QtWidgets.QMessageBox.warning(self, "警告", "请先添加几何体!")
+ return
+
+ export_name = self.export_name_edit.text().strip()
+ if not export_name:
+ QtWidgets.QMessageBox.warning(self, "警告", "请输入导出组名称!")
+ return
+
+ # 确认对话框
+ reply = QtWidgets.QMessageBox.question(
+ self,
+ "确认",
+ f"将创建导出骨骼组: {export_name}\n是否继续?",
+ QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No
+ )
+
+ if reply == QtWidgets.QMessageBox.No:
+ return
+
+ try:
+ self.info_text.clear()
+ self.info_text.append("开始创建导出骨骼...\n")
+
+ # 获取排除关键词
+ exclude_keywords_text = self.exclude_keywords_edit.text().strip()
+ exclude_keywords = [k.strip() for k in exclude_keywords_text.split(',') if k.strip()] if exclude_keywords_text else None
+
+ # 获取根骨骼限制
+ root_joint = self.root_joint_edit.text().strip() or None
+
+ if exclude_keywords:
+ self.info_text.append(f"排除关键词: {', '.join(exclude_keywords)}")
+
+ if root_joint:
+ if cmds.objExists(root_joint):
+ self.info_text.append(f"根骨骼限制: {root_joint}")
+ else:
+ self.info_text.append(f"警告: 根骨骼 '{root_joint}' 不存在,将忽略此限制")
+ root_joint = None
+
+ # 获取有权重的骨骼
+ weighted_joints = self.get_weighted_joints(self.geometry_list, exclude_keywords, root_joint)
+
+ if not weighted_joints:
+ QtWidgets.QMessageBox.warning(self, "警告", "未找到有权重的骨骼!")
+ return
+
+ self.info_text.append(f"找到 {len(weighted_joints)} 个有权重的骨骼")
+
+ # 删除已存在的导出组
+ if cmds.objExists(export_name):
+ cmds.delete(export_name)
+ self.info_text.append(f"删除已存在的 {export_name}")
+
+ # 创建导出组
+ export_group = cmds.group(empty=True, name=export_name)
+ self.info_text.append(f"创建导出组: {export_group}")
+
+ # 复制骨骼
+ if self.keep_hierarchy_cb.isChecked():
+ # 保持层级关系
+ duplicated_joints = self.duplicate_joints_with_hierarchy(
+ weighted_joints,
+ export_group
+ )
+ else:
+ # 不保持层级,所有骨骼平铺
+ duplicated_joints = self.duplicate_joints_flat(
+ weighted_joints,
+ export_group
+ )
+
+ self.info_text.append(f"复制了 {len(duplicated_joints)} 个骨骼")
+
+ # 删除约束
+ if self.delete_constraints_cb.isChecked() and duplicated_joints:
+ deleted_constraints = self.delete_all_constraints(duplicated_joints)
+ if deleted_constraints > 0:
+ self.info_text.append(f"删除了 {deleted_constraints} 个约束")
+
+ # 重命名骨骼
+ if duplicated_joints:
+ self.rename_joints(
+ duplicated_joints,
+ self.prefix_edit.text().strip(),
+ self.suffix_edit.text().strip(),
+ self.remove_prefix_edit.text().strip(),
+ self.remove_suffix_edit.text().strip()
+ )
+
+ # 冻结变换
+ if self.freeze_transforms_cb.isChecked() and duplicated_joints:
+ try:
+ cmds.makeIdentity(duplicated_joints, apply=True, translate=True, rotate=True, scale=True)
+ self.info_text.append("已冻结变换")
+ except:
+ self.info_text.append("冻结变换失败(某些骨骼可能有约束)")
+
+ # 选择导出组
+ cmds.select(export_group)
+
+ self.info_text.append(f"\n成功创建导出骨骼!")
+ self.info_text.append(f"导出组: {export_group}")
+
+ QtWidgets.QMessageBox.information(
+ self,
+ "成功",
+ f"成功创建导出骨骼!\n导出组: {export_group}\n骨骼数量: {len(duplicated_joints)}"
+ )
+
+ except Exception as e:
+ error_msg = f"创建导出骨骼失败: {str(e)}"
+ self.info_text.append(f"\n错误: {error_msg}")
+ import traceback
+ self.info_text.append(traceback.format_exc())
+ QtWidgets.QMessageBox.critical(self, "错误", error_msg)
+
+ def duplicate_joints_with_hierarchy(self, joint_list, parent_group):
+ """复制骨骼并保持层级关系(只复制有权重的骨骼)"""
+ duplicated_joints = []
+ joint_mapping = {} # 原始骨骼 -> 复制骨骼的映射
+
+ # 第一步:复制所有骨骼
+ for joint in joint_list:
+ # 复制单个骨骼(不复制子节点)
+ dup_joint = cmds.duplicate(joint, parentOnly=True, returnRootsOnly=True)[0]
+
+ # 重命名(去掉Maya自动添加的数字后缀)
+ short_name = joint.split('|')[-1]
+ dup_joint = cmds.rename(dup_joint, short_name + "_export")
+
+ joint_mapping[joint] = dup_joint
+ duplicated_joints.append(dup_joint)
+
+ # 第二步:重建层级关系(跳过没有权重的中间骨骼)
+ for original_joint, dup_joint in joint_mapping.items():
+ # 查找最近的有权重的父骨骼
+ parent_joint = self.find_weighted_parent(original_joint, joint_list)
+
+ if parent_joint and parent_joint in joint_mapping:
+ # 如果找到有权重的父骨骼,建立父子关系
+ try:
+ cmds.parent(dup_joint, joint_mapping[parent_joint])
+ except:
+ pass
+ else:
+ # 如果没有找到,放到导出组下
+ try:
+ cmds.parent(dup_joint, parent_group)
+ except:
+ pass # 可能已经在导出组下了
+
+ return duplicated_joints
+
+ def find_weighted_parent(self, joint, weighted_joint_list):
+ """查找最近的有权重的父骨骼"""
+ current = joint
+
+ while True:
+ # 获取父节点
+ parent = cmds.listRelatives(current, parent=True, fullPath=True)
+
+ if not parent:
+ # 没有父节点了
+ return None
+
+ parent_node = parent[0]
+
+ # 检查父节点是否是joint
+ if cmds.nodeType(parent_node) != "joint":
+ # 父节点不是骨骼
+ return None
+
+ # 检查父骨骼是否在权重骨骼列表中
+ if parent_node in weighted_joint_list:
+ return parent_node
+
+ # 继续向上查找
+ current = parent_node
+
+ def duplicate_joints_flat(self, joint_list, parent_group):
+ """复制骨骼(平铺,不保持层级)"""
+ duplicated_joints = []
+
+ for joint in joint_list:
+ # 复制单个骨骼
+ dup_joint = cmds.duplicate(joint, parentOnly=True, returnRootsOnly=True)[0]
+
+ # 重命名
+ short_name = joint.split('|')[-1]
+ dup_joint = cmds.rename(dup_joint, short_name + "_export")
+
+ # 放到导出组下
+ cmds.parent(dup_joint, parent_group)
+
+ duplicated_joints.append(dup_joint)
+
+ return duplicated_joints
+
+ def delete_all_constraints(self, joint_list):
+ """删除所有约束"""
+ deleted_count = 0
+
+ # 获取所有骨骼(包括子骨骼)
+ all_joints = []
+ for joint in joint_list:
+ all_joints.append(joint)
+ descendants = cmds.listRelatives(joint, allDescendents=True, type="joint", fullPath=True) or []
+ all_joints.extend(descendants)
+
+ all_joints = list(set(all_joints)) # 去重
+
+ # 删除约束
+ for joint in all_joints:
+ # 获取连接到这个骨骼的所有约束
+ constraints = cmds.listConnections(joint, type="constraint") or []
+
+ for constraint in set(constraints): # 去重
+ if cmds.objExists(constraint):
+ try:
+ cmds.delete(constraint)
+ deleted_count += 1
+ except:
+ pass
+
+ return deleted_count
+
+ def rename_joints(self, joint_list, add_prefix, add_suffix, remove_prefix, remove_suffix):
+ """重命名骨骼"""
+ if not any([add_prefix, add_suffix, remove_prefix, remove_suffix]):
+ return
+
+ # 解析要移除的前缀和后缀(支持逗号分隔)
+ remove_prefixes = [p.strip() for p in remove_prefix.split(',') if p.strip()]
+ remove_suffixes = [s.strip() for s in remove_suffix.split(',') if s.strip()]
+
+ renamed_count = 0
+
+ for joint in joint_list:
+ old_name = joint.split('|')[-1]
+ new_name = old_name
+
+ # 移除后缀
+ for suffix in remove_suffixes:
+ if new_name.endswith(suffix):
+ new_name = new_name[:-len(suffix)]
+
+ # 移除前缀
+ for prefix in remove_prefixes:
+ if new_name.startswith(prefix):
+ new_name = new_name[len(prefix):]
+
+ # 添加前缀
+ if add_prefix:
+ new_name = add_prefix + new_name
+
+ # 添加后缀
+ if add_suffix:
+ new_name = new_name + add_suffix
+
+ # 重命名
+ if new_name != old_name:
+ try:
+ cmds.rename(joint, new_name)
+ renamed_count += 1
+ except:
+ pass
+
+ if renamed_count > 0:
+ self.info_text.append(f"重命名了 {renamed_count} 个骨骼")
+
+ def select_export_group(self):
+ """选择导出组"""
+ export_name = self.export_name_edit.text().strip()
+
+ if cmds.objExists(export_name):
+ cmds.select(export_name)
+ self.info_text.append(f"已选择: {export_name}")
+ else:
+ QtWidgets.QMessageBox.warning(self, "警告", f"导出组 '{export_name}' 不存在!")
+
+ def delete_export_group(self):
+ """删除导出组"""
+ export_name = self.export_name_edit.text().strip()
+
+ if not cmds.objExists(export_name):
+ QtWidgets.QMessageBox.warning(self, "警告", f"导出组 '{export_name}' 不存在!")
+ return
+
+ reply = QtWidgets.QMessageBox.question(
+ self,
+ "确认删除",
+ f"确定要删除导出组 '{export_name}' 吗?",
+ QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No
+ )
+
+ if reply == QtWidgets.QMessageBox.Yes:
+ cmds.delete(export_name)
+ self.info_text.append(f"已删除: {export_name}")
+
+
+def show():
+ """显示UI"""
+ global standardize_skeleton_ui
+
+ try:
+ standardize_skeleton_ui.close()
+ standardize_skeleton_ui.deleteLater()
+ except:
+ pass
+
+ standardize_skeleton_ui = StandardizeSkeletonUI()
+ standardize_skeleton_ui.show()
+
+
+if __name__ == "__main__":
+ show()
diff --git a/2025/scripts/rigging_tools/ngskintools2/README.md b/2025/scripts/rigging_tools/ngskintools2/README.md
deleted file mode 100644
index 1d112fa..0000000
--- a/2025/scripts/rigging_tools/ngskintools2/README.md
+++ /dev/null
@@ -1,61 +0,0 @@
-# ngSkinTools2 模块
-
-ngSkinTools2 是一个强大的 Maya 蒙皮权重编辑工具。
-
-## 📁 文件夹结构
-
-```
-ngskintools2/ # ngSkinTools2 核心模块
-├── __init__.py # 模块初始化(原始)
-├── launcher.py # 启动器脚本(新增)
-├── api/ # API 接口
-├── ui/ # 用户界面
-├── operations/ # 操作功能
-└── README.md # 本文档
-```
-
-## 🚀 使用方法
-
-### 从工具架启动
-
-1. 打开 Maya
-2. 切换到 **Nexus_Rigging** 工具架
-3. 点击 **ngSkin** 按钮
-
-### 从 Python 启动
-
-```python
-from rigging_tools.ngskintools2 import launcher
-launcher.LaunchNgSkinTools()
-```
-
-### 直接使用 ngSkinTools2 API
-
-```python
-from rigging_tools.ngskintools2 import open_ui
-open_ui()
-```
-
-## ✨ 主要功能
-
-- 高级权重绘制和编辑
-- 权重镜像和传递
-- 多层权重管理
-- 权重导入/导出
-- 影响对象管理
-
-## 📝 注意事项
-
-- 自动检测 Maya 版本并加载对应插件
-- 支持 Maya 2018-2026 版本
-- 如果当前版本没有完全匹配的插件,会自动使用向下兼容的版本
-- 建议在绑定工作流程中使用
-
-## 🔧 版本兼容性
-
-启动器会自动检测当前 Maya 版本并加载对应的插件:
-- **完全匹配**:优先使用与 Maya 版本完全匹配的插件
-- **向下兼容**:如果没有完全匹配,使用小于等于当前版本的最高版本插件
-- **兜底策略**:如果当前版本比所有可用插件都旧,使用最旧的可用插件
-
-支持的 Maya 版本:2018, 2019, 2020, 2022, 2023, 2024, 2025, 2026
diff --git a/2025/scripts/rigging_tools/ngskintools2/api/influenceMapping.py b/2025/scripts/rigging_tools/ngskintools2/api/influenceMapping.py
index 40d1cb4..7a82137 100644
--- a/2025/scripts/rigging_tools/ngskintools2/api/influenceMapping.py
+++ b/2025/scripts/rigging_tools/ngskintools2/api/influenceMapping.py
@@ -432,7 +432,7 @@ class InfluenceMappingConfig(Object):
return
if axis is not None and not isinstance(axis, int):
- raise Exception("invalid axis type, need int")
+ raise Exception("无效的轴类型,需要整数")
self.__mirror_axis = axis
@@ -487,10 +487,10 @@ class InfluenceMapping(Object):
def __init__(self):
self.config = InfluenceMappingConfig() # type:InfluenceMappingConfig
- "assigned config"
+ "分配的配置"
self.influences = [] # type: list[InfluenceInfo]
- "Source influences list. Can be assigned to result of :py:meth:`Layers.list_influences`"
+ "源影响列表. 可以分配给结果 :py:meth:`Layers.list_influences`"
self.destinationInfluences = None
self.calculatedMapping = None
@@ -498,7 +498,7 @@ class InfluenceMapping(Object):
def calculate(self):
mirror_mode = self.config.mirror_axis is not None
- log.info("calculate influence mapping, mirror mode: %s", mirror_mode)
+ log.info("计算影响映射,镜像模式: %s", mirror_mode)
if self.destinationInfluences is None:
self.destinationInfluences = self.influences
diff --git a/2025/scripts/rigging_tools/ngskintools2/api/layers.py b/2025/scripts/rigging_tools/ngskintools2/api/layers.py
index 9f4dc4e..5de8c37 100644
--- a/2025/scripts/rigging_tools/ngskintools2/api/layers.py
+++ b/2025/scripts/rigging_tools/ngskintools2/api/layers.py
@@ -56,7 +56,7 @@ class LayerEffects(Object):
mirror_mask = mirror_dq = mirror_weights = everything
logger.info(
- "configure mirror: layer %s mask %r weights %r dq %r direction %r",
+ "配置镜像: 图层 %s 遮罩 %r 权重 %r dq %r 方向 %r",
self.__layer.name,
mirror_mask,
mirror_weights,
@@ -103,7 +103,7 @@ class Layer(Object):
@classmethod
def load(cls, mesh, layer_id):
if layer_id < 0:
- raise Exception("invalid layer ID: %s" % layer_id)
+ raise Exception("无效图层 ID: %s" % layer_id)
result = Layer(mesh, layer_id)
result.reload()
return result
@@ -112,7 +112,7 @@ class Layer(Object):
self.mesh = mesh
self.id = id
self.effects = LayerEffects(self) # type: LayerEffects
- "configure effects for this layer"
+ "配置此图层的效果"
self.__state = None
if state is not None:
diff --git a/2025/scripts/rigging_tools/ngskintools2/api/mirror.py b/2025/scripts/rigging_tools/ngskintools2/api/mirror.py
index e9f0e37..041df27 100644
--- a/2025/scripts/rigging_tools/ngskintools2/api/mirror.py
+++ b/2025/scripts/rigging_tools/ngskintools2/api/mirror.py
@@ -63,7 +63,7 @@ class Mirror(Object):
"""
:type mapping: map[int] -> int
"""
- log.info("mapping updated: %r", mapping)
+ log.info("映射已更新: %r", mapping)
mapping_as_string = ','.join(str(k) + "," + str(v) for (k, v) in list(mapping.items()))
plugin.ngst2Layers(self.target, configureMirrorMapping=True, influencesMapping=mapping_as_string)
@@ -119,7 +119,7 @@ class Mirror(Object):
existing_ref_mesh = self.get_reference_mesh()
if existing_ref_mesh:
cmds.select(existing_ref_mesh)
- raise Exception("symmetry mesh already configured for %s: %s" % (str(sc), existing_ref_mesh))
+ raise Exception("对称网格已配置为 %s: %s" % (str(sc), existing_ref_mesh))
def get_shape(node):
return cmds.listRelatives(node, shapes=True)[0]
@@ -177,7 +177,7 @@ def set_reference_mesh_from_selection():
selection = cmds.ls(sl=True, long=True)
if len(selection) != 2:
- log.debug("wrong selection size")
+ log.debug("错误的选择尺寸")
return
m = Mirror(selection[1])
diff --git a/2025/scripts/rigging_tools/ngskintools2/api/session.py b/2025/scripts/rigging_tools/ngskintools2/api/session.py
index 4423c92..094a1fb 100644
--- a/2025/scripts/rigging_tools/ngskintools2/api/session.py
+++ b/2025/scripts/rigging_tools/ngskintools2/api/session.py
@@ -83,7 +83,7 @@ class Session(Object):
@signal.on(self.events.targetChanged)
def on_target_change():
- log.info("target changed: clearing target context")
+ log.info("目标已更改:清除目标上下文")
self.context.selected_layers.set([])
self.events.nodeSelectionChanged.emit()
diff --git a/2025/scripts/rigging_tools/ngskintools2/api/target_info.py b/2025/scripts/rigging_tools/ngskintools2/api/target_info.py
index c5ea229..67b987b 100644
--- a/2025/scripts/rigging_tools/ngskintools2/api/target_info.py
+++ b/2025/scripts/rigging_tools/ngskintools2/api/target_info.py
@@ -67,7 +67,7 @@ def add_influences(influences, target):
def long_names(names):
result = set(cmds.ls(names, long=True))
if len(result) != len(names):
- raise Exception("could not convert to a list of influences names: " + str(names))
+ raise Exception("无法转换为影响名称列表: " + str(names))
return result
existing = long_names([i.name if not i.path else i.path for i in list_influences(skin_cluster)])
diff --git a/2025/scripts/rigging_tools/ngskintools2/api/tools.py b/2025/scripts/rigging_tools/ngskintools2/api/tools.py
index c10a304..228ed97 100644
--- a/2025/scripts/rigging_tools/ngskintools2/api/tools.py
+++ b/2025/scripts/rigging_tools/ngskintools2/api/tools.py
@@ -103,7 +103,7 @@ def merge_layers(layers):
# verify that all layers are from the same parent
for i, j in zip(layers[:-1], layers[1:]):
if i.mesh != j.mesh:
- raise Exception("layers are not from the same mesh")
+ raise Exception("层不是来自同一个网格")
result = plugin.ngst2tools(
tool="mergeLayers",
diff --git a/2025/scripts/rigging_tools/ngskintools2/api/transfer.py b/2025/scripts/rigging_tools/ngskintools2/api/transfer.py
index 9c175c9..87c70b5 100644
--- a/2025/scripts/rigging_tools/ngskintools2/api/transfer.py
+++ b/2025/scripts/rigging_tools/ngskintools2/api/transfer.py
@@ -49,7 +49,7 @@ class LayersTransfer(Object):
def calc_influences_mapping_as_flat_list(self):
mapping_pairs = list(self.influences_mapping.asIntIntMapping(self.influences_mapping.calculate()).items())
if len(mapping_pairs) == 0:
- raise Exception("no mapping between source and destination influences")
+ raise Exception("源和目标影响之间没有映射")
# convert dict to flat array
return list(itertools.chain.from_iterable(mapping_pairs))
diff --git a/2025/scripts/rigging_tools/ngskintools2/decorators.py b/2025/scripts/rigging_tools/ngskintools2/decorators.py
index f2f03b2..92a7f0d 100644
--- a/2025/scripts/rigging_tools/ngskintools2/decorators.py
+++ b/2025/scripts/rigging_tools/ngskintools2/decorators.py
@@ -54,12 +54,12 @@ class Undo(Object):
self.name = name
def __enter__(self):
- log.debug("UNDO chunk %r: start", self.name)
+ log.debug("UNDO chunk %r: 开始", self.name)
cmds.undoInfo(openChunk=True, chunkName=self.name)
return self
def __exit__(self, _type, value, traceback):
- log.debug("UNDO chunk %r: end", self.name)
+ log.debug("UNDO chunk %r: 结束", self.name)
cmds.undoInfo(closeChunk=True)
diff --git a/2025/scripts/rigging_tools/ngskintools2/docs/Resources/appstore-combined.min.css b/2025/scripts/rigging_tools/ngskintools2/docs/Resources/appstore-combined.min.css
deleted file mode 100644
index 6fa4209..0000000
--- a/2025/scripts/rigging_tools/ngskintools2/docs/Resources/appstore-combined.min.css
+++ /dev/null
@@ -1,9 +0,0 @@
-/*!
- * Bootstrap v2.3.2
- *
- * Copyright 2013 Twitter, Inc
- * Licensed under the Apache License v2.0
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Designed and built with all the love in the world by @mdo and @fat.
- */.clearfix{*zoom:1}.clearfix:before,.clearfix:after{display:table;line-height:0;content:""}.clearfix:after{clear:both}.hide-text{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.input-block-level{display:block;width:100%;min-height:30px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}article,aside,details,figcaption,figure,footer,header,hgroup,nav,section{display:block}audio,canvas,video{display:inline-block;*display:inline;*zoom:1}audio:not([controls]){display:none}html{font-size:100%;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}a:focus{outline:thin dotted #333;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}a:hover,a:active{outline:0}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sup{top:-0.5em}sub{bottom:-0.25em}img{width:auto\9;height:auto;max-width:100%;vertical-align:middle;border:0;-ms-interpolation-mode:bicubic}#map_canvas img,.google-maps img{max-width:none}button,input,select,textarea{margin:0;font-size:100%;vertical-align:middle}button,input{*overflow:visible;line-height:normal}button::-moz-focus-inner,input::-moz-focus-inner{padding:0;border:0}button,html input[type="button"],input[type="reset"],input[type="submit"]{cursor:pointer;-webkit-appearance:button}label,select,button,input[type="button"],input[type="reset"],input[type="submit"],input[type="radio"],input[type="checkbox"]{cursor:pointer}input[type="search"]{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;-webkit-appearance:textfield}input[type="search"]::-webkit-search-decoration,input[type="search"]::-webkit-search-cancel-button{-webkit-appearance:none}textarea{overflow:auto;vertical-align:top}@media print{*{color:#000!important;text-shadow:none!important;background:transparent!important;box-shadow:none!important}a,a:visited{text-decoration:underline}a[href]:after{content:" (" attr(href) ")"}abbr[title]:after{content:" (" attr(title) ")"}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100%!important}@page{margin:.5cm}p,h2,h3{orphans:3;widows:3}h2,h3{page-break-after:avoid}}body{margin:0;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;line-height:20px;color:#333;background-color:#fff}a{color:#08c;text-decoration:none}a:hover,a:focus{color:#005580;text-decoration:underline}.img-rounded{-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px}.img-polaroid{padding:4px;background-color:#fff;border:1px solid #ccc;border:1px solid rgba(0,0,0,0.2);-webkit-box-shadow:0 1px 3px rgba(0,0,0,0.1);-moz-box-shadow:0 1px 3px rgba(0,0,0,0.1);box-shadow:0 1px 3px rgba(0,0,0,0.1)}.img-circle{-webkit-border-radius:500px;-moz-border-radius:500px;border-radius:500px}.row{margin-left:-20px;*zoom:1}.row:before,.row:after{display:table;line-height:0;content:""}.row:after{clear:both}[class*="span"]{float:left;min-height:1px;margin-left:20px}.container,.navbar-static-top .container,.navbar-fixed-top .container,.navbar-fixed-bottom .container{width:940px}.span12{width:940px}.span11{width:860px}.span10{width:780px}.span9{width:700px}.span8{width:620px}.span7{width:540px}.span6{width:460px}.span5{width:380px}.span4{width:300px}.span3{width:220px}.span2{width:140px}.span1{width:60px}.offset12{margin-left:980px}.offset11{margin-left:900px}.offset10{margin-left:820px}.offset9{margin-left:740px}.offset8{margin-left:660px}.offset7{margin-left:580px}.offset6{margin-left:500px}.offset5{margin-left:420px}.offset4{margin-left:340px}.offset3{margin-left:260px}.offset2{margin-left:180px}.offset1{margin-left:100px}.row-fluid{width:100%;*zoom:1}.row-fluid:before,.row-fluid:after{display:table;line-height:0;content:""}.row-fluid:after{clear:both}.row-fluid [class*="span"]{display:block;float:left;width:100%;min-height:30px;margin-left:2.127659574468085%;*margin-left:2.074468085106383%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.row-fluid [class*="span"]:first-child{margin-left:0}.row-fluid .controls-row [class*="span"]+[class*="span"]{margin-left:2.127659574468085%}.row-fluid .span12{width:100%;*width:99.94680851063829%}.row-fluid .span11{width:91.48936170212765%;*width:91.43617021276594%}.row-fluid .span10{width:82.97872340425532%;*width:82.92553191489361%}.row-fluid .span9{width:74.46808510638297%;*width:74.41489361702126%}.row-fluid .span8{width:65.95744680851064%;*width:65.90425531914893%}.row-fluid .span7{width:57.44680851063829%;*width:57.39361702127659%}.row-fluid .span6{width:48.93617021276595%;*width:48.88297872340425%}.row-fluid .span5{width:40.42553191489362%;*width:40.37234042553192%}.row-fluid .span4{width:31.914893617021278%;*width:31.861702127659576%}.row-fluid .span3{width:23.404255319148934%;*width:23.351063829787233%}.row-fluid .span2{width:14.893617021276595%;*width:14.840425531914894%}.row-fluid .span1{width:6.382978723404255%;*width:6.329787234042553%}.row-fluid .offset12{margin-left:104.25531914893617%;*margin-left:104.14893617021275%}.row-fluid .offset12:first-child{margin-left:102.12765957446808%;*margin-left:102.02127659574467%}.row-fluid .offset11{margin-left:95.74468085106382%;*margin-left:95.6382978723404%}.row-fluid .offset11:first-child{margin-left:93.61702127659574%;*margin-left:93.51063829787232%}.row-fluid .offset10{margin-left:87.23404255319149%;*margin-left:87.12765957446807%}.row-fluid .offset10:first-child{margin-left:85.1063829787234%;*margin-left:84.99999999999999%}.row-fluid .offset9{margin-left:78.72340425531914%;*margin-left:78.61702127659572%}.row-fluid .offset9:first-child{margin-left:76.59574468085106%;*margin-left:76.48936170212764%}.row-fluid .offset8{margin-left:70.2127659574468%;*margin-left:70.10638297872339%}.row-fluid .offset8:first-child{margin-left:68.08510638297872%;*margin-left:67.9787234042553%}.row-fluid .offset7{margin-left:61.70212765957446%;*margin-left:61.59574468085106%}.row-fluid .offset7:first-child{margin-left:59.574468085106375%;*margin-left:59.46808510638297%}.row-fluid .offset6{margin-left:53.191489361702125%;*margin-left:53.085106382978715%}.row-fluid .offset6:first-child{margin-left:51.063829787234035%;*margin-left:50.95744680851063%}.row-fluid .offset5{margin-left:44.68085106382979%;*margin-left:44.57446808510638%}.row-fluid .offset5:first-child{margin-left:42.5531914893617%;*margin-left:42.4468085106383%}.row-fluid .offset4{margin-left:36.170212765957444%;*margin-left:36.06382978723405%}.row-fluid .offset4:first-child{margin-left:34.04255319148936%;*margin-left:33.93617021276596%}.row-fluid .offset3{margin-left:27.659574468085104%;*margin-left:27.5531914893617%}.row-fluid .offset3:first-child{margin-left:25.53191489361702%;*margin-left:25.425531914893618%}.row-fluid .offset2{margin-left:19.148936170212764%;*margin-left:19.04255319148936%}.row-fluid .offset2:first-child{margin-left:17.02127659574468%;*margin-left:16.914893617021278%}.row-fluid .offset1{margin-left:10.638297872340425%;*margin-left:10.53191489361702%}.row-fluid .offset1:first-child{margin-left:8.51063829787234%;*margin-left:8.404255319148938%}[class*="span"].hide,.row-fluid [class*="span"].hide{display:none}[class*="span"].pull-right,.row-fluid [class*="span"].pull-right{float:right}.container{margin-right:auto;margin-left:auto;*zoom:1}.container:before,.container:after{display:table;line-height:0;content:""}.container:after{clear:both}.container-fluid{padding-right:20px;padding-left:20px;*zoom:1}.container-fluid:before,.container-fluid:after{display:table;line-height:0;content:""}.container-fluid:after{clear:both}p{margin:0 0 10px}.lead{margin-bottom:20px;font-size:21px;font-weight:200;line-height:30px}small{font-size:85%}strong{font-weight:bold}em{font-style:italic}cite{font-style:normal}.muted{color:#999}a.muted:hover,a.muted:focus{color:#808080}.text-warning{color:#c09853}a.text-warning:hover,a.text-warning:focus{color:#a47e3c}.text-error{color:#b94a48}a.text-error:hover,a.text-error:focus{color:#953b39}.text-info{color:#3a87ad}a.text-info:hover,a.text-info:focus{color:#2d6987}.text-success{color:#468847}a.text-success:hover,a.text-success:focus{color:#356635}.text-left{text-align:left}.text-right{text-align:right}.text-center{text-align:center}h1,h2,h3,h4,h5,h6{margin:10px 0;font-family:inherit;font-weight:bold;line-height:20px;color:inherit;text-rendering:optimizelegibility}h1 small,h2 small,h3 small,h4 small,h5 small,h6 small{font-weight:normal;line-height:1;color:#999}h1,h2,h3{line-height:40px}h1{font-size:38.5px}h2{font-size:31.5px}h3{font-size:24.5px}h4{font-size:17.5px}h5{font-size:14px}h6{font-size:11.9px}h1 small{font-size:24.5px}h2 small{font-size:17.5px}h3 small{font-size:14px}h4 small{font-size:14px}.page-header{padding-bottom:9px;margin:20px 0 30px;border-bottom:1px solid #eee}ul,ol{padding:0;margin:0 0 10px 25px}ul ul,ul ol,ol ol,ol ul{margin-bottom:0}li{line-height:20px}ul.unstyled,ol.unstyled{margin-left:0;list-style:none}ul.inline,ol.inline{margin-left:0;list-style:none}ul.inline>li,ol.inline>li{display:inline-block;*display:inline;padding-right:5px;padding-left:5px;*zoom:1}dl{margin-bottom:20px}dt,dd{line-height:20px}dt{font-weight:bold}dd{margin-left:10px}.dl-horizontal{*zoom:1}.dl-horizontal:before,.dl-horizontal:after{display:table;line-height:0;content:""}.dl-horizontal:after{clear:both}.dl-horizontal dt{float:left;width:160px;overflow:hidden;clear:left;text-align:right;text-overflow:ellipsis;white-space:nowrap}.dl-horizontal dd{margin-left:180px}hr{margin:20px 0;border:0;border-top:1px solid #eee;border-bottom:1px solid #fff}abbr[title],abbr[data-original-title]{cursor:help;border-bottom:1px dotted #999}abbr.initialism{font-size:90%;text-transform:uppercase}blockquote{padding:0 0 0 15px;margin:0 0 20px;border-left:5px solid #eee}blockquote p{margin-bottom:0;font-size:17.5px;font-weight:300;line-height:1.25}blockquote small{display:block;line-height:20px;color:#999}blockquote small:before{content:'\2014 \00A0'}blockquote.pull-right{float:right;padding-right:15px;padding-left:0;border-right:5px solid #eee;border-left:0}blockquote.pull-right p,blockquote.pull-right small{text-align:right}blockquote.pull-right small:before{content:''}blockquote.pull-right small:after{content:'\00A0 \2014'}q:before,q:after,blockquote:before,blockquote:after{content:""}address{display:block;margin-bottom:20px;font-style:normal;line-height:20px}code,pre{padding:0 3px 2px;font-family:Monaco,Menlo,Consolas,"Courier New",monospace;font-size:12px;color:#333;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}code{padding:2px 4px;color:#d14;white-space:nowrap;background-color:#f7f7f9;border:1px solid #e1e1e8}pre{display:block;padding:9.5px;margin:0 0 10px;font-size:13px;line-height:20px;word-break:break-all;word-wrap:break-word;white-space:pre;white-space:pre-wrap;background-color:#f5f5f5;border:1px solid #ccc;border:1px solid rgba(0,0,0,0.15);-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}pre.prettyprint{margin-bottom:20px}pre code{padding:0;color:inherit;white-space:pre;white-space:pre-wrap;background-color:transparent;border:0}.pre-scrollable{max-height:340px;overflow-y:scroll}form{margin:0 0 20px}fieldset{padding:0;margin:0;border:0}legend{display:block;width:100%;padding:0;margin-bottom:20px;font-size:21px;line-height:40px;color:#333;border:0;border-bottom:1px solid #e5e5e5}legend small{font-size:15px;color:#999}label,input,button,select,textarea{font-size:14px;font-weight:normal;line-height:20px}input,button,select,textarea{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif}label{display:block;margin-bottom:5px}select,textarea,input[type="text"],input[type="password"],input[type="datetime"],input[type="datetime-local"],input[type="date"],input[type="month"],input[type="time"],input[type="week"],input[type="number"],input[type="email"],input[type="url"],input[type="search"],input[type="tel"],input[type="color"],.uneditable-input{display:inline-block;height:20px;padding:4px 6px;margin-bottom:10px;font-size:14px;line-height:20px;color:#555;vertical-align:middle;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}input,textarea,.uneditable-input{width:206px}textarea{height:auto}textarea,input[type="text"],input[type="password"],input[type="datetime"],input[type="datetime-local"],input[type="date"],input[type="month"],input[type="time"],input[type="week"],input[type="number"],input[type="email"],input[type="url"],input[type="search"],input[type="tel"],input[type="color"],.uneditable-input{background-color:#fff;border:1px solid #ccc;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-webkit-transition:border linear .2s,box-shadow linear .2s;-moz-transition:border linear .2s,box-shadow linear .2s;-o-transition:border linear .2s,box-shadow linear .2s;transition:border linear .2s,box-shadow linear .2s}textarea:focus,input[type="text"]:focus,input[type="password"]:focus,input[type="datetime"]:focus,input[type="datetime-local"]:focus,input[type="date"]:focus,input[type="month"]:focus,input[type="time"]:focus,input[type="week"]:focus,input[type="number"]:focus,input[type="email"]:focus,input[type="url"]:focus,input[type="search"]:focus,input[type="tel"]:focus,input[type="color"]:focus,.uneditable-input:focus{border-color:rgba(82,168,236,0.8);outline:0;outline:thin dotted \9;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(82,168,236,0.6);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(82,168,236,0.6);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(82,168,236,0.6)}input[type="radio"],input[type="checkbox"]{margin:4px 0 0;margin-top:1px \9;*margin-top:0;line-height:normal}input[type="file"],input[type="image"],input[type="submit"],input[type="reset"],input[type="button"],input[type="radio"],input[type="checkbox"]{width:auto}select,input[type="file"]{height:30px;*margin-top:4px;line-height:30px}select{width:220px;background-color:#fff;border:1px solid #ccc}select[multiple],select[size]{height:auto}select:focus,input[type="file"]:focus,input[type="radio"]:focus,input[type="checkbox"]:focus{outline:thin dotted #333;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.uneditable-input,.uneditable-textarea{color:#999;cursor:not-allowed;background-color:#fcfcfc;border-color:#ccc;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,0.025);-moz-box-shadow:inset 0 1px 2px rgba(0,0,0,0.025);box-shadow:inset 0 1px 2px rgba(0,0,0,0.025)}.uneditable-input{overflow:hidden;white-space:nowrap}.uneditable-textarea{width:auto;height:auto}input:-moz-placeholder,textarea:-moz-placeholder{color:#999}input:-ms-input-placeholder,textarea:-ms-input-placeholder{color:#999}input::-webkit-input-placeholder,textarea::-webkit-input-placeholder{color:#999}.radio,.checkbox{min-height:20px;padding-left:20px}.radio input[type="radio"],.checkbox input[type="checkbox"]{float:left;margin-left:-20px}.controls>.radio:first-child,.controls>.checkbox:first-child{padding-top:5px}.radio.inline,.checkbox.inline{display:inline-block;padding-top:5px;margin-bottom:0;vertical-align:middle}.radio.inline+.radio.inline,.checkbox.inline+.checkbox.inline{margin-left:10px}.input-mini{width:60px}.input-small{width:90px}.input-medium{width:150px}.input-large{width:210px}.input-xlarge{width:270px}.input-xxlarge{width:530px}input[class*="span"],select[class*="span"],textarea[class*="span"],.uneditable-input[class*="span"],.row-fluid input[class*="span"],.row-fluid select[class*="span"],.row-fluid textarea[class*="span"],.row-fluid .uneditable-input[class*="span"]{float:none;margin-left:0}.input-append input[class*="span"],.input-append .uneditable-input[class*="span"],.input-prepend input[class*="span"],.input-prepend .uneditable-input[class*="span"],.row-fluid input[class*="span"],.row-fluid select[class*="span"],.row-fluid textarea[class*="span"],.row-fluid .uneditable-input[class*="span"],.row-fluid .input-prepend [class*="span"],.row-fluid .input-append [class*="span"]{display:inline-block}input,textarea,.uneditable-input{margin-left:0}.controls-row [class*="span"]+[class*="span"]{margin-left:20px}input.span12,textarea.span12,.uneditable-input.span12{width:926px}input.span11,textarea.span11,.uneditable-input.span11{width:846px}input.span10,textarea.span10,.uneditable-input.span10{width:766px}input.span9,textarea.span9,.uneditable-input.span9{width:686px}input.span8,textarea.span8,.uneditable-input.span8{width:606px}input.span7,textarea.span7,.uneditable-input.span7{width:526px}input.span6,textarea.span6,.uneditable-input.span6{width:446px}input.span5,textarea.span5,.uneditable-input.span5{width:366px}input.span4,textarea.span4,.uneditable-input.span4{width:286px}input.span3,textarea.span3,.uneditable-input.span3{width:206px}input.span2,textarea.span2,.uneditable-input.span2{width:126px}input.span1,textarea.span1,.uneditable-input.span1{width:46px}.controls-row{*zoom:1}.controls-row:before,.controls-row:after{display:table;line-height:0;content:""}.controls-row:after{clear:both}.controls-row [class*="span"],.row-fluid .controls-row [class*="span"]{float:left}.controls-row .checkbox[class*="span"],.controls-row .radio[class*="span"]{padding-top:5px}input[disabled],select[disabled],textarea[disabled],input[readonly],select[readonly],textarea[readonly]{cursor:not-allowed;background-color:#eee}input[type="radio"][disabled],input[type="checkbox"][disabled],input[type="radio"][readonly],input[type="checkbox"][readonly]{background-color:transparent}.control-group.warning .control-label,.control-group.warning .help-block,.control-group.warning .help-inline{color:#c09853}.control-group.warning .checkbox,.control-group.warning .radio,.control-group.warning input,.control-group.warning select,.control-group.warning textarea{color:#c09853}.control-group.warning input,.control-group.warning select,.control-group.warning textarea{border-color:#c09853;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.control-group.warning input:focus,.control-group.warning select:focus,.control-group.warning textarea:focus{border-color:#a47e3c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #dbc59e;-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #dbc59e;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #dbc59e}.control-group.warning .input-prepend .add-on,.control-group.warning .input-append .add-on{color:#c09853;background-color:#fcf8e3;border-color:#c09853}.control-group.error .control-label,.control-group.error .help-block,.control-group.error .help-inline{color:#b94a48}.control-group.error .checkbox,.control-group.error .radio,.control-group.error input,.control-group.error select,.control-group.error textarea{color:#b94a48}.control-group.error input,.control-group.error select,.control-group.error textarea{border-color:#b94a48;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.control-group.error input:focus,.control-group.error select:focus,.control-group.error textarea:focus{border-color:#953b39;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #d59392;-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #d59392;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #d59392}.control-group.error .input-prepend .add-on,.control-group.error .input-append .add-on{color:#b94a48;background-color:#f2dede;border-color:#b94a48}.control-group.success .control-label,.control-group.success .help-block,.control-group.success .help-inline{color:#468847}.control-group.success .checkbox,.control-group.success .radio,.control-group.success input,.control-group.success select,.control-group.success textarea{color:#468847}.control-group.success input,.control-group.success select,.control-group.success textarea{border-color:#468847;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.control-group.success input:focus,.control-group.success select:focus,.control-group.success textarea:focus{border-color:#356635;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #7aba7b;-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #7aba7b;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #7aba7b}.control-group.success .input-prepend .add-on,.control-group.success .input-append .add-on{color:#468847;background-color:#dff0d8;border-color:#468847}.control-group.info .control-label,.control-group.info .help-block,.control-group.info .help-inline{color:#3a87ad}.control-group.info .checkbox,.control-group.info .radio,.control-group.info input,.control-group.info select,.control-group.info textarea{color:#3a87ad}.control-group.info input,.control-group.info select,.control-group.info textarea{border-color:#3a87ad;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.control-group.info input:focus,.control-group.info select:focus,.control-group.info textarea:focus{border-color:#2d6987;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #7ab5d3;-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #7ab5d3;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #7ab5d3}.control-group.info .input-prepend .add-on,.control-group.info .input-append .add-on{color:#3a87ad;background-color:#d9edf7;border-color:#3a87ad}input:focus:invalid,textarea:focus:invalid,select:focus:invalid{color:#b94a48;border-color:#ee5f5b}input:focus:invalid:focus,textarea:focus:invalid:focus,select:focus:invalid:focus{border-color:#e9322d;-webkit-box-shadow:0 0 6px #f8b9b7;-moz-box-shadow:0 0 6px #f8b9b7;box-shadow:0 0 6px #f8b9b7}.form-actions{padding:19px 20px 20px;margin-top:20px;margin-bottom:20px;background-color:#f5f5f5;border-top:1px solid #e5e5e5;*zoom:1}.form-actions:before,.form-actions:after{display:table;line-height:0;content:""}.form-actions:after{clear:both}.help-block,.help-inline{color:#595959}.help-block{display:block;margin-bottom:10px}.help-inline{display:inline-block;*display:inline;padding-left:5px;vertical-align:middle;*zoom:1}.input-append,.input-prepend{display:inline-block;margin-bottom:10px;font-size:0;white-space:nowrap;vertical-align:middle}.input-append input,.input-prepend input,.input-append select,.input-prepend select,.input-append .uneditable-input,.input-prepend .uneditable-input,.input-append .dropdown-menu,.input-prepend .dropdown-menu,.input-append .popover,.input-prepend .popover{font-size:14px}.input-append input,.input-prepend input,.input-append select,.input-prepend select,.input-append .uneditable-input,.input-prepend .uneditable-input{position:relative;margin-bottom:0;*margin-left:0;vertical-align:top;-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0}.input-append input:focus,.input-prepend input:focus,.input-append select:focus,.input-prepend select:focus,.input-append .uneditable-input:focus,.input-prepend .uneditable-input:focus{z-index:2}.input-append .add-on,.input-prepend .add-on{display:inline-block;width:auto;height:20px;min-width:16px;padding:4px 5px;font-size:14px;font-weight:normal;line-height:20px;text-align:center;text-shadow:0 1px 0 #fff;background-color:#eee;border:1px solid #ccc}.input-append .add-on,.input-prepend .add-on,.input-append .btn,.input-prepend .btn,.input-append .btn-group>.dropdown-toggle,.input-prepend .btn-group>.dropdown-toggle{vertical-align:top;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.input-append .active,.input-prepend .active{background-color:#a9dba9;border-color:#46a546}.input-prepend .add-on,.input-prepend .btn{margin-right:-1px}.input-prepend .add-on:first-child,.input-prepend .btn:first-child{-webkit-border-radius:4px 0 0 4px;-moz-border-radius:4px 0 0 4px;border-radius:4px 0 0 4px}.input-append input,.input-append select,.input-append .uneditable-input{-webkit-border-radius:4px 0 0 4px;-moz-border-radius:4px 0 0 4px;border-radius:4px 0 0 4px}.input-append input+.btn-group .btn:last-child,.input-append select+.btn-group .btn:last-child,.input-append .uneditable-input+.btn-group .btn:last-child{-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0}.input-append .add-on,.input-append .btn,.input-append .btn-group{margin-left:-1px}.input-append .add-on:last-child,.input-append .btn:last-child,.input-append .btn-group:last-child>.dropdown-toggle{-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0}.input-prepend.input-append input,.input-prepend.input-append select,.input-prepend.input-append .uneditable-input{-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.input-prepend.input-append input+.btn-group .btn,.input-prepend.input-append select+.btn-group .btn,.input-prepend.input-append .uneditable-input+.btn-group .btn{-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0}.input-prepend.input-append .add-on:first-child,.input-prepend.input-append .btn:first-child{margin-right:-1px;-webkit-border-radius:4px 0 0 4px;-moz-border-radius:4px 0 0 4px;border-radius:4px 0 0 4px}.input-prepend.input-append .add-on:last-child,.input-prepend.input-append .btn:last-child{margin-left:-1px;-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0}.input-prepend.input-append .btn-group:first-child{margin-left:0}input.search-query{padding-right:14px;padding-right:4px \9;padding-left:14px;padding-left:4px \9;margin-bottom:0;-webkit-border-radius:15px;-moz-border-radius:15px;border-radius:15px}.form-search .input-append .search-query,.form-search .input-prepend .search-query{-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.form-search .input-append .search-query{-webkit-border-radius:14px 0 0 14px;-moz-border-radius:14px 0 0 14px;border-radius:14px 0 0 14px}.form-search .input-append .btn{-webkit-border-radius:0 14px 14px 0;-moz-border-radius:0 14px 14px 0;border-radius:0 14px 14px 0}.form-search .input-prepend .search-query{-webkit-border-radius:0 14px 14px 0;-moz-border-radius:0 14px 14px 0;border-radius:0 14px 14px 0}.form-search .input-prepend .btn{-webkit-border-radius:14px 0 0 14px;-moz-border-radius:14px 0 0 14px;border-radius:14px 0 0 14px}.form-search input,.form-inline input,.form-horizontal input,.form-search textarea,.form-inline textarea,.form-horizontal textarea,.form-search select,.form-inline select,.form-horizontal select,.form-search .help-inline,.form-inline .help-inline,.form-horizontal .help-inline,.form-search .uneditable-input,.form-inline .uneditable-input,.form-horizontal .uneditable-input,.form-search .input-prepend,.form-inline .input-prepend,.form-horizontal .input-prepend,.form-search .input-append,.form-inline .input-append,.form-horizontal .input-append{display:inline-block;*display:inline;margin-bottom:0;vertical-align:middle;*zoom:1}.form-search .hide,.form-inline .hide,.form-horizontal .hide{display:none}.form-search label,.form-inline label,.form-search .btn-group,.form-inline .btn-group{display:inline-block}.form-search .input-append,.form-inline .input-append,.form-search .input-prepend,.form-inline .input-prepend{margin-bottom:0}.form-search .radio,.form-search .checkbox,.form-inline .radio,.form-inline .checkbox{padding-left:0;margin-bottom:0;vertical-align:middle}.form-search .radio input[type="radio"],.form-search .checkbox input[type="checkbox"],.form-inline .radio input[type="radio"],.form-inline .checkbox input[type="checkbox"]{float:left;margin-right:3px;margin-left:0}.control-group{margin-bottom:10px}legend+.control-group{margin-top:20px;-webkit-margin-top-collapse:separate}.form-horizontal .control-group{margin-bottom:20px;*zoom:1}.form-horizontal .control-group:before,.form-horizontal .control-group:after{display:table;line-height:0;content:""}.form-horizontal .control-group:after{clear:both}.form-horizontal .control-label{float:left;width:160px;padding-top:5px;text-align:right}.form-horizontal .controls{*display:inline-block;*padding-left:20px;margin-left:180px;*margin-left:0}.form-horizontal .controls:first-child{*padding-left:180px}.form-horizontal .help-block{margin-bottom:0}.form-horizontal input+.help-block,.form-horizontal select+.help-block,.form-horizontal textarea+.help-block,.form-horizontal .uneditable-input+.help-block,.form-horizontal .input-prepend+.help-block,.form-horizontal .input-append+.help-block{margin-top:10px}.form-horizontal .form-actions{padding-left:180px}table{max-width:100%;background-color:transparent;border-collapse:collapse;border-spacing:0}.table{width:100%;margin-bottom:20px}.table th,.table td{padding:8px;line-height:15px;text-align:left;vertical-align:top;border-top:1px solid #ddd}.table th{font-weight:bold}.table thead th{vertical-align:bottom}.table caption+thead tr:first-child th,.table caption+thead tr:first-child td,.table colgroup+thead tr:first-child th,.table colgroup+thead tr:first-child td,.table thead:first-child tr:first-child th,.table thead:first-child tr:first-child td{border-top:0}.table tbody+tbody{border-top:2px solid #ddd}.table .table{background-color:#fff}.table-condensed th,.table-condensed td{padding:4px 5px}.table-bordered{border:1px solid #ddd;border-collapse:separate;*border-collapse:collapse;border-left:0;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.table-bordered th,.table-bordered td{border-left:1px solid #ddd}.table-bordered caption+thead tr:first-child th,.table-bordered caption+tbody tr:first-child th,.table-bordered caption+tbody tr:first-child td,.table-bordered colgroup+thead tr:first-child th,.table-bordered colgroup+tbody tr:first-child th,.table-bordered colgroup+tbody tr:first-child td,.table-bordered thead:first-child tr:first-child th,.table-bordered tbody:first-child tr:first-child th,.table-bordered tbody:first-child tr:first-child td{border-top:0}.table-bordered thead:first-child tr:first-child>th:first-child,.table-bordered tbody:first-child tr:first-child>td:first-child,.table-bordered tbody:first-child tr:first-child>th:first-child{-webkit-border-top-left-radius:4px;border-top-left-radius:4px;-moz-border-radius-topleft:4px}.table-bordered thead:first-child tr:first-child>th:last-child,.table-bordered tbody:first-child tr:first-child>td:last-child,.table-bordered tbody:first-child tr:first-child>th:last-child{-webkit-border-top-right-radius:4px;border-top-right-radius:4px;-moz-border-radius-topright:4px}.table-bordered thead:last-child tr:last-child>th:first-child,.table-bordered tbody:last-child tr:last-child>td:first-child,.table-bordered tbody:last-child tr:last-child>th:first-child,.table-bordered tfoot:last-child tr:last-child>td:first-child,.table-bordered tfoot:last-child tr:last-child>th:first-child{-webkit-border-bottom-left-radius:4px;border-bottom-left-radius:4px;-moz-border-radius-bottomleft:4px}.table-bordered thead:last-child tr:last-child>th:last-child,.table-bordered tbody:last-child tr:last-child>td:last-child,.table-bordered tbody:last-child tr:last-child>th:last-child,.table-bordered tfoot:last-child tr:last-child>td:last-child,.table-bordered tfoot:last-child tr:last-child>th:last-child{-webkit-border-bottom-right-radius:4px;border-bottom-right-radius:4px;-moz-border-radius-bottomright:4px}.table-bordered tfoot+tbody:last-child tr:last-child td:first-child{-webkit-border-bottom-left-radius:0;border-bottom-left-radius:0;-moz-border-radius-bottomleft:0}.table-bordered tfoot+tbody:last-child tr:last-child td:last-child{-webkit-border-bottom-right-radius:0;border-bottom-right-radius:0;-moz-border-radius-bottomright:0}.table-bordered caption+thead tr:first-child th:first-child,.table-bordered caption+tbody tr:first-child td:first-child,.table-bordered colgroup+thead tr:first-child th:first-child,.table-bordered colgroup+tbody tr:first-child td:first-child{-webkit-border-top-left-radius:4px;border-top-left-radius:4px;-moz-border-radius-topleft:4px}.table-bordered caption+thead tr:first-child th:last-child,.table-bordered caption+tbody tr:first-child td:last-child,.table-bordered colgroup+thead tr:first-child th:last-child,.table-bordered colgroup+tbody tr:first-child td:last-child{-webkit-border-top-right-radius:4px;border-top-right-radius:4px;-moz-border-radius-topright:4px}.table-striped tbody>tr:nth-child(odd)>td,.table-striped tbody>tr:nth-child(odd)>th{background-color:#f9f9f9}.table-hover tbody tr:hover>td,.table-hover tbody tr:hover>th{background-color:#f5f5f5}table td[class*="span"],table th[class*="span"],.row-fluid table td[class*="span"],.row-fluid table th[class*="span"]{display:table-cell;float:none;margin-left:0}.table td.span1,.table th.span1{float:none;width:44px;margin-left:0}.table td.span2,.table th.span2{float:none;width:124px;margin-left:0}.table td.span3,.table th.span3{float:none;width:204px;margin-left:0}.table td.span4,.table th.span4{float:none;width:284px;margin-left:0}.table td.span5,.table th.span5{float:none;width:364px;margin-left:0}.table td.span6,.table th.span6{float:none;width:444px;margin-left:0}.table td.span7,.table th.span7{float:none;width:524px;margin-left:0}.table td.span8,.table th.span8{float:none;width:604px;margin-left:0}.table td.span9,.table th.span9{float:none;width:684px;margin-left:0}.table td.span10,.table th.span10{float:none;width:764px;margin-left:0}.table td.span11,.table th.span11{float:none;width:844px;margin-left:0}.table td.span12,.table th.span12{float:none;width:924px;margin-left:0}.table tbody tr.success>td{background-color:#dff0d8}.table tbody tr.error>td{background-color:#f2dede}.table tbody tr.warning>td{background-color:#fcf8e3}.table tbody tr.info>td{background-color:#d9edf7}.table-hover tbody tr.success:hover>td{background-color:#d0e9c6}.table-hover tbody tr.error:hover>td{background-color:#ebcccc}.table-hover tbody tr.warning:hover>td{background-color:#faf2cc}.table-hover tbody tr.info:hover>td{background-color:#c4e3f3}[class^="icon-"],[class*=" icon-"]{display:inline-block;width:14px;height:14px;margin-top:1px;*margin-right:.3em;line-height:14px;vertical-align:text-top;background-image:url("../img/glyphicons-halflings.png");background-position:14px 14px;background-repeat:no-repeat}.icon-white,.nav-pills>.active>a>[class^="icon-"],.nav-pills>.active>a>[class*=" icon-"],.nav-list>.active>a>[class^="icon-"],.nav-list>.active>a>[class*=" icon-"],.navbar-inverse .nav>.active>a>[class^="icon-"],.navbar-inverse .nav>.active>a>[class*=" icon-"],.dropdown-menu>li>a:hover>[class^="icon-"],.dropdown-menu>li>a:focus>[class^="icon-"],.dropdown-menu>li>a:hover>[class*=" icon-"],.dropdown-menu>li>a:focus>[class*=" icon-"],.dropdown-menu>.active>a>[class^="icon-"],.dropdown-menu>.active>a>[class*=" icon-"],.dropdown-submenu:hover>a>[class^="icon-"],.dropdown-submenu:focus>a>[class^="icon-"],.dropdown-submenu:hover>a>[class*=" icon-"],.dropdown-submenu:focus>a>[class*=" icon-"]{background-image:url("../img/glyphicons-halflings-white.png")}.icon-glass{background-position:0 0}.icon-music{background-position:-24px 0}.icon-search{background-position:-48px 0}.icon-envelope{background-position:-72px 0}.icon-heart{background-position:-96px 0}.icon-star{background-position:-120px 0}.icon-star-empty{background-position:-144px 0}.icon-user{background-position:-168px 0}.icon-film{background-position:-192px 0}.icon-th-large{background-position:-216px 0}.icon-th{background-position:-240px 0}.icon-th-list{background-position:-264px 0}.icon-ok{background-position:-288px 0}.icon-remove{background-position:-312px 0}.icon-zoom-in{background-position:-336px 0}.icon-zoom-out{background-position:-360px 0}.icon-off{background-position:-384px 0}.icon-signal{background-position:-408px 0}.icon-cog{background-position:-432px 0}.icon-trash{background-position:-456px 0}.icon-home{background-position:0 -24px}.icon-file{background-position:-24px -24px}.icon-time{background-position:-48px -24px}.icon-road{background-position:-72px -24px}.icon-download-alt{background-position:-96px -24px}.icon-download{background-position:-120px -24px}.icon-upload{background-position:-144px -24px}.icon-inbox{background-position:-168px -24px}.icon-play-circle{background-position:-192px -24px}.icon-repeat{background-position:-216px -24px}.icon-refresh{background-position:-240px -24px}.icon-list-alt{background-position:-264px -24px}.icon-lock{background-position:-287px -24px}.icon-flag{background-position:-312px -24px}.icon-headphones{background-position:-336px -24px}.icon-volume-off{background-position:-360px -24px}.icon-volume-down{background-position:-384px -24px}.icon-volume-up{background-position:-408px -24px}.icon-qrcode{background-position:-432px -24px}.icon-barcode{background-position:-456px -24px}.icon-tag{background-position:0 -48px}.icon-tags{background-position:-25px -48px}.icon-book{background-position:-48px -48px}.icon-bookmark{background-position:-72px -48px}.icon-print{background-position:-96px -48px}.icon-camera{background-position:-120px -48px}.icon-font{background-position:-144px -48px}.icon-bold{background-position:-167px -48px}.icon-italic{background-position:-192px -48px}.icon-text-height{background-position:-216px -48px}.icon-text-width{background-position:-240px -48px}.icon-align-left{background-position:-264px -48px}.icon-align-center{background-position:-288px -48px}.icon-align-right{background-position:-312px -48px}.icon-align-justify{background-position:-336px -48px}.icon-list{background-position:-360px -48px}.icon-indent-left{background-position:-384px -48px}.icon-indent-right{background-position:-408px -48px}.icon-facetime-video{background-position:-432px -48px}.icon-picture{background-position:-456px -48px}.icon-pencil{background-position:0 -72px}.icon-map-marker{background-position:-24px -72px}.icon-adjust{background-position:-48px -72px}.icon-tint{background-position:-72px -72px}.icon-edit{background-position:-96px -72px}.icon-share{background-position:-120px -72px}.icon-check{background-position:-144px -72px}.icon-move{background-position:-168px -72px}.icon-step-backward{background-position:-192px -72px}.icon-fast-backward{background-position:-216px -72px}.icon-backward{background-position:-240px -72px}.icon-play{background-position:-264px -72px}.icon-pause{background-position:-288px -72px}.icon-stop{background-position:-312px -72px}.icon-forward{background-position:-336px -72px}.icon-fast-forward{background-position:-360px -72px}.icon-step-forward{background-position:-384px -72px}.icon-eject{background-position:-408px -72px}.icon-chevron-left{background-position:-432px -72px}.icon-chevron-right{background-position:-456px -72px}.icon-plus-sign{background-position:0 -96px}.icon-minus-sign{background-position:-24px -96px}.icon-remove-sign{background-position:-48px -96px}.icon-ok-sign{background-position:-72px -96px}.icon-question-sign{background-position:-96px -96px}.icon-info-sign{background-position:-120px -96px}.icon-screenshot{background-position:-144px -96px}.icon-remove-circle{background-position:-168px -96px}.icon-ok-circle{background-position:-192px -96px}.icon-ban-circle{background-position:-216px -96px}.icon-arrow-left{background-position:-240px -96px}.icon-arrow-right{background-position:-264px -96px}.icon-arrow-up{background-position:-289px -96px}.icon-arrow-down{background-position:-312px -96px}.icon-share-alt{background-position:-336px -96px}.icon-resize-full{background-position:-360px -96px}.icon-resize-small{background-position:-384px -96px}.icon-plus{background-position:-408px -96px}.icon-minus{background-position:-433px -96px}.icon-asterisk{background-position:-456px -96px}.icon-exclamation-sign{background-position:0 -120px}.icon-gift{background-position:-24px -120px}.icon-leaf{background-position:-48px -120px}.icon-fire{background-position:-72px -120px}.icon-eye-open{background-position:-96px -120px}.icon-eye-close{background-position:-120px -120px}.icon-warning-sign{background-position:-144px -120px}.icon-plane{background-position:-168px -120px}.icon-calendar{background-position:-192px -120px}.icon-random{width:16px;background-position:-216px -120px}.icon-comment{background-position:-240px -120px}.icon-magnet{background-position:-264px -120px}.icon-chevron-up{background-position:-288px -120px}.icon-chevron-down{background-position:-313px -119px}.icon-retweet{background-position:-336px -120px}.icon-shopping-cart{background-position:-360px -120px}.icon-folder-close{width:16px;background-position:-384px -120px}.icon-folder-open{width:16px;background-position:-408px -120px}.icon-resize-vertical{background-position:-432px -119px}.icon-resize-horizontal{background-position:-456px -118px}.icon-hdd{background-position:0 -144px}.icon-bullhorn{background-position:-24px -144px}.icon-bell{background-position:-48px -144px}.icon-certificate{background-position:-72px -144px}.icon-thumbs-up{background-position:-96px -144px}.icon-thumbs-down{background-position:-120px -144px}.icon-hand-right{background-position:-144px -144px}.icon-hand-left{background-position:-168px -144px}.icon-hand-up{background-position:-192px -144px}.icon-hand-down{background-position:-216px -144px}.icon-circle-arrow-right{background-position:-240px -144px}.icon-circle-arrow-left{background-position:-264px -144px}.icon-circle-arrow-up{background-position:-288px -144px}.icon-circle-arrow-down{background-position:-312px -144px}.icon-globe{background-position:-336px -144px}.icon-wrench{background-position:-360px -144px}.icon-tasks{background-position:-384px -144px}.icon-filter{background-position:-408px -144px}.icon-briefcase{background-position:-432px -144px}.icon-fullscreen{background-position:-456px -144px}.dropup,.dropdown{position:relative}.dropdown-toggle{*margin-bottom:-3px}.dropdown-toggle:active,.open .dropdown-toggle{outline:0}.caret{display:inline-block;width:0;height:0;vertical-align:top;border-top:4px solid #000;border-right:4px solid transparent;border-left:4px solid transparent;content:""}.dropdown .caret{margin-top:8px;margin-left:2px}.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:160px;padding:5px 0;margin:2px 0 0;list-style:none;background-color:#fff;border:1px solid #ccc;border:1px solid rgba(0,0,0,0.2);*border-right-width:2px;*border-bottom-width:2px;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0,0,0,0.2);-moz-box-shadow:0 5px 10px rgba(0,0,0,0.2);box-shadow:0 5px 10px rgba(0,0,0,0.2);-webkit-background-clip:padding-box;-moz-background-clip:padding;background-clip:padding-box}.dropdown-menu.pull-right{right:0;left:auto}.dropdown-menu .divider{*width:100%;height:1px;margin:9px 1px;*margin:-5px 0 5px;overflow:hidden;background-color:#e5e5e5;border-bottom:1px solid #fff}.dropdown-menu>li>a{display:block;padding:3px 20px;clear:both;font-weight:normal;line-height:20px;color:#333;white-space:nowrap}.dropdown-menu>li>a:hover,.dropdown-menu>li>a:focus,.dropdown-submenu:hover>a,.dropdown-submenu:focus>a{color:#fff;text-decoration:none;background-color:#0081c2;background-image:-moz-linear-gradient(top,#08c,#0077b3);background-image:-webkit-gradient(linear,0 0,0 100%,from(#08c),to(#0077b3));background-image:-webkit-linear-gradient(top,#08c,#0077b3);background-image:-o-linear-gradient(top,#08c,#0077b3);background-image:linear-gradient(to bottom,#08c,#0077b3);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc',endColorstr='#ff0077b3',GradientType=0)}.dropdown-menu>.active>a,.dropdown-menu>.active>a:hover,.dropdown-menu>.active>a:focus{color:#fff;text-decoration:none;background-color:#0081c2;background-image:-moz-linear-gradient(top,#08c,#0077b3);background-image:-webkit-gradient(linear,0 0,0 100%,from(#08c),to(#0077b3));background-image:-webkit-linear-gradient(top,#08c,#0077b3);background-image:-o-linear-gradient(top,#08c,#0077b3);background-image:linear-gradient(to bottom,#08c,#0077b3);background-repeat:repeat-x;outline:0;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc',endColorstr='#ff0077b3',GradientType=0)}.dropdown-menu>.disabled>a,.dropdown-menu>.disabled>a:hover,.dropdown-menu>.disabled>a:focus{color:#999}.dropdown-menu>.disabled>a:hover,.dropdown-menu>.disabled>a:focus{text-decoration:none;cursor:default;background-color:transparent;background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.open{*z-index:1000}.open>.dropdown-menu{display:block}.dropdown-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:990}.pull-right>.dropdown-menu{right:0;left:auto}.dropup .caret,.navbar-fixed-bottom .dropdown .caret{border-top:0;border-bottom:4px solid #000;content:""}.dropup .dropdown-menu,.navbar-fixed-bottom .dropdown .dropdown-menu{top:auto;bottom:100%;margin-bottom:1px}.dropdown-submenu{position:relative}.dropdown-submenu>.dropdown-menu{top:0;left:100%;margin-top:-6px;margin-left:-1px;-webkit-border-radius:0 6px 6px 6px;-moz-border-radius:0 6px 6px 6px;border-radius:0 6px 6px 6px}.dropdown-submenu:hover>.dropdown-menu{display:block}.dropup .dropdown-submenu>.dropdown-menu{top:auto;bottom:0;margin-top:0;margin-bottom:-2px;-webkit-border-radius:5px 5px 5px 0;-moz-border-radius:5px 5px 5px 0;border-radius:5px 5px 5px 0}.dropdown-submenu>a:after{display:block;float:right;width:0;height:0;margin-top:5px;margin-right:-10px;border-color:transparent;border-left-color:#ccc;border-style:solid;border-width:5px 0 5px 5px;content:" "}.dropdown-submenu:hover>a:after{border-left-color:#fff}.dropdown-submenu.pull-left{float:none}.dropdown-submenu.pull-left>.dropdown-menu{left:-100%;margin-left:10px;-webkit-border-radius:6px 0 6px 6px;-moz-border-radius:6px 0 6px 6px;border-radius:6px 0 6px 6px}.dropdown .dropdown-menu .nav-header{padding-right:20px;padding-left:20px}.typeahead{z-index:1051;margin-top:2px;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.well{min-height:20px;padding:19px;margin-bottom:20px;background-color:#f5f5f5;border:1px solid #e3e3e3;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.05);box-shadow:inset 0 1px 1px rgba(0,0,0,0.05)}.well blockquote{border-color:#ddd;border-color:rgba(0,0,0,0.15)}.well-large{padding:24px;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px}.well-small{padding:9px;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.fade{opacity:0;-webkit-transition:opacity .15s linear;-moz-transition:opacity .15s linear;-o-transition:opacity .15s linear;transition:opacity .15s linear}.fade.in{opacity:1}.collapse{position:relative;height:0;overflow:hidden;-webkit-transition:height .35s ease;-moz-transition:height .35s ease;-o-transition:height .35s ease;transition:height .35s ease}.collapse.in{height:auto}.close{float:right;font-size:20px;font-weight:bold;line-height:20px;color:#000;text-shadow:0 1px 0 #fff;opacity:.2;filter:alpha(opacity=20)}.close:hover,.close:focus{color:#000;text-decoration:none;cursor:pointer;opacity:.4;filter:alpha(opacity=40)}button.close{padding:0;cursor:pointer;background:transparent;border:0;-webkit-appearance:none}.btn{display:inline-block;*display:inline;padding:4px 12px;margin-bottom:0;*margin-left:.3em;font-size:14px;line-height:20px;color:#333;text-align:center;text-shadow:0 1px 1px rgba(255,255,255,0.75);vertical-align:middle;cursor:pointer;background-color:#f5f5f5;*background-color:#e6e6e6;background-image:-moz-linear-gradient(top,#fff,#e6e6e6);background-image:-webkit-gradient(linear,0 0,0 100%,from(#fff),to(#e6e6e6));background-image:-webkit-linear-gradient(top,#fff,#e6e6e6);background-image:-o-linear-gradient(top,#fff,#e6e6e6);background-image:linear-gradient(to bottom,#fff,#e6e6e6);background-repeat:repeat-x;border:1px solid #ccc;*border:0;border-color:#e6e6e6 #e6e6e6 #bfbfbf;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);border-bottom-color:#b3b3b3;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff',endColorstr='#ffe6e6e6',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);*zoom:1;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05)}.btn:hover,.btn:focus,.btn:active,.btn.active,.btn.disabled,.btn[disabled]{color:#333;background-color:#e6e6e6;*background-color:#d9d9d9}.btn:active,.btn.active{background-color:#ccc \9}.btn:first-child{*margin-left:0}.btn:hover,.btn:focus{color:#333;text-decoration:none;background-position:0 -15px;-webkit-transition:background-position .1s linear;-moz-transition:background-position .1s linear;-o-transition:background-position .1s linear;transition:background-position .1s linear}.btn:focus{outline:thin dotted #333;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.btn.active,.btn:active{background-image:none;outline:0;-webkit-box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05)}.btn.disabled,.btn[disabled]{cursor:default;background-image:none;opacity:.65;filter:alpha(opacity=65);-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}.btn-large{padding:11px 19px;font-size:17.5px;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px}.btn-large [class^="icon-"],.btn-large [class*=" icon-"]{margin-top:4px}.btn-small{padding:2px 10px;font-size:11.9px;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.btn-small [class^="icon-"],.btn-small [class*=" icon-"]{margin-top:0}.btn-mini [class^="icon-"],.btn-mini [class*=" icon-"]{margin-top:-1px}.btn-mini{padding:0 6px;font-size:10.5px;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.btn-block{display:block;width:100%;padding-right:0;padding-left:0;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.btn-block+.btn-block{margin-top:5px}input[type="submit"].btn-block,input[type="reset"].btn-block,input[type="button"].btn-block{width:100%}.btn-primary.active,.btn-warning.active,.btn-danger.active,.btn-success.active,.btn-info.active,.btn-inverse.active{color:rgba(255,255,255,0.75)}.btn-primary{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#006dcc;*background-color:#04c;background-image:-moz-linear-gradient(top,#08c,#04c);background-image:-webkit-gradient(linear,0 0,0 100%,from(#08c),to(#04c));background-image:-webkit-linear-gradient(top,#08c,#04c);background-image:-o-linear-gradient(top,#08c,#04c);background-image:linear-gradient(to bottom,#08c,#04c);background-repeat:repeat-x;border-color:#04c #04c #002a80;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc',endColorstr='#ff0044cc',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.btn-primary:hover,.btn-primary:focus,.btn-primary:active,.btn-primary.active,.btn-primary.disabled,.btn-primary[disabled]{color:#fff;background-color:#04c;*background-color:#003bb3}.btn-primary:active,.btn-primary.active{background-color:#039 \9}.btn-warning{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#faa732;*background-color:#f89406;background-image:-moz-linear-gradient(top,#fbb450,#f89406);background-image:-webkit-gradient(linear,0 0,0 100%,from(#fbb450),to(#f89406));background-image:-webkit-linear-gradient(top,#fbb450,#f89406);background-image:-o-linear-gradient(top,#fbb450,#f89406);background-image:linear-gradient(to bottom,#fbb450,#f89406);background-repeat:repeat-x;border-color:#f89406 #f89406 #ad6704;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffbb450',endColorstr='#fff89406',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.btn-warning:hover,.btn-warning:focus,.btn-warning:active,.btn-warning.active,.btn-warning.disabled,.btn-warning[disabled]{color:#fff;background-color:#f89406;*background-color:#df8505}.btn-warning:active,.btn-warning.active{background-color:#c67605 \9}.btn-danger{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#da4f49;*background-color:#bd362f;background-image:-moz-linear-gradient(top,#ee5f5b,#bd362f);background-image:-webkit-gradient(linear,0 0,0 100%,from(#ee5f5b),to(#bd362f));background-image:-webkit-linear-gradient(top,#ee5f5b,#bd362f);background-image:-o-linear-gradient(top,#ee5f5b,#bd362f);background-image:linear-gradient(to bottom,#ee5f5b,#bd362f);background-repeat:repeat-x;border-color:#bd362f #bd362f #802420;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffee5f5b',endColorstr='#ffbd362f',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.btn-danger:hover,.btn-danger:focus,.btn-danger:active,.btn-danger.active,.btn-danger.disabled,.btn-danger[disabled]{color:#fff;background-color:#bd362f;*background-color:#a9302a}.btn-danger:active,.btn-danger.active{background-color:#942a25 \9}.btn-success{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#5bb75b;*background-color:#51a351;background-image:-moz-linear-gradient(top,#62c462,#51a351);background-image:-webkit-gradient(linear,0 0,0 100%,from(#62c462),to(#51a351));background-image:-webkit-linear-gradient(top,#62c462,#51a351);background-image:-o-linear-gradient(top,#62c462,#51a351);background-image:linear-gradient(to bottom,#62c462,#51a351);background-repeat:repeat-x;border-color:#51a351 #51a351 #387038;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff62c462',endColorstr='#ff51a351',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.btn-success:hover,.btn-success:focus,.btn-success:active,.btn-success.active,.btn-success.disabled,.btn-success[disabled]{color:#fff;background-color:#51a351;*background-color:#499249}.btn-success:active,.btn-success.active{background-color:#408140 \9}.btn-info{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#49afcd;*background-color:#2f96b4;background-image:-moz-linear-gradient(top,#5bc0de,#2f96b4);background-image:-webkit-gradient(linear,0 0,0 100%,from(#5bc0de),to(#2f96b4));background-image:-webkit-linear-gradient(top,#5bc0de,#2f96b4);background-image:-o-linear-gradient(top,#5bc0de,#2f96b4);background-image:linear-gradient(to bottom,#5bc0de,#2f96b4);background-repeat:repeat-x;border-color:#2f96b4 #2f96b4 #1f6377;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de',endColorstr='#ff2f96b4',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.btn-info:hover,.btn-info:focus,.btn-info:active,.btn-info.active,.btn-info.disabled,.btn-info[disabled]{color:#fff;background-color:#2f96b4;*background-color:#2a85a0}.btn-info:active,.btn-info.active{background-color:#24748c \9}.btn-inverse{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#363636;*background-color:#222;background-image:-moz-linear-gradient(top,#444,#222);background-image:-webkit-gradient(linear,0 0,0 100%,from(#444),to(#222));background-image:-webkit-linear-gradient(top,#444,#222);background-image:-o-linear-gradient(top,#444,#222);background-image:linear-gradient(to bottom,#444,#222);background-repeat:repeat-x;border-color:#222 #222 #000;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff444444',endColorstr='#ff222222',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.btn-inverse:hover,.btn-inverse:focus,.btn-inverse:active,.btn-inverse.active,.btn-inverse.disabled,.btn-inverse[disabled]{color:#fff;background-color:#222;*background-color:#151515}.btn-inverse:active,.btn-inverse.active{background-color:#080808 \9}button.btn,input[type="submit"].btn{*padding-top:3px;*padding-bottom:3px}button.btn::-moz-focus-inner,input[type="submit"].btn::-moz-focus-inner{padding:0;border:0}button.btn.btn-large,input[type="submit"].btn.btn-large{*padding-top:7px;*padding-bottom:7px}button.btn.btn-small,input[type="submit"].btn.btn-small{*padding-top:3px;*padding-bottom:3px}button.btn.btn-mini,input[type="submit"].btn.btn-mini{*padding-top:1px;*padding-bottom:1px}.btn-link,.btn-link:active,.btn-link[disabled]{background-color:transparent;background-image:none;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}.btn-link{color:#08c;cursor:pointer;border-color:transparent;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.btn-link:hover,.btn-link:focus{color:#005580;text-decoration:underline;background-color:transparent}.btn-link[disabled]:hover,.btn-link[disabled]:focus{color:#333;text-decoration:none}.btn-group{position:relative;display:inline-block;*display:inline;*margin-left:.3em;font-size:0;white-space:nowrap;vertical-align:middle;*zoom:1}.btn-group:first-child{*margin-left:0}.btn-group+.btn-group{margin-left:5px}.btn-toolbar{margin-top:10px;margin-bottom:10px;font-size:0}.btn-toolbar>.btn+.btn,.btn-toolbar>.btn-group+.btn,.btn-toolbar>.btn+.btn-group{margin-left:5px}.btn-group>.btn{position:relative;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.btn-group>.btn+.btn{margin-left:-1px}.btn-group>.btn,.btn-group>.dropdown-menu,.btn-group>.popover{font-size:14px}.btn-group>.btn-mini{font-size:10.5px}.btn-group>.btn-small{font-size:11.9px}.btn-group>.btn-large{font-size:17.5px}.btn-group>.btn:first-child{margin-left:0;-webkit-border-bottom-left-radius:4px;border-bottom-left-radius:4px;-webkit-border-top-left-radius:4px;border-top-left-radius:4px;-moz-border-radius-bottomleft:4px;-moz-border-radius-topleft:4px}.btn-group>.btn:last-child,.btn-group>.dropdown-toggle{-webkit-border-top-right-radius:4px;border-top-right-radius:4px;-webkit-border-bottom-right-radius:4px;border-bottom-right-radius:4px;-moz-border-radius-topright:4px;-moz-border-radius-bottomright:4px}.btn-group>.btn.large:first-child{margin-left:0;-webkit-border-bottom-left-radius:6px;border-bottom-left-radius:6px;-webkit-border-top-left-radius:6px;border-top-left-radius:6px;-moz-border-radius-bottomleft:6px;-moz-border-radius-topleft:6px}.btn-group>.btn.large:last-child,.btn-group>.large.dropdown-toggle{-webkit-border-top-right-radius:6px;border-top-right-radius:6px;-webkit-border-bottom-right-radius:6px;border-bottom-right-radius:6px;-moz-border-radius-topright:6px;-moz-border-radius-bottomright:6px}.btn-group>.btn:hover,.btn-group>.btn:focus,.btn-group>.btn:active,.btn-group>.btn.active{z-index:2}.btn-group .dropdown-toggle:active,.btn-group.open .dropdown-toggle{outline:0}.btn-group>.btn+.dropdown-toggle{*padding-top:5px;padding-right:8px;*padding-bottom:5px;padding-left:8px;-webkit-box-shadow:inset 1px 0 0 rgba(255,255,255,0.125),inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:inset 1px 0 0 rgba(255,255,255,0.125),inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 1px 0 0 rgba(255,255,255,0.125),inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05)}.btn-group>.btn-mini+.dropdown-toggle{*padding-top:2px;padding-right:5px;*padding-bottom:2px;padding-left:5px}.btn-group>.btn-small+.dropdown-toggle{*padding-top:5px;*padding-bottom:4px}.btn-group>.btn-large+.dropdown-toggle{*padding-top:7px;padding-right:12px;*padding-bottom:7px;padding-left:12px}.btn-group.open .dropdown-toggle{background-image:none;-webkit-box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05)}.btn-group.open .btn.dropdown-toggle{background-color:#e6e6e6}.btn-group.open .btn-primary.dropdown-toggle{background-color:#04c}.btn-group.open .btn-warning.dropdown-toggle{background-color:#f89406}.btn-group.open .btn-danger.dropdown-toggle{background-color:#bd362f}.btn-group.open .btn-success.dropdown-toggle{background-color:#51a351}.btn-group.open .btn-info.dropdown-toggle{background-color:#2f96b4}.btn-group.open .btn-inverse.dropdown-toggle{background-color:#222}.btn .caret{margin-top:8px;margin-left:0}.btn-large .caret{margin-top:6px}.btn-large .caret{border-top-width:5px;border-right-width:5px;border-left-width:5px}.btn-mini .caret,.btn-small .caret{margin-top:8px}.dropup .btn-large .caret{border-bottom-width:5px}.btn-primary .caret,.btn-warning .caret,.btn-danger .caret,.btn-info .caret,.btn-success .caret,.btn-inverse .caret{border-top-color:#fff;border-bottom-color:#fff}.btn-group-vertical{display:inline-block;*display:inline;*zoom:1}.btn-group-vertical>.btn{display:block;float:none;max-width:100%;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.btn-group-vertical>.btn+.btn{margin-top:-1px;margin-left:0}.btn-group-vertical>.btn:first-child{-webkit-border-radius:4px 4px 0 0;-moz-border-radius:4px 4px 0 0;border-radius:4px 4px 0 0}.btn-group-vertical>.btn:last-child{-webkit-border-radius:0 0 4px 4px;-moz-border-radius:0 0 4px 4px;border-radius:0 0 4px 4px}.btn-group-vertical>.btn-large:first-child{-webkit-border-radius:6px 6px 0 0;-moz-border-radius:6px 6px 0 0;border-radius:6px 6px 0 0}.btn-group-vertical>.btn-large:last-child{-webkit-border-radius:0 0 6px 6px;-moz-border-radius:0 0 6px 6px;border-radius:0 0 6px 6px}.alert{padding:8px 35px 8px 14px;margin-bottom:20px;text-shadow:0 1px 0 rgba(255,255,255,0.5);background-color:#fcf8e3;border:1px solid #fbeed5;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.alert,.alert h4{color:#c09853}.alert h4{margin:0}.alert .close{position:relative;top:-2px;right:-21px;line-height:20px}.alert-success{color:#468847;background-color:#dff0d8;border-color:#d6e9c6}.alert-success h4{color:#468847}.alert-danger,.alert-error{color:#b94a48;background-color:#f2dede;border-color:#eed3d7}.alert-danger h4,.alert-error h4{color:#b94a48}.alert-info{color:#3a87ad;background-color:#d9edf7;border-color:#bce8f1}.alert-info h4{color:#3a87ad}.alert-block{padding-top:14px;padding-bottom:14px}.alert-block>p,.alert-block>ul{margin-bottom:0}.alert-block p+p{margin-top:5px}.nav{margin-bottom:20px;margin-left:0;list-style:none}.nav>li>a{display:block}.nav>li>a:hover,.nav>li>a:focus{text-decoration:none;background-color:#eee}.nav>li>a>img{max-width:none}.nav>.pull-right{float:right}.nav-header{display:block;padding:3px 15px;font-size:11px;font-weight:bold;line-height:20px;color:#999;text-shadow:0 1px 0 rgba(255,255,255,0.5);text-transform:uppercase}.nav li+.nav-header{margin-top:9px}.nav-list{padding-right:15px;padding-left:15px;margin-bottom:0}.nav-list>li>a,.nav-list .nav-header{margin-right:-15px;margin-left:-15px;text-shadow:0 1px 0 rgba(255,255,255,0.5)}.nav-list>li>a{padding:3px 15px}.nav-list>.active>a,.nav-list>.active>a:hover,.nav-list>.active>a:focus{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.2);background-color:#08c}.nav-list [class^="icon-"],.nav-list [class*=" icon-"]{margin-right:2px}.nav-list .divider{*width:100%;height:1px;margin:9px 1px;*margin:-5px 0 5px;overflow:hidden;background-color:#e5e5e5;border-bottom:1px solid #fff}.nav-tabs,.nav-pills{*zoom:1}.nav-tabs:before,.nav-pills:before,.nav-tabs:after,.nav-pills:after{display:table;line-height:0;content:""}.nav-tabs:after,.nav-pills:after{clear:both}.nav-tabs>li,.nav-pills>li{float:left}.nav-tabs>li>a,.nav-pills>li>a{padding-right:12px;padding-left:12px;margin-right:2px;line-height:14px}.nav-tabs{border-bottom:1px solid #ddd}.nav-tabs>li{margin-bottom:-1px}.nav-tabs>li>a{padding-top:8px;padding-bottom:8px;line-height:20px;border:1px solid transparent;-webkit-border-radius:4px 4px 0 0;-moz-border-radius:4px 4px 0 0;border-radius:4px 4px 0 0}.nav-tabs>li>a:hover,.nav-tabs>li>a:focus{border-color:#eee #eee #ddd}.nav-tabs>.active>a,.nav-tabs>.active>a:hover,.nav-tabs>.active>a:focus{color:#555;cursor:default;background-color:#fff;border:1px solid #ddd;border-bottom-color:transparent}.nav-pills>li>a{padding-top:8px;padding-bottom:8px;margin-top:2px;margin-bottom:2px;-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px}.nav-pills>.active>a,.nav-pills>.active>a:hover,.nav-pills>.active>a:focus{color:#fff;background-color:#08c}.nav-stacked>li{float:none}.nav-stacked>li>a{margin-right:0}.nav-tabs.nav-stacked{border-bottom:0}.nav-tabs.nav-stacked>li>a{border:1px solid #ddd;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.nav-tabs.nav-stacked>li:first-child>a{-webkit-border-top-right-radius:4px;border-top-right-radius:4px;-webkit-border-top-left-radius:4px;border-top-left-radius:4px;-moz-border-radius-topright:4px;-moz-border-radius-topleft:4px}.nav-tabs.nav-stacked>li:last-child>a{-webkit-border-bottom-right-radius:4px;border-bottom-right-radius:4px;-webkit-border-bottom-left-radius:4px;border-bottom-left-radius:4px;-moz-border-radius-bottomright:4px;-moz-border-radius-bottomleft:4px}.nav-tabs.nav-stacked>li>a:hover,.nav-tabs.nav-stacked>li>a:focus{z-index:2;border-color:#ddd}.nav-pills.nav-stacked>li>a{margin-bottom:3px}.nav-pills.nav-stacked>li:last-child>a{margin-bottom:1px}.nav-tabs .dropdown-menu{-webkit-border-radius:0 0 6px 6px;-moz-border-radius:0 0 6px 6px;border-radius:0 0 6px 6px}.nav-pills .dropdown-menu{-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px}.nav .dropdown-toggle .caret{margin-top:6px;border-top-color:#08c;border-bottom-color:#08c}.nav .dropdown-toggle:hover .caret,.nav .dropdown-toggle:focus .caret{border-top-color:#005580;border-bottom-color:#005580}.nav-tabs .dropdown-toggle .caret{margin-top:8px}.nav .active .dropdown-toggle .caret{border-top-color:#fff;border-bottom-color:#fff}.nav-tabs .active .dropdown-toggle .caret{border-top-color:#555;border-bottom-color:#555}.nav>.dropdown.active>a:hover,.nav>.dropdown.active>a:focus{cursor:pointer}.nav-tabs .open .dropdown-toggle,.nav-pills .open .dropdown-toggle,.nav>li.dropdown.open.active>a:hover,.nav>li.dropdown.open.active>a:focus{color:#fff;background-color:#999;border-color:#999}.nav li.dropdown.open .caret,.nav li.dropdown.open.active .caret,.nav li.dropdown.open a:hover .caret,.nav li.dropdown.open a:focus .caret{border-top-color:#fff;border-bottom-color:#fff;opacity:1;filter:alpha(opacity=100)}.tabs-stacked .open>a:hover,.tabs-stacked .open>a:focus{border-color:#999}.tabbable{*zoom:1}.tabbable:before,.tabbable:after{display:table;line-height:0;content:""}.tabbable:after{clear:both}.tab-content{overflow:auto}.tabs-below>.nav-tabs,.tabs-right>.nav-tabs,.tabs-left>.nav-tabs{border-bottom:0}.tab-content>.tab-pane,.pill-content>.pill-pane{display:none}.tab-content>.active,.pill-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{-webkit-border-radius:0 0 4px 4px;-moz-border-radius:0 0 4px 4px;border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:hover,.tabs-below>.nav-tabs>li>a:focus{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:hover,.tabs-below>.nav-tabs>.active>a:focus{border-color:transparent #ddd #ddd #ddd}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{min-width:74px;margin-right:0;margin-bottom:3px}.tabs-left>.nav-tabs{float:left;margin-right:19px;border-right:1px solid #ddd}.tabs-left>.nav-tabs>li>a{margin-right:-1px;-webkit-border-radius:4px 0 0 4px;-moz-border-radius:4px 0 0 4px;border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:hover,.tabs-left>.nav-tabs>li>a:focus{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs .active>a,.tabs-left>.nav-tabs .active>a:hover,.tabs-left>.nav-tabs .active>a:focus{border-color:#ddd transparent #ddd #ddd;*border-right-color:#fff}.tabs-right>.nav-tabs{float:right;margin-left:19px;border-left:1px solid #ddd}.tabs-right>.nav-tabs>li>a{margin-left:-1px;-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:hover,.tabs-right>.nav-tabs>li>a:focus{border-color:#eee #eee #eee #ddd}.tabs-right>.nav-tabs .active>a,.tabs-right>.nav-tabs .active>a:hover,.tabs-right>.nav-tabs .active>a:focus{border-color:#ddd #ddd #ddd transparent;*border-left-color:#fff}.nav>.disabled>a{color:#999}.nav>.disabled>a:hover,.nav>.disabled>a:focus{text-decoration:none;cursor:default;background-color:transparent}.navbar{*position:relative;*z-index:2;margin-bottom:20px;overflow:visible}.navbar-inner{min-height:40px;padding-right:20px;padding-left:20px;background-color:#fafafa;background-image:-moz-linear-gradient(top,#fff,#f2f2f2);background-image:-webkit-gradient(linear,0 0,0 100%,from(#fff),to(#f2f2f2));background-image:-webkit-linear-gradient(top,#fff,#f2f2f2);background-image:-o-linear-gradient(top,#fff,#f2f2f2);background-image:linear-gradient(to bottom,#fff,#f2f2f2);background-repeat:repeat-x;border:1px solid #d4d4d4;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff',endColorstr='#fff2f2f2',GradientType=0);*zoom:1;-webkit-box-shadow:0 1px 4px rgba(0,0,0,0.065);-moz-box-shadow:0 1px 4px rgba(0,0,0,0.065);box-shadow:0 1px 4px rgba(0,0,0,0.065)}.navbar-inner:before,.navbar-inner:after{display:table;line-height:0;content:""}.navbar-inner:after{clear:both}.navbar .container{width:auto}.nav-collapse.collapse{height:auto;overflow:visible}.navbar .brand{display:block;float:left;padding:10px 20px 10px;margin-left:-20px;font-size:20px;font-weight:200;color:#777;text-shadow:0 1px 0 #fff}.navbar .brand:hover,.navbar .brand:focus{text-decoration:none}.navbar-text{margin-bottom:0;line-height:40px;color:#777}.navbar-link{color:#777}.navbar-link:hover,.navbar-link:focus{color:#333}.navbar .divider-vertical{height:40px;margin:0 9px;border-right:1px solid #fff;border-left:1px solid #f2f2f2}.navbar .btn,.navbar .btn-group{margin-top:5px}.navbar .btn-group .btn,.navbar .input-prepend .btn,.navbar .input-append .btn,.navbar .input-prepend .btn-group,.navbar .input-append .btn-group{margin-top:0}.navbar-form{margin-bottom:0;*zoom:1}.navbar-form:before,.navbar-form:after{display:table;line-height:0;content:""}.navbar-form:after{clear:both}.navbar-form input,.navbar-form select,.navbar-form .radio,.navbar-form .checkbox{margin-top:5px}.navbar-form input,.navbar-form select,.navbar-form .btn{display:inline-block;margin-bottom:0}.navbar-form input[type="image"],.navbar-form input[type="checkbox"],.navbar-form input[type="radio"]{margin-top:3px}.navbar-form .input-append,.navbar-form .input-prepend{margin-top:5px;white-space:nowrap}.navbar-form .input-append input,.navbar-form .input-prepend input{margin-top:0}.navbar-search{position:relative;float:left;margin-top:5px;margin-bottom:0}.navbar-search .search-query{padding:4px 14px;margin-bottom:0;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:13px;font-weight:normal;line-height:1;-webkit-border-radius:15px;-moz-border-radius:15px;border-radius:15px}.navbar-static-top{position:static;margin-bottom:0}.navbar-static-top .navbar-inner{-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.navbar-fixed-top,.navbar-fixed-bottom{position:fixed;right:0;left:0;z-index:1030;margin-bottom:0}.navbar-fixed-top .navbar-inner,.navbar-static-top .navbar-inner{border-width:0 0 1px}.navbar-fixed-bottom .navbar-inner{border-width:1px 0 0}.navbar-fixed-top .navbar-inner,.navbar-fixed-bottom .navbar-inner{padding-right:0;padding-left:0;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.navbar-static-top .container,.navbar-fixed-top .container,.navbar-fixed-bottom .container{width:940px}.navbar-fixed-top{top:0}.navbar-fixed-top .navbar-inner,.navbar-static-top .navbar-inner{-webkit-box-shadow:0 1px 10px rgba(0,0,0,0.1);-moz-box-shadow:0 1px 10px rgba(0,0,0,0.1);box-shadow:0 1px 10px rgba(0,0,0,0.1)}.navbar-fixed-bottom{bottom:0}.navbar-fixed-bottom .navbar-inner{-webkit-box-shadow:0 -1px 10px rgba(0,0,0,0.1);-moz-box-shadow:0 -1px 10px rgba(0,0,0,0.1);box-shadow:0 -1px 10px rgba(0,0,0,0.1)}.navbar .nav{position:relative;left:0;display:block;float:left;margin:0 10px 0 0}.navbar .nav.pull-right{float:right;margin-right:0}.navbar .nav>li{float:left}.navbar .nav>li>a{float:none;padding:10px 15px 10px;color:#777;text-decoration:none;text-shadow:0 1px 0 #fff}.navbar .nav .dropdown-toggle .caret{margin-top:8px}.navbar .nav>li>a:focus,.navbar .nav>li>a:hover{color:#333;text-decoration:none;background-color:transparent}.navbar .nav>.active>a,.navbar .nav>.active>a:hover,.navbar .nav>.active>a:focus{color:#555;text-decoration:none;background-color:#e5e5e5;-webkit-box-shadow:inset 0 3px 8px rgba(0,0,0,0.125);-moz-box-shadow:inset 0 3px 8px rgba(0,0,0,0.125);box-shadow:inset 0 3px 8px rgba(0,0,0,0.125)}.navbar .btn-navbar{display:none;float:right;padding:7px 10px;margin-right:5px;margin-left:5px;color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#ededed;*background-color:#e5e5e5;background-image:-moz-linear-gradient(top,#f2f2f2,#e5e5e5);background-image:-webkit-gradient(linear,0 0,0 100%,from(#f2f2f2),to(#e5e5e5));background-image:-webkit-linear-gradient(top,#f2f2f2,#e5e5e5);background-image:-o-linear-gradient(top,#f2f2f2,#e5e5e5);background-image:linear-gradient(to bottom,#f2f2f2,#e5e5e5);background-repeat:repeat-x;border-color:#e5e5e5 #e5e5e5 #bfbfbf;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2f2f2',endColorstr='#ffe5e5e5',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.075);-moz-box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.075);box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.075)}.navbar .btn-navbar:hover,.navbar .btn-navbar:focus,.navbar .btn-navbar:active,.navbar .btn-navbar.active,.navbar .btn-navbar.disabled,.navbar .btn-navbar[disabled]{color:#fff;background-color:#e5e5e5;*background-color:#d9d9d9}.navbar .btn-navbar:active,.navbar .btn-navbar.active{background-color:#ccc \9}.navbar .btn-navbar .icon-bar{display:block;width:18px;height:2px;background-color:#f5f5f5;-webkit-border-radius:1px;-moz-border-radius:1px;border-radius:1px;-webkit-box-shadow:0 1px 0 rgba(0,0,0,0.25);-moz-box-shadow:0 1px 0 rgba(0,0,0,0.25);box-shadow:0 1px 0 rgba(0,0,0,0.25)}.btn-navbar .icon-bar+.icon-bar{margin-top:3px}.navbar .nav>li>.dropdown-menu:before{position:absolute;top:-7px;left:9px;display:inline-block;border-right:7px solid transparent;border-bottom:7px solid #ccc;border-left:7px solid transparent;border-bottom-color:rgba(0,0,0,0.2);content:''}.navbar .nav>li>.dropdown-menu:after{position:absolute;top:-6px;left:10px;display:inline-block;border-right:6px solid transparent;border-bottom:6px solid #fff;border-left:6px solid transparent;content:''}.navbar-fixed-bottom .nav>li>.dropdown-menu:before{top:auto;bottom:-7px;border-top:7px solid #ccc;border-bottom:0;border-top-color:rgba(0,0,0,0.2)}.navbar-fixed-bottom .nav>li>.dropdown-menu:after{top:auto;bottom:-6px;border-top:6px solid #fff;border-bottom:0}.navbar .nav li.dropdown>a:hover .caret,.navbar .nav li.dropdown>a:focus .caret{border-top-color:#333;border-bottom-color:#333}.navbar .nav li.dropdown.open>.dropdown-toggle,.navbar .nav li.dropdown.active>.dropdown-toggle,.navbar .nav li.dropdown.open.active>.dropdown-toggle{color:#555;background-color:#e5e5e5}.navbar .nav li.dropdown>.dropdown-toggle .caret{border-top-color:#777;border-bottom-color:#777}.navbar .nav li.dropdown.open>.dropdown-toggle .caret,.navbar .nav li.dropdown.active>.dropdown-toggle .caret,.navbar .nav li.dropdown.open.active>.dropdown-toggle .caret{border-top-color:#555;border-bottom-color:#555}.navbar .pull-right>li>.dropdown-menu,.navbar .nav>li>.dropdown-menu.pull-right{right:0;left:auto}.navbar .pull-right>li>.dropdown-menu:before,.navbar .nav>li>.dropdown-menu.pull-right:before{right:12px;left:auto}.navbar .pull-right>li>.dropdown-menu:after,.navbar .nav>li>.dropdown-menu.pull-right:after{right:13px;left:auto}.navbar .pull-right>li>.dropdown-menu .dropdown-menu,.navbar .nav>li>.dropdown-menu.pull-right .dropdown-menu{right:100%;left:auto;margin-right:-1px;margin-left:0;-webkit-border-radius:6px 0 6px 6px;-moz-border-radius:6px 0 6px 6px;border-radius:6px 0 6px 6px}.navbar-inverse .navbar-inner{background-color:#1b1b1b;background-image:-moz-linear-gradient(top,#222,#111);background-image:-webkit-gradient(linear,0 0,0 100%,from(#222),to(#111));background-image:-webkit-linear-gradient(top,#222,#111);background-image:-o-linear-gradient(top,#222,#111);background-image:linear-gradient(to bottom,#222,#111);background-repeat:repeat-x;border-color:#252525;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff222222',endColorstr='#ff111111',GradientType=0)}.navbar-inverse .brand,.navbar-inverse .nav>li>a{color:#999;text-shadow:0 -1px 0 rgba(0,0,0,0.25)}.navbar-inverse .brand:hover,.navbar-inverse .nav>li>a:hover,.navbar-inverse .brand:focus,.navbar-inverse .nav>li>a:focus{color:#fff}.navbar-inverse .brand{color:#999}.navbar-inverse .navbar-text{color:#999}.navbar-inverse .nav>li>a:focus,.navbar-inverse .nav>li>a:hover{color:#fff;background-color:transparent}.navbar-inverse .nav .active>a,.navbar-inverse .nav .active>a:hover,.navbar-inverse .nav .active>a:focus{color:#fff;background-color:#111}.navbar-inverse .navbar-link{color:#999}.navbar-inverse .navbar-link:hover,.navbar-inverse .navbar-link:focus{color:#fff}.navbar-inverse .divider-vertical{border-right-color:#222;border-left-color:#111}.navbar-inverse .nav li.dropdown.open>.dropdown-toggle,.navbar-inverse .nav li.dropdown.active>.dropdown-toggle,.navbar-inverse .nav li.dropdown.open.active>.dropdown-toggle{color:#fff;background-color:#111}.navbar-inverse .nav li.dropdown>a:hover .caret,.navbar-inverse .nav li.dropdown>a:focus .caret{border-top-color:#fff;border-bottom-color:#fff}.navbar-inverse .nav li.dropdown>.dropdown-toggle .caret{border-top-color:#999;border-bottom-color:#999}.navbar-inverse .nav li.dropdown.open>.dropdown-toggle .caret,.navbar-inverse .nav li.dropdown.active>.dropdown-toggle .caret,.navbar-inverse .nav li.dropdown.open.active>.dropdown-toggle .caret{border-top-color:#fff;border-bottom-color:#fff}.navbar-inverse .navbar-search .search-query{color:#fff;background-color:#515151;border-color:#111;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,0.1),0 1px 0 rgba(255,255,255,0.15);-moz-box-shadow:inset 0 1px 2px rgba(0,0,0,0.1),0 1px 0 rgba(255,255,255,0.15);box-shadow:inset 0 1px 2px rgba(0,0,0,0.1),0 1px 0 rgba(255,255,255,0.15);-webkit-transition:none;-moz-transition:none;-o-transition:none;transition:none}.navbar-inverse .navbar-search .search-query:-moz-placeholder{color:#ccc}.navbar-inverse .navbar-search .search-query:-ms-input-placeholder{color:#ccc}.navbar-inverse .navbar-search .search-query::-webkit-input-placeholder{color:#ccc}.navbar-inverse .navbar-search .search-query:focus,.navbar-inverse .navbar-search .search-query.focused{padding:5px 15px;color:#333;text-shadow:0 1px 0 #fff;background-color:#fff;border:0;outline:0;-webkit-box-shadow:0 0 3px rgba(0,0,0,0.15);-moz-box-shadow:0 0 3px rgba(0,0,0,0.15);box-shadow:0 0 3px rgba(0,0,0,0.15)}.navbar-inverse .btn-navbar{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#0e0e0e;*background-color:#040404;background-image:-moz-linear-gradient(top,#151515,#040404);background-image:-webkit-gradient(linear,0 0,0 100%,from(#151515),to(#040404));background-image:-webkit-linear-gradient(top,#151515,#040404);background-image:-o-linear-gradient(top,#151515,#040404);background-image:linear-gradient(to bottom,#151515,#040404);background-repeat:repeat-x;border-color:#040404 #040404 #000;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff151515',endColorstr='#ff040404',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.navbar-inverse .btn-navbar:hover,.navbar-inverse .btn-navbar:focus,.navbar-inverse .btn-navbar:active,.navbar-inverse .btn-navbar.active,.navbar-inverse .btn-navbar.disabled,.navbar-inverse .btn-navbar[disabled]{color:#fff;background-color:#040404;*background-color:#000}.navbar-inverse .btn-navbar:active,.navbar-inverse .btn-navbar.active{background-color:#000 \9}.breadcrumb{padding:8px 15px;margin:0 0 20px;list-style:none;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.breadcrumb>li{display:inline-block;*display:inline;text-shadow:0 1px 0 #fff;*zoom:1}.breadcrumb>li>.divider{padding:0 5px;color:#ccc}.breadcrumb>.active{color:#999}.pagination{margin:20px 0}.pagination ul{display:inline-block;*display:inline;margin-bottom:0;margin-left:0;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;*zoom:1;-webkit-box-shadow:0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:0 1px 2px rgba(0,0,0,0.05);box-shadow:0 1px 2px rgba(0,0,0,0.05)}.pagination ul>li{display:inline}.pagination ul>li>a,.pagination ul>li>span{float:left;padding:4px 12px;line-height:20px;text-decoration:none;background-color:#fff;border:1px solid #ddd;border-left-width:0}.pagination ul>li>a:hover,.pagination ul>li>a:focus,.pagination ul>.active>a,.pagination ul>.active>span{background-color:#f5f5f5}.pagination ul>.active>a,.pagination ul>.active>span{color:#999;cursor:default}.pagination ul>.disabled>span,.pagination ul>.disabled>a,.pagination ul>.disabled>a:hover,.pagination ul>.disabled>a:focus{color:#999;cursor:default;background-color:transparent}.pagination ul>li:first-child>a,.pagination ul>li:first-child>span{border-left-width:1px;-webkit-border-bottom-left-radius:4px;border-bottom-left-radius:4px;-webkit-border-top-left-radius:4px;border-top-left-radius:4px;-moz-border-radius-bottomleft:4px;-moz-border-radius-topleft:4px}.pagination ul>li:last-child>a,.pagination ul>li:last-child>span{-webkit-border-top-right-radius:4px;border-top-right-radius:4px;-webkit-border-bottom-right-radius:4px;border-bottom-right-radius:4px;-moz-border-radius-topright:4px;-moz-border-radius-bottomright:4px}.pagination-centered{text-align:center}.pagination-right{text-align:right}.pagination-large ul>li>a,.pagination-large ul>li>span{padding:11px 19px;font-size:17.5px}.pagination-large ul>li:first-child>a,.pagination-large ul>li:first-child>span{-webkit-border-bottom-left-radius:6px;border-bottom-left-radius:6px;-webkit-border-top-left-radius:6px;border-top-left-radius:6px;-moz-border-radius-bottomleft:6px;-moz-border-radius-topleft:6px}.pagination-large ul>li:last-child>a,.pagination-large ul>li:last-child>span{-webkit-border-top-right-radius:6px;border-top-right-radius:6px;-webkit-border-bottom-right-radius:6px;border-bottom-right-radius:6px;-moz-border-radius-topright:6px;-moz-border-radius-bottomright:6px}.pagination-mini ul>li:first-child>a,.pagination-small ul>li:first-child>a,.pagination-mini ul>li:first-child>span,.pagination-small ul>li:first-child>span{-webkit-border-bottom-left-radius:3px;border-bottom-left-radius:3px;-webkit-border-top-left-radius:3px;border-top-left-radius:3px;-moz-border-radius-bottomleft:3px;-moz-border-radius-topleft:3px}.pagination-mini ul>li:last-child>a,.pagination-small ul>li:last-child>a,.pagination-mini ul>li:last-child>span,.pagination-small ul>li:last-child>span{-webkit-border-top-right-radius:3px;border-top-right-radius:3px;-webkit-border-bottom-right-radius:3px;border-bottom-right-radius:3px;-moz-border-radius-topright:3px;-moz-border-radius-bottomright:3px}.pagination-small ul>li>a,.pagination-small ul>li>span{padding:2px 10px;font-size:11.9px}.pagination-mini ul>li>a,.pagination-mini ul>li>span{padding:0 6px;font-size:10.5px}.pager{margin:20px 0;text-align:center;list-style:none;*zoom:1}.pager:before,.pager:after{display:table;line-height:0;content:""}.pager:after{clear:both}.pager li{display:inline}.pager li>a,.pager li>span{display:inline-block;padding:5px 14px;background-color:#fff;border:1px solid #ddd;-webkit-border-radius:15px;-moz-border-radius:15px;border-radius:15px}.pager li>a:hover,.pager li>a:focus{text-decoration:none;background-color:#f5f5f5}.pager .next>a,.pager .next>span{float:right}.pager .previous>a,.pager .previous>span{float:left}.pager .disabled>a,.pager .disabled>a:hover,.pager .disabled>a:focus,.pager .disabled>span{color:#999;cursor:default;background-color:#fff}.modal-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1040;background-color:#000}.modal-backdrop.fade{opacity:0}.modal-backdrop,.modal-backdrop.fade.in{opacity:.8;filter:alpha(opacity=80)}.modal{position:fixed;top:10%;left:50%;z-index:1050;width:560px;margin-left:-280px;background-color:#fff;border:1px solid #999;border:1px solid rgba(0,0,0,0.3);*border:1px solid #999;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;outline:0;-webkit-box-shadow:0 3px 7px rgba(0,0,0,0.3);-moz-box-shadow:0 3px 7px rgba(0,0,0,0.3);box-shadow:0 3px 7px rgba(0,0,0,0.3);-webkit-background-clip:padding-box;-moz-background-clip:padding-box;background-clip:padding-box}.modal.fade{top:-25%;-webkit-transition:opacity .3s linear,top .3s ease-out;-moz-transition:opacity .3s linear,top .3s ease-out;-o-transition:opacity .3s linear,top .3s ease-out;transition:opacity .3s linear,top .3s ease-out}.modal.fade.in{top:20%}.modal-header{padding:9px 15px;border-bottom:1px solid #eee}.modal-header .close{margin-top:2px}.modal-header h3{margin:0;line-height:30px}.modal-body{position:relative;max-height:400px;padding:15px;overflow-y:auto}.modal-form{margin-bottom:0}.modal-footer{padding:14px 15px 15px;margin-bottom:0;text-align:right;background-color:#f5f5f5;border-top:1px solid #ddd;-webkit-border-radius:0 0 6px 6px;-moz-border-radius:0 0 6px 6px;border-radius:0 0 6px 6px;*zoom:1;-webkit-box-shadow:inset 0 1px 0 #fff;-moz-box-shadow:inset 0 1px 0 #fff;box-shadow:inset 0 1px 0 #fff}.modal-footer:before,.modal-footer:after{display:table;line-height:0;content:""}.modal-footer:after{clear:both}.modal-footer .btn+.btn{margin-bottom:0;margin-left:5px}.modal-footer .btn-group .btn+.btn{margin-left:-1px}.modal-footer .btn-block+.btn-block{margin-left:0}.tooltip{position:absolute;z-index:1030;display:block;font-size:11px;line-height:1.4;opacity:0;filter:alpha(opacity=0);visibility:visible}.tooltip.in{opacity:.8;filter:alpha(opacity=80)}.tooltip.top{padding:5px 0;margin-top:-3px}.tooltip.right{padding:0 5px;margin-left:3px}.tooltip.bottom{padding:5px 0;margin-top:3px}.tooltip.left{padding:0 5px;margin-left:-3px}.tooltip-inner{max-width:200px;padding:8px;color:#fff;text-align:center;text-decoration:none;background-color:#000;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.tooltip-arrow{position:absolute;width:0;height:0;border-color:transparent;border-style:solid}.tooltip.top .tooltip-arrow{bottom:0;left:50%;margin-left:-5px;border-top-color:#000;border-width:5px 5px 0}.tooltip.right .tooltip-arrow{top:50%;left:0;margin-top:-5px;border-right-color:#000;border-width:5px 5px 5px 0}.tooltip.left .tooltip-arrow{top:50%;right:0;margin-top:-5px;border-left-color:#000;border-width:5px 0 5px 5px}.tooltip.bottom .tooltip-arrow{top:0;left:50%;margin-left:-5px;border-bottom-color:#000;border-width:0 5px 5px}.popover{position:absolute;top:0;left:0;z-index:1010;display:none;max-width:276px;padding:1px;text-align:left;white-space:normal;background-color:#fff;border:1px solid #ccc;border:1px solid rgba(0,0,0,0.2);-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0,0,0,0.2);-moz-box-shadow:0 5px 10px rgba(0,0,0,0.2);box-shadow:0 5px 10px rgba(0,0,0,0.2);-webkit-background-clip:padding-box;-moz-background-clip:padding;background-clip:padding-box}.popover.top{margin-top:-10px}.popover.right{margin-left:10px}.popover.bottom{margin-top:10px}.popover.left{margin-left:-10px}.popover-title{padding:8px 14px;margin:0;font-size:14px;font-weight:normal;line-height:18px;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;-webkit-border-radius:5px 5px 0 0;-moz-border-radius:5px 5px 0 0;border-radius:5px 5px 0 0}.popover-title:empty{display:none}.popover-content{padding:9px 14px}.popover .arrow,.popover .arrow:after{position:absolute;display:block;width:0;height:0;border-color:transparent;border-style:solid}.popover .arrow{border-width:11px}.popover .arrow:after{border-width:10px;content:""}.popover.top .arrow{bottom:-11px;left:50%;margin-left:-11px;border-top-color:#999;border-top-color:rgba(0,0,0,0.25);border-bottom-width:0}.popover.top .arrow:after{bottom:1px;margin-left:-10px;border-top-color:#fff;border-bottom-width:0}.popover.right .arrow{top:50%;left:-11px;margin-top:-11px;border-right-color:#999;border-right-color:rgba(0,0,0,0.25);border-left-width:0}.popover.right .arrow:after{bottom:-10px;left:1px;border-right-color:#fff;border-left-width:0}.popover.bottom .arrow{top:-11px;left:50%;margin-left:-11px;border-bottom-color:#999;border-bottom-color:rgba(0,0,0,0.25);border-top-width:0}.popover.bottom .arrow:after{top:1px;margin-left:-10px;border-bottom-color:#fff;border-top-width:0}.popover.left .arrow{top:50%;right:-11px;margin-top:-11px;border-left-color:#999;border-left-color:rgba(0,0,0,0.25);border-right-width:0}.popover.left .arrow:after{right:1px;bottom:-10px;border-left-color:#fff;border-right-width:0}.thumbnails{margin-left:-20px;list-style:none;*zoom:1}.thumbnails:before,.thumbnails:after{display:table;line-height:0;content:""}.thumbnails:after{clear:both}.row-fluid .thumbnails{margin-left:0}.thumbnails>li{float:left;margin-bottom:20px;margin-left:20px}.thumbnail{display:block;padding:4px;line-height:20px;border:1px solid #ddd;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;-webkit-box-shadow:0 1px 3px rgba(0,0,0,0.055);-moz-box-shadow:0 1px 3px rgba(0,0,0,0.055);box-shadow:0 1px 3px rgba(0,0,0,0.055);-webkit-transition:all .2s ease-in-out;-moz-transition:all .2s ease-in-out;-o-transition:all .2s ease-in-out;transition:all .2s ease-in-out}a.thumbnail:hover,a.thumbnail:focus{border-color:#08c;-webkit-box-shadow:0 1px 4px rgba(0,105,214,0.25);-moz-box-shadow:0 1px 4px rgba(0,105,214,0.25);box-shadow:0 1px 4px rgba(0,105,214,0.25)}.thumbnail>img{display:block;max-width:100%;margin-right:auto;margin-left:auto}.thumbnail .caption{padding:9px;color:#555}.media,.media-body{overflow:hidden;*overflow:visible;zoom:1}.media,.media .media{margin-top:15px}.media:first-child{margin-top:0}.media-object{display:block}.media-heading{margin:0 0 5px}.media>.pull-left{margin-right:10px}.media>.pull-right{margin-left:10px}.media-list{margin-left:0;list-style:none}.label,.badge{display:inline-block;padding:2px 4px;font-size:11.844px;font-weight:bold;line-height:14px;color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);white-space:nowrap;vertical-align:baseline;background-color:#999}.label{-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.badge{padding-right:9px;padding-left:9px;-webkit-border-radius:9px;-moz-border-radius:9px;border-radius:9px}.label:empty,.badge:empty{display:none}a.label:hover,a.label:focus,a.badge:hover,a.badge:focus{color:#fff;text-decoration:none;cursor:pointer}.label-important,.badge-important{background-color:#b94a48}.label-important[href],.badge-important[href]{background-color:#953b39}.label-warning,.badge-warning{background-color:#f89406}.label-warning[href],.badge-warning[href]{background-color:#c67605}.label-success,.badge-success{background-color:#468847}.label-success[href],.badge-success[href]{background-color:#356635}.label-info,.badge-info{background-color:#3a87ad}.label-info[href],.badge-info[href]{background-color:#2d6987}.label-inverse,.badge-inverse{background-color:#333}.label-inverse[href],.badge-inverse[href]{background-color:#1a1a1a}.btn .label,.btn .badge{position:relative;top:-1px}.btn-mini .label,.btn-mini .badge{top:0}@-webkit-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@-moz-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@-ms-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@-o-keyframes progress-bar-stripes{from{background-position:0 0}to{background-position:40px 0}}@keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}.progress{height:20px;margin-bottom:20px;overflow:hidden;background-color:#f7f7f7;background-image:-moz-linear-gradient(top,#f5f5f5,#f9f9f9);background-image:-webkit-gradient(linear,0 0,0 100%,from(#f5f5f5),to(#f9f9f9));background-image:-webkit-linear-gradient(top,#f5f5f5,#f9f9f9);background-image:-o-linear-gradient(top,#f5f5f5,#f9f9f9);background-image:linear-gradient(to bottom,#f5f5f5,#f9f9f9);background-repeat:repeat-x;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5',endColorstr='#fff9f9f9',GradientType=0);-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,0.1);-moz-box-shadow:inset 0 1px 2px rgba(0,0,0,0.1);box-shadow:inset 0 1px 2px rgba(0,0,0,0.1)}.progress .bar{float:left;width:0;height:100%;font-size:12px;color:#fff;text-align:center;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#0e90d2;background-image:-moz-linear-gradient(top,#149bdf,#0480be);background-image:-webkit-gradient(linear,0 0,0 100%,from(#149bdf),to(#0480be));background-image:-webkit-linear-gradient(top,#149bdf,#0480be);background-image:-o-linear-gradient(top,#149bdf,#0480be);background-image:linear-gradient(to bottom,#149bdf,#0480be);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff149bdf',endColorstr='#ff0480be',GradientType=0);-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,0.15);-moz-box-shadow:inset 0 -1px 0 rgba(0,0,0,0.15);box-shadow:inset 0 -1px 0 rgba(0,0,0,0.15);-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;-webkit-transition:width .6s ease;-moz-transition:width .6s ease;-o-transition:width .6s ease;transition:width .6s ease}.progress .bar+.bar{-webkit-box-shadow:inset 1px 0 0 rgba(0,0,0,0.15),inset 0 -1px 0 rgba(0,0,0,0.15);-moz-box-shadow:inset 1px 0 0 rgba(0,0,0,0.15),inset 0 -1px 0 rgba(0,0,0,0.15);box-shadow:inset 1px 0 0 rgba(0,0,0,0.15),inset 0 -1px 0 rgba(0,0,0,0.15)}.progress-striped .bar{background-color:#149bdf;background-image:-webkit-gradient(linear,0 100%,100% 0,color-stop(0.25,rgba(255,255,255,0.15)),color-stop(0.25,transparent),color-stop(0.5,transparent),color-stop(0.5,rgba(255,255,255,0.15)),color-stop(0.75,rgba(255,255,255,0.15)),color-stop(0.75,transparent),to(transparent));background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-moz-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);-webkit-background-size:40px 40px;-moz-background-size:40px 40px;-o-background-size:40px 40px;background-size:40px 40px}.progress.active .bar{-webkit-animation:progress-bar-stripes 2s linear infinite;-moz-animation:progress-bar-stripes 2s linear infinite;-ms-animation:progress-bar-stripes 2s linear infinite;-o-animation:progress-bar-stripes 2s linear infinite;animation:progress-bar-stripes 2s linear infinite}.progress-danger .bar,.progress .bar-danger{background-color:#dd514c;background-image:-moz-linear-gradient(top,#ee5f5b,#c43c35);background-image:-webkit-gradient(linear,0 0,0 100%,from(#ee5f5b),to(#c43c35));background-image:-webkit-linear-gradient(top,#ee5f5b,#c43c35);background-image:-o-linear-gradient(top,#ee5f5b,#c43c35);background-image:linear-gradient(to bottom,#ee5f5b,#c43c35);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffee5f5b',endColorstr='#ffc43c35',GradientType=0)}.progress-danger.progress-striped .bar,.progress-striped .bar-danger{background-color:#ee5f5b;background-image:-webkit-gradient(linear,0 100%,100% 0,color-stop(0.25,rgba(255,255,255,0.15)),color-stop(0.25,transparent),color-stop(0.5,transparent),color-stop(0.5,rgba(255,255,255,0.15)),color-stop(0.75,rgba(255,255,255,0.15)),color-stop(0.75,transparent),to(transparent));background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-moz-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent)}.progress-success .bar,.progress .bar-success{background-color:#5eb95e;background-image:-moz-linear-gradient(top,#62c462,#57a957);background-image:-webkit-gradient(linear,0 0,0 100%,from(#62c462),to(#57a957));background-image:-webkit-linear-gradient(top,#62c462,#57a957);background-image:-o-linear-gradient(top,#62c462,#57a957);background-image:linear-gradient(to bottom,#62c462,#57a957);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff62c462',endColorstr='#ff57a957',GradientType=0)}.progress-success.progress-striped .bar,.progress-striped .bar-success{background-color:#62c462;background-image:-webkit-gradient(linear,0 100%,100% 0,color-stop(0.25,rgba(255,255,255,0.15)),color-stop(0.25,transparent),color-stop(0.5,transparent),color-stop(0.5,rgba(255,255,255,0.15)),color-stop(0.75,rgba(255,255,255,0.15)),color-stop(0.75,transparent),to(transparent));background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-moz-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent)}.progress-info .bar,.progress .bar-info{background-color:#4bb1cf;background-image:-moz-linear-gradient(top,#5bc0de,#339bb9);background-image:-webkit-gradient(linear,0 0,0 100%,from(#5bc0de),to(#339bb9));background-image:-webkit-linear-gradient(top,#5bc0de,#339bb9);background-image:-o-linear-gradient(top,#5bc0de,#339bb9);background-image:linear-gradient(to bottom,#5bc0de,#339bb9);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de',endColorstr='#ff339bb9',GradientType=0)}.progress-info.progress-striped .bar,.progress-striped .bar-info{background-color:#5bc0de;background-image:-webkit-gradient(linear,0 100%,100% 0,color-stop(0.25,rgba(255,255,255,0.15)),color-stop(0.25,transparent),color-stop(0.5,transparent),color-stop(0.5,rgba(255,255,255,0.15)),color-stop(0.75,rgba(255,255,255,0.15)),color-stop(0.75,transparent),to(transparent));background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-moz-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent)}.progress-warning .bar,.progress .bar-warning{background-color:#faa732;background-image:-moz-linear-gradient(top,#fbb450,#f89406);background-image:-webkit-gradient(linear,0 0,0 100%,from(#fbb450),to(#f89406));background-image:-webkit-linear-gradient(top,#fbb450,#f89406);background-image:-o-linear-gradient(top,#fbb450,#f89406);background-image:linear-gradient(to bottom,#fbb450,#f89406);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffbb450',endColorstr='#fff89406',GradientType=0)}.progress-warning.progress-striped .bar,.progress-striped .bar-warning{background-color:#fbb450;background-image:-webkit-gradient(linear,0 100%,100% 0,color-stop(0.25,rgba(255,255,255,0.15)),color-stop(0.25,transparent),color-stop(0.5,transparent),color-stop(0.5,rgba(255,255,255,0.15)),color-stop(0.75,rgba(255,255,255,0.15)),color-stop(0.75,transparent),to(transparent));background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-moz-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent)}.accordion{margin-bottom:20px}.accordion-group{margin-bottom:2px;border:1px solid #e5e5e5;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.accordion-heading{border-bottom:0}.accordion-heading .accordion-toggle{display:block;padding:8px 15px}.accordion-toggle{cursor:pointer}.accordion-inner{padding:9px 15px;border-top:1px solid #e5e5e5}.carousel{position:relative;margin-bottom:20px;line-height:1}.carousel-inner{position:relative;width:100%;overflow:hidden}.carousel-inner>.item{position:relative;display:none;-webkit-transition:.6s ease-in-out left;-moz-transition:.6s ease-in-out left;-o-transition:.6s ease-in-out left;transition:.6s ease-in-out left}.carousel-inner>.item>img,.carousel-inner>.item>a>img{display:block;line-height:1}.carousel-inner>.active,.carousel-inner>.next,.carousel-inner>.prev{display:block}.carousel-inner>.active{left:0}.carousel-inner>.next,.carousel-inner>.prev{position:absolute;top:0;width:100%}.carousel-inner>.next{left:100%}.carousel-inner>.prev{left:-100%}.carousel-inner>.next.left,.carousel-inner>.prev.right{left:0}.carousel-inner>.active.left{left:-100%}.carousel-inner>.active.right{left:100%}.carousel-control{position:absolute;top:40%;left:15px;width:40px;height:40px;margin-top:-20px;font-size:60px;font-weight:100;line-height:30px;color:#fff;text-align:center;background:#222;border:3px solid #fff;-webkit-border-radius:23px;-moz-border-radius:23px;border-radius:23px;opacity:.5;filter:alpha(opacity=50)}.carousel-control.right{right:15px;left:auto}.carousel-control:hover,.carousel-control:focus{color:#fff;text-decoration:none;opacity:.9;filter:alpha(opacity=90)}.carousel-indicators{position:absolute;top:15px;right:15px;z-index:5;margin:0;list-style:none}.carousel-indicators li{display:block;float:left;width:10px;height:10px;margin-left:5px;text-indent:-999px;background-color:#ccc;background-color:rgba(255,255,255,0.25);border-radius:5px}.carousel-indicators .active{background-color:#fff}.carousel-caption{position:absolute;right:0;bottom:0;left:0;padding:15px;background:#333;background:rgba(0,0,0,0.75)}.carousel-caption h4,.carousel-caption p{line-height:20px;color:#fff}.carousel-caption h4{margin:0 0 5px}.carousel-caption p{margin-bottom:0}.hero-unit{padding:60px;margin-bottom:30px;font-size:18px;font-weight:200;line-height:30px;color:inherit;background-color:#eee;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px}.hero-unit h1{margin-bottom:0;font-size:60px;line-height:1;letter-spacing:-1px;color:inherit}.hero-unit li{line-height:30px}.pull-right{float:right}.pull-left{float:left}.hide{display:none}.show{display:block}.invisible{visibility:hidden}.affix{position:fixed}article,aside,details,figcaption,figure,footer,header,hgroup,nav,section{display:block}audio,canvas,video{display:inline-block;*display:inline;*zoom:1}audio:not([controls]){display:none}[hidden]{display:none}html{font-size:100%;overflow-y:scroll;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}body{margin:0;font-size:13px;line-height:1.231}body,button,input,select,textarea{font-family:sans-serif;color:#222}::-moz-selection{background:#7c85d8;color:#fff;text-shadow:none}::selection{background:#7c85d8;color:#fff;text-shadow:none}a{color:#08e}a:visited{color:#08e}a:hover{color:#04e}a:focus{outline:thin dotted}a:hover,a:active{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:bold}blockquote{margin:1em 40px}dfn{font-style:italic}hr{display:block;height:1px;border:0;border-top:1px solid #ccc;margin:1em 0;padding:0}ins{background:#ff9;color:#000;text-decoration:none}mark{background:#ff0;color:#000;font-style:italic;font-weight:bold}pre,code,kbd,samp{font-family:monospace,monospace;_font-family:'courier new',monospace;font-size:1em}pre{white-space:pre;white-space:pre-wrap;word-wrap:break-word}q{quotes:none}q:before,q:after{content:"";content:none}small{font-size:85%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-0.5em}sub{bottom:-0.25em}ul,ol{margin:0;padding:0 0 0 20px}dd{margin:0 0 0 40px}nav ul,nav ol{list-style:none;list-style-image:none;margin:0;padding:2px 0 0}img{border:0;-ms-interpolation-mode:bicubic;vertical-align:middle}svg:not(:root){overflow:hidden}figure{margin:0}form{margin:0}fieldset{border:0;margin:0;padding:0}label{cursor:pointer}legend{border:0;*margin-left:-7px;padding:0}button,input,select,textarea{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle}button,input{line-height:normal;*overflow:visible}table button,table input{*overflow:auto}button,input[type="button"],input[type="reset"],input[type="submit"]{cursor:pointer;-webkit-appearance:button}input[type="checkbox"],input[type="radio"]{box-sizing:border-box}input[type="search"]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}input[type="search"]::-webkit-search-decoration{-webkit-appearance:none}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}textarea{overflow:auto;vertical-align:top;resize:none}input:invalid,textarea:invalid{background-color:#f0dddd}table{border-collapse:collapse;border-spacing:0}td{vertical-align:top}.ir{display:block;border:0;text-indent:-999em;overflow:hidden;background-color:transparent;background-repeat:no-repeat;text-align:left;direction:ltr}.ir br{display:none}.hidden{display:none!important;visibility:hidden}.visuallyhidden{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.visuallyhidden.focusable:active,.visuallyhidden.focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}.invisible{visibility:hidden}.clearfix:before,.clearfix:after{content:"";display:table}.clearfix:after{clear:both}.clearfix{zoom:1}@media print{*{background:transparent!important;color:black!important;text-shadow:none!important;filter:none!important;-ms-filter:none!important}a,a:visited{text-decoration:underline}a[href]:after{content:" (" attr(href) ")"}abbr[title]:after{content:" (" attr(title) ")"}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100%!important}@page{margin:.5cm}p,h2,h3{orphans:3;widows:3}h2,h3{page-break-after:avoid}}.ui-resizable{position:relative}.ui-resizable-handle{position:absolute;font-size:.1px;z-index:99999;display:block}.ui-resizable-disabled .ui-resizable-handle,.ui-resizable-autohide .ui-resizable-handle{display:none}.ui-resizable-n{cursor:n-resize;height:7px;width:100%;top:-5px;left:0}.ui-resizable-s{cursor:s-resize;height:7px;width:100%;bottom:-5px;left:0}.ui-resizable-e{cursor:e-resize;cursor:col-resize;width:5px;right:-2px;top:0;height:100%}.ui-resizable-w{cursor:w-resize;width:7px;left:-5px;top:0;height:100%}.ui-resizable-se{cursor:se-resize;width:12px;height:12px;right:1px;bottom:1px}.ui-resizable-sw{cursor:sw-resize;width:9px;height:9px;left:-5px;bottom:-5px}.ui-resizable-nw{cursor:nw-resize;width:9px;height:9px;left:-5px;top:-5px}.ui-resizable-ne{cursor:ne-resize;width:9px;height:9px;right:-5px;top:-5px}.ui-button{display:inline-block;position:relative;padding:0;margin:0;text-decoration:none!important;cursor:pointer;text-align:center;zoom:1;overflow:hidden;color:#2a2a2a;background:#d8d8d8 url(../images/buttons/ui-button.png) repeat-x left top;border:1px solid #a8a8a8;border-bottom-color:#9e9e9e;font-size:12px;height:24px;-moz-box-shadow:0 1px 0 rgba(0,0,0,0.05);-webkit-box-shadow:0 1px 0 rgba(0,0,0,0.05);box-shadow:0 1px 0 rgba(0,0,0,0.05);-moz-border-radius:2px;-webkit-border-radius:2px;border-radius:2px}input.ui-button{border-color:#888}.ie7 .ui-button{overflow:visible}a.ui-button,span.ui-button{height:22px;line-height:22px;color:#2a2a2a}input.ui-button,.ui-button .ui-button-text{line-height:23px;color:#2a2a2a;text-shadow:0 1px 1px #f2f2f2;padding:0 10px}.ui-button-text-only .ui-button-text{padding:0 20px}button.ui-button::-moz-focus-inner{border:0;padding:0}.ie7 input.ui-button,.ie7 button.ui-button .ui-button-text{line-height:20px}.ie9 .ui-button .ui-button-text{line-height:24px}.ui-button:focus{outline:0 none}.ui-button:focus,.ui-button:hover,.ui-state-focus,.ui-state-hover{background-position:left -40px}.ui-custom-active,.ui-custom-active:focus,.ui-custom-active:hover,.ui-state-active,.ui-state-active:focus,.ui-state-active:hover,.ui-button:active{background-position:left -120px;border-color:#909090}.ui-button[disabled],.ui-button[disabled]:hover,.ui-button.default[disabled],.ui-custom-active[disabled],.ui-button[disabled]:active{background-position:left top;border-color:#999;cursor:default;-moz-box-shadow:0 1px 0 rgba(0,0,0,0.05);-webkit-box-shadow:0 1px 0 rgba(0,0,0,0.05);box-shadow:0 1px 0 rgba(0,0,0,0.05)}input.ui-button[disabled],input.ui-button[disabled]:hover{border-color:#ccc;color:#999;text-shadow:0 0 transparent}.ui-button.transparent[disabled]:hover{background:none!important;border-color:transparent!important;-moz-box-shadow:0 0 transparent!important;-webkit-box-shadow:0 0 transparent!important;box-shadow:0 0 transparent!important}.ui-button[disabled] .ui-button-text,.ui-button[disabled]:hover .ui-button-text,.ui-custom-active[disabled] .ui-button-text,.ui-button[disabled]:active .ui-button-text{color:#777;text-shadow:0 1px 1px #ddd}.ui-button.default{border-color:#2e52bc;-moz-box-shadow:0 0 3px #2e52bc,0 0 2px #2e52bc;-webkit-box-shadow:0 0 3px #2e52bc,0 0 2px #2e52bc;box-shadow:0 0 3px #2e52bc,0 0 2px #2e52bc}.ui-button-medium,a.ui-button-medium,span.ui-button-medium{height:30px;background-image:url(../images/buttons/ui-button-medium.png)}a.ui-button-medium,span.ui-button-medium{height:28px;line-height:28px}.ui-button-medium .ui-button-text{line-height:28px}.ie7 button.ui-button.ui-button-medium .ui-button-text{line-height:26px}.ie9 .ui-button-medium .ui-button-text{line-height:28px}.ui-button-medium-blue,a.ui-button-medium-blue,span.ui-button-medium-blue{font-weight:bold;font-size:14px;border-color:#2e6dc5;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;-moz-box-shadow:0 1px 0 rgba(0,0,0,0.15);-webkit-box-shadow:0 1px 0 rgba(0,0,0,0.15);box-shadow:0 1px 0 rgba(0,0,0,0.15)}.ui-button-medium-blue:active,.ui-button-medium-blue.ui-custom-active{border-color:#1e5be6}.cssgradients .ui-button-medium-blue{background:-webkit-gradient(linear,left top,left bottom,from(#699bdc),to(#3464b1));background:-moz-linear-gradient(#699bdc,#3464b1);background:-webkit-linear-gradient(#699bdc,#3464b1)}.cssgradients .ui-button-medium-blue:hover,.cssgradients .ui-button-medium-blue:focus{background:-webkit-gradient(linear,left top,left bottom,from(#7ca9e8),to(#4575c1));background:-moz-linear-gradient(#7ca9e8,#4575c1);background:-webkit-linear-gradient(#7ca9e8,#4575c1)}.cssgradients .ui-button-medium-blue:active,.cssgradients .ui-button-medium-blue.ui-custom-active{background:-webkit-gradient(linear,left top,left bottom,from(#5e8bca),to(#2757a3));background:-moz-linear-gradient(#5e8bca,#2757a3);background:-webkit-linear-gradient(#5e8bca,#2757a3)}.no-cssgradients .ui-button-medium-blue{background-color:#5b88c8;background-image:url(../images/buttons/btn_blue_28.png)}.no-cssgradients .ui-button-medium-blue:focus,.no-cssgradients .ui-button-medium-blue:hover{background-position:0 -30px}.no-cssgradients .ui-button-medium-blue:active{background-position:0 -60px}.ui-button-medium-blue .ui-button-text{line-height:26px;color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.60);font-size:14px;letter-spacing:-0.01em;padding:0}.ui-button-small,span.ui-button-small{height:16px;line-height:15px;background-image:url(../images/buttons/ui-button-small.png)}.ui-button-icon-only .ui-button-text{height:16px;display:block}span.ui-button-thin{height:21px;line-height:22px}.ui-button-thin .ui-button-text{line-height:20px}.ui-button-small.ui-button-icon-only{width:16px}.ui-button.transparent{min-width:0;background-image:none;background-color:transparent;border-color:transparent;-moz-box-shadow:0 0 transparent;-webkit-box-shadow:0 0 transparent;box-shadow:0 0 transparent}.ui-button.transparent:focus,.ui-button.transparent:hover,.ui-button.transparent:active,.ui-custom-active.transparent{background-color:#d8d8d8;background-image:url(../images/buttons/ui-button.png);-moz-box-shadow:0 1px 0 rgba(0,0,0,0.05);-webkit-box-shadow:0 1px 0 rgba(0,0,0,0.05);box-shadow:0 1px 0 rgba(0,0,0,0.05)}.ui-button-medium.ui-button.transparent:focus,.ui-button-medium.ui-button.transparent:hover,.ui-button-medium.ui-button.transparent:active,.ui-button-medium.ui-custom-active.transparent{background-image:url(../images/buttons/ui-button-medium.png);-moz-box-shadow:0 1px 0 rgba(0,0,0,0.05);-webkit-box-shadow:0 1px 0 rgba(0,0,0,0.05);box-shadow:0 1px 0 rgba(0,0,0,0.05)}.ui-button-small.ui-button.transparent:focus,.ui-button-small.ui-button.transparent:hover,.ui-button-small.ui-button.transparent:active,.ui-button-small.ui-custom-active.transparent{background-image:url(../images/buttons/ui-button-small.png);-moz-box-shadow:0 1px 0 rgba(0,0,0,0.05);-webkit-box-shadow:0 1px 0 rgba(0,0,0,0.05);box-shadow:0 1px 0 rgba(0,0,0,0.05)}.ui-button-small.ui-button.transparent:active,.ui-button-small.ui-custom-active.transparent{background-color:#a7a7a7;outline:0 none}.ui-button.transparent:focus,.ui-button.transparent:hover{border-color:#a8a8a8;border-bottom-color:#9e9e9e;-moz-box-shadow:0 1px 0 rgba(0,0,0,0.05);-webkit-box-shadow:0 1px 0 rgba(0,0,0,0.05);box-shadow:0 1px 0 rgba(0,0,0,0.05)}.ui-button.transparent:active,.ui-state-active.transparent,.ui-state-active.transparent:focus,.ui-state-active.transparent:hover,.ui-custom-active.transparent,.ui-custom-active.transparent:focus,.ui-custom-active.transparent:hover{border-color:#909090;-moz-box-shadow:0 1px 0 rgba(0,0,0,0.05);-webkit-box-shadow:0 1px 0 rgba(0,0,0,0.05);box-shadow:0 1px 0 rgba(0,0,0,0.05)}.ui-button.transparent .ui-button-text{padding:0 10px}.ui-button.ui-plain-button:focus,.ui-button.ui-plain-button:hover{border-color:#e0e0e0;border-top-color:#e7e7e7;border-bottom-color:#ddd;background:#e7e7e7;background:-webkit-gradient(linear,left top,left bottom,from(#e7e7e7),to(#ddd));background:-moz-linear-gradient(#e7e7e7,#ddd);background:-webkit-linear-gradient(#e7e7e7,#ddd);-moz-box-shadow:0 0 transparent;-webkit-box-shadow:0 0 transparent;box-shadow:0 0 transparent}.ui-button.ui-plain-button:active,.ui-custom-active.ui-plain-button:focus,.ui-custom-active.ui-plain-button:hover,.ui-custom-active.ui-plain-button{border-color:#b2b2b2;border-top-color:#b7b7b7;border-bottom-color:#a8a8a8;background:#b7b7b7;background:-webkit-gradient(linear,left top,left bottom,from(#b7b7b7),to(#a8a8a8));background:-moz-linear-gradient(#b7b7b7,#a8a8a8);background:-webkit-linear-gradient(#b7b7b7,#a8a8a8);-moz-box-shadow:0 0 transparent;-webkit-box-shadow:0 0 transparent;box-shadow:0 0 transparent}.ui-button.selected,.ui-button.selected:focus,.ui-button.selected:active,.ui-button.selected:hover,.ui-state-focus.selected,.ui-state-hover.selected{background-image:url(../images/buttons/ui-button.png);background-position:left -80px;border-color:#404e69;background-color:#536587}.ui-icon{display:block;text-indent:-99999px;overflow:hidden;background-repeat:no-repeat;width:16px;height:16px}.ui-button-medium .ui-icon{width:24px;height:24px;margin-left:4px}.ui-button-icon-only .ui-icon,.ui-button-text-icon-primary .ui-icon,.ui-button-text-icon-secondary .ui-icon,.ui-button-text-icons .ui-icon,.ui-button-icons-only .ui-icon,.ui-button .spinner{position:absolute;top:50%;margin-top:-8px}.ui-button-icon-only .ui-icon{left:50%;margin-left:-8px}.ui-button-text-icon-primary .ui-button-icon-primary,.ui-button-icons-only .ui-button-icon-primary{position:static;margin-top:0;float:left}.ui-button-text-icon-secondary .ui-button-icon-secondary,.ui-button-text-icons .ui-button-icon-secondary,.ui-button-icons-only .ui-button-icon-secondary{right:.5em}.ui-button-text-icons .ui-button-icon-secondary,.ui-button-icons-only .ui-button-icon-secondary{right:.5em}.ui-button-icons-only .ui-icon{margin-left:0!important}.ui-icon-menu{background-image:url(../images/buttons/btn_popup_sort.png);background-position:right 7px}.ui-icon-add{background-image:url("../images/icons/ico_add.png");background-position:center center}.ui-icon-addressbook{background-image:url("../images/buttons/addressBook.png");background-position:left center}.ui-icon-addressbook:hover{background-position:-22px center}.ui-icon-grid-view{background-image:url("../images/icons/ico_view_modes.png");margin-top:-7px!important}.selected .ui-icon-grid-view{background-position:0 -25px}.ui-icon-list-view{background-image:url("../images/icons/ico_view_modes.png");background-position:-24px 0;margin-top:-7px!important}.selected .ui-icon-list-view{background-position:-23px -25px}.ui-icon-upload{background-image:url(../images/buttons/upload.png);margin-left:4px;margin-right:-4px;height:17px!important;margin-top:3px!important}.ui-icon-new-folder{background-image:url(../images/buttons/new_folder.png);background-position:left bottom;margin-left:3px;margin-right:-3px;margin-top:3px!important;height:18px!important;width:18px!important}.ui-icon-back{background-image:url('../images/buttons/back_button.png');background-position:8px 0;margin-top:2px!important}.ui-icon-empty-trash{background-image:url(../images/buttons/empty_trash.png);height:18px!important;width:18px;margin-left:5px;margin-top:3px!important}.ui-icon-drop-down{background-image:url(../images/buttons/btn_drop_down.png);background-position:50% 6px}.ui-icon-up-button{background-image:url(../images/icons/ico_up_button.png);background-position:2px 1px}.ui-icon-comment{background-image:url("../images/icons/ico_comment.png");background-position:center center}.ie7 .ui-icon-comment,.ie9 .ui-icon-comment{margin-top:-7px!important}.ie8 .ui-icon-comment{margin-top:-9px!important}.ui-icon-comment+.ui-button-text{height:19px}.ui-icon-actions{background-image:url("../images/buttons/btn_file_actions.png");background-position:-20px 0;width:16px!important;height:17px!important;left:4px}.ui-icon-categories{background-image:url("../images/buttons/btn_file_actions.png");background-position:-40px 0;width:18px!important;height:18px!important;left:3px;margin-top:-8px!important}.ui-icon-comments{background-image:url("../images/buttons/btn_file_actions.png");background-position:-100px -41px;width:18px;margin-left:3px;margin-top:4px!important}.ui-icon-actions-big{background-image:url("../images/buttons/btn_file_actions.png");background-position:-20px 0;width:16px!important;height:17px!important;left:4px!important;top:3px!important;position:relative!important}.ui-icon-categories-big{background-image:url("../images/buttons/btn_file_actions.png");background-position:-40px 0;width:18px!important;height:18px!important;left:3px!important;top:3px!important;position:relative!important}.ui-button.ui-button-text-icon-primary .ui-button-text{padding-left:5px;vertical-align:middle}.ui-button-medium.ui-button.ui-button-text-icon-primary .ui-button-text{padding-left:4px;line-height:28px}.ui-button.ui-button-text-icon-secondary .ui-button-text{padding-right:16px}.ui-button.with_spinner{padding-left:6px}.ui-button .spinner{margin-top:-11px}.ui-icon-wrench{background:url('../images/buttons/wrench.png') no-repeat 0 0;left:4px!important}.ui-menu{display:block;float:left;list-style:none outside none;margin:0;padding:0}.ui-autocomplete{border:1px solid #666;border-top:0 none;background-color:white}.ui-menu .ui-menu-item{clear:left;float:left;margin:0;padding:0;width:100%;overflow:hidden}.ui-autocomplete .ui-menu-item a{display:block;padding:5px;cursor:pointer}.ui-autocomplete .ui-menu-item a:focus,.ui-autocomplete .ui-menu-item a:hover,.ui-autocomplete .ui-menu-item a.ui-state-hover{color:#222;background-position:top left}.ui-autocomplete .ui-menu-item a.ui-state-hover{background:#f2f2f2}#fancybox-loading{position:fixed;top:50%;left:50%;width:40px;height:40px;margin-top:-20px;margin-left:-20px;cursor:pointer;overflow:hidden;z-index:1104;display:none}#fancybox-loading div{position:absolute;top:0;left:0;width:40px;height:480px;background-image:url('../images/layout/fancybox/fancybox.png')}#fancybox-overlay{position:absolute;top:0;left:0;width:100%;z-index:1100;display:none}#fancybox-tmp{padding:0;margin:0;border:0;overflow:auto;display:none}#fancybox-wrap{position:absolute;top:0;left:0;padding:20px;z-index:1101;outline:0;display:none}#fancybox-outer{position:relative;width:100%;height:100%;background:#fff}#fancybox-content{width:0;height:0;padding:0;outline:0;position:relative;overflow:hidden;z-index:1102;border:0 solid #fff}#fancybox-hide-sel-frame{position:absolute;top:0;left:0;width:100%;height:100%;background:transparent;z-index:1101}#fancybox-close{position:absolute;top:-15px;right:-15px;width:30px;height:30px;background:transparent url('../images/layout/fancybox/fancybox.png') -40px 0;cursor:pointer;z-index:1103;display:none}#fancybox-error{color:#444;font:normal 12px/20px Arial;padding:14px;margin:0}#fancybox-img{width:100%;height:100%;padding:0;margin:0;border:0;outline:0;line-height:0;vertical-align:top}#fancybox-frame{width:100%;height:100%;border:0;display:block}#fancybox-left,#fancybox-right{position:absolute;bottom:0;height:100%;width:35%;cursor:pointer;outline:0;background:transparent url('../images/layout/fancybox/blank.gif');z-index:1102;display:none}#fancybox-left{left:0}#fancybox-right{right:0}#fancybox-left-ico,#fancybox-right-ico{position:absolute;top:50%;left:-9999px;width:30px;height:30px;margin-top:-15px;cursor:pointer;z-index:1102;display:block}#fancybox-left-ico{background-image:url('../images/layout/fancybox/fancybox.png');background-position:-40px -30px}#fancybox-right-ico{background-image:url('../images/layout/fancybox/fancybox.png');background-position:-40px -60px}#fancybox-left:hover,#fancybox-right:hover{visibility:visible}#fancybox-left:hover span{left:20px}#fancybox-right:hover span{left:auto;right:20px}.fancybox-bg{position:absolute;padding:0;margin:0;border:0;width:20px;height:20px;z-index:1001}#fancybox-bg-n{top:-20px;left:0;width:100%;background-image:url('../images/layout/fancybox/fancybox-x.png')}#fancybox-bg-ne{top:-20px;right:-20px;background-image:url('../images/layout/fancybox/fancybox.png');background-position:-40px -162px}#fancybox-bg-e{top:0;right:-20px;height:100%;background-image:url('../images/layout/fancybox/fancybox-y.png');background-position:-20px 0}#fancybox-bg-se{bottom:-20px;right:-20px;background-image:url('../images/layout/fancybox/fancybox.png');background-position:-40px -182px}#fancybox-bg-s{bottom:-20px;left:0;width:100%;background-image:url('../images/layout/fancybox/fancybox-x.png');background-position:0 -20px}#fancybox-bg-sw{bottom:-20px;left:-20px;background-image:url('../images/layout/fancybox/fancybox.png');background-position:-40px -142px}#fancybox-bg-w{top:0;left:-20px;height:100%;background-image:url('../images/layout/fancybox/fancybox-y.png')}#fancybox-bg-nw{top:-20px;left:-20px;background-image:url('../images/layout/fancybox/fancybox.png');background-position:-40px -122px}#fancybox-title{font-family:Helvetica;font-size:12px;z-index:1102}.fancybox-title-inside{padding-bottom:10px;text-align:center;color:#333;background:#fff;position:relative}.fancybox-title-outside{padding-top:10px;color:#fff}.fancybox-title-over{position:absolute;bottom:0;left:0;color:#FFF;text-align:left}#fancybox-title-over{padding:10px;background-image:url('../images/layout/fancybox/fancy_title_over.png');display:block}.fancybox-title-float{position:absolute;left:0;bottom:-20px;height:32px}#fancybox-title-float-wrap{border:0;border-collapse:collapse;width:auto}#fancybox-title-float-wrap td{border:0;white-space:nowrap}#fancybox-title-float-left{padding:0 0 0 15px;background:url('../images/layout/fancybox/fancybox.png') -40px -90px no-repeat}#fancybox-title-float-main{color:#FFF;line-height:29px;font-weight:bold;padding:0 0 3px 0;background:url('../images/layout/fancybox/fancybox-x.png') 0 -40px}#fancybox-title-float-right{padding:0 0 0 15px;background:url('../images/layout/fancybox/fancybox.png') -55px -90px no-repeat}.fancybox-ie6 #fancybox-close{background:transparent;filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='../images/layout/fancybox/fancy_close.png',sizingMethod='scale')}.fancybox-ie6 #fancybox-left-ico{background:transparent;filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='../images/layout/fancybox/fancy_nav_left.png',sizingMethod='scale')}.fancybox-ie6 #fancybox-right-ico{background:transparent;filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='../images/layout/fancybox/fancy_nav_right.png',sizingMethod='scale')}.fancybox-ie6 #fancybox-title-over{background:transparent;filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='../images/layout/fancybox/fancy_title_over.png',sizingMethod='scale');zoom:1}.fancybox-ie6 #fancybox-title-float-left{background:transparent;filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='../images/layout/fancybox/fancy_title_left.png',sizingMethod='scale')}.fancybox-ie6 #fancybox-title-float-main{background:transparent;filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='../images/layout/fancybox/fancy_title_main.png',sizingMethod='scale')}.fancybox-ie6 #fancybox-title-float-right{background:transparent;filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='../images/layout/fancybox/fancy_title_right.png',sizingMethod='scale')}.fancybox-ie6 #fancybox-bg-w,.fancybox-ie6 #fancybox-bg-e,.fancybox-ie6 #fancybox-left,.fancybox-ie6 #fancybox-right,#fancybox-hide-sel-frame{height:expression(this.parentNode.clientHeight+"px")}#fancybox-loading.fancybox-ie6{position:absolute;margin-top:0;top:expression((-20+(document.documentElement.clientHeight ? document.documentElement.clientHeight/2:document.body.clientHeight/2)+(ignoreMe = document.documentElement.scrollTop ? document.documentElement.scrollTop:document.body.scrollTop))+'px')}#fancybox-loading.fancybox-ie6 div{background:transparent;filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='../images/layout/fancybox/fancy_loading.png',sizingMethod='scale')}.fancybox-ie .fancybox-bg{background:transparent!important}.fancybox-ie #fancybox-bg-n{filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='../images/layout/fancybox/fancy_shadow_n.png',sizingMethod='scale')}.fancybox-ie #fancybox-bg-ne{filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='../images/layout/fancybox/fancy_shadow_ne.png',sizingMethod='scale')}.fancybox-ie #fancybox-bg-e{filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='../images/layout/fancybox/fancy_shadow_e.png',sizingMethod='scale')}.fancybox-ie #fancybox-bg-se{filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='../images/layout/fancybox/fancy_shadow_se.png',sizingMethod='scale')}.fancybox-ie #fancybox-bg-s{filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='../images/layout/fancybox/fancy_shadow_s.png',sizingMethod='scale')}.fancybox-ie #fancybox-bg-sw{filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='../images/layout/fancybox/fancy_shadow_sw.png',sizingMethod='scale')}.fancybox-ie #fancybox-bg-w{filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='../images/layout/fancybox/fancy_shadow_w.png',sizingMethod='scale')}.fancybox-ie #fancybox-bg-nw{filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='../images/layout/fancybox/fancy_shadow_nw.png',sizingMethod='scale')}.jcarousel-skin-tango .jcarousel-container{background:#FFF;border:1px solid #cecece;-moz-border-radius:0 0 4px 4px;-webkit-border-radius:0 0 4px 4px;border-radius:0 0 4px 4px}.jcarousel-skin-tango .jcarousel-item.jcarousel-item-horizontal.jcarousel-item-selected{border:solid 2px #09c}.jcarousel-skin-tango .jcarousel-container-horizontal{padding:15px 23px 15px 22px}.jcarousel-skin-tango .jcarousel-clip{overflow:hidden}.jcarousel-skin-tango .jcarousel-clip-horizontal{height:90px;width:843px}.jcarousel-skin-tango .jcarousel-item{width:93px;height:70px}.jcarousel-skin-tango .jcarousel-item-horizontal{margin:0 10px;padding:3px;border:solid 1px #ccc;background:#fafafa}.jcarousel-skin-tango .jcarousel-item-horizontal:hover,.jcarousel-skin-tango .jcarousel-item-horizontal:focus{padding:2px;border:solid 2px #bfbfbf}.jcarousel-skin-tango .jcarousel-direction-rtl .jcarousel-item-horizontal{margin-left:10px;margin-right:0}.jcarousel-skin-tango .jcarousel-item-vertical{margin-bottom:10px}.jcarousel-skin-tango .jcarousel-item-placeholder{background:#fff;color:#000}.jcarousel-skin-tango .jcarousel-next-horizontal{position:absolute;top:32px;right:5px;width:12px;height:16px;cursor:pointer;background:transparent url(../images/icons/carousel/icon_slideshow_triangle.png) no-repeat 0 -60px}.jcarousel-skin-tango .jcarousel-next-horizontal:hover,.jcarousel-skin-tango .jcarousel-next-horizontal:focus,.jcarousel-skin-tango .jcarousel-next-horizontal:active{background-position:0 -100px}.jcarousel-skin-tango .jcarousel-next-disabled-horizontal,.jcarousel-skin-tango .jcarousel-next-disabled-horizontal:hover,.jcarousel-skin-tango .jcarousel-next-disabled-horizontal:focus,.jcarousel-skin-tango .jcarousel-next-disabled-horizontal:active{cursor:default;background:0}.jcarousel-skin-tango .jcarousel-prev-horizontal{position:absolute;top:32px;left:5px;width:12px;height:16px;cursor:pointer;background:transparent url(../images/icons/carousel/icon_slideshow_triangle.png) no-repeat 0 0}.jcarousel-skin-tango .jcarousel-prev-horizontal:hover,.jcarousel-skin-tango .jcarousel-prev-horizontal:focus,.jcarousel-skin-tango .jcarousel-prev-horizontal:active{background-position:0 -40px}.jcarousel-skin-tango .jcarousel-prev-disabled-horizontal,.jcarousel-skin-tango .jcarousel-prev-disabled-horizontal:hover,.jcarousel-skin-tango .jcarousel-prev-disabled-horizontal:focus,.jcarousel-skin-tango .jcarousel-prev-disabled-horizontal:active{cursor:default;background:0}.about_contents div,.about_contents span,.about_contents object,.about_contents p,.about_contents strong,.about_contents ul,.about_contents li,.about_contents label,.about_contents header,.about_contents section{background:none repeat scroll 0 0 transparent;border:0 none;font-size:100%;margin:0;outline:0 none;padding:0;vertical-align:baseline}.about_contents{width:500px}.about_contents header{background-color:#000;height:28px;border-radius:6px 6px 0 0;border-bottom:1px solid #333;color:#fff;font-size:13px;font-weight:bold;padding:10px 0 0 10px}.about_contents .about_banner{background:url("../images/layout/Exchangebanner.png") no-repeat scroll 0 0 transparent;height:74px}.about_contents .about_banner p{font-size:16px;color:#fff;text-shadow:0 2px 2px rgba(0,0,0,0.65);width:344px;padding-top:18px;padding-left:30px}.about_contents .about_content{height:212px;overflow-y:scroll;overflow-x:hidden;background-color:#eee;font-size:9px;color:#2a2a2a}.about_contents .margin_top{height:20px;left:0;position:absolute;right:0;top:113px;width:483px;background-color:#eee}.about_contents .margin_bottom{bottom:0;height:15px;left:0;position:absolute;right:0;width:483px;border-bottom:20px solid #eee;background:-webkit-gradient(linear,left top,left bottom,from(rgba(238,238,238,0)),to(rgba(238,238,238,1)));background:-webkit-linear-gradient(rgba(238,238,238,0),rgba(238,238,238,1));background:-moz-linear-gradient(rgba(238,238,238,0),rgba(238,238,238,1));background:-ms-linear-gradient(rgba(238,238,238,0),rgba(238,238,238,1))}.no-cssgradients .about_contents .margin_bottom{background:url("../images/layout/about_box_gradient_fade.png") repeat-x 0 0 transparent}.about_contents div.about_terms{margin-left:15px;margin-right:20px;padding-top:20px}.about_contents .about_terms p{margin-bottom:15px}.about_contents .about_terms p a{color:#06e}.about_contents .about_wrapper{padding-bottom:30px}.no_border{border:0!important;border-radius:6px 6px 0 0!important}.dropdown,.dropdown div,.dropdown li,.dropdown div::after{-webkit-transition:all 150ms ease-in-out;-moz-transition:all 150ms ease-in-out;-ms-transition:all 150ms ease-in-out;transition:all 150ms ease-in-out}.dropdown .selected::after,.dropdown.scrollable div::after{-webkit-pointer-events:none;-moz-pointer-events:none;-ms-pointer-events:none;pointer-events:none}.dropdown{position:relative;width:200px;border:1px solid #ccc;cursor:pointer;background:#fff;border-radius:3px;-webkit-user-select:none;-moz-user-select:none;user-select:none}.dropdown.open{z-index:2}.dropdown:hover{box-shadow:0 0 5px rgba(82,168,236,0.8);border:solid 1px #52a8ec}.dropdown.focus{box-shadow:0 0 5px rgba(51,102,248,.4)}.dropdown .carat{position:absolute;right:12px;top:50%;margin-top:-4px;border:6px solid transparent;border-top:8px solid #000}.dropdown.open .carat{margin-top:-10px;border-top:6px solid transparent;border-bottom:8px solid #000}.dropdown.disabled .carat{border-top-color:#999}.dropdown .old{position:absolute;left:0;top:0;height:0;width:0;overflow:hidden}.dropdown select{position:absolute;left:0;top:0}.dropdown.touch .old{width:100%;height:100%}.dropdown.touch select{width:100%;height:100%;opacity:0}.dropdown .selected,.dropdown li{display:block;font-size:12px;line-height:1;color:#000;padding:9px 12px;overflow:hidden;white-space:nowrap}.dropdown.disabled .selected{color:#999}.dropdown .selected::after{content:'';position:absolute;right:0;top:0;bottom:0;width:60px;border-radius:0 2px 2px 0;box-shadow:inset -55px 0 25px -20px #fff}.dropdown div{position:absolute;height:0;left:-1px;right:-1px;top:100%;margin-top:-1px;background:#fff;border:1px solid #ccc;border-top:1px solid #eee;border-radius:0 0 3px 3px;overflow:hidden;opacity:0}.dropdown.open div{opacity:1;z-index:2}.dropdown.scrollable div::after{content:'';position:absolute;left:0;right:0;bottom:0;height:50px;box-shadow:inset 0 -50px 30px -35px #fff}.dropdown.scrollable.bottom div::after{opacity:0}.dropdown ul{position:absolute;left:0;top:0;height:100%;width:100%;list-style:none;overflow:hidden}.dropdown.scrollable.open ul{overflow-y:auto}.dropdown li{list-style:none;padding:8px 12px}.dropdown li.focus{background:#d24a67;position:relative;z-index:3;color:#fff}.dropdown li.active{font-weight:700}.bootstrap-tagsinput{display:inline-block;padding-right:6px;color:#555;vertical-align:middle;border-radius:4px;max-width:200px;line-height:22px;position:relative;top:-1px}.bootstrap-tagsinput input{display:none;border:0;box-shadow:none;background-color:transparent;padding:0;margin:0;width:auto!important;max-width:inherit}.bootstrap-tagsinput input:focus{border:0;box-shadow:none}.bootstrap-tagsinput .tag{margin-right:2px;color:#666;padding:5px 5px 5px 5px;font-size:12px;background:white;text-shadow:none;font-weight:lighter}.bootstrap-tagsinput .tag [data-role="remove"]{margin-left:2px;cursor:pointer;font-size:15px;color:#aaa;position:relative;top:0}.bootstrap-tagsinput .tag [data-role="remove"]:after{content:"| x";padding:0 2px}.bootstrap-tagsinput .tag [data-role="remove"]:hover{box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05)}.bootstrap-tagsinput .tag [data-role="remove"]:hover:active{box-shadow:inset 0 3px 5px rgba(0,0,0,0.125)}.search-page span{font-family:Arial;color:#666}.search-page a{font-size:12px;color:#29abe2}.overview-title{min-width:1220px}.search-page .overview-title{border-bottom:1px solid #CCC;font-size:16px;height:36px;left:0;padding:10px 0 6px 0;-moz-box-align:initial;-moz-box-pack:initial;-ms-flex-align:start;-webkit-box-pack:initial;-webkit-box-align:baseline;-ms-flex-pack:inherit}.overview-title>div>a{font-size:16px;font-weight:bold;color:#666}.overview-title div:first-child{padding-top:7px;margin-left:30px}.overview-title .emphasized{font-weight:bold;color:#333}.overview-title .view-selection input{display:none}.overview-title .view-selection input+label{padding:0}.overview-title .view-selection input:checked+label{background:#DDD;border-radius:5px}.search-page .list-display-options{height:50px;left:0;-moz-box-align:initial;-ms-flex-align:start;position:relative}.widget-element-app-search-list-view.widget-hoverable{width:auto;height:auto}.widget-element-app-search-list-view{padding:15px 10px;border:1px solid #e3e3e3;width:initial}.widget-element-app-search-list-view:nth-child(2n){margin-left:-5px}.widget-element-app-search-list-view:nth-child(n+2){margin-top:-5px}.list-display-options .list-display-option-left{left:0;margin-top:18px;position:absolute}.list-display-option-left span{color:#29abe2}.list-header-fancy .list-display-options .list-display-option-left{margin-top:0}.list-display-options .list-display-option-right{position:absolute;right:0;margin-top:10px;display:block;align-items:baseline;width:auto;min-width:400px;text-align:right}.list-display-option-right span{color:#29abe2}.list-display-option-right .dropdown{width:50px;height:24px;float:right;margin-left:4px;text-align:left;border:1px solid #b3b3b3;border-radius:3px}.list-display-option-right .dropdown .selected{padding:6px}.list-display-option-right .dropdown .selected::after{box-shadow:none}.list-display-options input{width:16px;margin-bottom:0;height:16px;border:1px solid #b3b3b3}.list-display-options select{width:70px}.list-display-options span{font-size:12px}.filter-catalog-container{width:200px;margin-right:5px}a.filter-catalog-show-more{color:#808080}.filter-catalog-seperator{height:1px;background:#AAA}.filter-catalog span{width:120px;flex-shrink:0;-webkit-flex-shrink:0;-ms-flex:0 0 auto;font-size:12px;padding-right:5px}.filter-title label{height:24px;width:16px;padding:0;border:0}.filter-catalog label[class="radio"]{margin-right:25px}.filter-catalog .radio{position:relative;bottom:1px;font-size:12px;display:inline-block}.filter-catalog input{position:absolute;left:0;top:-1px}.filter-catalog .filter-catalog-item label{font-size:12px}.filter-catalog .filter-title{margin-top:20px;margin-bottom:5px}.filter-catalog .filter-title span{font-size:14px;color:#29abe2}.filter-catalog .filter-catalog-item{line-height:20px;position:relative;padding-left:20px;margin-bottom:5px;color:#808080;font-size:12px}.filter-catalog-container .filter-tag-input{margin-top:10px}.filter-catalog-container .bootstrap-tagsinput .tag{margin-top:5px;margin-right:5px;background:#29abe2;color:white;white-space:normal}.bootstrap-tagsinput .tag [data-role="remove"]{color:white}.bootstrap-tagsinput .tag [data-role="remove"]:after{content:"x"}#clear-all-tags{margin-top:6px;display:inline-block}.view-selection{float:right;margin-right:3px}.view-selection input{width:0;height:0;visibility:collapse}.view-selection .btn{padding:0;height:24px;width:24px;border:0}.search-page span.message-with-link{color:#29abe2}.show_all{cursor:pointer;color:#369} html,body{background-color:#f8f8f8}.bold{font-weight:bold}.float-left{float:left}.float-right{float:right}.busy{cursor:progress}.hidden{display:none}body a{cursor:pointer}body a:focus{outline:0}.min-size{min-width:975px}.clear{clear:both;display:block;overflow:hidden;visibility:hidden;width:0;height:0}.highlight-text{color:#29abe2!important}.display-table{display:table!important}.display-table .row{display:table-row!important}.display-table .cell{display:table-cell!important}.text-center-align-container{text-align:center}.text-right-align-container{text-align:right}.vertical-top-align-container>*{vertical-align:top}.vertical-middle-align-container>*{vertical-align:middle}.vertical-bottom-align-container>*{vertical-align:bottom}.inline-container>*{display:inline-block}.inline{display:inline}.inline-block{display:inline-block}.block{display:block!important}.message-with-link,.message-with-link a{font-size:12px;color:#29abe2}.message-with-link a{font-weight:normal;text-decoration:underline!important}.thin-border{border:solid 1px #CCC}.color-blue1{color:#29abe2}a.flat-button:visited,.flat-button{color:white;width:auto;text-align:center;font-size:14px;border-radius:6px;border:0;padding:4px 20px;margin:1px;-webkit-transition:opacity .8s;-moz-transition:opacity .8s;-o-transition:opacity .8s;transition:opacity .8s;display:inline-block}.flat-button-slim{font-size:12px;line-height:14px}.flat-button[disabled]{opacity:.5}.flat-button[disabled]:hover{cursor:not-allowed;opacity:.5}.flat-button:hover{color:white;cursor:pointer;opacity:.8;-webkit-transition:opacity .2s;-moz-transition:opacity .2s;-o-transition:opacity .2s;transition:opacity .2s}.flat-button:active{opacity:1}.flat-button.flat-button-normal{background:#29abe2}.flat-button.app-os-lang-btn{background:#dcdcdc}.flat-button.flat-button-emphasis{background:#0071bc}.flat-button.flat-button-radio{min-width:100px}.flat-button.flat-button-radio input[type=radio]{display:none;border-radius:0}.flat-button.flat-button-radio input:checked+span{background:#29abe2;color:white;border-color:transparent}.flat-button.flat-button-radio input+span{background:#f2f2f2;display:inline-block;color:black;min-width:100px;padding:7px 15px;border:1px #ccc solid;width:100%}.flat-button.flat-button-group{width:100%;background:#e6e6e6;color:black;border-radius:0;border:1px #b8b8b8 solid;margin:5px 5px;padding:5px 3px}.flat-button.flat-button-group-active{background:#29abe2;color:white;border-radius:0;border-style:none}.flat-button.flat-button-positive{background:#77bb68}.flat-button.flat-button-negative{color:#29abe2;background:white;border:1px #29abe2 solid}.flat-button.flat-button-warning{background:#fcb237}.table{color:#595959;font-size:12px}.table .color-bar-left{border-left:5px solid #e6e6e6}.color-bar-right{display:inline-block;width:5px!important;padding:0!important;height:20px;right:30px;position:relative}.table th,.table td{padding:5px 10px;border:0;vertical-align:middle;text-align:center}.table.left-align th,.table.left-align td{text-align:left}.table td:first-child~td{border-left:solid 1px #e6e6e6}.table th{background:#e6e6e6}.table th .order-arrow{float:right;color:#4d4d4d;display:block}.table th .order-arrow.up:after{content:"▴"}.table th .order-arrow.down:after{content:"▾"}.table tr{border-bottom:solid 1px #29abe2;background:white}.table .show-all:hover~div{visibility:visible}.table .show-all-container{border:solid 1px #29abe2;background:white;position:absolute;padding:5px 10px;visibility:hidden}.table .show-all-container ul{padding:0;margin:0}.table .show-all-container ul li{padding:3px}.table .show-all-container i{display:block;background:url(../images/icons/dialog-arrow.png) no-repeat;width:15px;height:6px;position:absolute;top:-6px;left:23px}a{text-decoration:none!important}h1,h2,h3,h4,h5,h6{font-weight:bold;font-size:100%;margin:0;padding:0;line-height:normal}ul,ol,li,dl,dd,dt{list-style:none}li{line-height:normal}.nomarginpadding{margin:0;padding:0}.detail-main .description ul,.developer-submit-product ul,.helpdoc-page ul,.detail-main .description ol,.developer-submit-product ol,.helpdoc-page ol{padding-left:17px}.detail-main .description ul li,.developer-submit-product ul li,.helpdoc-page ul li{list-style:disc}.detail-main .description ol li,.developer-submit-product ol li,.helpdoc-page ol li{list-style:decimal}.details-main .seller{float:left}body,button,input,select,textarea{font-family:Arial,Verdana,Sans-Serif}.overlay_text{color:#999;line-height:18px;font-weight:normal!important;position:absolute;cursor:text!important;text-shadow:none!important}.spinner{width:16px;height:16px;background:url(../images/icons/spinner_16.png) no-repeat left top}.spinned{display:none!important}.spinner_container{padding-left:20px;line-height:24px;position:relative;cursor:wait;white-space:nowrap;display:inline-block}.spinner_container .spinner{position:absolute;top:4px;left:0}.popup_menu.flat_menu .spinner_container{padding-left:25px;padding-right:3px}.popup_menu.flat_menu .spinner_container .spinner{left:5px}.local_spinner{padding-left:31px}.local_spinner .spinner{left:9px}.line-separator{height:1px;width:100%;background:#CCC;margin:6px 0 6px 0}.sub-title{font-size:12px;color:black;display:inline-block}#flash_message{z-index:11203;position:fixed;left:50%;padding:11px 30px 9px 50px;color:#fff;font-size:14px;cursor:default;text-shadow:0 1px 0 #000;text-shadow:0 1px 0 rgba(0,0,0,0.85);border:1px solid #75a3ff;border-color:rgba(117,163,255,0.7);background-color:#1e3559;background:-webkit-gradient(linear,left top,left bottom,from(#1e3559),to(#172944));background:-webkit-linear-gradient(#1e3559,#172944);background:-moz-linear-gradient(#1e3559,#172944);-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px}#flash_message img,#flash_message .spinner{position:absolute;left:26px;top:13px}#flash_message #off_button_div{width:24px;height:24px;position:absolute;right:5px;top:8px;background-image:url(../images/buttons/close_24.png);cursor:pointer}#flash_message.success{background:#1e3559 url(../images/icons/flash_success.png) no-repeat 26px 13px;background:url(../images/icons/flash_success.png) no-repeat 26px 13px,-webkit-gradient(linear,left top,left bottom,from(#1e3559),to(#172944));background:url(../images/icons/flash_success.png) no-repeat 26px 13px,-webkit-linear-gradient(#1e3559,#172944);background:url(../images/icons/flash_success.png) no-repeat 26px 13px,-moz-linear-gradient(#1e3559,#172944)}#flash_message.error{background:#1e3559 url(../images/icons/error_16.png) no-repeat 26px 13px;background:url(../images/icons/error_16.png) no-repeat 26px 13px,-webkit-gradient(linear,left top,left bottom,from(#1e3559),to(#172944));background:url(../images/icons/error_16.png) no-repeat 26px 13px,-webkit-linear-gradient(#1e3559,#172944);background:url(../images/icons/error_16.png) no-repeat 26px 13px,-moz-linear-gradient(#1e3559,#172944)}.header-icon{width:18px!important;height:23px!important;margin:0 10px 0 5px!important;position:relative;top:-4px}.icon-my-downloads{background:url('../images/icons/mydownloads_idle.png') no-repeat!important}li.disabled .icon-my-downloads{background:url('../images/icons/mydownloads_disabled.png')!important}li:hover .icon-my-downloads{background:url('../images/icons/mydownloads_hover.png') no-repeat!important}.icon-my-uploads{background:url('../images/icons/myuploads_idle.png') no-repeat!important}li.disabled .icon-my-uploads{background:url('../images/icons/myuploads_disabled.png') no-repeat!important}li:hover .icon-my-uploads{background:url('../images/icons/myuploads_hover.png') no-repeat!important}.main-middle-content{width:1280px;margin-left:auto;margin-right:auto;margin-top:15px;display:flex;padding-bottom:15px}.left-mainmiddlecontent{width:190px;margin-right:15px;float:left}.navigation-content .navigation-header,.filter-catalog-container .filter-catalog-title{border:1px solid #d3d3d3;min-height:30px;text-align:center;line-height:30px;background:#e6e6e6;font-size:18px;color:#4d4d4d}.navigation-content .navigation-a{position:relative;margin:0;padding:0}.dropdown-menu-store,.navigation-content .navigation-a .popover{min-width:190px}.navigation-content li{text-align:left;min-height:25px;line-height:24px;color:#808080}.first-a{margin-left:35px}.sub-a{margin-left:5px}.second-a{margin-left:5px}.navigation-content .navigation-a-li{border-bottom:1px solid #838383;position:relative}.navigation-content li:hover{background:#29abe2;color:White}.navigation-content li a{font-size:12px;color:inherit}.navigation-content .btn-group .dropdown-toggle{width:189px}.apps-wrapper{margin:0 auto}.right-mainmiddlecontent{min-height:500px;width:1050px;padding-left:14px;float:left;border-left:1px solid #b3b3b3}.apps-content .apps-section .show-all{float:right;font-size:13px;text-decoration:none}.apps-section h2{margin-bottom:10px;margin-top:10px;color:#777;line-height:40px;font-size:24px;font-family:Arial}.apps-content .apps-carousel{width:1051px;padding:10px 0}.apps-content .apps-carousel h2{margin-bottom:12px}.apps-content .apps-carousel-box{float:left}.short-carousel-wrapper .apps-carousel-box{width:525px}.long-carousel-wrapper .apps-carousel-box{width:100%}.apps-carousel .apps-carousel-box .carousel .carousel-item-ul{margin:0;padding:0}.short-carousel-wrapper .apps-carousel-box-not-first h2{margin-left:10px}.widget-title{height:40px;overflow:hidden;text-overflow:ellipsis}ul.apps-list .s-price-cont{float:left!important;height:18px}ul.apps-list .s-price-cont>span.price,ul.apps-list .s-price-cont .sr-subscriberonly{color:#29abe2!important;font-size:12px!important}ul.apps-list .badge-hover-stub div{text-align:left}ul.apps-list li{background-color:rgba(255,255,255,0.7);cursor:pointer}ul.apps-list li:hover,#result-list .widget-element-app-layout:hover{-moz-box-shadow:0 0 5px rgba(170,170,170,0.4);-webkit-box-shadow:0 0 5px rgba(170,170,170,0.4);-ms-box-shadow:0 0 5px rgba(170,170,170,0.4);box-shadow:0 0 5px rgba(170,170,170,0.4);background-color:rgba(255,255,255,1)}ul.apps-list li img,ul.apps-list li .product-data-container{float:left}ul.apps-list li .product-data-container{padding-left:10px;width:90px}ul.apps li.small-widget-element .product-data-container{max-width:85px}ul.apps li.middle-widget-element .product-data-container{max-width:128px}ul.apps li.large-widget-element .product-data-container{max-width:110px}ul.apps-list li .product-data-container .seller{color:grey}ul.apps-list li.large-widget-element .product-data-container .seller{font-size:11px;height:17px}ul.apps-list li.middle-widget-element .product-data-container .seller,ul.apps-list li.small-widget-element .product-data-container .seller{font-size:12px;height:14px;line-height:13px}ul.apps-list li.small-widget-element .product-data-container .product-rating-small{margin:0}ul.apps-list li .product-data-image{float:left}ul.apps-list li.large-widget-element{width:260px;height:90px}ul.apps-list li.middle-widget-element{width:208px}ul.apps-list li.small-widget-element{width:165px;height:72px}.apps-section-middle ul.apps-list li.small-widget-element{margin:12px 12px 0}.apps-content .apps-section-last{margin-bottom:0;padding-bottom:27px}ul.apps-list li.large-widget-element .product-data-image{margin-left:5px}ul.apps-list li.middle-widget-element .product-data-image,ul.apps-list li.small-widget-element .product-data-image{margin-left:3px}ul.apps-list li h3{color:#444;font-weight:bold;font-family:Arial}ul.apps-list li .product-comment{margin:0;font-size:12px;width:13px!important}ul.apps-list li.large-widget-element h3{line-height:14px;font-size:12px;color:#4d4d4d;height:30px}ul.apps-list li.middle-widget-element h3,ul.apps-list li.small-widget-element h3{line-height:15px;font-size:12px}ul.apps-list li.large-widget-element .ellipsis{width:160px!important}ul.apps-list li.middle-widget-element .ellipsis{width:125px!important}ul.apps-list li.small-widget-element .ellipsis{width:85px!important}ul.apps-list li.large-widget-element h3.ellipsis{white-space:normal!important}ul.apps-list .product-data-image img{-o-border-radius:5px;-ms-border-radius:5px;-moz-border-radius:5px;-webkit-border-radius:5px;border-radius:5px;border:1px solid #e3e3e3}ul.apps-list li.large-widget-element img{width:80px;height:80px}ul.apps-list li.middle-widget-element img,ul.apps-list li.small-widget-element img{width:60px;height:60px}.long-carousel-wrapper #carousel-slider-widget-layout-0{padding-right:0}.short-carousel-wrapper #carousel-slider-widget-layout-1{padding-left:5px;border-left:1px solid #ccc}.long-carousel-wrapper #carousel-slider-widget-layout-1{padding-left:0}.short-carousel-wrapper .carousel-slider-widget-sub-layout{width:525px}.long-carousel-wrapper .carousel-slider-widget-sub-layout{width:1030px}.carousel-slider-widget{margin:0 13px 0 12px}.carousel-slider-widget .carousel-inner{overflow:visible}.carousel-slider-widget .carousel-inner .item{height:auto;overflow:visible}.carousel-slider-widget .carousel-control{top:55%!important;width:12px!important;height:20px!important;background-position:center!important;background-repeat:no-repeat!important}.carousel-slider-widget .left.carousel-control{left:-15px;background:url('../images/buttons/Arrow_Left.png')}.carousel-slider-widget .right.carousel-control{right:-15px;background:url('../images/buttons/Arrow_Right.png')}.carousel-slider-widget .carousel-item-ul{float:left}.apps-list-big .widget-element-app-content{height:80px}#header #base{max-width:1205px;min-width:1110px;padding:4px 0;margin:0 auto}#header .branding{color:#CCC;text-decoration:none;float:left;position:relative;top:7px;line-height:16px;border:0}#header .branding h1{margin:0;padding:0;line-height:27px;font-size:22px}#header .language-changer{float:left;margin:10px 0 0 20px}#header .btn-group .dropdown-toggle:focus{outline:0}#header .dropdown-toggle{background-color:transparent;border:1px solid #ccc;box-shadow:none;-webkit-box-shadow:none;-moz-box-shadhow:none}#header .language-changer .dropdown-menu>li:hover{background-color:#0081c2}#header .language-changer .dropdown-menu{border-radius:6px;-webkit-border-radius:6px;-moz-border-radius:6px}#logged_user_name{cursor:default;padding-right:10px;color:#29abe2;background:url("../images/icons/menu_arrow_blue.png") no-repeat right center}nav.user-panel .signin_link{cursor:pointer;color:#29abe2}nav.user-panel .drop_down ul,#neck .drop_down ul{background-color:#000;background-color:rgba(0,0,0,0.75);border:1px solid #222;border-color:rgba(204,204,204,0.33);padding:5px 5px 3px;margin:0;white-space:nowrap;min-width:0;position:absolute;right:0;top:90%;z-index:9999;line-height:1.75;list-style-type:none;visibility:hidden}.product-info .drop_down ul{background-color:#f2f2f2;border-color:#555;border-style:solid;border-width:1px;padding:0 0 3px 0;margin-top:0;white-space:nowrap;min-width:0;position:absolute;z-index:9999;line-height:1.75;list-style-type:none;visibility:hidden}.product-info .drop_down .details_link{cursor:default;padding-right:10px;background:url(../images/buttons/btn_popup_sort.png) no-repeat right 7px}#neck .drop_down ul{left:0;top:25px;width:150px;background-color:#d7d7d7;border:1px solid #222;border-color:rgba(204,204,204,0.33);padding:5px;margin:0;white-space:nowrap;min-width:0;-moz-border-radius:2px;-webkit-border-radius:2px;border-radius:2px;position:absolute;z-index:9999;line-height:1;list-style-type:none;visibility:hidden}nav.user-panel .drop_down ul li,#neck .drop_down ul li{padding-top:5px;padding-bottom:0;margin-top:5px;border-top:1px solid #383838;height:auto!important;line-height:normal!important}nav.user-panel .drop_down ul li:first-child,#neck .drop_down ul li:first-child{border:0 none;padding:0;margin:0}.product-info .drop_down ul li{padding-left:3px;padding-right:3px;padding-top:3px}.drop_down a{padding:0 5px;text-decoration:none;cursor:pointer}.product-info a.details_link,.product-info .drop_down{float:left}.product-info .drop_down a{padding-right:5px}nav.user-panel .drop_down a{display:block;line-height:22px!important;height:22px!important;font-size:12px;color:#fff!important;filter:alpha(opacity=100)!important;-moz-opacity:1!important;-khtml-opacity:1!important;opacity:1!important;padding:0;border:none!important}.product-info .drop_down a,#neck .drop_down a{display:block;line-height:22px;font-size:12px;-moz-border-radius:2px;-webkit-border-radius:2px;border-radius:2px;color:#000!important}.product-info .drop_down a:hover{color:#fff!important}nav.user-panel .drop_down a:hover,.product-info .drop_down a:hover,#neck .drop_down a:hover{background:#29abe2}nav.user-panel li.drop_down:hover,#neck span.drop_down:hover{position:relative;z-index:599;cursor:default}.product-info .drop_down :hover{z-index:599;cursor:default}nav.user-panel li.drop_down:hover>ul,.product-info .drop_down:hover>ul,#neck span.drop_down:hover>ul{visibility:visible}.bannertext{left:250px;position:absolute;right:150px;text-align:center;top:11px;color:#dc0719;font-style:italic;overflow:hidden;white-space:nowrap}.error_page{margin:20px auto}#neck .neck-content{height:50px;width:100%;margin:auto;padding-top:15px}#neck .breadcrumb{float:left;padding:0;margin-right:10px;margin-left:20px;margin-bottom:0}#neck .breadcrumb>a,#neck .breadcrumb>span:not(.breadcrumb-divider){display:inline-block;vertical-align:-2px;font-size:20px}#neck .breadcrumb .breadcrumb-divider{color:#111}#neck .breadcrumb a:link,#neck .breadcrumb a:visited{color:#343434}#neck .breadcrumb a:hover,#neck .breadcrumb a:active{color:#06e}#neck .breadcrumb .home{display:inline-block;width:22px;height:22px;background:url(../images/icons/icon_home.svg) no-repeat;vertical-align:-4px}#neck .breadcrumb span.drop_down{padding:0 12px 0 10px}#neck .breadcrumb span span.arrow{background:url(../images/buttons/btn_popup_sort.png) no-repeat right 6px;padding:0 10px 0 0}#my-drafts .details_link,#my-drafts .details_link:hover,#my-drafts .details_link:active,#my-drafts .details_link:visited,#my-publishedlist .details_link,#my-publishedlist .details_link:hover,#my-publishedlist .details_link:active,#my-publishedlist .details_link:visited,#my-published .details_link,#my-published .details_link:hover,#my-published .details_link:active,#my-published .details_link:visited,#detail .app-benefit-notification a:focus{border:0;width:400px;text-align:left;word-wrap:break-word;outline-style:none}.navbar-toolbar #search-plugin{margin-top:9px}#search-plugin .dropdown{float:left}#fancybox-outer{padding:0;background:transparent;-ms-box-shadow:0 0 12px rgba(0,0,0,0.65);-moz-box-shadow:0 0 12px rgba(0,0,0,0.65);-webkit-box-shadow:0 0 12px rgba(0,0,0,0.65);box-shadow:0 0 12px rgba(0,0,0,0.65);-moz-background-clip:padding;-webkit-background-clip:padding;background-clip:padding-box}#fancybox-content{background:transparent;border:1px solid #5b5b5b;-moz-background-clip:padding;-webkit-background-clip:padding;background-clip:padding-box}#fancybox-close{top:10px;right:9px;width:13px;height:13px;background-image:url("../images/buttons/close_13.png");background-position:0 0}.license-add{top:10px;right:9px;width:13px;height:13px;background-image:url("../images/buttons/close_13.png");background-position:0 0;transform:rotate(45deg)}.license-remove{top:10px;right:9px;width:13px;height:13px;background-image:url("../images/buttons/close_13.png");background-position:0 0}#fancybox-close:focus,#fancybox-close:hover{background-position:0 bottom}.license-add:focus,.license-add:hover{background-position:0 bottom}.license-remove:focus,.license-remove:hover{background-position:0 bottom}.img-mask{position:absolute;left:0;top:0;width:100%;height:100%;background-color:rgba(255,255,255,0.7)}.overlay_window{background-color:#f5f5f5}.overlay_window>header{background-color:#e6e6e6;padding:0 10px;height:29px;position:relative}.overlay_window>header h1{overflow:hidden;white-space:nowrap;text-overflow:ellipsis;font-size:14px;font-weight:normal;padding-top:6px}.overlay_window .body_container{border-top:solid 1px #cfcfcf;background-color:#fff}.overlay_window .body{padding:15px;background-color:#f4f4f4}.overlay_window .un-body{margin:0 -15px;padding-bottom:1px;overflow:hidden}.overlay_window .body h2{font-size:16px}.overlay_window .body p{margin-bottom:15px}.overlay_window .body p:last-child{margin-bottom:0}.overlay_window .body label{font-size:12px}.overlay_window .body .title.simple{font-weight:normal}.overlay_window .body .title.error{color:#f00}.overlay_window .body #select_btn{margin-top:10px}.overlay_window .controls{text-align:right}.overlay_window .controls button.close_btn{float:left}.overlay_window .controls.highlighted{padding:10px;margin:0}.overlay_window header .minimize{position:absolute;right:0;top:6px;border-right:1px solid #999;padding:1px 6px 1px 0}.overlay_window header .minimize_btn{cursor:pointer;display:block;height:16px;width:16px;background:url(../images/buttons/btn_minimize.png) no-repeat left top}.overlay_window header .minimize_btn:focus,.overlay_window header .minimize_btn:hover{background-position:left bottom}#download-link-popup{font-size:12px}#download-link-popup>.body_container{padding:15px;text-align:center}#download-link-popup .body_container>span{margin-bottom:5px;display:inline-block}#download-link-popup .body_container>span:last-of-type{font-style:italic;font-size:11px}#main{margin:0 auto;width:1280px}.search-main#main,.detail-main#main,.language-os-selector#main,.boutique#main{padding-left:0}.search-main#main{width:1265px}.search-main #facets-pane{margin-left:30px}.my-uploads-page#main{padding-left:0}.developer-description#main{padding-left:0}#main.search-page,#main.boutique{overflow:auto}.boutique #content{margin-left:120px}#goTop{display:none;position:fixed;right:20px;bottom:145px;width:50px;height:50px;-webkit-transition:opacity .2s;-moz-transition:opacity .2s;-o-transition:opacity .2s;transition:opacity .2s;z-index:9999}#goTop:hover{-moz-opacity:.8;-khtml-opacity:.8;opacity:.8;cursor:pointer}.sort-option{height:25px;background:#fff;margin-right:6px;border-bottom:solid 1px #29abe2}.sort-img-group{width:12px;height:14px;margin-bottom:-3px;display:-moz-inline-box;display:inline-block}.sort-img-group-asc{background:url("../images/icons/up_arrow_idle.png"),url("../images/icons/down_arrow_selected.png") 0 7px;background-repeat:no-repeat}.sort-img-group-desc{background:url("../images/icons/up_arrow_selected.png"),url("../images/icons/down_arrow_idle.png") 0 7px;background-repeat:no-repeat}.sort-option .sort-common{font:12px arial;text-align:center;height:25px;line-height:25px;padding-left:15px;padding-right:15px;margin-right:-4px;display:-moz-inline-box;display:inline-block}.sort-option .sort-common:hover{color:#29abe2;background:#e6e6e6;cursor:pointer}.sort-option .sort-unhightlighted{color:#29abe2;background:#fff}.sort-option .sort-hightlighted{color:#fff;background:#29abe2}.widget-hoverable{width:200px;height:100px}.widget-hoverable{background:white;border:1px solid #e3e3e3}.widget-hoverable .default-area{width:100%;height:100%}.widget-drawer{height:0;width:260px;background:white;border:1px solid #e3e3e3;border-top:0;margin-left:-1px;overflow:hidden;outline:1px solid transparent;-webkit-transform:scaleY(0);-o-transform:scaleY(0);-ms-transform:scaleY(0);transform:scaleY(0);-webkit-transform-origin:top;-o-transform-origin:top;-ms-transform-origin:top;transform-origin:top;overflow:hidden;-webkit-transition:-webkit-transform .3s ease;-webkit-transition:-webkit-transform .3s ease;-webkit-transition:-webkit-transform .3s ease;transition:transform .3s ease}.widget-hoverable:hover .widget-drawer{max-height:120px;position:absolute;height:auto;z-index:999;-webkit-transform:scaleY(1);-o-transform:scaleY(1);-ms-transform:scaleY(1);transform:scaleY(1);box-shadow:0 2px 5px -2px rgba(170,170,170,0.4);-moz-box-shadow:0 2px 5px -2px rgba(170,170,170,0.4);-webkit-box-shadow:0 2px 5px -2px rgba(170,170,170,0.4);-ms-box-shadow:0 2px 5px -2px rgba(170,170,170,0.4)}.widget-drawer span{color:#666;font-size:12px;display:block;word-wrap:break-word;margin:6px}.apps-carousel-section .widget-hoverable{height:80px;margin-right:-5px}.apps-carousel-section .widget-drawer{width:165px}.apps-section-middle ul.apps-list .widget-hoverable{height:70px;width:203px}.apps-section-middle .widget-drawer{width:203px}ul.apps-list li{padding-top:8px}ul.apps-list li.widget-element-app.large-widget-element:not(:nth-child(4n+1)){margin-left:-5px}ul.apps-list li.widget-element-app.large-widget-element:nth-child(n+5){margin-top:-5px}.apps-section-middle ul.apps-list li.widget-element-app:not(:nth-child(5n+1)){margin-left:-5px}.apps-section-middle ul.apps-list li.widget-element-app:nth-child(n+5){margin-top:-5px}#result-list.apps-list-big .s-price-cont{position:absolute;right:auto;bottom:10px;left:310px;width:110px}#result-list.apps-list-big .s-price-cont .price{text-align:left;font-size:12px;color:#29abe2;overflow:hidden;text-overflow:ellipsis}#result-list.apps-list-big .title.ellipsis{width:305px;color:#444;font-weight:bold}#result-list .widget-element-app-layout{background-color:rgba(255,255,255,0.7);cursor:pointer}#result-list.apps-list-big .sr-subscriberonly.ellipsis{width:100px;text-align:left}.search-results h3{color:#4d4d4d;margin:0;font-size:12px;font-weight:bold;line-height:20px}#result-list-new-wrapper #result-list{margin:0;border:0;background-color:transparent}#result-list-new-wrapper ul.apps-list li.small-widget-element{margin:12px 12px 0;border:1px solid #b3b3b3;-ms-border-radius:3px;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px}ul.apps-list-big .product-data-container{float:left;width:411px;position:relative;height:82px;margin-left:8px}ul.apps-list-big .seller{position:absolute;left:230px;top:6px;color:#666;font-size:12px;text-align:right}ul.apps-list-big .rating-wrapper{position:absolute;left:310px;width:110px;top:0}ul.apps-list-big .small-widget-element{-ms-border-radius:18px;-moz-border-radius:18px;-webkit-border-radius:18px;border-radius:18px;border:1px solid #d3d3d3;padding:9px;box-shadow:3px 3px 2px rgba(0,0,0,0.2);-moz-box-shadow:3px 3px 2px rgba(0,0,0,0.2);-webkit-box-shadow:3px 3px 2px rgba(0,0,0,0.2);-ms-box-shadow:3px 3px 2px rgba(0,0,0,0.2)}ul.apps-list-big .small-widget-element .product-data-image{-o-border-radius:18px;-ms-border-radius:18px;-moz-border-radius:18px;-webkit-border-radius:18px;border-radius:18px;width:80px;border:1px solid #aaa}ul.apps-list-big .small-widget-element .product-data-image img{-o-border-radius:18px;-ms-border-radius:18px;-moz-border-radius:18px;-webkit-border-radius:18px;border-radius:18px;width:80px;height:80px}.widget-element-app-search-list-view .product-data-image{width:82px}.widget-element-app-search-list-view img{width:80px;height:80px;-webkit-border-radius:5px;border-radius:5px;border:1px solid #e3e3e3}ul.apps-list .short-description-wrapper{position:absolute;top:73px;word-wrap:break-word;width:150px;color:#666;font-size:12px}ul.apps-list-big .short-description-wrapper{display:block;color:#808080;width:305px;word-wrap:break-word;font-size:11px;height:60px;overflow-y:hidden}#content{width:700px;display:inline;float:left;margin:0 10px}.normal-search#search-form{float:left;width:600px}#search-form .search-form-filter{width:235px;height:22px;float:left;margin:1px 0}#search-form .search-form-keyword{color:#666;font-size:12px;height:16px;line-height:16px;width:90%;margin:0;border:0;background:transparent;margin-top:6px;margin-bottom:6px;-ms-box-shadow:none;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;padding-right:0;padding-left:4px;outline:0}.show-all-wrapper{float:left;line-height:38px;margin-left:10px}#search-form .show_all{font-size:12px;color:#4674a7;float:left;margin-left:8px;line-height:22px;cursor:pointer;width:140px;text-align:right}#search-form .show_all:hover{color:#039}#search-form #show_all_display{float:left;width:100px;height:18px;overflow:hidden;text-overflow:ellipsis}#search-form .search-form-submit,#app-management .app-search .search-form-submit{right:1px;padding:0;background:url(../images/icons/icon_search.png) no-repeat scroll center center transparent;border:0;cursor:pointer;position:relative}#categories-nav{margin-top:10px}ul.dropdown,ul.dropdown li,ul.dropdown ul{list-style:none;margin:0;padding:0}ul.dropdown{position:relative;z-index:597;float:left;width:660px;height:26px;background:#000;padding:0 20px}ul.dropdown li{float:left;line-height:26px;zoom:1;font-size:15px;padding:0 33px 0 0;cursor:default;border:0}ul.dropdown li a{color:#FFF;cursor:pointer}ul.dropdown li:hover{position:relative;z-index:599;cursor:default}ul.dropdown li:hover>ul{visibility:visible}ul.dropdown .dirr span{background:url(../images/icons/menu_arrow_white.png) no-repeat right 8px;padding-right:15px}ul.dropdown ul{visibility:hidden;position:absolute;top:100%;left:0;z-index:598;width:100%;background:#0d0d0d;-moz-box-shadow:2px 2px 2px rgba(24,24,24,0.33);-webkit-box-shadow:2px 2px 2px rgba(24,24,24,0.33);-ms-box-shadow:2px 2px 2px rgba(24,24,24,0.33);box-shadow:2px 2px 2px rgba(24,24,24,0.33)}ul.dropdown ul.nav-1{width:300px;left:0}ul.dropdown ul.nav-2{width:280px;left:0}ul.dropdown ul.nav-3{width:225px;left:-50px}ul.dropdown ul li{float:none;padding:2px 5px}ul.dropdown ul li:hover{background:#507fc1}ul.dropdown ul li a{color:#d9d9d9;font-size:13px}.homepage-module,.detailpage-module{margin-bottom:20px;float:left}.image-homepage{position:relative;min-height:220px}#image-title-homepage{position:absolute;left:23px;top:23px;color:#000;font-size:16px;width:654px;font-weight:bold;text-shadow:0 0 8px rgba(255,255,255,1)}#image-des-homepage{position:absolute;left:23px;top:48px;color:#000;font-size:12px;width:420px;line-height:1.3;text-shadow:0 0 8px rgba(255,255,255,1)}#carousel-slider{height:200px}.carousel-control{background:url('../images/sprite.png');width:35px;height:72px;border:0;zoom:60%}.left.carousel-control{background-position:-50px -50px}.right.carousel-control{background-position:-100px -50px}.carousel-indicators{bottom:15px;right:auto;top:auto;left:60px}.carousel-indicators li{cursor:pointer;border-radius:0;margin-left:20px;width:10px;height:10px;background-color:grey}.carousel-inner .item{width:100%;height:200px;overflow:hidden;background-repeat:no-repeat;background-position:center center}.landing-view #carousel-slider{-moz-box-shadow:0 0 5px rgba(0,0,0,0.4);-webkit-box-shadow:0 0 5px rgba(0,0,0,0.4);-ms-box-shadow:0 0 5px rgba(0,0,0,0.4);box-shadow:0 0 5px rgba(0,0,0,0.4);height:200px}.landing-view .carousel-caption,.home-view .carousel-caption{top:0;padding:35px 0 0 120px;position:absolute;top:0;background:-webkit-linear-gradient(left,rgba(35,35,35,0.8),rgba(35,35,35,0));background:-moz-linear-gradient(left,rgba(35,35,35,0.8),rgba(35,35,35,0));background:-o-linear-gradient(left,rgba(35,35,35,0.8),rgba(35,35,35,0));background:-ms-linear-gradient(left,rgba(35,35,35,0.8),rgba(35,35,35,0));background:linear,left,rgba(35,35,35,0.8),rgba(35,35,35,0);filter:alpha(opacity=80 finishopacity=0 style=1) progid:DXImageTransform.Microsoft.gradient(startColorstr='rgb(35,35,35)',endColorstr='rgb(35,35,35)',GradientType=0)}#landing-container{width:1280px;margin-left:auto;margin-right:auto}#landing-container .button-wrapper{position:absolute;z-index:4;top:150px;right:80px}#landing-container .carousel .button-wrapper button{height:30px;min-width:150px;font-size:14px;color:#fff;font-family:'Open Sans',Arial,'FrutigerNextPro',sans-serif;text-shadow:none;border-radius:0}#landing-container .carousel .button-wrapper .btn-signup{background:#00c000;border:0;margin-right:10px}#landing-container .carousel .button-wrapper .btn-fusion-hero{background:#f89706 url('../images/icons/fusion-download.png') no-repeat center right 10px;border:0;padding-right:35px}#landing-container .carousel .button-wrapper .btn-signin{background:#259fff;border:0}.landing-view .carousel .carousel-inner .item .carousel-caption h2,.home-view .carousel .carousel-inner .item .carousel-caption h2{font-family:'Open Sans',Arial,'FrutigerNextPro',sans-serif;font-size:20px;text-shadow:0 0 10px rgba(0,0,0,0.6);color:#FFF;padding:5px 10px;display:inline-block;font-weight:initial}.landing-view .carousel .carousel-inner .item .carousel-caption pre,.home-view .carousel .carousel-inner .item .carousel-caption pre{line-height:22px;font-family:'Open Sans',Arial,'FrutigerNextPro',sans-serif;font-size:16px;padding:5px 10px;color:#FFF;text-shadow:0 0 10px rgba(0,0,0,0.6);max-width:700px;border:0;background-color:transparent;overflow:hidden;word-wrap:normal;word-break:keep-all}.button-wrapper .signin_link{text-decoration:none}.page-tool-wrapper{width:1220px;margin:0 auto;border-top:1px solid #cecece;overflow:auto}#main .page-tool{margin:10px auto;width:730px;padding:20px 0}#main .page-tool #signup-box{height:48px;width:332px;padding-top:20px;padding-bottom:20px}#main .page-tool #signup-box .text{margin:10px 0 0;color:#666;font-size:12px}#main .overlay-link{margin-right:30px}#main .opening-soon{margin-left:auto;margin-right:auto;width:604px;height:270px;background-repeat:no-repeat;padding:20px;background-image:url("../images/layout/opening_soon_bg.png")}.landing-view #main,.home-view#main{margin:0!important;width:auto!important;background:#f1f0f0}.landing-view #landing-banner #banner-carousel .carousel-list li h1{color:#444;text-shadow:0 0 8px rgba(255,255,255,1);font-size:40px;font-weight:normal;margin:48px 0 0 130px}.landing-view #landing-banner #banner-carousel .carousel-list li h1.maintenance-header{margin-top:100px}.landing-view #landing-banner #banner-carousel .carousel-list li h2{color:#444;text-shadow:0 0 8px rgba(255,255,255,1);font-size:19px;width:600px;font-weight:bold;margin:20px 0 0 130px}.landing-view #landing-banner #banner-carousel .carousel-list li p{color:#444;text-shadow:0 0 8px rgba(255,255,255,1);font-size:14px;width:400px;margin:20px 0 0 130px}.landing-view #landing-banner{margin:0 auto;width:1180px;position:relative}.landing-view #learn-more{width:920px;margin:0 auto 80px auto}.landing-view #landing-banner #banner-carousel{width:1180px;height:400px;position:relative;overflow:hidden}.landing-view #landing-banner #banner-carousel .carousel-list{width:20000em;position:absolute;list-style:none;margin:0;padding:0}.landing-view #landing-banner #banner-carousel .carousel-list li{float:left;width:1180px;height:400px}.landing-view #landing-banner #banner-carousel .carousel-list li.banner-carousel-0{background:url('../images/layout/landing_hero.jpg') no-repeat 0 0}.landing-view #learn-more .maintenance-page{width:435px;margin:54px 0;float:right}.landing-view #learn-more .maintenance-page h1{font-size:16px;font-weight:bold}.landing-view #learn-more .maintenance-page p{font-size:14px}.landing-view #learn-more .maintenance-page{float:none}.landing-view #header #base{min-width:400px}.storenav-button{background:transparent url(../images/buttons/storenav_btn.png?timestamp=20131012) repeat-x 0 0;display:inline-block;margin:0;border:0;min-width:300px;height:45px;color:#555;text-align:center;line-height:45px;font-size:12pt;text-shadow:0 0 8px rgba(255,255,255,1);font-weight:normal;padding:0 10px;-moz-box-shadow:.5px .5px 1px 1px #959595;-webkit-box-shadow:.5px .5px 1px 1px #959595;-ms-box-shadow:.5px .5px 1px 1px #959595;box-shadow:.5px .5px 1px 1px #959595}.storenav-button:hover{background:transparent url(../images/buttons/storenav_btn.png?timestamp=20131012) repeat-x 0 -45px;cursor:pointer}.storenav-button:active,.storenav-button.ui-custom-active{background:transparent url(../images/buttons/storenav_btn.png?timestamp=20131012) repeat-x 0 -90px}a.storenav-button.select-store{color:#fff}.landing-view .dropdown-menu>li>a{line-height:25px}.navbar .dropdown-menu .popover-menu{padding:0;margin:5px 0!important}.navbar .dropdown-menu .popover-menu>li{line-height:25px}.navbar .dropdown-menu .popover-menu>li>a{display:block;padding:0 20px;text-decoration:none;color:black}.navbar .dropdown-menu .popover-menu>li>a:hover{color:white;background-color:#0081c2}.navbar .nav{padding:0}.navbar-header{margin-top:15px}.navbar-brand{background:url(../images/layout/Header_Logo.png) no-repeat;width:241px;height:23px;float:left;text-indent:-9999px;overflow:hidden;background-size:100%}.navbar-default{margin:0;padding:0 20px;border-bottom:1px solid #ccc;background:white}.navbar-toolbar{margin:0;padding:0 20px;background:#f1f0f0}.navbar-default .container{height:50px}.navbar-toolbar .container{height:52px}.navbar-toolbar .navbar{margin:14px 0 11px}.landing-view .navbar-toolbar .navbar{margin:11px 0}.navbar-toolbar .navbar .btn-group{margin-top:0}.btn{background-image:none}.navbar-collapse{height:auto;overflow:visible}.navbar .navbar-nav li{padding:5px 0;height:24px;line-height:24px}.user-panel li.drop_down{padding:0}.navbar .navbar-nav li a{cursor:pointer;padding:0 15px;height:45px;line-height:45px;position:relative;top:-2px;color:#29abe2}.navbar .navbar-nav li a:hover{color:#40cdf5}.login-panel li.depression,.login-panel li.depression{outline:1px solid lightgrey;background:-webkit-gradient(linear,top,bottom,from(#ccc),to(#ededed));background:-webkit-linear-gradient(#ccc,#ededed);background:-moz-linear-gradient(#ccc,#ededed)}.login-panel .depression-panel-myDownloads>li a{border-left:none}.login-panel .depression-panel-myUploads>li.myUploads-li a,.login-panel .depression-panel-myUploads .user-panel{border-left:none}.user-panel{border-left:solid 1px rgba(187,196,198,0.5);padding-left:15px;margin-top:8px}.navbar .navbar-nav li a.a-help-20{border-left:none;padding:0}[class^="icon-"],[class*=" icon-"]{width:20px;height:20px;margin-top:0}.icon-help-20{background:url(../images/icons/help-20x20.png) no-repeat}.search-wrapper .search-box-store-selector{visibility:visible;opacity:0;filter:alpha(opacity=0);-moz-opacity:0;-khtml-opacity:0;position:absolute;top:8px;right:-35px;width:180px}.search-wrapper .nav-search-scope{overflow:hidden;position:relative}.nav-right{float:right;width:auto;display:inline-block}.nav-fill{width:auto;height:35px;position:relative;margin-right:110px}.nav-search-field{position:relative;height:35px}.search-wrapper .search-form-content{border:1px solid lightgrey;background:white}.search-wrapper .search-form-content.active{border-color:#51a7e8;-ms-box-shadow:0 0 5px rgba(81,167,232,0.5);-webkit-box-shadow:0 0 5px rgba(81,167,232,0.5);-moz-box-shadow:0 0 5px rgba(81,167,232,0.5);box-shadow:0 0 5px rgba(81,167,232,0.5)}.search-wrapper .nav-search-scope{position:relative;float:left;height:37px;margin:0;overflow:hidden}.search-wrapper .nav-search-facade{position:relative;float:left;padding:6px 5px 7px 5px;font-size:12px;line-height:14px;margin:5px 0;cursor:pointer;border-left:1px solid lightgrey}.search-wrapper .nav-search-facade .caret{margin-top:5px;margin-left:2px}.search-wrapper .nav-search-submit{position:relative;float:left;height:35px;width:35px;overflow:hidden;cursor:pointer;background:#29abe2}.search-suggestions-box-ul{font:12px Arial;color:#666;position:relative;left:-1px;top:-1px;border:1px solid #ccc;background:#fff;z-index:99;overflow:hidden}.search-suggestions-box-ul li{line-height:25px;cursor:pointer;margin-left:-20px;padding-left:5px}.search-suggestions-box-ul li.selected{background-color:#eee}#search-suggestions-box li:hover{background:#eee}.detail-search-suggestion ul{overflow:hidden;top:0}.detail-search-suggestion li{margin-left:0}.nav-search-submit .nav-input{position:relative;display:block;height:100%;width:100%;line-height:33px;text-indent:-1000px;padding:0;border:0;cursor:pointer;outline:0}.navbar .popover{width:400px;-webkit-border-top-left-radius:0;-webkit-border-bottom-left-radius:0;border-top-left-radius:0;border-bottom-left-radius:0;overflow:hidden}.navbar .popover-content{text-align:center}.navbar .dropdown-menu{-webkit-border-top-right-radius:0;-webkit-border-bottom-right-radius:0;border-top-right-radius:0;border-bottom-right-radius:0;-ms-box-shadow:0 0 5px #000;-webkit-box-shadow:5px 5px 10px rgba(0,0,0,0.2);-moz-box-shadow:5px 5px 10px rgba(0,0,0,0.2);box-shadow:5px 5px 10px rgba(0,0,0,0.2)}.navbar .dropdown-menu>li>a:hover{background-image:none;color:white;background-color:#0081c2;background-color:rgba(0,129,194,0.5)}.navbar .dropdown-menu>li>a.maintainHover{color:white;background-color:#0081c2}#featured-products{margin-top:10px;margin-bottom:10px;background-color:White;border:1px solid #cecece;background-color:white;-moz-border-radius:0 0 4px 4px;-webkit-border-radius:0 0 4px 4px;border-radius:0 0 4px 4px;-ms-box-shadow:0 1px 0 #f1f1f1;-moz-box-shadow:0 1px 0 #f1f1f1;-webkit-box-shadow:0 1px 0 #f1f1f1;box-shadow:0 1px 0 #f1f1f1}#featured-products h2{font-size:16px;color:#404040;font-weight:bold;line-height:28px;height:28px;padding:10px 20px 10px;background-color:white}#featured-products h3{font-size:16px;color:black;margin:7px 0 0;font-weight:normal}#featured-products ul{padding:0 12px 8px;width:674px;color:black;margin:0}#featured-products ul li{position:relative;height:90px;float:left;width:216px;margin:3px 3px 12px 0;padding:0}#featured-products ul li:hover,#featured-products ul li:focus{background:#d5deeb;-moz-border-radius:4px;-webkit-border-radius:4px;border-radius:4px;cursor:pointer}#featured-products ul li:hover a{cursor:pointer}#featured-products ul li:active{background:#9fb3d1}#featured-products .featured_image{width:80px;height:80px;float:left;margin:0 5px 0 0;overflow:hidden}#featured-products ul li div.product-content-container{padding:5px}#featured-products .product-data-container{float:left}#featured-products .product-data-container #product-title{width:120px}#featured-products ul li .title{font-size:12px;color:#000;margin:0}#featured-products ul li .seller,#featured-products ul li .reviews{font-size:10px;color:#808080;display:block}#featured-products ul li .reviews{clear:both}#featured-products ul li .ratingamount{font-size:10px;color:#666;display:block;margin-bottom:3px}#featured-products ul li .price{color:#000;display:block}#featured-products ul li .price.free{color:green}#featured-products ul li .overlay-link{width:100%;height:100%;position:absolute;left:0;top:0;outline:0;z-index:100}#featured-products ul li.clear{height:0}#show_more_all div{text-align:right;padding-top:10px;padding-bottom:20px;padding-right:20px;vertical-align:bottom;font-family:Arial;font-size:12px;color:#4675a8}#show_more_all div a{color:#4675a8}.product-rating-small{float:left;width:65px;height:15px;margin:2px 0 0 0}.product-comment{float:left;height:15px;width:35px;margin:2px 0 0 10px;vertical-align:middle;font:12px arial,Helvetica,sans-serif;color:#808080}.product-comment img{margin:0 0 0 3px}.search-results-stars{float:right}.product-rating-small .star-rating{float:left;width:13px;height:12px;cursor:default;display:block;background:url(../images/icons/star_small.png) no-repeat 0 0;overflow:hidden}.product-rating-small .star-on{background-position:0 -12px!important}.product-rating-small .star-off{background-position:0 0!important}.product-rating-search{float:none}#add-comment .errors{color:red;float:right}#add-comment .not_visible{display:none}#add-comment .error_tag,#add-comment .error{color:red}#add-comment #title{margin-bottom:10px;width:351px;height:16px}#add-comment textarea.error_border,#add-comment input.error_border{border-color:red}#add-comment .comment-rate.error_border{border:1px solid red}.search-page #right{margin-left:20px}#right{width:220px;margin-left:10px;display:inline;float:left}#bestsellers{width:223px}.no-cssgradients #bestsellers h2{background:#e1e1e1 url(../images/layout/backgrounds/bg_h2_title.png) repeat-x 0 0}#bestsellers h2{font-size:16px;font-weight:normal;text-align:center;height:28px;color:#404040;margin:0;padding:0;border:1px solid #cecece;border-bottom:0;line-height:28px;-moz-border-radius:4px 4px 0 0;-webkit-border-radius:4px 4px 0 0;border-radius:4px 4px 0 0;background:-webkit-gradient(linear,left top,left bottom,from(#f0f0f0),to(#e3e3e3));background:-webkit-linear-gradient(#f0f0f0,#e3e3e3);background:-moz-linear-gradient(#f0f0f0,#e3e3e3)}#bestsellers ul{position:relative;top:0;margin:0;padding:0;border:1px solid #cecece;background-color:#fff;-moz-border-radius:0 0 4px 4px;-webkit-border-radius:0 0 4px 4px;border-radius:0 0 4px 4px;-ms-box-shadow:0 1px 0 #f1f1f1;-moz-box-shadow:0 1px 0 #f1f1f1;-webkit-box-shadow:0 1px 0 #f1f1f1;box-shadow:0 1px 0 #f1f1f1}#bestsellers li{border-top:1px solid #d9d9d9;position:relative;height:54px;padding:0;margin:0;display:block}#bestsellers .container{height:42px;width:auto;padding:6px 10px;cursor:pointer}#bestsellers ul li:first-child{border-top:0 none}#bestsellers li:hover,#bestsellers li:focus{background:#d5deeb}#bestsellers li:active{background:#9fb3d1}#bestsellers div.container img.bestseller-icon{width:40px;height:40px;float:left;margin-right:10px;overflow:hidden}#bestsellers .title{color:#000;font:12px arial,Helvetica,sans-serif;margin:0;display:inline-block;width:78px}#bestsellers .description{color:#666;font-size:10px;float:left;margin:0}#bestsellers .price{float:right;font:12px arial,Helvetica,sans-serif;color:#000;vertical-align:bottom}#bestsellers .price.free{color:#008000}#bestsellers .overlay-link{width:100%;height:100%;position:absolute;left:0;top:0;outline:0;z-index:100}.bestsellers-content{float:left;width:150px;height:40px}.leftwing #bestsellers{width:234px}.leftwing .bestsellers-content{width:161px}.leftwing #bestsellers .title{width:89px}.ga-data{text-align:center}.ga-value span{font-size:16px;color:#333}.ga-image-sliders{border-radius:4px;border:1px solid #cecece;overflow-x:hidden;width:348px!important}.ga-image-sliders ul{width:1400px;border:0;height:49px;margin:0;padding:0;background:#e4e4e4;border-bottom:1px solid #cecece}.ga-image-sliders li,.ga-image-sliders li span{width:350px;height:50px}.ga-image-sliders li .ga-title{padding-top:5px;padding-bottom:5px}.ga-image-sliders li .ga-title span{font-size:12px;color:#1c2e84}.ga-image-sliders li{float:left;color:#333;border-top:0}.ga-image-sliders .ga-more-static{height:38px;text-align:center;font-size:15px;background:#f2f2f2}.ga-image-sliders .ga-more-static div{padding-top:10px}.ga-image-sliders .ga-more-static a{font-weight:bold;font-size:12px}.ga-image-sliders .ga-more-static a:link,.ga-image-sliders .ga-more-static a:visited,.ga-image-sliders .ga-more-static a:hover{color:#1c2e84}#quicklinks{float:left;clear:both;padding:0;margin:0 10px 20px 0;display:inline-block;border:1px solid #cecece}#quicklinks a{color:#369}#quicklinks h2{font-size:16px;font-weight:normal;text-align:center;height:28px;color:#333;line-height:28px;-moz-border-radius:4px 4px 0 0;-webkit-border-radius:4px 4px 0 0;border-radius:4px 4px 0 0;background:-webkit-gradient(linear,left top,left bottom,from(#f0f0f0),to(#e3e3e3));background:-webkit-linear-gradient(#f0f0f0,#e3e3e3);background:-moz-linear-gradient(#f0f0f0,#e3e3e3)}#quicklinks ul{padding-left:10px;width:220px;float:left}#quicklinks ul li{padding-bottom:5px}#quicklinks .quicklinks-body{border-top:1px solid #cecece}#facets .facets-constraints .title,#quicklinks li .title{font-size:12px;color:#369;cursor:pointer}#quicklinks li .title{font-size:12px}#quicklinks li.hidden-links{display:none}#facets .facets-constraints .count,#quicklinks li .count{font-size:12px;color:#999}#quicklinks li .count{font-size:11px}#quicklinks .show-all-body{width:210px;padding:10px 10px 10px 12px;border-top:1px solid #cecece}#quicklinks .show-all-body span.show_all{cursor:pointer;font-size:12px;color:#4674a7;font-weight:bold}.no-cssgradients #signup-box{background:#eee}.no-cssgradients #signup-box:hover{background-color:#d9d9d9}#signup-box{float:left;width:205px;text-align:center;color:#222;font-size:11px;padding:13px 8px;background:#e4e4e4;-moz-border-radius:4px;-webkit-border-radius:4px;border-radius:4px;-ms-box-shadow:0 1px 0 #f1f1f1;-moz-box-shadow:0 1px 0 #f1f1f1;-webkit-box-shadow:0 1px 0 #f1f1f1;box-shadow:0 1px 0 #f1f1f1;border:1px solid #cecece;cursor:pointer;display:block}#signup-box .title{margin:0;color:#1c2e84;font-size:14px;font-weight:bold;line-height:1.2}#signup-box .text{margin:5px 0 5px}#signup-box .overlay-link{width:100%;height:100%;position:absolute;left:0;top:0;outline:0;z-index:100}#twitter-widget-0{width:85px!important;float:right}.fb-like{margin-right:2px;float:right}.s-price-cont.s-price-cont-hidden{display:none}.detail-page .detail-module{float:left}.detail-page #content{width:938px;margin:0;margin-bottom:100px}.detail-page #content-wrapper{margin-bottom:10px}.detail-page #detail{padding:10px;background:#fff;border:1px solid #ccc;-moz-border-radius:4px 4px 0 0;-webkit-border-radius:4px 4px 0 0;border-radius:4px 4px 0 0}.detail-page #detail subscriptionDes .subscriptionDes{vertical-align:middle}.detail-page #detail img.subscriptionBadge{float:none;width:24px;height:24px;margin:0}.detail-page #detail .strikeout-price{text-decoration:line-through;vertical-align:middle;padding:0 10px 0 0;cursor:default}.detail-page .description p{word-wrap:break-word;word-break:normal}.detail-page #detail img.product-icon,#app-detail-for-publisher img.product-icon{float:left;height:120px;width:120px;margin:0 15px 5px 0}#app-detail-for-publisher hr{width:960px}.detail-page #detail .title-rating{float:left}.detail-page #detail .icons-cont{width:100%;margin-top:20px}.detail-page #detail .badge-div{float:left}.detail-page #detail .badge-div-visible{visibility:visible}.detail-page #detail .badge-div-hidden{visibility:hidden}.detail-page .badge-div .subscriptionBadge{float:left}.detail-page .purchase-container .caret{border-top:4px solid #fff}#detail-title{margin:0 10px 2px 0;font-size:20px;padding:0;width:80%;color:#4d4d4d;overflow:hidden;text-overflow:Ellipsis;white-space:nowrap;-o-text-overflow:ellipsis;-ms-text-overflow:ellipsis}#detail-social{float:right}#detail .detail-versions-cont .detail-version-cat{float:left;cursor:default;line-height:26px;width:135px}#detail .detail-versions-cont{margin-bottom:10px}#detail .{background:left}.product-rating-big{float:left;width:90px;height:15px;margin:7px 0}.title-rating .product-rating-big{margin:0}.product-rating-big .star-rating{float:left;width:18px;height:16px;cursor:default;display:block;background:url(../images/icons/star_big.png) no-repeat 0 0;overflow:hidden}.product-rating-big .star-on{background-position:0 -16px!important}.product-rating-big .star-off{background-position:0 0!important}.product-rating-search{float:none}.detail-versions-cont .flat-button{border-radius:2px;min-width:150px}.detail-versions-cont .app-version-btn{color:#4d4d4d}#content-wrapper .reviews-count{line-height:32px;margin-left:5px;font-size:12px}#detail .seller{font-size:14px;color:#29abe2}#detail .release-date{font-size:12px;float:right;color:#808080}#detail .description{color:#333;margin:10px 0 10px;font-size:14px;line-height:130%;-ms-word-break:break-word;word-break:break-word;-ms-word-wrap:break-word;word-wrap:break-word}#detail .download-free-notification{clear:both;color:#4675a8;margin:20px 0 20px;font-size:12px;font-weight:bold}#detail .education-free-notification,#detail .app-benefit-notification{clear:both;color:gray;font-size:12px;float:right;font-style:italic}#detail .app-benefit-notification{float:left}#detail .education-free-notification a,#detail .app-benefit-notification a{color:#1a52ad}#detail .description p{margin:0}#detail #extra hr{margin-top:10px;margin-bottom:10px}#detail #extra .detail-versions-cont hr{margin-top:2px;margin-bottom:2px}#extra .purchase-container{height:25px;float:right;max-width:300px;cursor:pointer;margin-bottom:16px}#extra .purchase-container .btn{height:30px;line-height:30px}#extra .version-title{color:#808080;font-size:14px}.price_btn_blue{width:auto;padding:0 20px;border:0;font-size:14px;cursor:pointer;height:25px;text-align:center;line-height:25px;color:#fff}#extra a.price_btn_blue,#extra span.price_btn_blue,#extra a.price_btn_blue:hover{color:white}#detail #detail_testinfo{border:1px solid #00c;padding:5px}#detail .detail_testresult{margin-left:10px;font-style:italic}#extra .purchase_container{display:none}#screenshots .jcarousel-skin-tango .jcarousel-container{background:0;border:0;padding:0 22px}.no-cssgradients #screenshots h2.title,.no-cssgradients .jcarousel-skin-tango{background-color:#f0f0f0}#screenshots ul{height:140px;overflow:hidden;margin:0;padding:0}#screenshots ul li{position:relative}#screenshots .text-container{margin:0 50px 10px;font-size:12px;color:#666}#screenshots .text-container .title{font-weight:bold;line-height:26px}#screenshots ul li span{text-align:center;overflow:hidden;display:block;color:#4d4d4d}#screenshots ul li img{display:block;position:absolute;margin:auto;top:0;bottom:0;left:0;right:0;max-height:74px}.preview-container{height:505px;margin:0 50px 15px 50px;border:1px solid #cecece;position:relative}.preview-container>iframe{width:100%}.preview-container>img,.preview-container>iframe{position:absolute;max-height:100%;max-width:100%;top:0;bottom:0;right:0;left:0;margin:auto;border:0}.preview-next:hover,.preview-prev:hover{opacity:1}.preview-next,.preview-prev{width:20px;height:30px;top:160px;z-index:10;cursor:pointer;position:absolute;opacity:.5}.preview-container .preview-next{background:url(../images/icons/next.png) no-repeat;right:-30px}.preview-container .preview-prev{background:url(../images/icons/prev.png) no-repeat;left:-30px}.preview-overlay{z-index:10;position:relative;height:100%;cursor:pointer}.preview-overlay:hover{background:rgba(0,0,0,0.1) url(../images/icons/zoom.png) no-repeat center;background-size:10%}.video-overlay{background:rgba(0,0,0,0.15) url(../images/buttons/play.png) no-repeat center;height:100%;width:100%;position:absolute;z-index:10;margin:-3px}.video-overlay:hover{cursor:pointer;background:transparent url(../images/buttons/play.png) no-repeat center}.detail-page #right{width:328px;margin-bottom:100px}.side-panel{font-size:12px}.side-panel span#language{word-break:normal}.side-panel h2{font-size:16px;font-weight:normal;padding:0 10px;height:28px;color:#404040;border:1px solid #cecece;line-height:28px;-moz-border-radius:4px 4px 0 0;-webkit-border-radius:4px 4px 0 0;border-radius:4px 4px 0 0;background:-webkit-gradient(linear,left top,left bottom,from(#f0f0f0),to(#e3e3e3));background:-webkit-linear-gradient(#f0f0f0,#e3e3e3);background:-moz-linear-gradient(#f0f0f0,#e3e3e3);text-align:center}.side-panel h3{height:25px;background:-webkit-gradient(linear,left top,left bottom,from(#f0f0f0),to(#e3e3e3));background:-webkit-linear-gradient(#f0f0f0,#e3e3e3);background:-moz-linear-gradient(#f0f0f0,#e3e3e3);font-weight:normal;border:1px solid #cecece;border-bottom:0;border-top:0;line-height:25px;padding:0 8px;color:#000}.side-panel ul.compatible-with-list,ul.subscriber-benefit-product-list{margin:0;padding:0}.side-panel li.hidden-subscriber-benefit-products,li.hidden-compatible-with-list{display:none}.side-panel li.your-subscription{font-weight:bold}.side-panel #purchase{border:1px solid #bfbfbf;background-color:White;padding:10px;margin-bottom:10px;padding-bottom:42px}.side-panel #purchase .price-str{font-size:24px}#purchase .flat-button{width:100%;padding:4px 0}#price-options .flat-button{height:50px;border-radius:0;font-size:24px;color:#29abe2;border:2px solid #29abe2}#price-options .flat-button.selected{color:white}.side-panel .download-info{min-height:15px;padding:5px 0;margin-top:10px}.side-panel .download-info-subscription{padding-bottom:10px}.side-panel .show-more,.show-less{color:#1a52ad;display:inline-block;white-space:nowrap;cursor:pointer}.break-word{word-wrap:break-word;word-break:break-all}.side-panel .download-info .property{float:left}.side-panel .download-info-subscription .property{margin-bottom:10px}.side-panel #show-more-benefit-products,.side-panel #show-less-benefit-products{margin-bottom:10px}.side-panel .download-info .compatible-with-list .compatible-with-list-group{margin-top:8px}.side-panel .download-info .subscriber-benefit-product-list li,.side-panel .download-info .compatible-with-list li{margin:0 0 2px 0}.side-panel .download-info .value{float:right}.side-panel .detail-comptible{padding-bottom:0}.side-panel .promote-item:hover{background:#f0f0f0}.side-panel .promote-item>img{width:50px;height:50px;float:left;margin-right:10px}.side-panel .s-price-cont{float:none;margin-top:5px}.detail-page .product-rating-small{margin-right:5px}.side-panel .product-rating-small{width:auto}.side-panel .ellipsis{width:190px}.side-panel .show-more-apps{margin:5px;float:right}.side-panel .show-more-apps a{color:steelblue}.side-panel.apps-promote-panel{border:1px solid #cecece;background-color:white;padding-bottom:10px}.side-panel.apps-promote-panel H2{border:0;border-bottom:1px solid #cecece;padding:5px;text-align:center;margin-top:0}.side-panel.apps-promote-panel .company-title{font-size:18px}.side-panel.apps-promote-panel .company-numberitem{font-size:14px;color:#4d4d4d}.side-panel.apps-promote-panel .company-number{font-size:18px;font-weight:bold;color:#808080}.side-panel.apps-promote-panel .info-logo{width:80px;height:80px;margin-right:5px;margin-left:10px}.side-panel.apps-promote-panel .promote-item{height:80px;margin-top:5px;margin-bottom:5px;color:#4d4d4d}.side-panel.apps-promote-panel .company-info-cont{height:80px}.side-panel.apps-promote-panel .promote-item .product-title{margin-bottom:20px;font-size:14px;width:220px;font-weight:bold}.side-panel.apps-promote-panel .promote-item .s-price-cont{color:#29abe2}.side-panel.apps-promote-panel .company-info-cont .info-logo{float:left;margin-right:10px}.side-panel.apps-promote-panel .service-list li{font-size:12px;color:#4d4d4d;margin:0 0 10px 10px}.side-panel.apps-promote-panel ul{margin-top:15px}.side-panel.apps-promote-panel .list-title{font-size:18px;color:#4d4d4d;margin:5px 0 5px 10px}.detail-page h2{font-size:18px;margin:10px 0 10px 0;font-weight:normal;text-align:left;height:28px;color:#4d4d4d;border-bottom:0;line-height:28px}#reviews #summary{background-color:white;-moz-border-radius:4px 4px 4px 4px;-webkit-border-radius:4px 4px 4px 4px;border-radius:4px 4px 4px 4px;border:1px solid #cecece;padding:10px;overflow:hidden}#reviews #summary img{width:40px;padding-right:10px;float:left}#reviews #summary .title-author{display:inline-block;float:left}#reviews #summary .title-author span{padding-top:4px;float:left;max-width:100px}#reviews #summary .title-author h3{max-width:100px}#reviews #summary .reviews-info{display:inline-block;padding-left:10px;width:auto;overflow:hidden}#reviews #summary .write-review-link{width:auto;display:inline-block;float:left}.compatible-version{color:grey}.compatible-version-title{font-weight:bold}.reviews-info h3{float:left;line-height:35px;font-size:20px;font-weight:normal;color:#ccc}.get-tech-help{margin:0 5px;color:#1a52ad;line-height:35px}.reviews-info a.get-tech-help:hover{color:#1a52ad}.detail-page span.comment,.detail-page a.comment{padding:8px;margin-right:5px;color:#4d4d4d;cursor:pointer;float:left;border:1px solid #ccc;font-size:14px;width:auto}.detail-page span.noncomment{background:transparent url(../images/icons/comment.png) no-repeat 0 1px;padding-left:20px;margin-left:5px;color:Gray}.detail-page a.comment:hover{color:#3d87ff}#extra .log-in-to-comment span.pending:hover,.detail-page span.pending:hover{color:#1a52ad;cursor:default}.detail-page span.pending,.detail-page a.pending,.detail-page span.pending:hover,.detail-page a.pending:hover{color:#c3c3c3}#reviews #summary .reviews-stars{margin-top:6px}#reviews #summary .reviews-stars .product-rating-small{padding-right:5px}#reviews #summary .reviews-info .averagereview{float:left;margin-right:2px;max-width:190px;width:auto}#reviews #summary .reviews-info .reviews-count{display:block}#comments{width:650px;float:left;padding-bottom:30px}#comments-list{padding:0;margin:0}#comments .add-sub-comments{width:850px}.add-sub-comments .app-publisher{font-weight:bold}#comments .sub-comment-warning,#comments .delete-comment-warnning{color:#f60}#comments .delete-comment-warnning{display:inline}.sub-comment-form textarea{margin-bottom:10px;width:645px}.edit-a-comment-form textarea{margin-bottom:10px;width:600px}#comments .sub-comment-description-warning{border:1px solid #f60;padding:10px}.sub-comment-form-hidden,.sub-comment-link-hidden,.edit-a-comment-hidden,.edit-delete-comment-actions-hidden,.realdelete-cancel-comment-actions-hidden,.sub-comment-hidden,.edit-a-comment-form-hidden{display:none}.comment-action{color:#1a52ad;cursor:pointer}.comment-action:hover{color:#3d87ff;cursor:pointer}.comment-subject{display:block;font-size:13px;color:#595959;font-weight:bold;margin-bottom:10px}.comment-item{margin:20px 0;float:left;width:900px}.comment-item .add-sub-comments{float:left;margin-left:50px}#comments-list hr{width:938px;margin:0;float:left}#comments-list .sub-comment-entity hr{width:888px}.sub-comment-warning{margin-top:10px}.sub-comment-entity{margin-top:15px}.write-a-comment{margin-top:5px;float:left;padding-left:5px}.write-comment-form-submit,.write-a-comment-cancel{margin-right:10px;padding:2px}.sub-comment-description p{margin:0}.sub-comment-description{margin:10px 0;color:#595959}.comment-item .comment-info{float:left;padding-left:5px;width:895px}.comment-item .comment-date{display:inline;color:#a6a6a6;margin-bottom:15px}.comment-item .comment-name{margin-bottom:15px}.comment-item .comment-description{color:#595959}.comment-item .comment-description p{margin-bottom:0}.comment-item .veirified-download{font-size:11px;font-weight:bold;color:#f90}.comment-item .whats-verified-download{font-size:10px;color:#c9c9c9;text-decoration:underline;cursor:pointer}#add-comment{margin-bottom:40px;float:left;background-color:white;-moz-border-radius:4px 4px 4px 4px;-webkit-border-radius:4px 4px 4px 4px;border-radius:4px 4px 4px 4px;border:1px solid #cecece;padding:10px;display:none}#add-comment .title{font-weight:bold;margin-bottom:20px}#add-comment .title a{color:#1f5397}#comment-form .own-rate{float:left;width:260px;text-align:center}#comment-form .own-rate h2{display:inline}#comment-form .own-rate label{font-size:10px;font-weight:bold}#comment-form .own-rate span{font-size:10px}#comment-form .own-rate .product-rating-big{float:none;margin-left:auto;margin-right:auto;padding:10px}#comment-form .own-review{float:left;width:366px;text-align:center}#comment-form .own-review div{position:relative}#comment-form .own-review textarea{margin-top:0;margin-bottom:0;height:65px;width:351px;resize:none}#comment-form input,#comment-form textarea{padding:5px;border:solid 1px #bfbfbf;font-size:13px;font-style:normal;background:white url('../images/bg_form.png') left top repeat-x;background:-webkit-gradient(linear,left top,left 3,from(white),color-stop(1%,#f1f1f1),to(#fcfcfc));background:-moz-linear-gradient(top,white,#f1f1f1 1px,#fcfcfc 2px);box-shadow:rgba(0,0,0,0.1) 0 0 4px;-ms-box-shadow:rgba(0,0,0,0.1) 0 0 4px;-moz-box-shadow:rgba(0,0,0,0.1) 0 0 4px;-webkit-box-shadow:rgba(0,0,0,0.1) 0 0 4px}#comment-form .submit-comment,#comment-form .cancel-comment{width:auto;padding:0 11px;border:0;font-size:14px;color:white;cursor:pointer;height:25px;text-align:center;line-height:25px;margin-top:10px;-moz-box-shadow:none;-webkit-box-shadow:none;-ms-box-shadow:none;box-shadow:none}#comment-form .cancel-comment{margin-right:10px;display:inline-block;margin:0;border:1px solid #797979;white-space:nowrap;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;background-color:#999;-moz-box-shadow:none;-webkit-box-shadow:none}.gradient-button{background:linear-gradient(#6a91df,#314d7b);background:-webkit-gradient(linear,left top,left bottom,from(#6a91df),to(#314d7b));background:-webkit-linear-gradient(#6a91df,#314d7b);background:-moz-linear-gradient(#6a91df,#314d7b);background:-o-linear-gradient(#6a91df,#314d7b);display:inline-block;margin:0;border:1px solid #335080;white-space:nowrap;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;-ms-box-shadow:0 1px 0 rgba(0,0,0,0.4);-moz-box-shadow:0 1px 0 rgba(0,0,0,0.4);-webkit-box-shadow:0 1px 0 rgba(0,0,0,0.4);box-shadow:0 1px 0 rgba(0,0,0,0.4)}.no-cssgradients .gradient-button{background:#314d7b url(../images/icons/bg-gradient-dropdown.png) repeat-x 0 0}a .no-cssgradients .gradient-button:hover,a .no-cssgradients .gradient-button:focus{background-position:0 -26px}.no-cssgradients .gradient-button:active:hover{background-position:0 -32px}.no-cssgradients .gradient-button.disabled{color:#fff;background-position:0 -78px;cursor:default!important}.gradient-button:hover,.gradient-button:focus{background:linear-gradient(#80a1e4,#50688f);background:-webkit-gradient(linear,left top,left bottom,from(#80a1e4),to(#50688f));background:-webkit-linear-gradient(#80a1e4,#50688f);background:-moz-linear-gradient(#80a1e4,#50688f)}.gradient-button:active{background:linear-gradient(#5a7bbe,#2a4269);background:-webkit-gradient(linear,left top,left bottom,from(#5a7bbe),to(#2a4269));background:-webkit-linear-gradient(#5a7bbe,#2a4269);background:-moz-linear-gradient(#5a7bbe,#2a4269)}.gradient-button.disabled{color:#fff;opacity:.3;-moz-opacity:.3;-khtml-opacity:.3;background:linear-gradient(#96b1e9,#577ebc);background:-webkit-gradient(linear,left top,left bottom,from(#96b1e9),to(#577ebc));background:-webkit-linear-gradient(#96b1e9,#577ebc);background:-moz-linear-gradient(#96b1e9,#577ebc);cursor:default!important}.ui-button.disabled{opacity:.8;-moz-opacity:.8;-khtml-opacity:.8}.detail-page .helpdoc-element{margin-top:25px;width:830px}.detail-page .helpdoc-command{margin-top:10px}.detail-page .helpdoc-block{margin-top:10px;width:830px}.detail-page #helpdoc-element-screenshot{width:900px}.detail-page #helpdoc-tag{width:830px}.detail-page #helpdoc-tag a:link,.detail-page #helpdoc-tag a:hover,.detail-page #helpdoc-tag a:visited,.detail-page #helpdoc-tag a:active{float:left;font:12px arial,sans-serif;color:#4675a8;height:16px;padding:0 3px}.detail-page #helpdoc-tag a.helpdoc-breadcrumb{border-right:1px solid black}.detail-page .helpdoc-element a:link,.detail-page .helpdoc-element a:hover,.detail-page .helpdoc-element a:visited,.detail-page .helpdoc-element a:active{color:#4675a8}.detail-page .helpdoc-text{width:830px;word-wrap:break-word;font:12px arial,sans-serif black}.detail-page #helpdoc-head{margin-top:25px;width:830px}.detail-page #helpdoc-head-icon{float:left;width:80px;height:80px;margin-right:15px}.detail-page #helpdoc-head-description{width:735px;float:right}.detail-page #helpdoc-product-title{float:left}.detail-page #helpdoc-product-os{float:right;width:235px;text-align:right;overflow:hidden;font:12px arial,sans-serif black}.detail-page #helpdoc-head hr{margin-top:5px;margin-bottom:2px}.detail-page #helpdoc-head .seller{overflow:hidden;width:735px;font:12px arial,sans-serif #666}.detail-page #helpdoc-head .description{width:735px;margin-top:10px;height:32px;overflow:hidden;word-wrap:break-word}.detail-page a.helpdoc{color:#1a52ad}.detail-page #helpdoc-head .description p{width:735px;margin:0;overflow:hidden}.detail-page #helpdoc-tag{margin-top:10px}.detail-page .helpdoc-element-hidden{display:none}.detail-page .helpdoc-screenshot{float:left;width:215px;height:173px}.detail-page .helpdoc-img-container{width:180px;height:140px;text-align:center;border:1px solid #ccc}.detail-page .helpdoc-img-container:hover{border:1px solid gray}.detail-page .helpdoc-screenshot-img{max-height:130px;max-width:170px}.helpdoc-img-container .helper{display:inline-block;height:100%;vertical-align:middle}.detail-page .helpdoc-screenshot-label{text-align:center;text-overflow:ellipsis;width:180px;height:15px;float:left;overflow:hidden;margin-top:2px;font:12px arial,sans-serif black}.detail-page .helpdoc-table th{background-color:#f2f2f2}.detail-page .helpdoc-table td,.detail-page .helpdoc-table th{border:1px #b3b3b3 solid}.detail-page .helpdoc-version{margin-bottom:420px}.detail-page .helpdoc-table th{height:35px;text-align:left;padding-left:10px}.detail-page #helpdoc-table-command td{height:100px}.detail-page #helpdoc-table-version td{height:70px}.detail-page .helpdoc-table td img{max-width:80px;max-height:80px;margin:10px}.detail-page .helpdoc-table td p{margin-left:10px}.detail-page #helpdoc-head h1{font:bold 18px arial,sans-serif black;width:500px;overflow:hidden}.detail-page .helpdoc-element h1{font:bold 16px arial,sans-serif black;margin-bottom:5px}.detail-page #right-wrapper{color:#4d4d4d}.helpdoc-page #content{width:830px;margin:0 auto 100px auto;float:none;display:block}.detail-main .drawer{margin:0}.detail-main .subscriber-drawer{float:left}.no-result .purchase-panel{display:block}.no-result .purchase-result{display:none}.result-success .purchase-result-success{display:block}.result-success .purchase-result-not-success{display:none}.result-not-success .purchase-result-success{display:none}.result-not-success .purchase-result-not-success{display:block}.purchase-result-not-success-text a{color:red;text-decoration:underline}.multi-purchase-input-error{background:darksalmon!important}.purchase-panel{margin-top:5px}.purchase-panel>.purchase-action{margin-top:5px}.side-panel>span{font-size:14px}.purchase-panel #multi-purchase-btn{width:100%}.price-qty-total>.purchase-subtotal{font-weight:bold;font-size:14px}.purchase-action>.ui-button{width:100px;height:26px;border-radius:3px;font-size:14px;line-height:25px}.qty-purchased-limit>.off-button{background:url(../images/buttons/close_13.png) no-repeat 0 0;width:13px;height:13px;float:right;cursor:pointer}.qty-to-purchase{margin-top:10px}.qty-to-purchase-title{float:left;margin-right:5px;line-height:24px}.price-qty-total .stepper-input{float:left}.purchase-result-success-text{color:green}#multi-purchase-input{max-width:45px;padding:2px;text-align:center;margin-bottom:15px}.purchase-result-not-success-text{color:red}.purchase-result-info{margin:12px 0}.purchase-result-actions a{color:#1a52ad;cursor:pointer}.purchase-result-actions a:hover{color:#3d87ff}.purchase-result{margin-top:5px}.dealer-code{margin-top:10px}.dealer-code-title{float:left;margin-right:24px;line-height:24px}#dealer-code-input{max-width:45px;padding:2px;margin-bottom:4px}.dealer-code .explanation{display:inline-block;font-size:11px;color:#969696}.detail-page .dropdown.dropdown-wishlist{width:100%;margin-top:8px;border:0;box-shadow:none}.purchase-panel>.purchase-action{width:100%;border:0}#purchase>.dropdown-wishlist .dropdown-toggle{border:1px solid #29abe2;color:#29abe2;background:#fff;margin-top:0}.detail-page .purchase-container .dropdown-toggle .caret{border-top:4px solid #29abe2;position:relative;left:30%}.detail-page .purchase-container .dropdown-wishlist .dropdown-menu{border:1px solid #29abe2;color:#29abe2;background:#fff;text-align:center;height:inherit;margin-top:28px;color:#29abe2;border-top:0}.dropdown-wishlist .dropdown-menu>li>a:hover,.dropdown-menu>li>a:focus,.dropdown-submenu:hover>a,.dropdown-submenu:focus>a{background:0}.detail-page .purchase-container .dropdown-wishlist .divider{border-bottom:1px solid #29abe2;background-color:#fff;padding:0}.detail-page .purchase-container .dropdown-wishlist .dropdown-menu a{color:#29abe2}.side-panel .modal-header{border:0}.side-panel .modal-header h3{background:0;color:#29abe2;border:0;font-weight:700}.side-panel .modal-body .img-wrapper{padding-right:10px}.side-panel .modal-body input{width:97%;border:1px solid #29abe2}.side-panel .modal-footer{background:0;border:0}.side-panel .modal-footer .text-info{width:48%;background:0;border:1px solid #29abe2;color:#29abe2}.side-panel .modal-footer .btn-primary{width:49%;background:#29abe2}.side-panel #purchase #wishlistsmodel .price-str{font-size:20px;margin-top:14px}.pagination-content{display:inline-flex;display:-ms-flexbox;padding:0;border:1px solid #b3b3b3;border-radius:7px;background:white;height:24px}.pagination-content li.beginning-dots,.pagination-content li.final-dots{float:left;width:18px;line-height:20px;padding:0 6px;margin:0;text-align:center}.pagination-content li.beginning-dots:hover,.pagination-content li.final-dots:hover{background:0}.pagination-content li.pag,.pagination-content li.prev,.pagination-content li.next{float:left;width:22px;height:22px;line-height:20px;padding:2px 0 0 0;text-align:center;cursor:pointer}.pagination-content li.first{border-top-left-radius:7px;border-bottom-left-radius:7px}.pagination-content li.last{border-top-right-radius:7px;border-bottom-right-radius:7px}.pagination-content li.leftborder-pageitem{border-left:1px solid #b3b3b3}.pagination-content li.pag:hover,.pagination-content li.prev:hover,.pagination-content li.next:hover{background:#DDD;border-color:#999}.pagination-content li.current a{color:#29abe2}.pagination-content li a{color:#808080;display:block}.page_input_container{margin:4px 0 0 20px}.page_input_label{margin:3px 0 0 0;float:left}.page_input_textbox{float:left;height:16px;width:26px;border:1px solid #cecece;margin:0 4px 0 4px;padding:1px;text-align:center;height:10px!important}.page_input_go{float:left;border:1px solid #cecece;padding:2px 5px 1px 5px;height:15px;background:#f7f7f7}.page_input_go span,.page_input_go span:visited,.page_input_go span:hover{color:#4d4d4d}.quick-search-wrapper{margin-bottom:5px;height:22px}.quick-search-wrapper h3{float:left;margin:0 20px 0 0;height:22px;line-height:22px}.quick-search-wrapper .quick-search-form-filter{width:235px;height:22px;float:left}#search-results-extra hr{clear:both;margin:10px 0}.pagination-spinner{float:left;margin:7px;height:16px;width:16px;line-height:16px;display:none}.my-downloads-page#main{margin-bottom:50px}.my-downloads-page #content{width:1000px;display:block;float:none;margin:0 auto}.my-downloads-page .page-title{margin-bottom:30px;margin-left:-132px}.my-downloads-page .description-container{width:200px;word-wrap:break-word;word-break:normal}.my-downloads-page .cancel-subscription{text-align:right}#my-downloads table{margin:10px 0 20px 0;text-align:left;font-size:11px}#my-downloads table td,#my-downloads table thead th{border:0 none;padding:5px;vertical-align:middle}#my-downloads table td{border-left:1px solid #e6e6e6}#my-downloads table td:first-child{border:0}#my-downloads table tr{border-bottom:1px solid #e6e6e6}#my-downloads table td.info-cell{width:170px;min-width:147px}#my-downloads table td.description-cell{width:200px}#my-downloads table td.company-cell,#my-downloads table td.store-cell{width:90px}#my-downloads table td.update-cell{width:80px}#my-downloads table td.purchase-qty-cell{width:100px}#my-downloads table td.info-cell img{width:40px;height:40px;float:left;margin:3px 6px 3px 2px}#my-downloads table td.info-cell .product-info{float:left;width:95px;margin-top:4px}#my-downloads table td.info-cell .product-info a,#my-downloads table td.info-cell .product-info span{display:block;margin-bottom:5px;color:#595959}#my-downloads table td.info-cell .product-info a:focus,#my-downloads table td.info-cell .product-info a:hover{color:#06e}#my-downloads table td.update-cell img{margin:0 2px}#my-downloads table td.update-cell a{color:#1a52ad}#my-downloads table td.update-cell a:hover{color:#3d87ff}#my-downloads table td.help-cell img{margin:0 6px}#my-downloads table caption,#my-downloads h2{font:20px Arial;color:#4d4d4d;margin-bottom:2px;text-align:left}#my-downloads h2{margin-top:10px}#my-downloads h3{font-size:16px;font-weight:normal;color:#333}#my-downloads table thead tr{background:#999}#my-downloads table thead tr th{color:#FFF;text-align:left;font-size:12px}#my-downloads table tbody{color:#595959}#my-downloads table tbody .fullDescription-container p{margin:0 0 5px}#my-downloads table .odd-row{background:#f2f2f2}#my-downloads table .even-row{background:#FFF}.purchase-qty-cell,.purchase-date-cell{text-align:center}.purchase-date-div{width:120px}.purchase-date-span{float:left}.open .purchase-date-more{display:block}.purchase-date-more{display:none}.open .cell-more{display:none}.cell-more{cursor:pointer;display:inline}.open .cell-less{display:inline}.cell-less{cursor:pointer;display:none}td.description-cell .more_less{cursor:pointer;font-weight:bold;text-decoration:underline}.tooltip{display:none;position:absolute;min-height:10px;padding:7px 8px;z-index:84001;color:#666;border:1px solid #808080;border-color:rgba(0,0,0,.5);background-color:#f7f7f7;background:-webkit-gradient(linear,left top,left bottom,from(rgba(255,255,255,0.95)),to(rgba(230,230,230,0.95)));background:-webkit-linear-gradient(rgba(255,255,255,0.95),rgba(230,230,230,0.95));background:-moz-linear-gradient(rgba(255,255,255,0.95),rgba(230,230,230,0.95));-moz-border-radius:2px;-webkit-border-radius:2px;border-radius:2px;-moz-box-shadow:0 1px 2px rgba(0,0,0,.3);-webkit-box-shadow:0 1px 2px rgba(0,0,0,.3);box-shadow:0 1px 2px rgba(0,0,0,.3);-moz-background-clip:padding;-webkit-background-clip:padding;background-clip:padding-box;max-width:200px}.tooltip .pointer{position:absolute;top:-6px;left:5px;width:100%;height:6px;background:url(../images/icons/tooltip_pointer.png) no-repeat left top}.tooltip.right .pointer{left:auto;right:5px;background-position:right top}.tooltip.visible{display:block}.has_tooltip{cursor:help}#my-downloads table thead tr th.sortable{cursor:pointer}#my-downloads table thead tr th:hover,#my-downloads table thead tr th:focus{background:#575757}#my-downloads table thead tr th:active,#my-downloads table thead tr th.current{background:#3d3d3d}#my-downloads .order-arrow{float:right;margin:5px 3px 5px 5px;background:url(../images/icons/sort_arrow.png) no-repeat;height:4px;width:7px;display:none}#my-downloads .up{background-position:0 -4px}#my-downloads .down{background-position:0 0}#my-downloads table thead tr th.current a.order-arrow{display:block}#my-downloads table thead tr .th-titles{float:left;margin-right:2px}.my-uploads-page{padding-top:20px;width:960px}.my-uploads-page label{cursor:default}.my-uploads-page #content{width:960px;margin-left:122px}#my-published table input{cursor:pointer;background-color:transparent;text-decoration:none;border:0;color:blue}.detail-page-for-publisher#main{width:1260px}.detail-page-for-publisher#main>div{display:inline-block;vertical-align:top;width:18%}.detail-page-for-publisher#main .p-detail-tabs{width:1000px;margin-left:20px}.detail-page-for-publisher#main .p-detail-notification{width:98%}.developer-description #content{width:1280px}.developer-description #content div p{text-align:justify;text-justify:inter-word}.developer-description #content .headline{margin:10px 0;color:#29abe2;font-size:18px;font-weight:normal}.developer-description #content .legal-content{border:1px solid #ccc;padding:15px 30px;overflow-y:auto;height:453px;background:white;margin-bottom:20px}.developer-description #content .legal-content p:first-child{margin-top:0}.developer-description #content .sell-notice-level-1{font-size:16px;font-weight:bold;margin:10px 0;color:#4d4d4d}.developer-description #content .sell-notice-level-2{font-size:16px;font-weight:normal;color:#333}.developer-description #content .sell-notice-level-3{font-size:12px;color:#4d4d4d}.developer-description #content .sell-notice-note{font-style:italic;color:#333;font-size:12px}.developer-description #content ul.list-items{padding-left:20px;color:#4d4d4d}.developer-description #content ul.list-items li{margin:0 0 5px 15px;list-style-type:disc}.developer-description #content .actions{margin-bottom:24px;padding:30px 0;height:33px}.developer-description #content .publish-link{width:150px;padding:5px 0;border:0;font-size:14px;cursor:pointer;text-align:center;color:white}.developer-description #content .back,.developer-description #content .signin_link{width:150px;border:0;padding:5px 0;font-size:14px;cursor:pointer;height:25px;text-align:center;color:white}.developer-description #content .publish-link,.developer-description #content .signin_link{float:right}.grey-button{background:linear-gradient(#666,#2e2e2e);background:-webkit-gradient(linear,left top,left bottom,from(#666),to(#2e2e2e));background:-webkit-linear-gradient(#666,#2e2e2e);background:-moz-linear-gradient(#666,#2e2e2e);background:-o-linear-gradient(#666,#2e2e2e);border:1px solid #303030}.no-cssgradients .grey-button{background:#2e2e2e url(../images/icons/bg-gradient-button-gray.png) repeat-x 0 0}.no-cssgradients .grey-button:hover,.no-cssgradients .grey-button:focus{background-position:0 -32px}.no-cssgradients .grey-button:active{background-position:0 -64px}.no-cssgradients .grey-button:disabled{background-position:0 -78px;cursor:default!important}.no-cssgradients .grey-button[disabled],.no-cssgradients .grey-button[disabled]:hover,.no-cssgradients .grey-button[disabled]:active{background-position:0 -96px;cursor:default!important}.grey-button:hover,.grey-button:focus{background:linear-gradient(#808080,#474747);background:-webkit-gradient(linear,left top,left bottom,from(#808080),to(#474747));background:-webkit-linear-gradient(#808080,#474747);background:-moz-linear-gradient(#808080,#474747)}.grey-button:active{background:linear-gradient(#595959,#1f1f1f);background:-webkit-gradient(linear,left top,left bottom,from(#595959),to(#1f1f1f));background:-webkit-linear-gradient(#595959,#1f1f1f);background:-moz-linear-gradient(#595959,#1f1f1f)}.grey-button:disabled{background:linear-gradient(#a6a6a6,#6e6e6e);background:-webkit-gradient(linear,left top,left bottom,from(#a6a6a6),to(#6e6e6e));background:-webkit-linear-gradient(#a6a6a6,#6e6e6e);background:-moz-linear-gradient(#a6a6a6,#6e6e6e);cursor:default!important}.developer-terms-and-conditions #content{width:1280px}.developer-terms-and-conditions #content .headline{margin:10px 0;color:#4d4d4d;font-size:16pt}.developer-terms-and-conditions #content .legal-content{border:1px solid #bfbfbf;background:white;padding:10px;overflow-y:auto;height:553px}.developer-terms-and-conditions #content .legal-content .legal-left{width:49%;float:left;margin-right:10px;padding-right:10px;border-right:solid 1px}.developer-terms-and-conditions #content .legal-content .legal-right{float:left;width:49%}.developer-terms-and-conditions #content .actions{margin-bottom:30px;padding-top:20px}.developer-terms-and-conditions #content p{color:#4d4d4d}.developer-terms-and-conditions #content .legal-content p:first-child{margin-top:0}.publisher-agreement-item-level-1{margin-left:12px;text-indent:-12px}.publisher-agreement-items-level-2-container p{margin-left:22px;text-indent:-22px}.publisher-agreement-items-level-3-container p{margin-left:52px;text-indent:-42px}.developer-terms-and-conditions #content .exhibit-a{margin-top:50px;text-decoration:underline}.eula-term-1-container p{margin-left:15px;padding-left:15px;text-indent:-15px}.eula-term-2-container p{margin-left:30px}.eula-term-3-container p{margin-left:45px}.developer-terms-and-conditions #content .agree-continue{float:right}.developer-terms-and-conditions #content .legal-form{height:25px}.developer-terms-and-conditions #content .legal-form .not-agree{margin-left:10px}.developer-terms-and-conditions #content .continue{padding:0 20px;font-size:14px;cursor:pointer;text-align:center;line-height:25px;color:white;float:left;background:#29abe2;border:1px #29abe2 solid;width:150px;height:25px}.developer-terms-and-conditions #content .cancel{padding:0 20px;font-size:14px;cursor:pointer;text-align:center;line-height:25px;color:#29abe2;float:left;background:white;border:1px #29abe2 solid;width:115px;height:25px}.developer-terms-and-conditions #content .legal-form .fields{margin-top:5px;line-height:25px;float:left;color:#4d4d4d}.developer-terms-and-conditions #legal-agree{float:left}.developer-terms-and-conditions #content .legal-form .label{display:block;float:left;margin-left:8px;background-color:transparent;color:red;font-weight:normal}.developer-terms-and-conditions #content .legal-form .separator{height:25px;width:1px;border-left:1px solid #a6a6a6;margin:0 8px;float:left}.wizard-navigation ul li span.status{position:absolute;top:24px;right:0;z-index:105;padding:0!important}.wizard-navigation ul li span.status.ok{background:transparent url(../images/icons/wizard_nav_ok.png) no-repeat left center;width:13px;height:16px}.developer-submit-product #content{color:#29abe2;width:1080px;padding-bottom:30px;padding-left:80px}.developer-submit-product label{cursor:default;margin:0;display:inline-block}.developer-submit-product #paymentgateway-settings label{display:block}.developer-submit-product .templates{display:none}.developer-submit-product #content h3.wizard-init{text-align:center;margin-top:190px}.developer-submit-product #content h2{color:#29abe2;margin:15px 0 5px;font-size:18px;float:left;font-weight:normal}.developer-submit-product #content .wizard-navigation{overflow:hidden;width:1080px;position:relative}.developer-submit-product #content .wizard-navigation ul{margin:20px 0 0 0;padding:0;height:27px;float:right;list-style:none}.developer-submit-product #content .wizard-navigation ul li{margin:0;padding:0;list-style:none;cursor:default;visibility:collapse;width:0;float:right}.developer-submit-product .topEmphasis{font-family:Arial;font-size:15px;color:#29abe2;font-weight:bold;margin-bottom:10px}.developer-submit-product #promptFlash,.developer-submit-product #promptFlash a,.developer-submit-product #promptFlash a:hover,.developer-submit-product #promptFlash a:active,.developer-submit-product #promptFlash a:visited{font-family:Arial;font-size:11px;color:#4675a8;font-weight:bold;margin-bottom:5px}.developer-submit-product #content .wizard-navigation ul li span{display:block;padding:5px 20px 5px 0;line-height:17px;font-size:14px;font-weight:normal}.developer-submit-product #content .wizard-navigation ul li.active{visibility:visible;width:auto}.developer-submit-product #content .wizard-side{border-top:1px solid #bfbfbf;border-bottom:1px solid #bfbfbf;border-left:1px solid #bfbfbf;width:152px;background-color:#4d4d4c;height:508px;float:left;color:white}.developer-submit-product #content .wizard-side li.add{display:none}.developer-submit-product #content .wizard-side p{padding:0 8px;margin:0;color:#b2b2b2;font-size:10px}.developer-submit-product #content .wizard-side h4{color:white;padding-left:12px;border-bottom:1px solid #333;margin:0;font-weight:bold;font-size:12px;line-height:27px}.developer-submit-product #content .wizard-side h5{color:white;padding:2px 0 2px 22px;margin:0;font-weight:normal;font-size:10px;line-height:13px}.developer-submit-product #content .wizard-side h5.add-language{background:transparent url(../images/icons/add_remove_language.png) no-repeat -400px center}.developer-submit-product #content .wizard-side h5.remove-language{background:transparent url(../images/icons/add_remove_language.png) no-repeat 0 center}.developer-submit-product #content .wizard-side ul{margin:0;padding:0}.developer-submit-product #content .wizard-side ul li{color:white;margin:0;padding:8px}.developer-submit-product #content .wizard-side ul li.selected{color:#fff;font-size:12px;background:#496b9b url(../images/icons/selected_language.png) no-repeat right center;border-bottom:1px solid #333}.developer-submit-product #content .wizard-side ul li.remove,.developer-submit-product #content .wizard-side ul li.template{display:none}.developer-submit-product #content .wizard-side .wizard-progress{height:20px;line-height:20px}.developer-submit-product #content .wizard-side .wizard-progress .progress-bar{width:75px;height:6px;padding:2px;background-color:#b7b7b7;float:left;margin-top:8px;-moz-border-radius:4px;-webkit-border-radius:4px;border-radius:4px}.developer-submit-product #content .wizard-side .wizard-progress .progress-bar .bar{display:block;height:6px;width:0;background-color:#666;-moz-border-radius:4px;-webkit-border-radius:4px;border-radius:4px}.developer-submit-product #VersionListDiv{float:left;padding-bottom:5px;width:100%}.developer-submit-product #content .wizard-side .wizard-progress .progress-bar .bar.red{background-image:-webkit-linear-gradient(bottom,#c0262c 0,#ec1b23 50%,#c0262c 100%);background-image:-moz-linear-gradient(bottom,#c0262c 0,#ec1b23 50%,#c0262c 100%);background-image:-ms-linear-gradient(bottom,#c0262c 0,#ec1b23 50%,#c0262c 100%);background-image:linear-gradient(bottom,#c0262c 0,#ec1b23 50%,#c0262c 100%)}.developer-submit-product #content .wizard-side .wizard-progress .progress-bar .bar.orange{background-image:-webkit-linear-gradient(bottom,#f6721d 0,#f3a22b 50%,#f6721d 100%);background-image:-moz-linear-gradient(bottom,#f6721d 0,#f3a22b 50%,#f6721d 100%);background-image:-ms-linear-gradient(bottom,#f6721d 0,#f3a22b 50%,#f6721d 100%);background-image:linear-gradient(bottom,#f6721d 0,#f3a22b 50%,#f6721d 100%)}.developer-submit-product #content .wizard-side .wizard-progress .progress-bar .bar.green{background-image:-webkit-linear-gradient(bottom,#38b448 0,#8ac53e 50%,#38b448 100%);background-image:-moz-linear-gradient(bottom,#38b448 0,#8ac53e 50%,#38b448 100%);background-image:-ms-linear-gradient(bottom,#38b448 0,#8ac53e 50%,#38b448 100%);background-image:linear-gradient(bottom,#38b448 0,#8ac53e 50%,#38b448 100%)}.developer-submit-product #content .wizard-side .wizard-progress .progress-percentage{float:left;padding:3px 0 0 7px}.developer-submit-product #content .wizard-side .wizard-progress .progress-help{background:url(../images/icons/help.png) no-repeat 0 0;width:16px;height:16px;float:left;margin:5px 0 0 9px}.developer-submit-product #content .wizard-content{border:1px solid #ccc;overflow-y:auto;overflow-x:hidden;width:1040px;padding:0 20px 10px 20px;float:left;background-color:#fff;position:relative}.developer-submit-product .wizard-content input[type="text"],.developer-submit-product .wizard-content textarea{-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.developer-submit-product #content .wizard-actions{margin-top:15px;float:left;width:1080px}.developer-submit-product #content .wizard-actions input[type="button"],.developer-submit-product #content .wizard-actions a{width:auto;padding:0 20px;border:0;font-size:14px;cursor:pointer;height:25px;text-align:center;line-height:25px;color:white}.developer-submit-product #content .wizard-actions .cancel{float:left;color:#29abe2;background:white;border:1px #29abe2 solid;width:150px;height:25px}.developer-submit-product #content .wizard-actions .back{float:left;display:none}.developer-submit-product #content .wizard-actions .save{float:right;width:150px;height:25px}.developer-submit-product #content .wizard-actions .continue{float:right;margin-left:8px;width:150px;height:25px}.developer-submit-product #content .wizard-actions .backtosummary,.developer-submit-product #content .wizard-actions .submit,.developer-submit-product #content .wizard-actions .preview{float:right;display:none;margin-left:8px}.developer-submit-product #content .finish-link{width:auto;padding:0 20px;border:0;font-size:14px;cursor:pointer;height:25px;text-align:center;line-height:25px;color:white}.remindErrorDiv{margin-bottom:10px}.remindErrorDiv .errorRemind a{font-size:13px;font-weight:bold;color:red;padding-bottom:5px;text-decoration:underline}#publish-step2-products .compatibility-des-sep{margin:0}#publish-step2-products .compatibility-des{width:790px}#publish-step2-products .families-products td:first-child{width:200px}#publish-step2-products table.version-grid{width:100%}.fancy-layer-image{content:url(../images/icons/ajax-loader400.gif);width:30px}#fancy-layer{height:100px}#fancy-layer.overlay_window{background:white}.wizard-tab{font-size:12px;position:relative}.no_float{float:none!important}.wizard-tab h4{float:left;margin-bottom:5px}#wizard-help-documentation h4{float:left}#wizard-help-documentation>span.explanation{margin:0}.wizard-tab h4+span.explanation{margin-bottom:5px}.wizard-tab #contact-info+span.explanation{display:inline-block}.wizard-tab span.required{display:inline;color:Red;font-weight:bold}.wizard-tab .explanation{display:inline-block;color:#666;font-weight:normal;font-size:11px}.command_tools .explanation{display:block;color:#666;font-weight:normal;font-size:11px}.command_tools .commandName{width:400px}.command_tools .sub-title{display:block}.command_tools textarea{width:400px}.thumbnail-preview .browse-button{float:left;margin-right:5px;font-size:12px;height:25px;width:150px}.file-info .explanation{display:inline-block;color:#666;font-weight:normal;font-size:11px}#privacyDetail{font-size:15px}#privacyDetail ul{padding:0;margin-left:4px}#privacyDetail li{margin:8px;list-style:none}#publish-step2-products .explanation,#publish-step2-categories .explanation{float:left;display:inline;width:790px}.wizard-tab span.error,#contact-info span.error{display:none;margin:2px 27px 2px 15px;color:#c80000;font-size:11px;background:transparent url(../images/icons/wizard_error.png) no-repeat left center;padding-left:14px}#contact-info span.error{float:none;margin-right:2px;margin-top:4px}.wizard-tab .text span.error{margin:2px 0 2px 0;float:none}#contact-info span.error.visible,.wizard-tab span.error.visible{display:inline}.wizard-tab .separator{display:block;height:10px}#publish-step2-products .separator,#publish-step2-categories .separator{display:inline-block;width:790px;height:20px}.wizard-tab textarea,.wizard-tab input[type="text"]{width:100%;margin-bottom:1px;border:1px solid #bbb;padding:2px;display:block}.wizard-tab .command_tools textarea,.wizard-tab .command_tools input[type="text"]{width:772px}.wizard-tab textarea.error,.wizard-tab input[type="text"].error{border:1px solid #c80000}.wizard-tab textarea{resize:none}#wizard-help-documentation textarea{display:inline}.wizard-tab input[type="radio"]{display:inline}.wizard-tab input[type="checkbox"]{display:inline;margin-right:10px}.wizard-tab #prices label{margin:10px 0;cursor:pointer}.wizard-tab h5{font-weight:normal;margin:0}#app-file>*:not(label){margin-left:0;width:auto}#app-file>textarea{width:97%;margin-top:5px}#app-file>label{font-size:12px}#app-file>label>input{position:relative;top:1px;margin-right:4px}.wizard-tab h4+.file-uploader{margin-top:10px}.wizard-tab .file-uploader .file{width:auto;padding:4px 4px 4px 0;background-color:white;min-height:25px;margin:5px 0}.wizard-tab .file-uploader .file .plupload input{cursor:pointer}.wizard-tab .file-uploader .file .plupload input[disabled]{display:none}.wizard-tab .file-uploader .file .file-info .thumbnail{float:left}.wizard-tab .file-uploader .file .file-info .file-name,.wizard-tab .file-uploader .file .file-info .file-size{float:left;padding:6px 10px 4px}.wizard-tab .file-uploader .file[data-uploader-state="uploading"] .file-info .file-name{max-width:135px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.wizard-tab #app-screenshot.file-uploader .file[data-uploader-state="uploading"],.wizard-tab #app-screenshot.file-uploader .file[data-uploader-state="queuedOnHold"],.wizard-tab #app-screenshot.file-uploader .file[data-uploader-state="uploadedOnHold"],.wizard-tab #app-screenshot.file-uploader .file[data-uploader-state="queued"]{min-height:75px}.wizard-tab .file-uploader .file .file-info .upload-progress{width:280px;height:20px;line-height:20px;position:absolute;right:115px}.wizard-tab .file-uploader .file .file-info .progress-bar{width:230px;height:6px;padding:2px;background-color:white;float:left;margin-top:8px;-moz-border-radius:4px;-webkit-border-radius:4px;border-radius:4px}.wizard-tab .file-uploader .file .file-info .progress-bar .bar{display:block;height:6px;width:0;min-width:1%;background-color:white;background-image:-webkit-linear-gradient(bottom,#29abe2 0,#6ac6ed 50%,#29abe2 100%);background-image:-moz-linear-gradient(bottom,#29abe2 0,#6ac6ed 50%,#29abe2 100%);background-image:-ms-linear-gradient(bottom,#29abe2 0,#6ac6ed 50%,#29abe2 100%);background-image:linear-gradient(bottom,#29abe2 0,#6ac6ed 50%,#29abe2 100%);-moz-border-radius:4px;-webkit-border-radius:4px;border-radius:4px}.wizard-tab .file-uploader .file .file-info .progress-percentage{float:left;padding:3px 0 0 10px}.wizard-tab .upload-button,.wizard-tab .cancel-button,.wizard-tab .remove-button{float:right;width:100px}.wizard-tab .browse-button{float:left;margin-right:5px;font-size:12px;height:25px;width:150px}.wizard-tab .uploader-loading .browse-button{visibility:hidden}#app-screenshot .thumbnail{width:205px;min-height:120px;display:none}.screenshot_tools{position:absolute;right:5px;top:40px;left:219px;bottom:5px}.screenshot_tools .description_container{position:absolute;left:0;right:0}.screenshot_tools input[type="checkbox"]{float:left;margin-right:5px;padding:0}.screenshot_tools .description_container .description{width:519px;margin:0}#wizard-help-documentation .cert-span{margin-top:3px;display:block;float:none;margin-left:0}#wizard-help-documentation .cert-span .cert-explanation{margin-left:23px}#wizard-help-documentation .cert-image{margin-bottom:5px}#wizard-help-documentation h4+span.cert-explanation{margin-top:0;margin-bottom:8px}#wizard-help-documentation .cert-explanation a,#wizard-help-documentation .cert-explanation a:link,#wizard-help-documentation .cert-explanation a:hover,#wizard-help-documentation .cert-explanation a:active,#wizard-help-documentation .cert-explanation a:visited{color:#29abe2}#wizard-file-uploading .errors,wizard-help-documentation .errors{position:relative;float:right}#publish-step2-companyandprice #prices,#publish-step2-companyandprice #applogintypes{display:block;margin:5px 0 5px}#publish-step2-companyandprice input.priceinput{width:150px;display:inline}#wizard-app-information #app-versions{width:100%}#wizard-app-information #app-versions .version .remove,#wizard-help-documentation #app-commands .command .remove-command{background:url(../images/buttons/close_24.png) no-repeat 0 0;width:24px;height:24px;top:-7px;position:absolute;right:-12px;cursor:pointer}#version-changed-input .mceEditor{margin-bottom:10px}#wizard-help-documentation #app-commands .command .remove-command.with_spinner{background:0}.file-info{position:relative}.file-info .remove-button+.with_spinner{display:inline-block;right:5px;position:absolute;top:5px}#wizard-app-information #app-versions .version.template,#wizard-help-documentation #app-commands .template{display:none;position:relative}#wizard-app-information #app-versions .version{margin-top:10px}#wizard-app-information #app-versions .version .number input{width:120px;margin-top:5px}#wizard-app-information #app-versions .version .description textarea{width:560px;margin-top:5px}#wizard-app-information #app-versions .version .number{width:145px;float:left}#wizard-app-information #app-versions .description{float:left;width:100%}#wizard-app-information .new-version{width:auto;margin-top:6px;cursor:pointer;text-align:center}#wizard-app-information #app-versions .version .remove{background:url(../images/buttons/close_24.png) no-repeat 0 0;width:24px;height:24px;top:-7px;position:absolute;right:-12px;cursor:pointer}#wizard-app-information #app-versions .version.template{display:none;position:relative}#publish-step2-companyandprice #payment-settings{display:none}#publish-step2-companyandprice{margin-bottom:14px}#wizard-file-uploading .add-screenshot-container{margin-top:6px}#wizard-file-uploading .add-screenshot-container>*{vertical-align:middle;margin-bottom:10px}.wizard-app-compatibility input[type="checkbox"]{margin:0 5px 0 5px;position:relative;top:2px}table.expandable-grid tr.title{background-color:#e5e5e5;border-bottom:1px solid #797979}table.expandable-grid tr.title td{padding-left:10px;font-size:13px;font-weight:bold;height:30px;line-height:30px}table.expandable-grid tr.expansor{border-bottom:0 solid #797979}table.expandable-grid tr.expansor.expanded{border-bottom:0}table.expandable-grid tr.expandable{border-bottom:0 solid #797979}table.expandable-grid{margin-top:5px;float:left;width:100%;border:0 solid #797979;border-collapse:collapse}table.expandable-grid tr{width:100%;border-collapse:collapse}table.version-grid{width:100%;margin:5px 0 10px 0}table.version-grid tr{border:1px #29abe2 solid}table.version-grid thead .store-version{width:80px}table.expandable-grid tr.expansor td{height:20px;cursor:pointer}table.expandable-grid tr.expansor td span{font-size:13px}table.expandable-grid tr.expansor.expanded td span div.arrow{background:url(../images/icons/expand-collapse-sprite.png) no-repeat top right}table.expandable-grid tr.expansor td span div.arrow{background:url(../images/icons/expand-collapse-sprite.png) no-repeat top left;margin:0 5px 0 5px;width:13px;height:13px;display:inline-block}#wizard-app-categories #app-families,#wizard-app-categories #store-list{margin:8px 0 8px}#wizard-app-categories #store-list{width:755px}#wizard-app-categories #store-list .store-title{width:200px}#wizard-app-categories .families-products .store-title.disabled{color:#b1b1b1}#publish-step2-categories .families-products td.label{color:black;background:transparent;text-shadow:none}#publish-step2-categories table.version-grid{margin-top:2px}#wizard-app-categories #store-list .store-version{width:100px}#wizard-app-categories #store-list tbody tr:nth-child(even){background-color:#e8e8e8}#wizard-app-categories #recommend{margin-top:10px;background-color:#e8e8e8;padding:5px}#wizard-app-categories .othercategory-container{display:inline-block;margin-top:20px}#wizard-help-documentation #app-commands{width:100%}#wizard-help-documentation #app-commands .command{margin-top:10px;padding:5px;position:relative}#wizard-help-documentation #app-commands .command h3{margin:0;font-weight:normal}#wizard-help-documentation #app-commands .command .file{width:717px}#wizard-help-documentation #app-commands .command .save-command{right:7px;bottom:7px}#wizard-help-documentation .new-command{width:150px;margin-top:5px;cursor:pointer;height:25px;text-align:center;line-height:25px;font-size:12px;display:block}#wizard-help-documentation .mceEditor{margin-top:5px;display:block}#wizard-app-summary .info{min-height:20px;padding:2px 5px;line-height:20px}#wizard-app-summary .info:nth-child(even){background-color:#e8e8e8}#wizard-app-summary .info .description{float:left;width:210px;font-weight:normal;color:#666}#wizard-app-summary .info>*{display:inline-block;margin-left:10px;color:black}#wizard-app-summary .info .value p{margin:0}#wizard-app-summary .summary-icon{width:80px;height:80px}#wizard-app-summary .summary-screenshot{border:1px #29abe2 solid;width:200px;height:120px}#wizard-app-summary .summary-screenshot img{height:120px}.developer-submit-complete #content{width:940px}.developer-submit-complete #content h1,.developer-submit-complete #content h2{color:#4d4d4d}#footer{border-top:1px solid #c4c4c4;height:38px;line-height:38px;background-color:#f3f3f3;font-size:11px;color:#999}.footer_wrap{margin:0 auto;height:38px;line-height:38px;background:url(../images/icons/adsk_footer_logo.png) no-repeat right center}.footer_wrap .copy{line-height:38px;height:38px;float:left;color:#949494}.copy p{margin:0;padding:0}.footer_wrap .legalese{float:left;list-style-type:none;margin:0;padding:0;height:38px;line-height:38px;padding:0}.footer_wrap .btn-group button{font-size:12px}.footer_wrap .btn-group .dropdown-menu{top:auto;bottom:100%;min-width:80px}.footer_wrap .btn-group .dropdown-menu li{font-size:12px;padding-left:6px}.footer_wrap .btn-group .dropdown-menu li:hover{color:white;background-color:#0081c2}.legalese li{list-style-type:none;margin-left:12px;float:left;cursor:pointer;line-height:38px}.legalese li a{color:#999}.legalese li a:hover,.legalese li:hover{color:#666}.contact_us{font-size:104%;font-weight:bold!important;color:#666}.paynow_button form input[type="submit"]{background:none repeat scroll 0 0 transparent;border:0 none;color:#fff;margin:0;padding:0}#supported_languages{width:400px}#supported_languages ul{padding:0;margin:0}#supported_languages ul li{color:#000;padding-left:25px;line-height:23px;cursor:pointer}.odd{background-color:#fff}.even{background-color:#f2f2f2}#supported_languages ul li:hover{background-color:#dae2ef}#supported_languages ul li.selected{background-color:#8899b4;color:#fff}#accept_terms_section{font-size:12px;width:780px}#accept_terms_section label{display:inline}#accept_terms_section .group_body_container{margin:20px}#accept_terms_section .group_body_container input[type="checkbox"]{margin-right:10px}#accept_terms_section .group_body_container>div{margin-bottom:20px}#accept_terms_section .group_body_container a{color:#039}#accept_terms_section .group_body_container p.legal{font-size:10px;font-style:italic;margin-left:27px}#accept_terms_section .group_body_container .receiveEmail label{display:inline-block;margin-left:23px}#accept_terms_section .group_body_container .receiveEmail input{position:absolute}.input_text_readonly{background-color:#f4f4f4;color:#555}#accept_terms_section .alert{color:red;margin-left:13px}#confirmationPopup button[data-type="Cancel"]{margin-right:6px}#confirmationPopup button{min-width:35px}#wizard-app-categories .families-products td.categorycheck input[type=checkbox]{margin-left:0}#wizard-app-categories .families-products td.label{width:210px}#wizard-app-products .selectAll{font-size:10px}#wizard-app-products .version-grid td label{font-size:12px;white-space:normal;display:inline-block}.faq-page h1{font-size:15pt;margin:15px 0;text-align:center}.faq-page .leftalig-headline{text-align:left}.faq-page h3{font-size:11pt}.faq-page p{margin:0 0 15px}.faq-page ul{margin:0 0 15px;padding:0;list-style:square inside none}.faq-page ul li{list-style:square inside none;margin-top:10px;margin-bottom:3px;margin-left:20px}.faq-page .numbered-ul li{list-style-type:decimal}.faq-page .circled-ul li{list-style-type:disc}.faq-page .empty-circled-ul li{list-style-type:circle}.faq-page ul li img{margin-top:5px}.faq-page .faq_notediv{margin-top:5px;margin-bottom:5px;border-bottom:1px solid #5b9bd5;border-top:1px solid #5b9bd5;color:#5b9bd5;padding:5px}.faq-page .cancel_subscription ol,.faq-page .cancel_subscription ol li{list-style:decimal!important}.faq-page .cancel_subscription ul,.faq-page .cancel_subscription ul li{list-style:disc!important}.faq-page .cancel_subscription ul{padding-left:40px!important}#back-to-top,#back-to-top:visited{margin:7px 0 7px 0;text-align:center;float:left;color:#369}.strikeout-price{text-decoration:line-through;vertical-align:middle;font-size:10px;color:#808080;padding:0;margin-right:15px;display:inline;clear:both}.product-badge-div-placeholder{margin:1px 0 1px 0;height:16px}#detail-info span.subscriptionDes{vertical-align:middle;font-size:12px;float:right}.subscriptionBadge{float:none;position:relative;width:16px;height:16px;margin:0}.big-subscriptionbadge{width:24px;height:24px}.badge-popup-div{position:absolute;display:none;left:-82px;width:180px;font-size:10px;overflow:hidden;z-index:9999;text-align:center}.subscriber-pop-up{left:0;top:10px}.big-badge-popup-offset{left:-78px}.badge-popup-content-div{border-style:solid;border-width:0 1px 1px 1px;border-color:#6d6e70;background-color:white;margin:0;padding:10px}.badge-popup-content-div p{margin:0;padding:0;color:#000}.badge-popup-content-div a{color:blue}.badge-popup-header-div{height:0;margin:0;padding:0}.badge-popup-div img.badge-popup-header-img{float:none;height:10px;width:180px;margin:0}.badge-hover-stub:hover .badge-popup-div{display:block}.subscriber-hover-stub,.badge-hover-stub{position:relative}.product-rating-small-bestseller .star-rating{width:13px;height:12px;cursor:default;display:inline-block;background:url(../images/icons/star_small.png) no-repeat 0 0;overflow:hidden;vertical-align:middle;margin:0 0 4px 2px}.product-rating-small-bestseller .star-on{background-position:0 -12px!important}.product-rating-small-bestseller .star-off{background-position:0 0!important}.ellipsis{width:120px;overflow:hidden;text-overflow:ellipsis;-o-text-overflow:ellipsis;-ms-text-overflow:ellipsis;white-space:nowrap;display:inline-block}#restrict_access_wrapper h2{color:#000;font-size:20px;font-weight:normal}#restrict_access_wrapper h3{font-weight:normal;color:#666;font-size:14px;margin:0 0 15px 0}#restrict_access_wrapper label{font-weight:bold}#restrict_access_wrapper #no_passcode_label li{padding-bottom:20px}#restrict_access_wrapper #no_passcode_controls li{padding-bottom:10px}#restrict_access_wrapper .ui-button{width:70px}#restrict_access_wrapper .text-box{width:200px}#restrict_access_wrapper .multi-line{width:400px;height:100px}#restrict_access_wrapper{margin:10px auto;width:900px;padding:10px}#restrict_access_wrapper #left_panel{float:left;width:80px;margin:10px;padding:10px}#restrict_access_wrapper #right_panel{float:left;width:650px;margin:10px;padding:10px}#restrict_access_wrapper #passcode_label{float:left;width:100px;padding:5px;text-align:right;margin-top:5px}#restrict_access_wrapper #passcode_controls{float:left;width:200px;padding:5px}#restrict_access_wrapper #passcode_submit{position:relative;left:115px;top:5px;clear:both}#restrict_access_wrapper #divider{border-top:1px solid #666;margin:20px 0}#restrict_access_wrapper #no_passcode_label{float:left;width:100px;padding:5px;text-align:right;margin-top:5px}#restrict_access_wrapper #no_passcode_controls{float:left;width:200px;padding:5px}#restrict_access_wrapper #no_passcode_submit{position:relative;left:115px;top:5px;clear:both}#restrict_access_wrapper .validation-summary-errors{position:relative;clear:both;left:115px}#restrict_access_wrapper #passcode_description{margin-bottom:0}#restrict_access_wrapper a:link,#restrict_access_wrapper a:visited,#restrict_access_wrapper a:hover{color:#1a52ad}#HealthStatus table{margin:10px 0 20px 0;text-align:left;font-size:11px;width:700px}#HealthStatus table td,#HealthStatus table thead th{padding:5px;vertical-align:middle;text-align:left}div.developer-submit-product span.profile-notice{float:left;color:#666}#app-detail-for-publisher #icon{float:left}#app-detail-for-publisher #detail-info div.title-rating span{float:right;padding-top:2px}#app-detail-for-publisher #detail-info div.description{margin-top:10px}option.disabled{background-color:lightgray}#language-selector-title{color:#29abe2;font-weight:normal;font-family:Arial;font-size:18px;margin-top:20px}#language-os-selector-info{float:left;border:1px #a8a8a8 solid;border-radius:4px;padding:20px 20px 10px 20px;margin:5px 10px 30px 0;background:white}#os-selector-info{float:none}#language-os-selector-desc{clear:both;padding-top:15px;font-size:11px;color:#999;font-family:Arial}#detail .language-os-select,#language-os-selector-info .language-os-select{width:130px;height:28px;padding-left:8px;border:1px solid #666;border-radius:2px;margin-right:10px}#language-os-selector-info .language-selector-group .language-selector-title,#os-selector-info .os-selector-title{margin-right:10px;color:#29abe2;font-family:Arial;font-size:20px}#language-os-selector-info .language-selector-group{float:left}#detail .language-os-select option,#language-os-selector-info .language-os-select option{line-height:20px;color:#000;font-family:Arial!important;font-size:12px!important}#language-os-selector-info separator span{color:#666;font-weight:normal;font-family:Arial;font-size:11px}.language-selector-cancelButton{height:31px;width:100px;float:left;font-weight:normal;font-family:Arial;font-size:14px}.language-selector-continueButton{height:31px;width:100px;float:right;margin-right:10px;color:#fff;font-weight:normal;font-family:Arial;font-size:14px}#action-wrapper .flat-button,#app-detail-for-publisher{width:230px;float:left;margin-bottom:13px}#action-wrapper span#action-link{margin-left:10px}#my-published .product-info{width:150px;float:left}#my-published .info-cell>div{display:inline-block}#my-published .image-info{width:58px;height:58px;float:left;margin-right:6px}#my-published .product-info a.details_link{width:150px}#my-published .product-info div.details_div{height:16px}#my-published a.publish-link{display:block;width:160px;height:31px}#apps-description{margin:2px 0 2px 0}.product-info .details_dropdownul{margin-top:0;padding:0}.product-info .details_dropdownul .drop_down{padding-top:5px}.product-info .details_dropdownul .live_version_info,.product-info .details_dropdownul .preview_version_info{cursor:default;padding-right:10px;background:url(../images/buttons/btn_popup_sort.png) no-repeat right 7px}#my-published #published-products td.language-cell div.live_version_info,#my-published #published-products td.language-cell div.preview_version_info{height:40px;overflow:hidden}#my-published .has_preview_version .live_version_info{display:none}.keyword-font{font-weight:bold;font-size:13px;color:#000}.normal-font{font-size:13px;color:#595959;word-wrap:break-word}.link-font{font-family:Arial;font-size:12px;color:#4675a8}.cash-font{font-family:Arial;font-size:16px;color:#000}.submit-font{font-family:Arial;font-size:12px;color:#fff}.description-font{font-family:Arial;font-size:11px;color:#666}.learn-more-font{font-family:Arial;font-size:11px;color:#4675a8;margin-bottom:7px}.detail-page #detail .gotoUrl,.detail-page #detail #detailosselector{height:28px;width:130px;border-color:#a8a8a8;border-radius:2px;background:linear-gradient(#f9f9f9,#d5d5d5);color:#000;font-weight:normal;font-family:Arial;font-size:12px}#store-management{width:900px;margin:0 auto;min-height:1200px}#store-management h3,#store-management .show-top-title{float:left}#store-management h1{margin:33px 0 25px}#store-management h3,#store-management .show-top-title{display:inline;line-height:30px}@media only screen and (max-width:780px){#store-management{margin:5%;width:90%}}#store-management .section{margin:20px 0}#store-management #selection.section{height:50px}#store-management .section .resp-content-div ul.sortable{margin-top:40px}#horizontalTab .resp-tabs-container{margin:0 7px 15px 0}#horizontalTab .settings-button{float:right;margin:5px 10px 5px 10px}#storeActions input{margin:5px}#store-management .special-group-widget-img{float:left;margin-right:7px}.selection-div{display:inline;margin-right:10px}.selection-div *{font-size:12px}.selection-div select{width:130px}#languageSelection{margin-left:10px}#store-management ul{list-style-type:none;margin:0;padding:0;margin-bottom:10px}#store-management .sortable li{float:left;width:180px;height:100px;margin:10px 10px;background:#ddd;border:1px solid lightgray;padding:1px;border-radius:5px}#store-management .sortable li:hover{border:1px solid #2a6496}#store-management li#draggable{float:left}#store-management .store-apps-container .sortable{width:650px;min-height:900px}#store-management .store-apps-container .sortable img{width:80px;height:80px;float:left}#store-management div.product-info{float:left;width:98px;position:relative;top:-20px;padding-left:2px}#store-management .publisher-name{display:block;overflow:hidden;width:98px;height:15px;font-weight:bold}#store-management #visible-settings{display:inline;font-weight:bold;font-size:14px;margin-left:10px}#store-management #select-app{display:inline;font-weight:bold;font-size:14px}#store-management #select-app{float:right;margin-right:80px}#store-management #select-app input{display:block;float:right}#store-management #select-app span{display:block}#store-management .button{width:auto;border:0;font-size:14px;cursor:pointer;height:24px;text-align:center;color:white}#store-management .store-action-input{width:70px}#store-management #store-reset-input{width:auto}#store-management span.add-app-hint-hidden{visibility:hidden;text-align:center}#store-management span.add-app-hint-visible{visibility:visible;text-align:center}#store-management .app-name{overflow:hidden;width:98px;height:62px;line-height:16px;word-wrap:break-word}.resp-vtabs .resp-tabs-list li span,.resp-vtabs .resp-tabs-list .input_widget_title{float:left;max-width:172px;width:172px}.resp-vtabs .resp-tabs-list .input_widget_title{display:none}#store-images .file{background:lightgray;margin-bottom:10px;height:205px;width:900px}#store-images .thumbnail,#store-images .thumbnail img{max-width:400px;max-height:165px}#store-images .storeimage_tools{position:absolute;top:5px;left:415px}#store-images .storeimage_tools label{margin-bottom:0}#store-images .storeimage_tools input{margin-bottom:2px;width:450px}#store-images .storeimage_tools textarea{margin-bottom:2px;width:450px}.fancy-chosen-tr,.fancy-chosen-tr span{color:red!important}.fancy-remove-app{visibility:hidden;position:relative;top:-10px;left:-10px;width:24px;height:24px;z-index:1;background-image:url(../images/buttons/close_24.png);cursor:pointer}.remove-widget{float:left;width:15px;height:15px;background:url(../images/buttons/widgetgroup_buttons.png) no-repeat -15px 0;cursor:pointer}.wg_edit-hidden,.wg_edit-widget,.eg-edit-widget{visibility:hidden;float:left;width:15px;height:15px;background:url(../images/buttons/widgetgroup_buttons.png) no-repeat 0 0;cursor:pointer;margin-right:5px;margin-left:5px}.wg_edit-accept,.eg-edit-accept{display:none;float:left;width:15px;height:15px;background:url(../images/buttons/widgetgroup_buttons.png) no-repeat -30px 0;cursor:pointer;margin-right:5px;margin-left:5px}.eg-edit-widget,.eg-edit-accept{float:right}.eg-name-input{width:140px;float:left;margin-bottom:0}#search-fancy-iframe{width:1300px;height:800px}#search-fancy-iframe thead{text-align:left;font-size:13px;border:1px solid #797979;background:gray;color:white}#search-fancy-iframe table td{border:1px solid #797979;padding:8px;vertical-align:middle}.fancy-search-main{height:760px;overflow-y:scroll}#result-list-div thead{text-align:left;font-size:13px;color:white;background:#999}#result-list-div th{height:25px;border:1px gray solid}#result-list-div td{border:1px gray solid;height:45px;vertical-align:middle}#result-list-div th:hover{background:#575757}#result-list-div .row-odd{background:#ededed}#result-list-div{width:100%}.fancy-compatibility{float:left;width:190px}.fancy-compatibility-visible{display:inline}.fancy-compatibility-hidden{display:none}.fancy-show-option,span.fancy-show-option{width:180px;float:left;cursor:pointer;color:#4675a8!important}.copy-settings{margin:10px 0}#copy-settings-info{color:red}#copy-settings-title{font-weight:bold}.fancy-copy-tabs{margin-right:5px}#copy-settings-tabs-title{font-weight:bold}.container-with-fixed-footer{margin-bottom:39px}#analytics-report{width:1370px;position:relative}#analytics-report #myTab>li>a{color:black}#analytics-report #selection .selection-div>h3{line-height:38px;color:#333;font-size:14px;font-weight:bold;margin-right:10px}#analytics-report #selection #languageSelection .dropdown{width:100px}#analytics-report #selection .selection-div>h3,#analytics-report #selection .selection-div>div{float:left}#analytics-report #selection .radio-wrapper{float:right}#analytics-report #selection #go{float:right;margin-left:20px;height:38px}#analytics-report #selection .recent-wrapper{float:left}#analytics-report #selection .radio-wrapper input[type="radio"]{float:left;margin-top:14px;margin-right:5px}#analytics-report #selection .radio-wrapper>span,#analytics-report #selection .radio-wrapper .recent-wrapper>span{line-height:40px;font-size:14px;color:#333;float:left;margin-right:5px}#analytics-report #selection .or{float:right;font-size:14px;font-weight:bold;line-height:40px;margin:0 10px}#analytics-report #selection .recent-wrapper .dropdown,#analytics-report #selection .recent-wrapper h3{float:left}#analytics-report #selection .recent-wrapper h3{line-height:38px;font-size:14px;color:#333;font-weight:normal}#analytics-report #selection .selection-div{float:left}#analytics-report #selection .input-daterange{float:left}#analytics-report #selection .input-daterange .input-sm{height:30px;margin-bottom:0;width:100px}#analytics-report #selection .input-daterange .input-group-addon{padding:11px 5px;margin-left:-4px}#analytics-report .nav-tabs>li{width:25%;text-align:center}#analytics-report .nav-tabs{padding:0}#analytics-report #info-box{position:absolute;right:0;top:-50px;background-color:#d9edf7;font-size:14px;line-height:30px;width:500px;text-align:center;display:none}#analytics-report .chart_act{cursor:pointer}#analytics-report #Statistics{min-height:1000px}#analytics-report .statistics-chart-div{float:left;margin-right:12px;margin-top:12px;display:flex;display:-moz-flex;display:-ms-flex;display:-webkit-flex}#analytics-report .statistics-detail{margin-top:50px;min-height:500px}#analytics-report .statistics-detail-header .detail-header-wrapper{float:left}#analytics-report .statistics-detail-header #goLineChart{margin-left:30px}#analytics-report .statistics-detail-header #granularity-span{margin-left:30px}#analytics-report .statistics-detail-body{padding:10px}#analytics-report .statistics-detail-body .pie-chart{display:block;height:400px;width:650px;float:left;margin:0 5px}#analytics-report .statistics-detail-body .pie-chart-content{position:relative;padding:0;width:100%;height:100%}#analytics-report .statistics-detail-body #line-chart-placeholder{height:400px}#analytics-report .nav-tabs{margin-top:25px}#analytics-report .nav-tabs li{text-align:center;width:200px}#analytics-report .nav-tabs .active{font-weight:bold}#analytics-report .nav-tabs li a,#analytics-report .nav-tabs li a:visited{color:Black}.chart_title{display:-moz-box;display:-webkit-box;display:box;box-pack:center;box-align:center}.chart-title-left .dropdown{height:25px;border:0;background:transparent;width:initial;font-size:13px;font-weight:bold}.chart-title-left .dropdown.focus,.chart-title-left .dropdown:hover{box-shadow:none;border:0}.chart-title-left .dropdown.open>div:last-child{min-width:100px}.chart-title-left .dropdown .selected{margin-left:0}.chart-title-left .dropdown .selected::after{box-shadow:none}.statistics-chart-div .chart_title .chart-title-left{margin-left:0}.chart-title-left .dropdown .carat{right:-12px;top:16px}.title-bar-action{right:0;top:0;position:absolute;margin-right:10px}.title-bar-action a{font-size:12px;font-weight:lighter;color:#468eb2}.analytic_chart_FullWidth,.analytic_chart_FullWidth .chart_title{width:100%}.analytic_chart_Middle,.analytic_chart_Middle .chart_title,.analytic_chart_Large,.analytic_chart_Large .chart_title{width:440px}.analytic_chart_Small,.analytic_chart_Small .chart_title{width:213px}.analytic_chart .chart_act{float:right}.analytic_chart .chart_str{font-size:18px;font-weight:bold}.analytic_chart_Middle .chart_contdiv,.analytic_chart_Small .chart_contdiv{height:109px;padding-top:20px;padding-left:10px;padding-right:10px}.analytic_chart_Large .chart_contdiv{height:281px;padding-top:20px;padding-left:10px;padding-right:10px}.analytic_chart_FullWidth .chart_contdiv{height:290px;padding-top:20px;padding-left:10px;padding-right:10px;background:white}.chart_contdiv>a,.chart_contdiv>a:hover,.chart_contdiv>a:visited{color:#468eb2}.analytic_chart_Middle .chart_cont,.analytic_chart_Small .chart_cont{height:62px;margin-bottom:5px}.analytic_chart_Large .chart_cont,.analytic_chart_FullWidth .chart_cont{height:230px;margin-bottom:5px;margin-left:12px}.analytic_chart .chart_title,.top-50-quickview h2{border-bottom:1px solid #29abe2;height:28px;background:#e6e6e6;color:#468eb2;font-weight:bold;font-size:15px;line-height:28px}.analytic_chart .chart_title span{margin-left:10px}.admin-tool-footer{bottom:0;width:100%}#admin_home_title{margin:50px;font-size:18px;text-align:center}.admin_home_element{margin-bottom:10px}#admin_home_content h2{margin-bottom:20px}#comment-management{width:1600px}#comment-management #selection{float:left}#comment-management #searchBar{float:right}#comment-management .section{width:100%;margin:0 10px}#comment-management{margin-bottom:540px}#comment-management a{color:#1a52ad;text-decoration:none}#comment-management select,#comment-management #query-term{margin-top:10px}#comment-management #checkbox-th{text-align:center}#comment-management .title-comment{float:left;width:400px;height:auto;text-overflow:ellipsis;text-align:left;overflow-y:hidden}#comment-management .title-area{width:400px;height:18px;margin:0;font-weight:bold;text-overflow:ellipsis;overflow:hidden;white-space:nowrap}#comment-management .comment-area{width:400px;word-wrap:break-word}#comment-management .comment-area-more{height:auto}#comment-management .comment-area-hide{overflow:hidden;max-height:40px}#comment-management .appname-area{text-align:left;width:200px;word-wrap:break-word}#comment-management .review-author-area{width:130px;word-wrap:break-word}#comment-management .publisher-area{width:130px;word-wrap:break-word}#comment-management .title-comment-td{height:auto;width:400px;padding:5px;text-align:left}#comment-management #actions{margin-bottom:10px}#comment-management td{text-align:center}#comment-management .description{color:Gray;font-size:12px}#comment-management #number-area{margin-bottom:5px}.hidden-element{visibility:hidden}#comment-management .my-modal-note{width:500px;height:300px}#comment-management .action-td{text-align:left}#comment-management .comments-table{font-size:12px}.comment-mangement-hightlight{background-color:lightcoral}#comment-management .tooltip{border:0;background-color:transparent;background:0;box-shadow:none;-moz-box-shadow:none;-webkit-box-shadow:none}#comment-management .note-textarea{height:40px;width:130px;word-wrap:break-word;text-align:left;overflow:hidden;resize:none;margin-bottom:0;border:0;background-color:transparent;box-shadow:none;cursor:default}#comment-management .note{overflow:hidden;height:40px;line-height:20px}#comment-management .note:before{content:"";float:left;width:5px;height:40px}#comment-management .note>*:first-child{float:right;width:100%;margin-left:-5px}#comment-management .note:after{content:"\02026";float:right;position:relative;top:-25px;left:100%;width:3em;margin-left:-3em;padding-right:5px;text-align:right}#comment-management .note-area{text-align:left}#download-entitlement-management{width:1205px;min-height:800px;margin:0 auto}#download-entitlement-management #base h1{font-size:18px;margin:10px 0}#download-entitlement-management #app-name{margin-bottom:20px}#download-entitlement-management #add-new-entitlement{float:left}#download-entitlement-management #add-new-entitlement input{width:100px}#download-entitlement-management #search-form{float:right}#download-entitlement-management #action-search-wrapper{margin-bottom:20px}#add-download-entitlement-input{width:424px;margin:20px 0 10px 0}#add-download-entitlement-form .error-email{color:red}.entitlement-table .notes .display-block{display:block}.entitlement-table .notes .display-none{display:none}.entitlement-table .notes .notes-edit-button,.entitlement-table .notes .notes-cancel,.entitlement-table .notes .notes-save{float:right}#footerloglink{width:120px;height:38px;float:right}.dropdown{font-size:12px;border-radius:0}.search-brief-component .dropdown{width:65px;float:right}#store-management .dropdown{float:left}.detail-page .dropdown{float:left;width:150px;margin-right:5px;padding:0}.dropdown ul{margin:0;padding:0}.dropdown li.focus{background:#29abe1;color:#fff}.dropdown .carat,.dropdown.open .carat{border-width:5px}.btn-group>.btn:last-child:not(:first-child),.btn-group>.dropdown-toggle:not(:first-child){border-bottom-left-radius:0;border-top-left-radius:0}.btn-group>.btn:first-child:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:2px}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}.drawer{background:#f2f2f2;overflow:hidden}.drawer .drawercontent{border:1px solid #ccc;padding:15px;display:none}.drawer.open .drawercontent{display:block}.drawer .normal-text{font:12px/24px arial,sans-serif;color:#000}.drawer .bold-text{font:bold 15px/24px arial,sans-serif;color:#000}.drawer .description-text{font:11px arial,sans-serif;color:#666}.qty-purchased-limit>.qty-limit,.qty-purchased-limit>.qty-purchased{float:left;line-height:15px}.qty-purchased-limit>.qty-limit{padding-top:1px;margin-left:15px}.qty-purchased-limit>.qty-limit-roof{color:red}.purchase-roof{display:none}.drawer .purchase-grid:not(:first-child){margin-left:30px}.drawer.open .drawercontent .subscrib-list{font-style:italic}.waiting-layer{width:398px;height:113px;background:#fff;border:1px solid #4675a8;-moz-box-shadow:rgba(0,0,0,0.25) 1px 1px 8px 3px;-ms-box-shadow:rgba(0,0,0,0.25) 1px 1px 8px 3px;-webkit-box-shadow:rgba(0,0,0,0.25) 1px 1px 8px 3px;box-shadow:rgba(0,0,0,0.25) 1px 1px 8px 3px}.waiting-layer #wrapper{width:370px;margin:auto}.waiting-layer #wrapper p{font-size:14px;color:#666;text-align:left;margin-top:25px}.waiting-layer #loader-wrapper{text-align:center;margin-top:15px}.waiting-layer #loader{width:24px;height:24px}#error-board{width:604px;margin:0 auto 0 auto;min-height:230px;background-color:white;padding:20px;background-image:url("../images/layout/error_board_bg.png");background-repeat:no-repeat;background-position:right top;-moz-box-shadow:1px 1px 3px rgba(0,0,0,0.25);-ms-box-shadow:1px 1px 3px rgba(0,0,0,0.25);-webkit-box-shadow:1px 1px 3px rgba(0,0,0,0.25);box-shadow:1px 1px 3px rgba(0,0,0,0.25)}#error-board-title,#main .opening-soon span{margin-bottom:30px;font-size:48px;color:#033333;line-height:100%}#main .opening-soon span{font-size:42px}#error-board-desc,#main .opening-soon p{font-size:16px;color:#666;line-height:180%}.whats-verified-download-main .headline{font-size:20px;color:#f90}#bluesnap-promotion-landing{display:none;text-align:center}#bluesnap-promotion-landing-text{font-family:'Myriad Pro';font-weight:400;font-size:24px}#bluesnap-promotion-landing-text2{font-family:'Arial Italic','Arial';font-weight:400;font-style:italic;font-size:18px;color:#666}#bluesnap-promotion-landing-banner{width:660px;padding:10px 10px 10px 10px}#bluesnap-promotion-detail{display:inline-block}#bluesnap-promotion-detail-logo-container{height:15px;vertical-align:middle}#bluesnap-promotion-detail-logo-container img{margin-top:15px}#bluesnap-promotion-detail img{height:inherit}#bluesnap-promotion-detail-text{font-family:'Arial Italic','Arial';font-weight:400;font-style:italic;font-size:10px;color:#369;float:right;height:24px}#process-payment-dialog{text-align:center;width:400px;padding:10px 10px 10px 10px}#process-payment-dialog div{margin-top:15px}#process-payment-dialog button{width:180px;height:28px;vertical-align:middle;margin-top:15px;margin-bottom:10px}.top-50-container{width:1200px}.top-50-container>*{width:100%;width:inherit;padding:10px}.horizontal-container{width:100%;display:-ms-flexbox;-ms-flex-pack:center;display:-moz-box;-moz-box-pack:center;-moz-box-align:center;display:-webkit-box;-webkit-box-pack:center;-webkit-box-align:center;display:box;box-pack:center;box-align:center}.top-50-quickview{margin:10px;width:33%}.top-50-quickview h2{padding-left:10px}.top-50-quickview ul{margin:0;padding:0}.top-50-quickview li:first-of-type{font-size:18px}.top-50-quickview li{background:white;padding:5px}.analytic-report-table-container>*{padding:8px}.analytic-report-table-container h1{font-size:18px}.analytic-report-table-container table{margin:10px}.analytic-report-table-container col{width:10%}.analytic-report-table-container td{text-align:left;vertical-align:middle}.analytic-report-table-container th{text-align:left}.analytic-report-table-container tr:nth-child(even){background:#f2f2f2}.analytic-report-table-container table *{padding:5px}.analytic-report-table-container thead{background:#f0f0f0}.statistics-chart-div.full-width{width:100%;position:relative}.file-list td{vertical-align:middle}.file-list label{margin:3px 3px}#featured-apps #result-list li{padding:10px;height:80px;overflow:visible}#featured-apps #result-list li:nth-child(odd){background:#ededed}#result-list{margin:0;padding:0;background:white;border:1px solid #CCC;border-top:0;width:100%}.admin-table table td,.master-table table td{border:1px solid #e6e6e6;height:40px;vertical-align:middle}#analytics-report a.admin-favorite{display:inline-block;height:7px;width:8px;background:url(../images/icons/star_big.png) no-repeat 2px 1px}#analytics-report a.admin-favorite.added{background:url(../images/icons/star_big.png) no-repeat 2px -16px}.search-type-area{height:25px;background:#fff;margin-right:6px;position:relative;display:none}.search-type{font:12px arial;text-align:center;height:25px;line-height:25px;padding-left:15px;padding-right:15px;margin-right:-4px;display:-moz-inline-box;display:inline-block}.search-type:hover{color:#29abe2!important;background:#e6e6e6!important;cursor:pointer}.search-type-unhightlighted{color:#29abe2!important;background:white}.search-type-hightlighted{color:white!important;background:#29abe2!important}.publisher-result-list{margin-left:-20px}.publisher-result-list li{height:130px;background-color:white;margin-right:6px;margin-bottom:6px}.pubsearch-result-row{height:100%;float:left;position:relative}.pubsearch-result-row-left{width:15%}.pubsearch-result-row-middle{margin-left:5px;width:70%}.pubsearch-result-row-right{width:13.5%}.pubsearch-result-image-link{height:98%;width:98%;background-color:white;display:inline-block;text-align:center;margin-right:2px}.pubsearch-result-image-helper{display:inline-block;height:100%;vertical-align:middle}.pubsearch-result-image{vertical-align:middle;display:inline-block;max-height:96%;max-width:96%;overflow:hidden}.pubsearch-result-name{margin-top:3px;font-size:14px;color:#29abe2;width:100%;overflow:hidden}.pubsearch-result-desc{margin-top:3px;font-size:12px;height:56px;width:100%;overflow:hidden}.publisher-consulting-services-region{position:absolute;bottom:-5px}.publisher-consulting-services-label{margin-bottom:3px;font-size:12px;width:100%}.pubsearch-consulting-service{margin-right:2px;float:left;width:auto;font-size:12px;vertical-align:bottom;margin-bottom:5px}.pubsearch-consulting-service-text{background-color:white;color:#29abe2}.pubsearch-result-row-right button{position:absolute!important;color:white;bottom:0;right:0;margin-bottom:6px;padding:5px}.pubsearch-apps-count{font-size:14px;color:#29abe2;font-weight:bold;position:relative;float:right;margin-top:5px;margin-right:2px}.pubsearch-apps-count-label{margin-top:5px;margin-right:5px;font-size:14px;position:relative;float:right}.ad-hide{display:none}.box-ad-hide{margin-left:189px}
\ No newline at end of file
diff --git a/2025/scripts/rigging_tools/ngskintools2/docs/Resources/linux64.png b/2025/scripts/rigging_tools/ngskintools2/docs/Resources/linux64.png
deleted file mode 100644
index 9e7f5bf..0000000
Binary files a/2025/scripts/rigging_tools/ngskintools2/docs/Resources/linux64.png and /dev/null differ
diff --git a/2025/scripts/rigging_tools/ngskintools2/docs/Resources/macos64.png b/2025/scripts/rigging_tools/ngskintools2/docs/Resources/macos64.png
deleted file mode 100644
index 8053b36..0000000
Binary files a/2025/scripts/rigging_tools/ngskintools2/docs/Resources/macos64.png and /dev/null differ
diff --git a/2025/scripts/rigging_tools/ngskintools2/docs/Resources/original_89910fa8-2c30-4376-a905-12c8a003d16b_.png b/2025/scripts/rigging_tools/ngskintools2/docs/Resources/original_89910fa8-2c30-4376-a905-12c8a003d16b_.png
deleted file mode 100644
index 65887c5..0000000
Binary files a/2025/scripts/rigging_tools/ngskintools2/docs/Resources/original_89910fa8-2c30-4376-a905-12c8a003d16b_.png and /dev/null differ
diff --git a/2025/scripts/rigging_tools/ngskintools2/docs/Resources/resized_5ca803cc-8cd1-4cbe-8825-98efaeef156e_.png b/2025/scripts/rigging_tools/ngskintools2/docs/Resources/resized_5ca803cc-8cd1-4cbe-8825-98efaeef156e_.png
deleted file mode 100644
index 412ca74..0000000
Binary files a/2025/scripts/rigging_tools/ngskintools2/docs/Resources/resized_5ca803cc-8cd1-4cbe-8825-98efaeef156e_.png and /dev/null differ
diff --git a/2025/scripts/rigging_tools/ngskintools2/docs/Resources/win64.png b/2025/scripts/rigging_tools/ngskintools2/docs/Resources/win64.png
deleted file mode 100644
index 3f3ee90..0000000
Binary files a/2025/scripts/rigging_tools/ngskintools2/docs/Resources/win64.png and /dev/null differ
diff --git a/2025/scripts/rigging_tools/ngskintools2/docs/index.html b/2025/scripts/rigging_tools/ngskintools2/docs/index.html
deleted file mode 100644
index a89a39a..0000000
--- a/2025/scripts/rigging_tools/ngskintools2/docs/index.html
+++ /dev/null
@@ -1,353 +0,0 @@
-
-
-
-
-
-
- Autodesk App Store - help file
-
-
-
-
-
-
-
ngSkinTools 2
-
-
-
-
Viktoras Makauskas
-
ngSkinTools is a skinning plugin for Autodesk® Maya®, introducing new concepts to character skinning such as layers, any-pose-mirroring, enhanced paint brushes, true smoothing, and more.
Skinning
-layers are a central feature of ngSkinTools. With them, you break your rig down
-into easier manageable parts and edit them separately, then blend everything
-together through layer transparency.
-
They’re
-not just a simple way to make your work more organized - they also physically
-isolate groups of influences from the rest of the rig, so paint and edit
-operations won’t mix-in influences you were not expecting. This also allows you
-to do things that were impossible before: per-layer mirroring, adjusting
-influence weight up/down through layer transparency, blend transferred weights
-with previous weights, to name a few.
-
-
Viewport
-tools
-
Just
-like in the previous version, ngSkinTools brings its own weight painting tools.
-Improving viewport experience is the main focus of V2, and it's complete revamp
-over the previous implementation.
-
-
Selecting
- influences on screen, a #1 requested feature from users, is nowhere. Just hold
- “S” and drag over the surface to select dominant influence from that part of
- the mesh, or hover over a joint pivot to select precisely the joints you
- want;
-
In
- addition to the usual surface projection mode for the brush, the new “screen”
- brush projection mode is useful when you want to quickly set weights for both
- sides of the mesh;
-
Custom
- shortcuts while in paint mode allow for quick access to intensity
-presets;
-
Color
- feedback is now provided through VP2 APIs, greatly improving the performance
- of displayed meshes.
-
-
Smoothing
-
Keeping
-weights in harmony with each other is not easy. ngSkinTools help you smooth
-weights with the control you need, allowing you to control the intensity, number
-of iterations and effective radius. For very dense meshes, added “iterations”
-argument now allows for the quicker spread of smoothness over larger areas of
-the mesh.
-
The
-“relax” tool from V1 is gone. With major performance rework, you’ll notice that
-simple flood-smoothing is now much faster and should be a near-instant operation
-even with large meshes.
-
The
-opposite “brother” of smooth brush, “sharpen”, is also there - for cases where
-you want to just bring out the dominant influences
-
-
Mirroring
-
Mirroring
-is one of the most frequent automated tasks you might want from your skinning
-tool. With ngSkinTools, you’ll be able to:
-
-
Mirror
- rigs in any pose; no need to switch to T-pose;
-
Have
- granular control over left/right/center influences mapping, matching
- left/right joints by naming convention, joint labels, etc;
-
Easily
- mirror parts of your rig by leveraging layers;
-
Automatic
- mirroring of weights to the opposite side as you paint so that you don’t need
- to get distracted from painting while working on symmetrical layers.
-
-
Layer
-effects
-
With
-the “mirror as a layer effect” feature, ngSkinTools introduce a new concept to
-ngSkinTools - layer effects. This differs from automatic mirroring of weights as
-it’s not directly modifying your layer weights; instead, it’s a post-effect that
-happens in the background buffer. This has multiple benefits, like a much
-cleaner seamline of left/right sides, the ability to tweak mirroring settings
-AFTER weights are painted, etc.
-
-
Compatibility
-
As
-it's predecessor, ngSkinTools2 operates on standard Maya skinCluster (also known
-as “smooth skin”), so no custom nodes will be required to use your rig. The
-plugin has a couple of custom nodes, but they’re only required while you work on
-setting up your skin weights and can be deleted after, so your work should stay
-compatible with most pipelines out there.
-
-
Performance
-
A
-lot of speed improvements have been made since V2, like improving the
-utilization of modern multi-core processors, or eliminating bottlenecks through
-much heavier use of performance profiling. Having a responsive, snappy tool is
-always a pleasure to work with.
-
-
-
-
-
General Usage Instructions
-
The installer from Autodesk App Store loads the application under the Custom shelf.
The installer that ran when you downloaded this plug-in from Autodesk App Store has already installed the plug-in. Windows only: To uninstall this plug-in, simply rerun the installer downloaded, and select the 'Uninstall' button, or you can uninstall it from 'Control Panel\Programs\Programs and Features', just as you would uninstall any other application from your system. The panel on the Plug-ins tab will not be removed until Maya is restarted.
-
-
-
Linux and OSX: To uninstall this plug-in, simply delete the module directory from your system. The panel on the Plug-ins tab will not be removed until Maya is restarted.
-
-
-
Download .msi and run it on your computer. The installation will place files in C:\ProgramData\Autodesk\ApplicationPlugins\ngskintools2 (unless your %ProgramData% the environment variable is different).
-
-
-
Using an autoloader system, nothing needs to be configured additionally. Maya scans autoloader locations for plugins at startup and configures each discovered plugin automatically. The autoloader will create a “ngSkinTools2” shelf with a button to open UI.
-
Now, restart Maya and a new tab ngSkinTools2 should appear on your shelf.
2.0.23 (2021-Mar-12)
-* Fixed: stylus pressure is not updated during the stroke;
-* Fixed: Maya crashes when smoothing an empty layer with "adjust existing influences only";
-* Fixed: (regression) UI is not opening on macOS;
-
-
-
-
-
- 2.0.23
-
-
-
2.0.23 (2021-Mar-10)
-* Added: adjustable brush size: don't reset to zero when changing brush size in the viewport.
-* Added: randomize influence colors in paint/display settings;
-* Added: layers on/off "eye" button in layers tree UI;
-* Fixed: ngSkinTools will not modify skinCluster's `normalizeWeights` value anymore; for performance boost, you still
- can disable skinCluster's normalization by setting `normalizeWeights=None`. In "normalizeWeights:interactive"
- skinCluster mode, Maya will no longer complain that "The weight total would have exceeded 1.0". ngSkinTools will try
- extra hard to normalize each vertex to a perfect 1.0;
-* Fixed: UI is not displayed correctly on high DPI displays when UI scaling is enabled in Maya;
-
-
-
-
-
- 2.0.22
-
-
-
2.0.22 (2021-Feb-06)
- Added: convenience tool for adding influences to existing skin clusters. Select influences, target mesh and select “Tools | Add Influence”;
- Fixed: weights will now display properly when viewport option “use default material” is turned on;
- Added: (v1 feature) Limit max influences per vertex before writing to skin cluster;
- Added: (v1 feature) Prune small weights before writing to skin cluster.
-
-2.0.21 (2021-Jan-11)
- Added: copy/paste vertex weights between different selections (tab “tools” - “copy component weights/paste average component weights”);
- Added: tool “fill transparency” - for all empty vertices in a layer, assign weights from closest non-empty vertex;
- Added: “duplicate layer” operation;
- Added: “Merge layers” operation: combine selected layers into one.
-
-2.0.20 (2020-Dec-02)
- Fixed: Linux: crashing on startup
-
-2.0.19 (2020-Nov-28)
- Added: influences mapping in mirror screen will now allow matching joints by DG connections; if symmetrical joints are linked between themselves with message connections, ngSkinTools will be able to leverage that information when mirroring weights;
- Added: symmetry mesh: an option to provide an alternative mesh for calculating vertex mapping for mirroring;
- Fixed: deleting visibility node can crash Maya sometimes, e.g. switching to component mode (F8) while paint tool is active
-
-2.0.18 (2020-Nov-20)
- Added: “use all joints” option for “weights from closest joint” tool; few internal optimizations to speedup operation;
- Added: “weights from closest joint” option: create a new layer
- Fixed: “weights from closest joint”: the tool is only using joints as spots, but not as segments;
- Fixed: after “weights from closest joint” operation influences list is not refreshed;
- Fixed: “weights from closest joint”: “assign” button sometimes disabled;
-
-2.0.17 (2020-Nov-19)
- Fixed: “resume in workspace” error while opening UI
-
-2.0.16 (2020-Nov-15)
- Added: skin data will be compressed for ngSkinTools data nodes, which should substantially reduce file size for scenes with lots of skinning layers;
- Added: paint mode intensity sliders are now exponential: “smooth”, “add” and “sharpen” sliders will now be more precise for lower values, and “scale” mode will allow for more precision when setting high values.
-
-2.0.15 (2020-Nov-10)
- Added: new “Set Weights” tab contains tools to apply weights to vertex/edge/polygon selection instead of painting.
- Added: a new option for smooth tool - “only adjust existing vertex influences”; when this is turned on, the smooth tool will prevent influences weights spreading across the surface
- Fixed: layer mirror effects correctly saved/loaded in files;
- Fixed: mask mirror effect was not correctly used by layer blending engine
-
-2.0.14 (2020-Oct-04)
- Fixed: occasional crashes when using mirror effect on layers;
- Additional stability fixes.
-
-2.0.13 (2020-Oct-04)
- Fixed: minor bug in 2.0.12 blocks UI from opening;
-
-2.0.12 (2020-Oct-03)
- Added: option to view used influences in influences list;
- Added: hide “DQ weights” channel in influences list if skin cluster skinning method is not set to “Weight Blended”;
-
-2.0.11 (2020-Oct-01)
- Fixed: broken Linux builds
-
-2.0.10 (2020-Sep-26)
- Added: pressing “f” while painting focuses viewport camera to current paint target; for joints and other influences, the current joint pivot is used as camera interest point; when current paint target is a mask, viewport centers around painted values;
- Fixed: influence mapping UI error if some influences are no joints;
-
-2.0.9 (2020-Sep-11)
- Fixed: undo paint crashing Maya;
- Fixed: incorrect brush behavior with multiple viewports open;
- Fixed: incorrect mesh display / VP2 transparency setting sensitive;
- Fixed: clearing selection while painting does not update the display of current mesh;
-
-
-
-
-
-
-
-
diff --git a/2025/scripts/rigging_tools/ngskintools2/launcher.py b/2025/scripts/rigging_tools/ngskintools2/launcher.py
index 06ddd41..19d7a37 100644
--- a/2025/scripts/rigging_tools/ngskintools2/launcher.py
+++ b/2025/scripts/rigging_tools/ngskintools2/launcher.py
@@ -1,158 +1,43 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
-
"""
-ngSkinTools2 启动器
-用于从工具架快速启动 ngSkinTools2
+ngSkinTools2 Launcher
+Provides a simple interface to launch ngSkinTools2 from Maya shelf buttons
"""
import sys
-import os
-
-def get_maya_version():
- """
- 获取当前 Maya 版本号
- 返回格式: '2023', '2024' 等
- """
- try:
- from maya import cmds
- maya_version = cmds.about(version=True)
- # Maya 版本格式可能是 "2023" 或 "2023.1" 等,取主版本号
- return maya_version.split('.')[0]
- except Exception as e:
- print(f"Failed to get Maya version: {e}")
- return None
-
-
-def find_compatible_plugin_dir(base_dir, maya_version):
- """
- 查找兼容的插件目录
- 优先使用完全匹配的版本,如果没有则向下查找最接近的版本
-
- Args:
- base_dir: 插件基础目录 (plug-ins/)
- maya_version: Maya 版本号字符串,如 '2023'
-
- Returns:
- 插件目录路径,如果找不到则返回 None
- """
- if not maya_version:
- return None
-
- try:
- maya_ver_int = int(maya_version)
- except ValueError:
- print(f"Invalid Maya version format: {maya_version}")
- return None
-
- # 列出所有可用的插件版本目录
- available_versions = []
- if os.path.exists(base_dir):
- for item in os.listdir(base_dir):
- item_path = os.path.join(base_dir, item)
- if os.path.isdir(item_path):
- try:
- ver_int = int(item)
- available_versions.append((ver_int, item_path))
- except ValueError:
- continue
-
- if not available_versions:
- return None
-
- # 按版本号排序
- available_versions.sort(reverse=True)
-
- # 首先尝试完全匹配
- for ver, path in available_versions:
- if ver == maya_ver_int:
- print(f"Found exact match plugin for Maya {maya_version}: {path}")
- return path
-
- # 如果没有完全匹配,使用小于等于当前版本的最高版本
- for ver, path in available_versions:
- if ver <= maya_ver_int:
- print(f"Using compatible plugin for Maya {maya_version}: {path} (version {ver})")
- return path
-
- # 如果当前版本比所有可用版本都旧,使用最旧的版本
- oldest_ver, oldest_path = available_versions[-1]
- print(f"Warning: Maya {maya_version} is older than available plugins. Using oldest: {oldest_path} (version {oldest_ver})")
- return oldest_path
def LaunchNgSkinTools():
"""
- 启动 ngSkinTools2 主界面
- 自动检测 Maya 版本并加载对应的插件
+ Launch ngSkinTools2 main UI window
+
+ This function handles two scenarios:
+ 1. If module alias exists (ngSkinTools2 -> rigging_tools.ngskintools2), use it
+ 2. If not, create the alias on-the-fly and then launch
"""
try:
- from maya import cmds, mel
-
- # 获取当前 Maya 版本
- maya_version = get_maya_version()
- if not maya_version:
- print("Warning: Could not determine Maya version, will try to continue anyway")
- else:
- print(f"Detected Maya version: {maya_version}")
-
- # 将当前目录添加到 Python 路径,并使用别名
- # 这样 ngSkinTools2 内部的 "from ngSkinTools2.ui" 就能找到模块
- current_dir = os.path.dirname(os.path.abspath(__file__))
- parent_dir = os.path.dirname(current_dir)
-
- # 添加父目录到路径
- if parent_dir not in sys.path:
- sys.path.insert(0, parent_dir)
-
- # 添加当前目录到路径,作为 ngSkinTools2 模块
- if current_dir not in sys.path:
- sys.path.insert(0, current_dir)
-
- # 在 sys.modules 中创建别名,让 ngSkinTools2 指向 ngskintools2
- import rigging_tools.ngskintools2 as ngskintools2_module
- sys.modules['ngSkinTools2'] = ngskintools2_module
-
- # 查找并添加插件路径
- # 根据 Maya 版本自动选择对应的插件目录
- plugin_base_dir = os.path.join(current_dir, 'plug-ins')
- plugin_dir = find_compatible_plugin_dir(plugin_base_dir, maya_version)
-
- if plugin_dir and os.path.exists(plugin_dir):
- # 添加插件路径
- current_plugin_path = os.environ.get('MAYA_PLUG_IN_PATH', '')
- if plugin_dir not in current_plugin_path:
- os.environ['MAYA_PLUG_IN_PATH'] = plugin_dir + os.pathsep + current_plugin_path
-
- # 加载插件
+ # Check if module alias already exists
+ if 'ngSkinTools2' not in sys.modules:
+ # Create the alias on-the-fly
try:
- # 检查插件是否已加载
- if not cmds.pluginInfo('ngSkinTools2', query=True, loaded=True):
- cmds.loadPlugin(os.path.join(plugin_dir, 'ngSkinTools2.mll'))
- print(f"ngSkinTools2 plugin loaded successfully from {plugin_dir}")
- else:
- print(f"ngSkinTools2 plugin already loaded")
- except RuntimeError:
- # 插件不存在,尝试加载
- try:
- cmds.loadPlugin(os.path.join(plugin_dir, 'ngSkinTools2.mll'))
- print(f"ngSkinTools2 plugin loaded successfully from {plugin_dir}")
- except Exception as plugin_error:
- print(f"Warning: Could not load ngSkinTools2 plugin: {plugin_error}")
- except Exception as plugin_error:
- print(f"Warning: Could not load ngSkinTools2 plugin: {plugin_error}")
- else:
- print(f"Warning: Plugin directory not found: {plugin_dir}")
+ import rigging_tools.ngskintools2
+ sys.modules['ngSkinTools2'] = rigging_tools.ngskintools2
+ print("Created ngSkinTools2 module alias")
+ except ImportError as import_err:
+ print(f"Error: Failed to import rigging_tools.ngskintools2 - {import_err}")
+ print("Please ensure the ngskintools2 directory is in the correct location")
+ return
- # 现在可以导入并打开 UI
- from rigging_tools.ngskintools2 import open_ui
+ # Now import and launch
+ from ngSkinTools2 import open_ui
open_ui()
- print("ngSkinTools2 UI opened successfully")
+ print("ngSkinTools2 launched successfully")
+
+ except ImportError as e:
+ print(f"Error: Failed to import ngSkinTools2 - {e}")
+ print("Please ensure ngSkinTools2 is properly installed")
except Exception as e:
- print(f"Failed to open ngSkinTools2: {e}")
+ print(f"Error: Failed to launch ngSkinTools2 - {e}")
import traceback
- traceback.print_exc()
-
-
-if __name__ == "__main__":
- LaunchNgSkinTools()
+ traceback.print_exc()
\ No newline at end of file
diff --git a/2025/scripts/rigging_tools/ngskintools2/license.txt b/2025/scripts/rigging_tools/ngskintools2/license.txt
deleted file mode 100644
index 69c070d..0000000
--- a/2025/scripts/rigging_tools/ngskintools2/license.txt
+++ /dev/null
@@ -1,32 +0,0 @@
-ngSkinTools Software License Agreement.
-
-
-This is a legal agreement between you and ngSkinTools author (Viktoras Makauskas) covering your use of
-ngSkinTools (the "Software").
-
-1) ngSkinTools is provided as freeware.
-
-2) ngSkinTools Software is owned by Viktoras Makauskas and is protected by copyright laws and international
-treaty provisions. Therefore, you must treat the Software like any other copyrighted material.
-
-3) You may not distribute, rent, sub-license or otherwise make available to others the Software or
-documentation or copies thereof, except as expressly permitted in this License without prior written consent
-from ngSkinTools author (Viktoras Makauskas). In the case of an authorized transfer, the transferee must agree
-to be bound by the terms and conditions of this License Agreement.
-
-4) You may not remove any proprietary notices, labels, trademarks on the Software or documentation. You may not
-modify, de-compile, disassemble or reverse engineer the Software.
-
-5) Limited warranty: ngSkinTools software and documentation are "as is" without any warranty as to their
-performance, merchantability or fitness for any particular purpose. The licensee assumes the entire risk as to
-the quality and performance of the software. In no event shall ngSkinTools author or anyone else who has been
-involved in the creation, development, production, or delivery of this software be liable for any direct,
-incidental or consequential damages, such as, but not limited to, loss of anticipated profits, benefits, use,
-or data resulting from the use of this software, or arising out of any breach of warranty.
-
-Copyright (C) 2009-2020 Viktoras Makauskas
-
-http://www.ngskintools.com
-support@ngskintools.com
-
-All rights reserved.
diff --git a/2025/scripts/rigging_tools/ngskintools2/observableValue.py b/2025/scripts/rigging_tools/ngskintools2/observableValue.py
index f01c198..3410295 100644
--- a/2025/scripts/rigging_tools/ngskintools2/observableValue.py
+++ b/2025/scripts/rigging_tools/ngskintools2/observableValue.py
@@ -22,4 +22,4 @@ class ObservableValue(Object):
if default != Undefined:
return default
- raise Exception("using observable value before setting it")
+ raise Exception("在设置之前使用可观察值")
diff --git a/2025/scripts/rigging_tools/ngskintools2/operations/copy_paste_actions.py b/2025/scripts/rigging_tools/ngskintools2/operations/copy_paste_actions.py
index 916b25b..f362bc0 100644
--- a/2025/scripts/rigging_tools/ngskintools2/operations/copy_paste_actions.py
+++ b/2025/scripts/rigging_tools/ngskintools2/operations/copy_paste_actions.py
@@ -24,7 +24,7 @@ def action_copy_cut(session, parent, cut):
operation(session.state.currentLayer.layer, influences)
operation_name = "Cut" if cut else "Copy"
- result = actions.define_action(parent, operation_name + " weights to clipboard", callback=cut_copy_callback)
+ result = actions.define_action(parent, operation_name + " 将权重复制到剪贴板", callback=cut_copy_callback) # 将权重复制到剪贴板 weights to clipboard
@signal.on(session.events.currentLayerChanged, session.events.currentInfluenceChanged, qtParent=parent)
def on_selection_changed():
@@ -49,13 +49,13 @@ def action_paste(session, parent, operation):
api.paste_weights(session.state.currentLayer.layer, operation, influences=influences)
labels = {
- PasteOperation.add: 'Paste weights (add to existing)',
- PasteOperation.subtract: 'Paste weight (subtract from existing)',
- PasteOperation.replace: 'Paste weights (replace existing)',
+ PasteOperation.add: '粘贴权重(添加到现有)',
+ PasteOperation.subtract: '粘贴权重(从现有值中减去)',
+ PasteOperation.replace: '粘贴权重(替换现有)',
}
result = actions.define_action(parent, labels[operation], callback=paste_callback)
- result.setToolTip("Paste previously copied weights from clipboard")
+ result.setToolTip("从剪贴板粘贴先前复制的权重")
@signal.on(session.events.currentLayerChanged)
def on_selection_changed():
diff --git a/2025/scripts/rigging_tools/ngskintools2/operations/import_export_actions.py b/2025/scripts/rigging_tools/ngskintools2/operations/import_export_actions.py
index 2a64020..17f7d6d 100644
--- a/2025/scripts/rigging_tools/ngskintools2/operations/import_export_actions.py
+++ b/2025/scripts/rigging_tools/ngskintools2/operations/import_export_actions.py
@@ -31,7 +31,7 @@ def buildAction_export(session, parent):
result = actions.define_action(
parent,
- "Export Layers to Json...",
+ "导出图层...",
callback=export_callback,
tooltip="Save layer info to external file, suitable for importing weights to different scene/mesh",
)
@@ -79,7 +79,7 @@ def buildAction_import(session, parent, file_dialog_func=None):
t.customize_callback = transfer_dialog
t.execute()
- result = actions.define_action(parent, "Import Layers from Json...", callback=import_callback, tooltip="Load previously exported weights")
+ result = actions.define_action(parent, "导入图层...", callback=import_callback, tooltip="Load previously exported weights")
@signal.on(session.events.targetChanged, qtParent=parent)
def update():
diff --git a/2025/scripts/rigging_tools/ngskintools2/operations/import_v1_actions.py b/2025/scripts/rigging_tools/ngskintools2/operations/import_v1_actions.py
index 2b19f45..9a74704 100644
--- a/2025/scripts/rigging_tools/ngskintools2/operations/import_v1_actions.py
+++ b/2025/scripts/rigging_tools/ngskintools2/operations/import_v1_actions.py
@@ -28,8 +28,8 @@ def build_action_import_v1(session, parent):
update_state()
session.events.targetChanged.emitIfChanged()
- result = actions.define_action(parent, "Convert From v1.0 Layers", callback=do_convert)
- result.setToolTip("Convert skinning layers from previous version of ngSkinTools; after completing this action, v1 nodes will be deleted.")
+ result = actions.define_action(parent, "从v1.0图层转换", callback=do_convert)
+ result.setToolTip("“转化旧版ngSkinTools的图层;完成此操作后,v1节点将被删除。")
@signal.on(session.events.targetChanged)
def update_state():
diff --git a/2025/scripts/rigging_tools/ngskintools2/operations/layers.py b/2025/scripts/rigging_tools/ngskintools2/operations/layers.py
index 028eb96..b3004ce 100644
--- a/2025/scripts/rigging_tools/ngskintools2/operations/layers.py
+++ b/2025/scripts/rigging_tools/ngskintools2/operations/layers.py
@@ -28,7 +28,7 @@ def initializeLayers(createFirstLayer=True):
layers = ngSkinTools2.api.init_layers(target)
with ngSkinTools2.api.suspend_updates(target):
if createFirstLayer:
- layer = layers.add("Base weights")
+ layer = layers.add("基础权重") #Base weights
layer.set_current()
Mirror(target).set_mirror_config(config.mirrorInfluencesDefaults)
@@ -36,7 +36,7 @@ def initializeLayers(createFirstLayer=True):
if ngSkinTools2.api.is_slow_mode_skin_cluster(target):
dialogs.info(
- "ngSkinTools switched to slow maya API for setting skin cluster weights for this skinCluster, to workaround a Maya bug when skinCluster uses dg nodes as inputs"
+ "切换为设置皮肤集群权重,以解决 Maya皮肤集群使用装点作为输入时的错误。"
)
@@ -73,15 +73,15 @@ def build_action_initialize_layers(session, parent):
def do_initialize():
if import_v1_actions.can_import(session):
q = (
- "Skinning layers from previous version of ngSkinTools are present on this mesh. This operation will initialize "
- "skinning layers from scratch, discarding previous layers information. Do you want to continue?"
+ "来自旧版 ngSkinTools的皮肤层存在于此网格上。此操作将初始化"
+ "从头开始剥离图层,丢弃之前的图层信息。您要继续吗?"
)
if not dialogs.yesNo(q):
return
initializeLayers()
- result = actions.define_action(parent, "Initialize Skinning Layers", callback=do_initialize)
+ result = actions.define_action(parent, "初始化蒙皮层", callback=do_initialize)
@signal.on(session.events.nodeSelectionChanged)
def update():
@@ -95,7 +95,7 @@ def build_action_initialize_layers(session, parent):
def buildAction_createLayer(session, parent):
from ngSkinTools2.ui import actions
- result = actions.define_action(parent, "Create Layer", callback=addLayer, icon=":/newLayerEmpty.png", shortcut=QtCore.Qt.Key_Insert)
+ result = actions.define_action(parent, "创建图层", callback=addLayer, icon=":/newLayerEmpty.png", shortcut=QtCore.Qt.Key_Insert)
@signal.on(session.events.targetChanged)
def update_to_target():
@@ -109,7 +109,7 @@ def buildAction_createLayer(session, parent):
def buildAction_deleteLayer(session, parent):
from ngSkinTools2.ui import actions
- result = actions.define_action(parent, "Delete Layer", callback=deleteSelectedLayers, shortcut=QtCore.Qt.Key_Delete)
+ result = actions.define_action(parent, "删除图层", callback=deleteSelectedLayers, shortcut=QtCore.Qt.Key_Delete)
@signal.on(session.context.selected_layers.changed, session.events.targetChanged, qtParent=parent)
def update_to_target():
@@ -126,12 +126,12 @@ def setCurrentLayer(layer):
:type layer: ngSkinTools2.api.layers.Layer
"""
if not session.active():
- logger.info("didn't set current layer: no session")
+ logger.info("未设置当前图层:没有会话")
if not session.state.layersAvailable:
- logger.info("didn't set current layer: layers not enabled")
+ logger.info("未设置当前图层:图层未启用")
- logger.info("setting current layer to %r on %r", layer, session.state.selectedSkinCluster)
+ logger.info("将当前图层设置为 %r on %r", layer, session.state.selectedSkinCluster)
layer.set_current()
session.events.currentLayerChanged.emitIfChanged()
@@ -158,7 +158,7 @@ def deleteSelectedLayers():
class ToggleEnabledAction(Action):
- name = "Enabled"
+ name = "启用图层" #Enabled
checkable = True
def __init__(self, session):
@@ -192,7 +192,7 @@ class ToggleEnabledAction(Action):
for i in selected_layers:
i.enabled = enabled
- logger.info("layers toggled: %r", selected_layers)
+ logger.info("图层已切换: %r", selected_layers)
session.events.layerListChanged.emitIfChanged()
@@ -209,8 +209,8 @@ def build_action_randomize_influences_colors(session, parent):
:type session: ngSkinTools2.api.session.Session
"""
- result = QAction("Randomize colors", parent)
- result.setToolTip("Choose random colors for each influence, selecting from Maya's pallete of indexed colors")
+ result = QAction("随机颜色", parent)
+ result.setToolTip("为每个影响选择随机颜色,从Maya的索引色板中选择。")
def color_filter(c):
brightness = c[0] * c[0] + c[1] * c[1] + c[2] * c[2]
diff --git a/2025/scripts/rigging_tools/ngskintools2/operations/paint.py b/2025/scripts/rigging_tools/ngskintools2/operations/paint.py
index 41d46d3..f9ec0ea 100644
--- a/2025/scripts/rigging_tools/ngskintools2/operations/paint.py
+++ b/2025/scripts/rigging_tools/ngskintools2/operations/paint.py
@@ -9,8 +9,8 @@ log = getLogger("operations/paint")
class FloodAction(Action):
- name = "Flood"
- tooltip = "Apply current brush to whole selection"
+ name = "填充" # Flood
+ tooltip = "将当前画笔应用于整个选择区域"
def run(self):
session.paint_tool.flood(self.session.state.currentLayer.layer, influences=self.session.state.currentLayer.layer.paint_targets)
@@ -28,8 +28,8 @@ class FloodAction(Action):
class PaintAction(Action):
- name = "Paint"
- tooltip = "Toggle paint tool"
+ name = "绘制" # Paint
+ tooltip = "切换绘制工具"
checkable = True
def run(self):
diff --git a/2025/scripts/rigging_tools/ngskintools2/operations/removeLayerData.py b/2025/scripts/rigging_tools/ngskintools2/operations/removeLayerData.py
index d8e91b7..f8cf0f2 100644
--- a/2025/scripts/rigging_tools/ngskintools2/operations/removeLayerData.py
+++ b/2025/scripts/rigging_tools/ngskintools2/operations/removeLayerData.py
@@ -43,14 +43,14 @@ def list_custom_nodes_for_meshes(meshes):
return list(itertools.chain.from_iterable([list_custom_nodes_for_mesh(i) for i in meshes]))
-message_scene_noCustomNodes = 'Scene does not contain any custom ngSkinTools nodes.'
-message_selection_noCustomNodes = 'Selection does not contain any custom ngSkinTools nodes.'
+message_scene_noCustomNodes = '场景中不包含任何自定义的ngSkinTools节点。'
+message_selection_noCustomNodes = '选择不包含任何自定义ngskinTools节点。'
message_scene_warning = (
- 'This command deletes all custom ngSkinTools nodes. Skin weights ' 'will be preserved, but all layer data will be lost. Do you want to continue?'
+ '此命令删除所有自定义ngSkinTools节点。蒙皮权重“”将被保留,但所有图层数据都将丢失。您想继续吗?'
)
message_selection_warning = (
- 'This command deletes custom ngSkinTools nodes for selection. Skin weights '
- 'will be preserved, but all layer data will be lost. Do you want to continue?'
+ '此命令删除要选择的自定义ngSkinTools节点。皮肤重量'
+ '将被保留,但所有图层数据都将丢失。您想继续吗?'
)
@@ -89,7 +89,7 @@ def remove_custom_nodes(interactive=False, session=None, meshes=None):
if PaintTool.is_painting():
# make sure that painting is canceled to restore mesh display etc
- cmds.setToolTo("Move")
+ cmds.setToolTo("移除") # Move
if session is not None:
session.events.targetChanged.emitIfChanged()
diff --git a/2025/scripts/rigging_tools/ngskintools2/operations/tools.py b/2025/scripts/rigging_tools/ngskintools2/operations/tools.py
index 27e8169..4aee804 100644
--- a/2025/scripts/rigging_tools/ngskintools2/operations/tools.py
+++ b/2025/scripts/rigging_tools/ngskintools2/operations/tools.py
@@ -54,7 +54,7 @@ def create_action__from_closest_joint(parent, session):
if not options.all_influences():
influences = layer.paint_targets
if not influences:
- dialogs.info("Select one or more influences in Influences list")
+ dialogs.info("在影响列表中选择一个或多个影响")
return
if options.create_new_layer():
@@ -77,8 +77,8 @@ def create_action__from_closest_joint(parent, session):
__create_tool_action__(
parent,
session,
- action_name=u"Assign From Closest Joint",
- action_tooltip="Assign 1.0 weight for closest influence per each vertex in selected layer",
+ action_name=u"从最近的关节分配",
+ action_tooltip="为选定层中每个顶点的最近影响分配权重1.0",
exec_handler=exec_handler,
),
options,
@@ -105,8 +105,8 @@ def create_action__unify_weights(parent, session):
__create_tool_action__(
parent,
session,
- action_name=u"Unify Weights",
- action_tooltip="For selected vertices, make verts the same for all verts",
+ action_name=u"统一权重", # Unify Weights
+ action_tooltip="对于选定的顶点,使所有顶点相同。", #对于选定的顶点,使所有顶点相同。
exec_handler=exec_handler,
),
options,
@@ -130,8 +130,8 @@ def create_action__merge_layers(parent, session):
return __create_tool_action__(
parent,
session,
- action_name=u"Merge",
- action_tooltip="Merge contents of this layer into underlying layer. Pre-effects weights will be used for this",
+ action_name=u"合并", # Merge
+ action_tooltip="将本层的元素合并到底层。预效果权重将用于此。",
exec_handler=exec_handler,
enabled_handler=enabled_handler,
)
@@ -155,8 +155,8 @@ def create_action__duplicate_layer(parent, session):
return __create_tool_action__(
parent,
session,
- action_name=u"Duplicate",
- action_tooltip="Duplicate selected layer(s)",
+ action_name=u"复制",
+ action_tooltip="复制选择的图层(多选)",
exec_handler=exec_handler,
)
@@ -176,8 +176,8 @@ def create_action__fill_transparency(parent, session):
return __create_tool_action__(
parent,
session,
- action_name=u"Fill Transparency",
- action_tooltip="All transparent vertices in the selected layer(s) receive weights from their closest non-empty neighbour vertex",
+ action_name=u"填充透明度",
+ action_tooltip="所选图层中的所有透明顶点接收其最近非空邻接顶点的权重,",
exec_handler=exec_handler,
)
@@ -195,8 +195,8 @@ def create_action__copy_component_weights(parent, session):
return __create_tool_action__(
parent,
session,
- action_name=u"Copy Component Weights",
- action_tooltip="Store components weights in memory for further component-based paste actions",
+ action_name=u"复制组件权重",
+ action_tooltip="将组件权重存储在内存中,以便进行进一步的基于组件的粘贴操作",
exec_handler=exec_handler,
)
@@ -214,8 +214,8 @@ def create_action__paste_average_component_weight(parent, session):
return __create_tool_action__(
parent,
session,
- action_name=u"Paste Average Component Weight",
- action_tooltip="Compute average of copied component weights and set that value to currently selected components",
+ action_name=u"粘贴平均组件权重",
+ action_tooltip="计算复制的组件重量的平均值,并将该值设置为当前选定的组件",
exec_handler=exec_handler,
)
@@ -229,7 +229,7 @@ def create_action__add_influences(parent, session):
def exec_handler():
selection = cmds.ls(sl=True, l=True)
if len(selection) < 2:
- logger.info("invalid selection: %s", selection)
+ logger.info("无效选择: %s", selection)
return
api.add_influences(selection[:-1], selection[-1])
cmds.select(selection[-1])
@@ -238,8 +238,8 @@ def create_action__add_influences(parent, session):
return __create_tool_action__(
parent,
session,
- action_name=u"Add Influences",
- action_tooltip="Add selected influences to current skin cluster.",
+ action_name=u"增加影响",
+ action_tooltip="将选定的影响添加到当前皮肤集群。",
exec_handler=exec_handler,
)
@@ -289,7 +289,7 @@ def create_action__select_affected_vertices(parent, session):
return __create_tool_action__(
parent,
session,
- action_name=u"Select Affected Vertices",
- action_tooltip="Select vertices that have non-zero weight for current influence.",
+ action_name=u"选择受影响的顶点",
+ action_tooltip="选择当前影响中权重不为要的顶点。",
exec_handler=exec_handler,
)
diff --git a/2025/scripts/rigging_tools/ngskintools2/operations/website_links.py b/2025/scripts/rigging_tools/ngskintools2/operations/website_links.py
index 3a36476..453e8e5 100644
--- a/2025/scripts/rigging_tools/ngskintools2/operations/website_links.py
+++ b/2025/scripts/rigging_tools/ngskintools2/operations/website_links.py
@@ -12,10 +12,10 @@ def website_base_url():
class WebsiteLinksActions(Object):
def __init__(self, parent):
- self.api_root = make_documentation_action(parent, "API Documentation", "/v2/api")
- self.user_guide = make_documentation_action(parent, "User Guide", "/v2/")
- self.changelog = make_documentation_action(parent, "Change Log", "/v2/changelog", icon=None)
- self.contact = make_documentation_action(parent, "Contact", "/contact/", icon=None)
+ self.api_root = make_documentation_action(parent, "API 文档", "/v2/api")
+ self.user_guide = make_documentation_action(parent, "用户指南", "/v2/")
+ self.changelog = make_documentation_action(parent, "更新日志", "/v2/changelog", icon=None)
+ self.contact = make_documentation_action(parent, "联系", "/contact/", icon=None)
def make_documentation_action(parent, title, url, icon=":/help.png"):
diff --git a/2025/scripts/rigging_tools/ngskintools2/signal.py b/2025/scripts/rigging_tools/ngskintools2/signal.py
index 7961484..ceecb38 100644
--- a/2025/scripts/rigging_tools/ngskintools2/signal.py
+++ b/2025/scripts/rigging_tools/ngskintools2/signal.py
@@ -24,8 +24,8 @@ class SignalQueue(Object):
def emit(self, handler):
if len(self.queue) > self.max_length:
- log.error("queue max length reached: emitting too many events?")
- raise Exception("queue max length reached: emitting too many events?")
+ log.error("队列最大长度已达到:发出的事件过多?")
+ raise Exception("队列最大长度已达到:正在发出太多事件?")
should_start = len(self.queue) == 0
@@ -53,7 +53,7 @@ class SignalQueue(Object):
current_handler += 1
if len(self.queue) > 50:
- log.info("handler queue finished with %d items", len(self.queue))
+ log.info("处理器队列完成,共 %d 项", len(self.queue))
self.queue = []
@@ -77,7 +77,7 @@ class Signal(Object):
def __init__(self, name):
if name is None:
- raise Exception("need name for debug purposes later")
+ raise Exception("需要稍后用于调试目的的名称")
self.name = name
self.handlers = []
self.executing = False
diff --git a/2025/scripts/rigging_tools/ngskintools2/ui/aboutwindow.py b/2025/scripts/rigging_tools/ngskintools2/ui/aboutwindow.py
index e96ffd2..cde00c6 100644
--- a/2025/scripts/rigging_tools/ngskintools2/ui/aboutwindow.py
+++ b/2025/scripts/rigging_tools/ngskintools2/ui/aboutwindow.py
@@ -19,7 +19,7 @@ def show(parent):
layout = QtWidgets.QVBoxLayout()
layout.addStretch()
layout.addWidget(QtWidgets.QLabel("
ngSkinTools
"))
- layout.addWidget(QtWidgets.QLabel("Version {0}".format(version.pluginVersion())))
+ layout.addWidget(QtWidgets.QLabel("当前版本 {0}".format(version.pluginVersion())))
layout.addWidget(QtWidgets.QLabel(version.COPYRIGHT))
url = QtWidgets.QLabel('{0}'.format(version.PRODUCT_URL))
@@ -65,7 +65,7 @@ def show(parent):
def buttonsRow(window):
layout = QtWidgets.QHBoxLayout()
layout.addStretch()
- btnClose = QtWidgets.QPushButton("Close")
+ btnClose = QtWidgets.QPushButton("退出")
btnClose.setMinimumWidth(100 * scale_multiplier)
layout.addWidget(btnClose)
layout.setContentsMargins(20 * scale_multiplier, 15 * scale_multiplier, 20 * scale_multiplier, 15 * scale_multiplier)
@@ -76,7 +76,7 @@ def show(parent):
window = QtWidgets.QWidget(parent, Qt.Window | Qt.WindowTitleHint | Qt.CustomizeWindowHint)
window.resize(600 * scale_multiplier, 500 * scale_multiplier)
window.setAttribute(Qt.WA_DeleteOnClose)
- window.setWindowTitle("About ngSkinTools")
+ window.setWindowTitle("关于 ngSkinTools")
layout = QtWidgets.QVBoxLayout()
window.setLayout(layout)
layout.setContentsMargins(0, 0, 0, 0)
diff --git a/2025/scripts/rigging_tools/ngskintools2/ui/actions.py b/2025/scripts/rigging_tools/ngskintools2/ui/actions.py
index 28b66af..45fac41 100644
--- a/2025/scripts/rigging_tools/ngskintools2/ui/actions.py
+++ b/2025/scripts/rigging_tools/ngskintools2/ui/actions.py
@@ -35,7 +35,7 @@ def build_action_delete_custom_nodes_for_selection(parent, session):
result = define_action(
parent,
- "Delete Custom Nodes For Selection",
+ "删除选中网格的Ng节点",
callback=lambda: removeLayerData.remove_custom_nodes_from_selection(interactive=True, session=session),
)
@@ -86,7 +86,7 @@ class Actions(Object):
self.toolsUnifyWeights, self.toolsUnifyWeightsOptions = tools.create_action__unify_weights(parent, session)
self.toolsDeleteCustomNodes = define_action(
- parent, "Delete All Custom Nodes", callback=lambda: removeLayerData.remove_custom_nodes(interactive=True, session=session)
+ parent, "删除所有网格的Ng节点", callback=lambda: removeLayerData.remove_custom_nodes(interactive=True, session=session)
)
self.toolsDeleteCustomNodesOnSelection = build_action_delete_custom_nodes_for_selection(parent, session)
@@ -135,10 +135,10 @@ class Actions(Object):
context.addAction(self.toggle_layer_enabled)
def addInfluencesActions(self, context):
- context.addAction(self.separator(context, "Actions"))
+ context.addAction(self.separator(context, "动作"))
context.addAction(self.toolsAssignFromClosestJointSelectedInfluences)
context.addAction(self.select_affected_vertices)
- context.addAction(self.separator(context, "Clipboard"))
+ context.addAction(self.separator(context, "剪贴板"))
context.addAction(self.cut_influences)
context.addAction(self.copy_influences)
context.addAction(self.paste_weights)
diff --git a/2025/scripts/rigging_tools/ngskintools2/ui/influenceMappingUI.py b/2025/scripts/rigging_tools/ngskintools2/ui/influenceMappingUI.py
index a77deef..b3991e8 100644
--- a/2025/scripts/rigging_tools/ngskintools2/ui/influenceMappingUI.py
+++ b/2025/scripts/rigging_tools/ngskintools2/ui/influenceMappingUI.py
@@ -36,7 +36,7 @@ def open_as_dialog(parent, matcher, result_callback):
window.close()
def save_defaults():
- if not yesNo("Save current settings as default?"):
+ if not yesNo("将当前设置保存为默认设置?"):
return
config.mirrorInfluencesDefaults = matcher.config.as_json()
@@ -47,18 +47,18 @@ def open_as_dialog(parent, matcher, result_callback):
return widgets.button_row(
[
- ("Apply", apply),
- ("Cancel", window.close),
+ ("应用", apply),
+ ("取消", window.close),
],
side_menu=[
- ("Save As Default", save_defaults),
- ("Load Defaults", load_defaults),
+ ("储存为默认值", save_defaults),
+ ("加载默认值", load_defaults),
],
)
window = QtWidgets.QDialog(parent)
cleanup.registerCleanupHandler(window.close)
- window.setWindowTitle("Influence Mirror Mapping")
+ window.setWindowTitle("影响镜像映射")
window.setAttribute(QtCore.Qt.WA_DeleteOnClose)
window.resize(720 * scale_multiplier, 500 * scale_multiplier)
window.setLayout(QtWidgets.QVBoxLayout())
@@ -102,10 +102,10 @@ def build_ui(parent, matcher):
split_path = path.rsplit("|", 1)
parent_path, name = split_path if len(split_path) == 2 else ["", split_path[0]]
- item = QtWidgets.QTreeWidgetItem([name, '-', '(not in skin cluster)' if is_intermediate else '?'])
+ item = QtWidgets.QTreeWidgetItem([name, '-', '(不在皮肤簇中)' if is_intermediate else '?'])
tree_items[path] = item
- parent_item = None if parent_path == "" else find_item(parent_path, True)
+ parent_item = None if parent_path is "" else find_item(parent_path, True)
if parent_item is not None:
parent_item.addChild(item)
@@ -142,7 +142,7 @@ def build_ui(parent, matcher):
def pattern():
result = QtWidgets.QTableWidget()
result.setColumnCount(2)
- result.setHorizontalHeaderLabels(["Pattern", "Opposite"] if mirror_mode else ["Source", "Destination"])
+ result.setHorizontalHeaderLabels(["左", "右"] if mirror_mode else ["来源", "目标"])
result.setEditTriggers(QtWidgets.QTableWidget.AllEditTriggers)
result.verticalHeader().setVisible(False)
@@ -209,12 +209,12 @@ def build_ui(parent, matcher):
def automaticRules():
form = QtWidgets.QFormLayout()
- use_joint_names = QtWidgets.QCheckBox("Match by joint name")
+ use_joint_names = QtWidgets.QCheckBox("匹配骨骼名称")
naming_patterns = pattern()
- use_position = QtWidgets.QCheckBox("Match by position")
+ use_position = QtWidgets.QCheckBox("匹配位置")
tolerance_scroll = tolerance()
- use_joint_labels = QtWidgets.QCheckBox("Match by joint label")
- use_dg_links = QtWidgets.QCheckBox("Match by dependency graph links")
+ use_joint_labels = QtWidgets.QCheckBox("匹配骨骼标签")
+ use_dg_links = QtWidgets.QCheckBox("匹配依存关系图连接")
def update_enabled_disabled():
def enable_form_row(form_item, e):
@@ -260,27 +260,27 @@ def build_ui(parent, matcher):
use_dg_links.setChecked(matcher.config.use_dg_link_matching)
update_enabled_disabled()
- g = QtWidgets.QGroupBox("Rules")
+ g = QtWidgets.QGroupBox("规则")
g.setLayout(form)
form.addRow(use_dg_links)
- form.addRow("Attribute name:", dg_attribute)
+ form.addRow("属性名称:", dg_attribute)
form.addRow(use_joint_labels)
form.addRow(use_joint_names)
- form.addRow("Naming scheme:", naming_patterns)
+ form.addRow("命名方案:", naming_patterns)
form.addRow(use_position)
- form.addRow("Position tolerance:", tolerance_scroll.layout())
+ form.addRow("位置容差:", tolerance_scroll.layout())
update_values()
return g
def scriptedRules():
- g = QtWidgets.QGroupBox("Scripted rules")
+ g = QtWidgets.QGroupBox("脚本规则")
g.setLayout(QtWidgets.QVBoxLayout())
g.layout().addWidget(QtWidgets.QLabel("TODO"))
return g
def manualRules():
- g = QtWidgets.QGroupBox("Manual overrides")
+ g = QtWidgets.QGroupBox("手动覆盖")
g.setLayout(QtWidgets.QVBoxLayout())
g.layout().addWidget(QtWidgets.QLabel("TODO"))
return g
@@ -302,7 +302,7 @@ def build_ui(parent, matcher):
def createMappingView():
view = QtWidgets.QTreeWidget()
view.setColumnCount(3)
- view.setHeaderLabels(["Source", "Destination", "Matched by rule"])
+ view.setHeaderLabels(["来源", "目标", "按规则匹配"])
view.setIndentation(7)
view.setExpandsOnDoubleClick(False)
@@ -316,14 +316,14 @@ def build_ui(parent, matcher):
:type mapping: dict[InfluenceInfo, InfluenceInfo]
"""
for treeItem in list(usedItems.values()):
- treeItem.setText(1, "(not matched)")
+ treeItem.setText(1, "(不匹配)")
treeItem.setText(2, "")
for k, v in list(mapping.items()):
treeItem = usedItems.get(k.path_name(), None)
if treeItem is None:
continue
- treeItem.setText(1, "(self)" if k == v['infl'] else v["infl"].shortestPath)
+ treeItem.setText(1, "(自己)" if k == v['infl'] else v["infl"].shortestPath)
treeItem.setText(2, v["matchedRule"])
treeItem.setData(1, linkedItemRole, v["infl"].path)
@@ -343,7 +343,7 @@ def build_ui(parent, matcher):
matches = matcher.calculate()
mappingView_updateMatches(matches)
- g = QtWidgets.QGroupBox("Calculated mapping")
+ g = QtWidgets.QGroupBox("计算映射")
g.setLayout(QtWidgets.QVBoxLayout())
mappingView, mappingView_updateMatches = createMappingView()
g.layout().addWidget(mappingView)
diff --git a/2025/scripts/rigging_tools/ngskintools2/ui/influencesview.py b/2025/scripts/rigging_tools/ngskintools2/ui/influencesview.py
index 2f5307b..8c18b93 100644
--- a/2025/scripts/rigging_tools/ngskintools2/ui/influencesview.py
+++ b/2025/scripts/rigging_tools/ngskintools2/ui/influencesview.py
@@ -19,9 +19,9 @@ def build_used_influences_action(parent):
result = actions.define_action(
parent,
- "Used Influences Only",
+ "只显示有权重的影响物",
callback=toggle,
- tooltip="If enabled, influences view will only show influences that have weights on current layer",
+ tooltip="如果启用,影响视图将仅显示当前层上有权重的影响。",
)
@signal.on(config.influences_show_used_influences_only.changed, qtParent=parent)
@@ -46,7 +46,7 @@ def build_set_influences_sorted_action(parent):
parent,
"Show influences sorted",
callback=toggle,
- tooltip="Sort influences by name",
+ tooltip="按名称排序影响",
)
@signal.on(config.influences_show_used_influences_only.changed, qtParent=parent)
@@ -108,7 +108,7 @@ def build_view(parent, actions, session, filter):
targets = (item_id,)
layer.locked_influences = add_or_remove(layer.locked_influences, targets, lock)
- log.info("updated locked influences to %r", layer.locked_influences)
+ log.info("更新锁定的影响为 %r", layer.locked_influences)
session.events.influencesListUpdated.emit()
return handler
@@ -170,14 +170,14 @@ def build_view(parent, actions, session, filter):
view.setSelectionMode(QtWidgets.QAbstractItemView.ExtendedSelection)
view.setContextMenuPolicy(QtCore.Qt.ActionsContextMenu)
actions.addInfluencesActions(view)
- view.addAction(actions.separator(parent, "View Options"))
+ view.addAction(actions.separator(parent, "显示设置"))
view.addAction(actions.show_used_influences_only)
view.addAction(actions.set_influences_sorted)
view.setIndentation(10 * scale_multiplier)
view.header().setStretchLastSection(False)
view.header().setSectionResizeMode(0, QtWidgets.QHeaderView.Stretch)
- view.setHeaderLabels(["Influences", ""])
+ view.setHeaderLabels(["影响物", ""])
view.header().setSectionResizeMode(1, QtWidgets.QHeaderView.Fixed)
view.setColumnWidth(1, 25 * scale_multiplier)
@@ -208,7 +208,7 @@ def build_view(parent, actions, session, filter):
if not session.state.currentLayer.layer:
build_items(view, [], None)
else:
- log.info("current layer changed to %s", session.state.currentLayer.layer)
+ log.info("当前图层更改为 %s", session.state.currentLayer.layer)
refresh_items()
current_influence_changed()
@@ -217,7 +217,7 @@ def build_view(parent, actions, session, filter):
if session.state.currentLayer.layer is None:
return
- log.info("current influence changed - updating item selection")
+ log.info("当前影响已更改-更新项目选择")
with qt.signals_blocked(view):
targets = session.state.currentLayer.layer.paint_targets
first = True
@@ -239,12 +239,12 @@ def build_view(parent, actions, session, filter):
if not session.state.currentLayer.layer:
return
- log.info("focused item changed: %r", get_item_id(curr))
+ log.info("焦点项已更改: %r", get_item_id(curr))
sync_paint_targets_to_selection()
@qt.on(view.itemSelectionChanged)
def sync_paint_targets_to_selection():
- log.info("syncing paint targets")
+ log.info("同步绘画目标")
selected_ids = [get_item_id(item) for item in view.selectedItems()]
selected_ids = [i for i in selected_ids if i is not None]
diff --git a/2025/scripts/rigging_tools/ngskintools2/ui/layersview.py b/2025/scripts/rigging_tools/ngskintools2/ui/layersview.py
index 708450c..a959849 100644
--- a/2025/scripts/rigging_tools/ngskintools2/ui/layersview.py
+++ b/2025/scripts/rigging_tools/ngskintools2/ui/layersview.py
@@ -48,12 +48,12 @@ def build_view(parent, actions):
child_layer = item_to_layer(child)
if child_layer.parent_id != parent_layer_id:
- log.info("changing layer parent: %r->%r (was %r)", parent_layer_id, child_layer, child_layer.parent_id)
+ log.info("更改图层父级: %r->%r (was %r)", parent_layer_id, child_layer, child_layer.parent_id)
child_layer.parent = parent_layer_id
new_index = tree_item.childCount() - i - 1
if child_layer.index != new_index:
- log.info("changing layer index: %r->%r (was %r)", child_layer, new_index, child_layer.index)
+ log.info("更改图层索引: %r->%r (was %r)", child_layer, new_index, child_layer.index)
child_layer.index = new_index
sync_item(child, child_layer.id)
@@ -82,7 +82,7 @@ def build_view(parent, actions):
view.setContextMenuPolicy(QtCore.Qt.ActionsContextMenu)
actions.addLayersActions(view)
- view.setHeaderLabels(["Layers", ""])
+ view.setHeaderLabels(["图层", ""])
# view.setHeaderHidden(True)
view.header().setMinimumSectionSize(1)
view.header().setStretchLastSection(False)
@@ -100,7 +100,7 @@ def build_view(parent, actions):
bar = QtWidgets.QToolBar(parent=parent)
bar.setMovable(False)
bar.setIconSize(QtCore.QSize(visibility_icon_size * scale_multiplier, visibility_icon_size * scale_multiplier))
- a = bar.addAction(icon_visible if layer is None or layer.enabled else icon_hidden, "Toggle enabled/disabled")
+ a = bar.addAction(icon_visible if layer is None or layer.enabled else icon_hidden, "切换 启用/禁用")
@qt.on(a.triggered)
def handler():
@@ -117,11 +117,11 @@ def build_view(parent, actions):
# build map "parent id->list of children "
- log.info("syncing items...")
+ log.info("同步项目q...")
# save selected layers IDs to restore item selection later
selected_layer_ids = {item_to_layer(item).id for item in view.selectedItems()}
- log.info("selected layer IDs: %r", selected_layer_ids)
+ log.info("选择层 IDs: %r", selected_layer_ids)
current_item_id = None if view.currentItem() is None else item_to_layer(view.currentItem()).id
hierarchy = {}
@@ -167,7 +167,7 @@ def build_view(parent, actions):
@signal.on(session.events.layerListChanged, qtParent=view)
def refresh_layer_list():
- log.info("event handler for layer list changed")
+ log.info("图层列表更改的事件处理程序")
if not session.state.layersAvailable:
build_items([])
else:
@@ -177,7 +177,7 @@ def build_view(parent, actions):
@signal.on(session.events.currentLayerChanged, qtParent=view)
def current_layer_changed():
- log.info("event handler for currentLayerChanged")
+ log.info("当前图层更改的事件处理程序")
layer = session.state.currentLayer.layer
current_item = view.currentItem()
if layer is None:
@@ -189,14 +189,14 @@ def build_view(parent, actions):
if prev_layer is None or prev_layer.id != layer.id:
item = tree_items.get(layer.id, None)
if item is not None:
- log.info("setting current item to " + item.text(0))
+ log.info("将当前项目设置为 " + item.text(0))
view.setCurrentItem(item, 0, QtCore.QItemSelectionModel.SelectCurrent | QtCore.QItemSelectionModel.ClearAndSelect)
item.setSelected(True)
@qt.on(view.currentItemChanged)
def current_item_changed(curr, _):
- log.info("current item changed")
+ log.info("当前项目已更改")
if curr is None:
return
@@ -209,7 +209,7 @@ def build_view(parent, actions):
@qt.on(view.itemChanged)
def item_changed(item, column):
- log.info("item changed")
+ log.info("项目已更改")
layers.renameLayer(item_to_layer(item), item.text(column))
@qt.on(view.itemSelectionChanged)
@@ -217,7 +217,7 @@ def build_view(parent, actions):
selection = [item_to_layer(item) for item in view.selectedItems()]
if selection != session.context.selected_layers(default=[]):
- log.info("new selected layers: %r", selection)
+ log.info("新选择图层: %r", selection)
session.context.selected_layers.set(selection)
refresh_layer_list()
diff --git a/2025/scripts/rigging_tools/ngskintools2/ui/mainwindow.py b/2025/scripts/rigging_tools/ngskintools2/ui/mainwindow.py
index e5b2e87..8b12a4f 100644
--- a/2025/scripts/rigging_tools/ngskintools2/ui/mainwindow.py
+++ b/2025/scripts/rigging_tools/ngskintools2/ui/mainwindow.py
@@ -46,20 +46,20 @@ def build_menu(parent, actions):
sub_item.setTearOffEnabled(True)
return sub_item
- sub = top_level_menu("File")
- sub.addSeparator().setText("Import/Export")
+ sub = top_level_menu("文件")
+ sub.addSeparator().setText("导入/导出")
sub.addAction(actions.importFile)
sub.addAction(actions.exportFile)
- sub = top_level_menu("Layers")
- sub.addSeparator().setText("Layer actions")
+ sub = top_level_menu("图层")
+ sub.addSeparator().setText("图层操作")
sub.addAction(actions.initialize)
sub.addAction(actions.import_v1)
actions.addLayersActions(sub)
- sub.addSeparator().setText("Copy")
+ sub.addSeparator().setText("复制")
sub.addAction(actions.transfer)
- sub = top_level_menu("Tools")
+ sub = top_level_menu("工具")
sub.addAction(actions.add_influences)
sub.addAction(actions.toolsAssignFromClosestJoint)
sub.addSeparator()
@@ -68,17 +68,17 @@ def build_menu(parent, actions):
sub.addAction(actions.toolsDeleteCustomNodesOnSelection)
sub.addAction(actions.toolsDeleteCustomNodes)
- sub = top_level_menu("View")
+ sub = top_level_menu("查看")
sub.addAction(actions.show_used_influences_only)
- sub = top_level_menu("Help")
+ sub = top_level_menu("帮助")
sub.addAction(actions.documentation.user_guide)
sub.addAction(actions.documentation.api_root)
sub.addAction(actions.documentation.changelog)
sub.addAction(actions.documentation.contact)
sub.addSeparator()
sub.addAction(actions.check_for_updates)
- sub.addAction("About...").triggered.connect(lambda: aboutwindow.show(parent))
+ sub.addAction("关于...").triggered.connect(lambda: aboutwindow.show(parent))
return menu
@@ -107,11 +107,11 @@ def build_ui(parent):
tabs = QtWidgets.QTabWidget(window)
- tabs.addTab(tabPaint.build_ui(tabs, actions), "Paint")
- tabs.addTab(tabSetWeights.build_ui(tabs), "Set Weights")
- tabs.addTab(tabMirror.build_ui(tabs), "Mirror")
- tabs.addTab(tabLayerEffects.build_ui(), "Effects")
- tabs.addTab(tabTools.build_ui(actions, session), "Tools")
+ tabs.addTab(tabPaint.build_ui(tabs, actions), "绘制")
+ tabs.addTab(tabSetWeights.build_ui(tabs), "设置权重")
+ tabs.addTab(tabMirror.build_ui(tabs), "镜像")
+ tabs.addTab(tabLayerEffects.build_ui(), "样式")
+ tabs.addTab(tabTools.build_ui(actions, session), "工具")
@signal.on(options.current_tab.changed)
def set_current_tab():
diff --git a/2025/scripts/rigging_tools/ngskintools2/ui/model_binds.py b/2025/scripts/rigging_tools/ngskintools2/ui/model_binds.py
index 314313c..da06573 100644
--- a/2025/scripts/rigging_tools/ngskintools2/ui/model_binds.py
+++ b/2025/scripts/rigging_tools/ngskintools2/ui/model_binds.py
@@ -19,4 +19,4 @@ def bind(ui, model):
model.set(ui.value())
else:
- raise Exception("could not bind control to model")
+ raise Exception("无法将控件绑定到模型")
diff --git a/2025/scripts/rigging_tools/ngskintools2/ui/options.py b/2025/scripts/rigging_tools/ngskintools2/ui/options.py
index df7ddca..076510b 100644
--- a/2025/scripts/rigging_tools/ngskintools2/ui/options.py
+++ b/2025/scripts/rigging_tools/ngskintools2/ui/options.py
@@ -99,10 +99,10 @@ def save_option(varName, value):
elif is_string(value):
key = 'sv'
else:
- raise ValueError("could not save option %s: invalid value %r" % (varName, value))
+ raise ValueError("无法保存选项 %s: 无效值 %r" % (varName, value))
kvargs = {key: (varName, value)}
- log.info("saving optionvar: %r", kvargs)
+ log.info("保存选项变量: %r", kvargs)
cmds.optionVar(**kvargs)
@@ -153,11 +153,11 @@ class Config(Object):
def __get_value__(self, name, default_value):
result = self.__state__.get(name, default_value)
- log.info("config: return %s=%r", name, result)
+ log.info("配置: return %s=%r", name, result)
return result
def __set_value__(self, name, value):
- log.info("config: save %s=%r", name, value)
+ log.info("配置: save %s=%r", name, value)
self.__state__[name] = value
self.save()
diff --git a/2025/scripts/rigging_tools/ngskintools2/ui/tabLayerEffects.py b/2025/scripts/rigging_tools/ngskintools2/ui/tabLayerEffects.py
index 56c53f6..4da7beb 100644
--- a/2025/scripts/rigging_tools/ngskintools2/ui/tabLayerEffects.py
+++ b/2025/scripts/rigging_tools/ngskintools2/ui/tabLayerEffects.py
@@ -36,9 +36,9 @@ def build_ui():
def build_properties():
layout = QtWidgets.QVBoxLayout()
- opacity = widgets.NumberSliderGroup(tooltip="multiply layer mask to control overall transparency of the layer.")
+ opacity = widgets.NumberSliderGroup(tooltip="多层蒙版来控制图层的整体透明度.")
opacity.set_value(1.0)
- layout.addLayout(createTitledRow("Opacity:", opacity.layout()))
+ layout.addLayout(createTitledRow("不透明度:", opacity.layout()))
def default_selection_opacity(layers):
if len(layers) > 0:
@@ -65,7 +65,7 @@ def build_ui():
update_values()
- group = QtWidgets.QGroupBox("Layer properties")
+ group = QtWidgets.QGroupBox("图层属性")
group.setLayout(layout)
return group
@@ -76,18 +76,18 @@ def build_ui():
i.effects.configure_mirror(**{option: value})
mirror_direction = QtWidgets.QComboBox()
- mirror_direction.addItem("Positive to negative", MirrorOptions.directionPositiveToNegative)
- mirror_direction.addItem("Negative to positive", MirrorOptions.directionNegativeToPositive)
- mirror_direction.addItem("Flip", MirrorOptions.directionFlip)
+ mirror_direction.addItem("从正到负", MirrorOptions.directionPositiveToNegative)
+ mirror_direction.addItem("从负到正", MirrorOptions.directionNegativeToPositive)
+ mirror_direction.addItem("翻转", MirrorOptions.directionFlip)
mirror_direction.setMinimumWidth(1)
@qt.on(mirror_direction.currentIndexChanged)
def value_changed():
- configure_mirror_all_layers("mirror_direction", mirror_direction.currentData())
+ configure_mirror_all_layers("镜像方向", mirror_direction.currentData())
- influences = QtWidgets.QCheckBox("Influence weights")
- mask = QtWidgets.QCheckBox("Layer mask")
- dq = QtWidgets.QCheckBox("Dual quaternion weights")
+ influences = QtWidgets.QCheckBox("影响物权重")
+ mask = QtWidgets.QCheckBox("图层蒙板")
+ dq = QtWidgets.QCheckBox("双四元数权重")
def configure_checkbox(checkbox, option):
@qt.on(checkbox.stateChanged)
@@ -125,21 +125,21 @@ def build_ui():
return result
layout = QtWidgets.QVBoxLayout()
- layout.addLayout(createTitledRow("Mirror effect on:", elements()))
- layout.addLayout(createTitledRow("Mirror direction:", mirror_direction))
+ layout.addLayout(createTitledRow("镜像效果打开:", elements()))
+ layout.addLayout(createTitledRow("镜像方向:", mirror_direction))
- group = QtWidgets.QGroupBox("Mirror")
+ group = QtWidgets.QGroupBox("镜像")
group.setLayout(layout)
return group
def build_skin_properties():
- use_max_influences = QtWidgets.QCheckBox("Limit max influences per vertex")
+ use_max_influences = QtWidgets.QCheckBox("限制每个顶点的最大影响物")
max_influences = widgets.NumberSliderGroup(min_value=1, max_value=5, tooltip="", value_type=int)
- use_prune_weight = QtWidgets.QCheckBox("Prune small weights before writing to skin cluster")
+ use_prune_weight = QtWidgets.QCheckBox("在写入蒙皮簇之前修剪小权重")
prune_weight = widgets.NumberSliderGroup(decimals=6, min_value=0.000001, max_value=0.05, tooltip="")
prune_weight.set_value(prune_weight.min_value)
- prune_weight.set_expo("start", 3)
+ prune_weight.set_expo("开始", 3)
@signal.on(session.events.targetChanged)
def update_ui():
@@ -164,7 +164,7 @@ def build_ui():
@qt.on(use_max_influences.stateChanged, use_prune_weight.stateChanged)
@signal.on(max_influences.valueChanged, prune_weight.valueChanged)
def update_values():
- log.info("updating effects tab")
+ log.info("更新效果标签页")
if session.state.layersAvailable:
session.state.layers.influence_limit_per_vertex = max_influences.value() if use_max_influences.isChecked() else 0
@@ -174,11 +174,11 @@ def build_ui():
layout = QtWidgets.QVBoxLayout()
layout.addWidget(use_max_influences)
- layout.addLayout(createTitledRow("Max influences:", max_influences.layout()))
+ layout.addLayout(createTitledRow("最大影响物:", max_influences.layout()))
layout.addWidget(use_prune_weight)
- layout.addLayout(createTitledRow("Prune below:", prune_weight.layout()))
+ layout.addLayout(createTitledRow("修剪以下:", prune_weight.layout()))
- group = QtWidgets.QGroupBox("Skin Properties")
+ group = QtWidgets.QGroupBox("蒙皮属性")
group.setLayout(layout)
update_ui()
diff --git a/2025/scripts/rigging_tools/ngskintools2/ui/tabMirror.py b/2025/scripts/rigging_tools/ngskintools2/ui/tabMirror.py
index c8873f8..bae7ec9 100644
--- a/2025/scripts/rigging_tools/ngskintools2/ui/tabMirror.py
+++ b/2025/scripts/rigging_tools/ngskintools2/ui/tabMirror.py
@@ -16,10 +16,10 @@ def build_ui(parent_window):
def build_mirroring_options_group():
def get_mirror_direction():
mirror_direction = QtWidgets.QComboBox()
- mirror_direction.addItem("Guess from stroke", MirrorOptions.directionGuess)
- mirror_direction.addItem("Positive to negative", MirrorOptions.directionPositiveToNegative)
- mirror_direction.addItem("Negative to positive", MirrorOptions.directionNegativeToPositive)
- mirror_direction.addItem("Flip", MirrorOptions.directionFlip)
+ mirror_direction.addItem("从笔划猜测", MirrorOptions.directionGuess)
+ mirror_direction.addItem("从正到负", MirrorOptions.directionPositiveToNegative)
+ mirror_direction.addItem("从负到正", MirrorOptions.directionNegativeToPositive)
+ mirror_direction.addItem("翻转", MirrorOptions.directionFlip)
mirror_direction.setMinimumWidth(1)
qt.select_data(mirror_direction, config.mirror_direction())
@@ -65,19 +65,19 @@ def build_ui(parent_window):
return seam_width_ctrl.layout()
def elements():
- influences = bind_checkbox(QtWidgets.QCheckBox("Influence weights"), config.mirror_weights)
- mask = bind_checkbox(QtWidgets.QCheckBox("Layer mask"), config.mirror_mask)
- dq = bind_checkbox(QtWidgets.QCheckBox("Dual quaternion weights"), config.mirror_dq)
+ influences = bind_checkbox(QtWidgets.QCheckBox("影响物权重"), config.mirror_weights)
+ mask = bind_checkbox(QtWidgets.QCheckBox("图层遮罩"), config.mirror_mask)
+ dq = bind_checkbox(QtWidgets.QCheckBox("双四元权重"), config.mirror_dq)
return influences, mask, dq
- result = QtWidgets.QGroupBox("Mirroring options")
+ result = QtWidgets.QGroupBox("镜像选项")
layout = QtWidgets.QVBoxLayout()
result.setLayout(layout)
- layout.addLayout(createTitledRow("Axis:", axis()))
- layout.addLayout(createTitledRow("Direction:", get_mirror_direction()))
- layout.addLayout(createTitledRow("Seam width:", mirror_seam_width()))
- layout.addLayout(createTitledRow("Elements to mirror:", *elements()))
+ layout.addLayout(createTitledRow("镜像轴:", axis()))
+ layout.addLayout(createTitledRow("方向:", get_mirror_direction()))
+ layout.addLayout(createTitledRow("接缝宽度:", mirror_seam_width()))
+ layout.addLayout(createTitledRow("镜像要素:", *elements()))
return result
@@ -86,10 +86,10 @@ def build_ui(parent_window):
def mirror_mesh_group():
mesh_name_edit = QtWidgets.QLineEdit("mesh1")
mesh_name_edit.setReadOnly(True)
- select_button = QtWidgets.QPushButton("Select")
- create_button = QtWidgets.QPushButton("Create")
+ select_button = QtWidgets.QPushButton("选择")
+ create_button = QtWidgets.QPushButton("创建")
set_button = QtWidgets.QPushButton("Set")
- set_button.setToolTip("Select symmetry mesh and a skinned target first")
+ set_button.setToolTip("首先选择对称网格和蒙皮目标")
layout = QtWidgets.QHBoxLayout()
layout.addWidget(mesh_name_edit)
@@ -144,13 +144,13 @@ def build_ui(parent_window):
return layout
vertex_mapping_mode = QtWidgets.QComboBox()
- vertex_mapping_mode.addItem("Closest point on surface", VertexTransferMode.closestPoint)
- vertex_mapping_mode.addItem("UV space", VertexTransferMode.uvSpace)
+ vertex_mapping_mode.addItem("曲面上最近的点", VertexTransferMode.closestPoint)
+ vertex_mapping_mode.addItem("UV空间", VertexTransferMode.uvSpace)
- result = QtWidgets.QGroupBox("Vertex Mapping")
+ result = QtWidgets.QGroupBox("顶点映射")
layout = QtWidgets.QVBoxLayout()
- layout.addLayout(createTitledRow("Mapping mode:", vertex_mapping_mode))
- layout.addLayout(createTitledRow("Symmetry mesh:", mirror_mesh_group()))
+ layout.addLayout(createTitledRow("映射模式:", vertex_mapping_mode))
+ layout.addLayout(createTitledRow("对称网格:", mirror_mesh_group()))
result.setLayout(layout)
@qt.on(vertex_mapping_mode.currentIndexChanged)
@@ -166,7 +166,7 @@ def build_ui(parent_window):
def influence_mapping_group():
def edit_mapping():
- mapping = QtWidgets.QPushButton("Preview and edit mapping")
+ mapping = QtWidgets.QPushButton("预览和编辑映射")
single_window_policy = qt.SingleWindowPolicy()
@@ -182,7 +182,7 @@ def build_ui(parent_window):
layout = QtWidgets.QVBoxLayout()
layout.addWidget(edit_mapping())
- result = QtWidgets.QGroupBox("Influences mapping")
+ result = QtWidgets.QGroupBox("影响物映射")
result.setLayout(layout)
return result
@@ -192,7 +192,7 @@ def build_ui(parent_window):
tab.innerLayout.addWidget(influence_mapping_group())
tab.innerLayout.addStretch()
- btn_mirror = QtWidgets.QPushButton("Mirror")
+ btn_mirror = QtWidgets.QPushButton("镜像")
tab.lowerButtonsRow.addWidget(btn_mirror)
@qt.on(btn_mirror.clicked)
diff --git a/2025/scripts/rigging_tools/ngskintools2/ui/tabPaint.py b/2025/scripts/rigging_tools/ngskintools2/ui/tabPaint.py
index 9ee6d56..f265d6e 100644
--- a/2025/scripts/rigging_tools/ngskintools2/ui/tabPaint.py
+++ b/2025/scripts/rigging_tools/ngskintools2/ui/tabPaint.py
@@ -50,14 +50,14 @@ def build_ui(parent, global_actions):
t.addAction(a)
t = QtWidgets.QToolBar()
- create_brush_mode_button(t, PaintMode.replace, "Replace", "Whatever")
- create_brush_mode_button(t, PaintMode.add, "Add", "")
- create_brush_mode_button(t, PaintMode.scale, "Scale", "")
+ create_brush_mode_button(t, PaintMode.replace, "替换", "替换")
+ create_brush_mode_button(t, PaintMode.add, "添加", "")
+ create_brush_mode_button(t, PaintMode.scale, "减少", "")
row.addWidget(t)
t = QtWidgets.QToolBar()
- create_brush_mode_button(t, PaintMode.smooth, "Smooth", "")
- create_brush_mode_button(t, PaintMode.sharpen, "Sharpen", "")
+ create_brush_mode_button(t, PaintMode.smooth, "平滑", "")
+ create_brush_mode_button(t, PaintMode.sharpen, "锐化", "")
row.addWidget(t)
@on_signal(et.tool_settings_changed, scope=row)
@@ -96,9 +96,9 @@ def build_ui(parent, global_actions):
update_to_tool()
qt.on(a.toggled)(toggled)
- add_brush_shape_action(':/circleSolid.png', 'Solid', BrushShape.solid, checked=True)
- add_brush_shape_action(':/circlePoly.png', 'Smooth', BrushShape.smooth)
- add_brush_shape_action(':/circleGaus.png', 'Gaus', BrushShape.gaus)
+ add_brush_shape_action(':/circleSolid.png', '硬边圆', BrushShape.solid, checked=True)
+ add_brush_shape_action(':/circlePoly.png', '软边圆', BrushShape.smooth)
+ add_brush_shape_action(':/circleGaus.png', '喷枪', BrushShape.gaus)
return result
@@ -136,23 +136,23 @@ def build_ui(parent, global_actions):
update_to_tool()
add(
- 'Surface',
- 'Using first surface hit under the mouse, update all nearby vertices that are connected by surface to the hit location. '
- + 'Only current shell will be updated.',
+ '表面',
+ '绘制由与曲面相连的模型顶点.'
+ + '仅更新当前shell.',
BrushProjectionMode.surface,
use_volume=False,
checked=True,
)
add(
- 'Volume',
- 'Using first surface hit under the mouse, update all nearby vertices, including those from other shells.',
+ '体积',
+ '绘制附近所有模型顶点,包括没有连接的顶点.',
BrushProjectionMode.surface,
use_volume=True,
checked=False,
)
add(
- 'Screen',
- 'Use screen projection of a brush, updating all vertices on all surfaces that are within the brush radius.',
+ '屏幕',
+ '从屏幕方向投影到笔刷半径内所有曲面上的顶点.',
BrushProjectionMode.screen,
use_volume=False,
checked=False,
@@ -163,53 +163,53 @@ def build_ui(parent, global_actions):
def stylus_pressure_selection():
# noinspection PyShadowingNames
result = QtWidgets.QComboBox()
- result.addItem("Unused")
- result.addItem("Multiply intensity")
- result.addItem("Multiply opacity")
- result.addItem("Multiply radius")
+ result.addItem("未使用")
+ result.addItem("倍增强度")
+ result.addItem("倍增不透明度")
+ result.addItem("倍增半径")
return result
layout = QtWidgets.QVBoxLayout()
- layout.addLayout(createTitledRow("Brush projection:", brush_projection_mode_row()))
- layout.addLayout(createTitledRow("Brush mode:", brush_mode_row3()))
- layout.addLayout(createTitledRow("Brush shape:", brush_shape_row()))
+ layout.addLayout(createTitledRow("笔刷投影:", brush_projection_mode_row()))
+ layout.addLayout(createTitledRow("笔刷模式:", brush_mode_row3()))
+ layout.addLayout(createTitledRow("笔刷形状:", brush_shape_row()))
intensity = widgets.NumberSliderGroup()
radius = widgets.NumberSliderGroup(
- max_value=100, tooltip="You can also set brush radius by just holding B " "and mouse-dragging in the viewport"
+ max_value=100, tooltip="可以通过在视口中按住 B " "并鼠标左键按住拖动来设置笔刷半径"
)
iterations = widgets.NumberSliderGroup(value_type=int, min_value=1, max_value=100)
- layout.addLayout(createTitledRow("Intensity:", intensity.layout()))
- layout.addLayout(createTitledRow("Brush radius:", radius.layout()))
- layout.addLayout(createTitledRow("Brush iterations:", iterations.layout()))
+ layout.addLayout(createTitledRow("强度:", intensity.layout()))
+ layout.addLayout(createTitledRow("笔刷半径:", radius.layout()))
+ layout.addLayout(createTitledRow("笔刷迭代次数:", iterations.layout()))
influences_limit = widgets.NumberSliderGroup(value_type=int, min_value=0, max_value=10)
- layout.addLayout(createTitledRow("Influences limit:", influences_limit.layout()))
+ layout.addLayout(createTitledRow("影响物限制:", influences_limit.layout()))
@signal.on(influences_limit.valueChanged)
def influences_limit_changed():
paint.influences_limit = influences_limit.value()
update_ui()
- fixed_influences = QtWidgets.QCheckBox("Only adjust existing vertex influences")
+ fixed_influences = QtWidgets.QCheckBox("仅调整顶点现有影响物,防止周围权重扩散")
fixed_influences.setToolTip(
- "When this option is enabled, smooth will only adjust existing influences per vertex, "
- "and won't include other influences from nearby vertices"
+ "启用此选项后,平滑-将仅调整每个顶点的现有影响物, "
+ "而不会包含来自附近顶点的影响物,防止周围权重扩散"
)
- layout.addLayout(createTitledRow("Weight bleeding:", fixed_influences))
+ layout.addLayout(createTitledRow("平滑辅助:", fixed_influences))
@qt.on(fixed_influences.stateChanged)
def fixed_influences_changed():
paint.fixed_influences_per_vertex = fixed_influences.isChecked()
- limit_to_component_selection = QtWidgets.QCheckBox("Limit to component selection")
- limit_to_component_selection.setToolTip("When this option is enabled, smoothing will only happen between selected components")
- layout.addLayout(createTitledRow("Isolation:", limit_to_component_selection))
+ limit_to_component_selection = QtWidgets.QCheckBox("限制在选中组件中平滑")
+ limit_to_component_selection.setToolTip("启用此选项后,仅在选定组件之间进行平滑")
+ layout.addLayout(createTitledRow("隔离选中组件:", limit_to_component_selection))
@qt.on(limit_to_component_selection.stateChanged)
def limit_to_component_selection_changed():
paint.limit_to_component_selection = limit_to_component_selection.isChecked()
- interactive_mirror = QtWidgets.QCheckBox("Interactive mirror")
+ interactive_mirror = QtWidgets.QCheckBox("交互式镜像")
layout.addLayout(createTitledRow("", interactive_mirror))
@qt.on(interactive_mirror.stateChanged)
@@ -217,7 +217,7 @@ def build_ui(parent, global_actions):
paint.mirror = interactive_mirror.isChecked()
update_ui()
- sample_joint_on_stroke_start = QtWidgets.QCheckBox("Sample current joint on stroke start")
+ sample_joint_on_stroke_start = QtWidgets.QCheckBox("在笔画开始时取样当前骨骼")
layout.addLayout(createTitledRow("", sample_joint_on_stroke_start))
@qt.on(sample_joint_on_stroke_start.stateChanged)
@@ -225,8 +225,8 @@ def build_ui(parent, global_actions):
paint.sample_joint_on_stroke_start = sample_joint_on_stroke_start.isChecked()
update_ui()
- redistribute_removed_weight = QtWidgets.QCheckBox("Distribute to other influences")
- layout.addLayout(createTitledRow("Removed weight:", redistribute_removed_weight))
+ redistribute_removed_weight = QtWidgets.QCheckBox("分配给其它影响物")
+ layout.addLayout(createTitledRow("移除的权重:", redistribute_removed_weight))
@qt.on(redistribute_removed_weight.stateChanged)
def redistribute_removed_weight_changed():
@@ -234,12 +234,12 @@ def build_ui(parent, global_actions):
update_ui()
stylus = stylus_pressure_selection()
- layout.addLayout(createTitledRow("Stylus pressure:", stylus))
+ layout.addLayout(createTitledRow("手绘板压力:", stylus))
@on_signal(et.tool_settings_changed, scope=layout)
def update_ui():
- log.info("updating paint settings ui")
- log.info("brush mode:%s, brush shape: %s", paint.mode, paint.brush_shape)
+ log.info("更新的绘制设置的ui")
+ log.info("画笔模式:%s, 画笔形状: %s", paint.mode, paint.brush_shape)
paint.update_plugin_brush_radius()
paint.update_plugin_brush_intensity()
@@ -280,7 +280,7 @@ def build_ui(parent, global_actions):
@signal.on(radius.valueChanged, qtParent=layout)
def radius_edited():
- log.info("updated brush radius")
+ log.info("更新笔刷半径")
paint.brush_radius = radius.value()
update_ui()
@@ -301,18 +301,18 @@ def build_ui(parent, global_actions):
update_ui()
- result = QtWidgets.QGroupBox("Brush behavior")
+ result = QtWidgets.QGroupBox("笔刷行为")
result.setLayout(layout)
return result
def build_display_settings():
- result = QtWidgets.QGroupBox("Display settings")
+ result = QtWidgets.QGroupBox("显示设置")
layout = QtWidgets.QVBoxLayout()
influences_display = QtWidgets.QComboBox()
- influences_display.addItem("All influences, multiple colors", WeightsDisplayMode.allInfluences)
- influences_display.addItem("Current influence, grayscale", WeightsDisplayMode.currentInfluence)
- influences_display.addItem("Current influence, colored", WeightsDisplayMode.currentInfluenceColored)
+ influences_display.addItem("所有权重,多种颜色", WeightsDisplayMode.allInfluences)
+ influences_display.addItem("当前权重,灰度", WeightsDisplayMode.currentInfluence)
+ influences_display.addItem("当前权重,彩色", WeightsDisplayMode.currentInfluenceColored)
influences_display.setMinimumWidth(1)
influences_display.setCurrentIndex(paint.display_settings.weights_display_mode)
@@ -327,11 +327,11 @@ def build_ui(parent, global_actions):
display_layout = QtWidgets.QVBoxLayout()
display_layout.addWidget(influences_display)
display_layout.addWidget(display_toolbar)
- layout.addLayout(createTitledRow("Influences display:", display_layout))
+ layout.addLayout(createTitledRow("权重显示:", display_layout))
mask_display = QtWidgets.QComboBox()
- mask_display.addItem("Default", MaskDisplayMode.default_)
- mask_display.addItem("Color ramp", MaskDisplayMode.color_ramp)
+ mask_display.addItem("默认", MaskDisplayMode.default_)
+ mask_display.addItem("彩色渐变", MaskDisplayMode.color_ramp)
mask_display.setMinimumWidth(1)
mask_display.setCurrentIndex(paint.display_settings.weights_display_mode)
@@ -340,14 +340,14 @@ def build_ui(parent, global_actions):
paint.display_settings.mask_display_mode = mask_display.currentData()
update_ui_to_tool()
- layout.addLayout(createTitledRow("Mask display:", mask_display))
+ layout.addLayout(createTitledRow("表面显示:", mask_display))
- show_effects = QtWidgets.QCheckBox("Show layer effects")
+ show_effects = QtWidgets.QCheckBox("显示图层效果")
layout.addLayout(createTitledRow("", show_effects))
- show_masked = QtWidgets.QCheckBox("Show masked weights")
+ show_masked = QtWidgets.QCheckBox("显示蒙皮权重")
layout.addLayout(createTitledRow("", show_masked))
- show_selected_verts_only = QtWidgets.QCheckBox("Hide unselected vertices")
+ show_selected_verts_only = QtWidgets.QCheckBox("隐藏未选择的顶点")
layout.addLayout(createTitledRow("", show_selected_verts_only))
@qt.on(show_effects.stateChanged)
@@ -363,7 +363,7 @@ def build_ui(parent, global_actions):
paint.display_settings.show_selected_verts_only = show_selected_verts_only.isChecked()
mesh_toolbar = QtWidgets.QToolBar()
- toggle_original_mesh = QAction("Show Original Mesh", mesh_toolbar)
+ toggle_original_mesh = QAction("显示原本模型", mesh_toolbar)
toggle_original_mesh.setCheckable(True)
mesh_toolbar.addAction(toggle_original_mesh)
layout.addLayout(createTitledRow("", mesh_toolbar))
@@ -374,7 +374,7 @@ def build_ui(parent, global_actions):
update_ui_to_tool()
wireframe_color_button = widgets.ColorButton()
- layout.addLayout(createTitledRow("Wireframe color:", wireframe_color_button))
+ layout.addLayout(createTitledRow("线框颜色:", wireframe_color_button))
@signal.on(wireframe_color_button.color_changed)
def update_wireframe_color():
diff --git a/2025/scripts/rigging_tools/ngskintools2/ui/tabSetWeights.py b/2025/scripts/rigging_tools/ngskintools2/ui/tabSetWeights.py
index 0e0e67d..34cd91c 100644
--- a/2025/scripts/rigging_tools/ngskintools2/ui/tabSetWeights.py
+++ b/2025/scripts/rigging_tools/ngskintools2/ui/tabSetWeights.py
@@ -1,3 +1,4 @@
+# -*- coding: UTF-8 -*-
from ngSkinTools2 import signal
from ngSkinTools2.api import PaintMode, PaintModeSettings, flood_weights
from ngSkinTools2.api.log import getLogger
@@ -70,14 +71,14 @@ def build_ui(parent):
toolbar.addAction(a)
t = QtWidgets.QToolBar()
- create_mode_button(t, PaintMode.replace, "Replace", "")
- create_mode_button(t, PaintMode.add, "Add", "")
- create_mode_button(t, PaintMode.scale, "Scale", "")
+ create_mode_button(t, PaintMode.replace, "替换", "")
+ create_mode_button(t, PaintMode.add, "添加", "")
+ create_mode_button(t, PaintMode.scale, "减少", "")
row.addWidget(t)
t = QtWidgets.QToolBar()
- create_mode_button(t, PaintMode.smooth, "Smooth", "")
- create_mode_button(t, PaintMode.sharpen, "Sharpen", "")
+ create_mode_button(t, PaintMode.smooth, "平滑", "")
+ create_mode_button(t, PaintMode.sharpen, "锐化", "")
row.addWidget(t)
actions[model.current_settings.mode].setChecked(True)
@@ -109,20 +110,20 @@ def build_ui(parent):
model.current_settings.iterations = iterations.value()
update_ui()
- fixed_influences = QtWidgets.QCheckBox("Only adjust existing vertex influences")
+ fixed_influences = QtWidgets.QCheckBox("仅调整顶点现有影响物,防止周围权重扩散")
fixed_influences.setToolTip(
- "When this option is enabled, smooth will only adjust existing influences per vertex, "
- "and won't include other influences from nearby vertices"
+ "启用此选项后,平滑-将仅调整每个顶点的现有影响物, "
+ "而不会包含来自附近顶点的影响物,防止周围权重扩散"
)
- volume_neighbours = QtWidgets.QCheckBox("Smooth across gaps and thin surfaces")
+ volume_neighbours = QtWidgets.QCheckBox("平滑间隙和薄表面")
volume_neighbours.setToolTip(
- "Use all nearby neighbours, regardless if they belong to same surface. "
- "This will allow for smoothing to happen across gaps and thin surfaces."
+ "使用所有附近相邻的面,无论它们是否属于同一个曲面."
+ "这将允许在间隙和薄曲面之间进行平滑."
)
- limit_to_component_selection = QtWidgets.QCheckBox("Limit to component selection")
- limit_to_component_selection.setToolTip("When this option is enabled, smoothing will only happen between selected components")
+ limit_to_component_selection = QtWidgets.QCheckBox("在选择的组件中平滑")
+ limit_to_component_selection.setToolTip("启用此选项后,仅在选定组件之间进行平滑")
@qt.on(fixed_influences.stateChanged)
@ui_lock.skip_if_updating
@@ -154,16 +155,16 @@ def build_ui(parent):
volume_neighbours.setChecked(model.current_settings.use_volume_neighbours)
volume_neighbours.setEnabled(model.current_settings.mode == PaintMode.smooth)
- settings_group = QtWidgets.QGroupBox("Mode Settings")
+ settings_group = QtWidgets.QGroupBox("模式设置")
layout = QtWidgets.QVBoxLayout()
- layout.addLayout(createTitledRow("Mode:", mode_row()))
- layout.addLayout(createTitledRow("Intensity:", intensity.layout()))
- layout.addLayout(createTitledRow("Iterations:", iterations.layout()))
- layout.addLayout(createTitledRow("Influences limit:", influences_limit.layout()))
- layout.addLayout(createTitledRow("Weight bleeding:", fixed_influences))
- layout.addLayout(createTitledRow("Volume smoothing:", volume_neighbours))
- layout.addLayout(createTitledRow("Isolation:", limit_to_component_selection))
+ layout.addLayout(createTitledRow("模式:", mode_row()))
+ layout.addLayout(createTitledRow("强度:", intensity.layout()))
+ layout.addLayout(createTitledRow("迭代次数:", iterations.layout()))
+ layout.addLayout(createTitledRow("影响物限制:", influences_limit.layout()))
+ layout.addLayout(createTitledRow("平滑辅助:", fixed_influences))
+ layout.addLayout(createTitledRow("体积平滑:", volume_neighbours))
+ layout.addLayout(createTitledRow("隔离选中组件:", limit_to_component_selection))
settings_group.setLayout(layout)
update_ui()
@@ -173,7 +174,7 @@ def build_ui(parent):
def common_settings():
layout = QtWidgets.QVBoxLayout()
- mirror = QtWidgets.QCheckBox("Mirror")
+ mirror = QtWidgets.QCheckBox("镜像")
layout.addLayout(createTitledRow("", mirror))
@qt.on(mirror.stateChanged)
@@ -182,8 +183,8 @@ def build_ui(parent):
for _, v in model.presets.items():
v.mirror = mirror.isChecked()
- redistribute_removed_weight = QtWidgets.QCheckBox("Distribute to other influences")
- layout.addLayout(createTitledRow("Removed weight:", redistribute_removed_weight))
+ redistribute_removed_weight = QtWidgets.QCheckBox("分配给其它影响物")
+ layout.addLayout(createTitledRow("移除的权重:", redistribute_removed_weight))
@qt.on(redistribute_removed_weight.stateChanged)
def redistribute_removed_weight_changed():
@@ -195,7 +196,7 @@ def build_ui(parent):
mirror.setChecked(model.current_settings.mirror)
redistribute_removed_weight.setChecked(model.current_settings.distribute_to_other_influences)
- group = QtWidgets.QGroupBox("Common Settings")
+ group = QtWidgets.QGroupBox("常用设置")
group.setLayout(layout)
update_ui()
@@ -203,8 +204,8 @@ def build_ui(parent):
return group
def apply_button():
- btn = QtWidgets.QPushButton("Apply")
- btn.setToolTip("Apply selected operation to vertex")
+ btn = QtWidgets.QPushButton("应用")
+ btn.setToolTip("将设定操作应用于选中顶点")
@qt.on(btn.clicked)
def clicked():
diff --git a/2025/scripts/rigging_tools/ngskintools2/ui/tabTools.py b/2025/scripts/rigging_tools/ngskintools2/ui/tabTools.py
index 08e6c5c..0b930a7 100644
--- a/2025/scripts/rigging_tools/ngskintools2/ui/tabTools.py
+++ b/2025/scripts/rigging_tools/ngskintools2/ui/tabTools.py
@@ -1,3 +1,4 @@
+# -*- coding: UTF-8 -*-
from ngSkinTools2 import signal
from ngSkinTools2.api.pyside import QtWidgets
from ngSkinTools2.api.session import Session
@@ -20,7 +21,7 @@ def build_ui(actions, session):
def influences_options():
result = QtWidgets.QVBoxLayout()
button_group = QtWidgets.QButtonGroup()
- for index, i in enumerate(["Use all available influences", "Use selected influences"]):
+ for index, i in enumerate(["使用所有可用的影响物", "使用选定的影响物"]):
radio = QtWidgets.QRadioButton(i)
button_group.addButton(radio, index)
result.addWidget(radio)
@@ -38,7 +39,7 @@ def build_ui(actions, session):
return result
- new_layer = QtWidgets.QCheckBox("Create new layer")
+ new_layer = QtWidgets.QCheckBox("创建新图层")
@qt.on(new_layer.toggled)
def update_new_layer():
@@ -53,11 +54,11 @@ def build_ui(actions, session):
update_ui()
- result = QtWidgets.QGroupBox("Assign weights from closest joint")
+ result = QtWidgets.QGroupBox("从最近的关节指定权重")
layout = QtWidgets.QVBoxLayout()
result.setLayout(layout)
- layout.addLayout(createTitledRow("Target layer", new_layer))
- layout.addLayout(createTitledRow("Influences", influences_options()))
+ layout.addLayout(createTitledRow("目标层", new_layer))
+ layout.addLayout(createTitledRow("影响物", influences_options()))
layout.addWidget(btn)
return result
@@ -69,25 +70,25 @@ def build_ui(actions, session):
model_binds.bind(intensity, options.overall_effect)
single_cluster_mode = QtWidgets.QCheckBox(
- "Single group mode",
+ "单组模式",
)
- single_cluster_mode.setToolTip("average weights across whole selection, ignoring separate shells or selection gaps")
+ single_cluster_mode.setToolTip("整个选择的平均权重,忽略单独的壳或选择间隙")
model_binds.bind(single_cluster_mode, options.single_cluster_mode)
btn = QtWidgets.QPushButton()
qt.bind_action_to_button(actions.toolsUnifyWeights, btn)
- result = QtWidgets.QGroupBox("Unify weights")
+ result = QtWidgets.QGroupBox("统一权重")
layout = QtWidgets.QVBoxLayout()
result.setLayout(layout)
- layout.addLayout(createTitledRow("Intensity:", intensity.layout()))
- layout.addLayout(createTitledRow("Clustering:", single_cluster_mode))
+ layout.addLayout(createTitledRow("强度:", intensity.layout()))
+ layout.addLayout(createTitledRow("集群:", single_cluster_mode))
layout.addWidget(btn)
return result
def other_tools_group():
- result = QtWidgets.QGroupBox("Other")
+ result = QtWidgets.QGroupBox("其它")
layout = QtWidgets.QVBoxLayout()
result.setLayout(layout)
layout.addWidget(to_button(actions.fill_layer_transparency))
diff --git a/2025/scripts/rigging_tools/ngskintools2/ui/targetui.py b/2025/scripts/rigging_tools/ngskintools2/ui/targetui.py
index 7b3f975..70ababc 100644
--- a/2025/scripts/rigging_tools/ngskintools2/ui/targetui.py
+++ b/2025/scripts/rigging_tools/ngskintools2/ui/targetui.py
@@ -25,7 +25,7 @@ def build_layers_ui(parent, actions, session):
filter = QtWidgets.QComboBox()
filter.setMinimumHeight(22 * scale_multiplier)
filter.setEditable(True)
- filter.lineEdit().setPlaceholderText("Search...")
+ filter.lineEdit().setPlaceholderText("搜索...")
result.addWidget(filter)
# noinspection PyShadowingNames
clear = QAction(result)
@@ -83,7 +83,7 @@ def build_no_layers_ui(parent, actions, session):
selection_display = QtWidgets.QLabel("pPlane1")
selection_display.setStyleSheet("font-weight: bold")
- selection_note = QtWidgets.QLabel("Skinning Layers cannot be attached to this object")
+ selection_note = QtWidgets.QLabel("蒙皮层无法附加到此对象")
selection_note.setWordWrap(True)
layout.addStretch(1)
@@ -104,11 +104,11 @@ def build_no_layers_ui(parent, actions, session):
selection_display.setText(session.state.selectedSkinCluster)
selection_display.setVisible(is_skinned)
- note = "Select a mesh with a skin cluster attached."
+ note = "选择附着蒙皮节点的网格."
if is_skinned:
- note = "Skinning layers are not yet initialized for this mesh."
+ note = "尚未为此网格初始化蒙皮层."
if import_v1_actions.can_import(session):
- note = "Skinning layers from previous ngSkinTools version are initialized on this mesh."
+ note = "ngSkinTools的旧版本的蒙皮层在此网格上初始化."
selection_note.setText(note)
diff --git a/2025/scripts/rigging_tools/ngskintools2/ui/transferDialog.py b/2025/scripts/rigging_tools/ngskintools2/ui/transferDialog.py
index 7b5d13e..9270010 100644
--- a/2025/scripts/rigging_tools/ngskintools2/ui/transferDialog.py
+++ b/2025/scripts/rigging_tools/ngskintools2/ui/transferDialog.py
@@ -1,3 +1,4 @@
+# -*- coding: UTF-8 -*-
from ngSkinTools2 import api, cleanup, signal
from ngSkinTools2.api import VertexTransferMode
from ngSkinTools2.api.pyside import QtCore, QtWidgets
@@ -43,8 +44,8 @@ def open(parent, model):
return widgets.button_row(
[
- ("Transfer", apply),
- ("Cancel", window.close),
+ ("传递", apply),
+ ("取消", window.close),
]
)
@@ -55,32 +56,32 @@ def open(parent, model):
result = QtWidgets.QVBoxLayout()
vertexMappingMode = QtWidgets.QComboBox()
- vertexMappingMode.addItem("Closest point on surface", VertexTransferMode.closestPoint)
- vertexMappingMode.addItem("UV space", VertexTransferMode.uvSpace)
- vertexMappingMode.addItem("By vertex ID (source and destination vert count must match)", VertexTransferMode.vertexId)
+ vertexMappingMode.addItem("表面上最近的点", VertexTransferMode.closestPoint)
+ vertexMappingMode.addItem("UV空间", VertexTransferMode.uvSpace)
+ vertexMappingMode.addItem("按顶点ID(源和目标顶点数必须匹配)", VertexTransferMode.vertexId)
- g = QtWidgets.QGroupBox("Selection")
+ g = QtWidgets.QGroupBox("选择")
layout = QtWidgets.QVBoxLayout()
g.setLayout(layout)
sourceLabel = QtWidgets.QLabel()
- layout.addLayout(createTitledRow("Source:", sourceLabel))
+ layout.addLayout(createTitledRow("来源:", sourceLabel))
destinationLabel = QtWidgets.QLabel()
- layout.addLayout(createTitledRow("Destination:", destinationLabel))
+ layout.addLayout(createTitledRow("目标:", destinationLabel))
result.addWidget(g)
- g = QtWidgets.QGroupBox("Vertex mapping")
+ g = QtWidgets.QGroupBox("顶点映射")
layout = QtWidgets.QVBoxLayout()
- layout.addLayout(createTitledRow("Mapping mode:", vertexMappingMode))
+ layout.addLayout(createTitledRow("映射模式:", vertexMappingMode))
g.setLayout(layout)
result.addWidget(g)
- g = QtWidgets.QGroupBox("Influences mapping")
+ g = QtWidgets.QGroupBox("影响物映射")
layout = QtWidgets.QVBoxLayout()
g.setLayout(layout)
- edit = QtWidgets.QPushButton("Configure")
+ edit = QtWidgets.QPushButton("配置")
qt.on(edit.clicked)(view_influences_settings)
button_row = QtWidgets.QHBoxLayout()
@@ -90,12 +91,12 @@ def open(parent, model):
result.addWidget(g)
- g = QtWidgets.QGroupBox("Other options")
+ g = QtWidgets.QGroupBox("其他选项")
layout = QtWidgets.QVBoxLayout()
g.setLayout(layout)
- keep_layers = QtWidgets.QCheckBox("Keep existing layers on destination")
- keep_layers_row = qt.wrap_layout_into_widget(createTitledRow("Destination layers:", keep_layers))
+ keep_layers = QtWidgets.QCheckBox("保留目标网格的已有图层")
+ keep_layers_row = qt.wrap_layout_into_widget(createTitledRow("目标图层:", keep_layers))
layout.addWidget(keep_layers_row)
@qt.on(keep_layers.stateChanged)
@@ -137,12 +138,12 @@ def open(parent, model):
tabs = QtWidgets.QTabWidget()
- tabs.addTab(qt.wrap_layout_into_widget(build_settings()), "Settings")
- tabs.addTab(qt.wrap_layout_into_widget(build_influenes_tab()), "Influences mapping")
+ tabs.addTab(qt.wrap_layout_into_widget(build_settings()), "设置")
+ tabs.addTab(qt.wrap_layout_into_widget(build_influenes_tab()), "影响物映射")
window = QtWidgets.QDialog(parent)
cleanup.registerCleanupHandler(window.close)
- window.setWindowTitle("Transfer")
+ window.setWindowTitle("传递")
window.setAttribute(QtCore.Qt.WA_DeleteOnClose)
window.resize(720 * scale_multiplier, 500 * scale_multiplier)
window.setLayout(QtWidgets.QVBoxLayout())
@@ -196,7 +197,7 @@ def build_transfer_action(session, parent):
t.customize_callback = transfer_dialog
t.execute()
- result = define_action(parent, "Transfer layers...", callback=handler)
+ result = define_action(parent, "传递图层...", callback=handler)
@signal.on(session.events.nodeSelectionChanged)
def on_selection_changed():
diff --git a/2025/scripts/rigging_tools/ngskintools2/ui/updatewindow.py b/2025/scripts/rigging_tools/ngskintools2/ui/updatewindow.py
index dfdf7e3..5ac09e1 100644
--- a/2025/scripts/rigging_tools/ngskintools2/ui/updatewindow.py
+++ b/2025/scripts/rigging_tools/ngskintools2/ui/updatewindow.py
@@ -1,3 +1,4 @@
+# -*- coding: UTF-8 -*-
import webbrowser
from ngSkinTools2.api import versioncheck
@@ -27,10 +28,10 @@ def show(parent, silent_mode):
result.setLayout(layout)
layout.setContentsMargins(20, 30, 20, 20)
- header = QtWidgets.QLabel("Checking for update...")
- result1 = QtWidgets.QLabel("Current version: 2.0.0")
- result2 = QtWidgets.QLabel("Update available: 2.0.1")
- download = QtWidgets.QPushButton("Download ngSkinTools v2.0.1")
+ header = QtWidgets.QLabel(u"检查更新中...")
+ result1 = QtWidgets.QLabel(u"当前版本: 2.1.4")
+ result2 = QtWidgets.QLabel("最新版本: 2.1.4")
+ download = QtWidgets.QPushButton("下载 中文ngSkinTools v2.0.1")
# layout.addWidget(QtWidgets.QLabel("Checking for updates..."))
layout.addWidget(header)
layout.addWidget(result1)
@@ -52,16 +53,16 @@ def show(parent, silent_mode):
:type info: ngSkinTools2.api.versioncheck.
"""
- header.setText("{0}".format('Update available!' if info.update_available else 'ngSkinTools is up to date.'))
+ header.setText("{0}".format('更新可用!' if info.update_available else '中文ngSkinTools 已经是最新版.'))
result1.setVisible(True)
- result1.setText("Current version: {0}".format(version.pluginVersion()))
+ result1.setText(u"当前版本: {0}".format(version.pluginVersion()))
if info.update_available:
result2.setVisible(True)
result2.setText(
- "Update available: {0}, released on {1}".format(info.latest_version, info.update_date.strftime("%d %B, %Y"))
+ u"最新版本: {0}, 发布于 {1}".format(info.latest_version, info.update_date.strftime("%d %B, %Y"))
)
download.setVisible(True)
- download.setText("Download ngSkinTools v" + info.latest_version)
+ download.setText(u"下载 中文ngSkinTools v" + info.latest_version)
@qt.on(download.clicked)
def open_link():
@@ -71,10 +72,10 @@ def show(parent, silent_mode):
# noinspection PyShadowingNames
def buttonsRow(window):
- btn_close = QtWidgets.QPushButton("Close")
+ btn_close = QtWidgets.QPushButton("取消")
btn_close.setMinimumWidth(100 * scale_multiplier)
- check_do_on_startup = bind_checkbox(QtWidgets.QCheckBox("Check for updates at startup"), config.checkForUpdatesAtStartup)
+ check_do_on_startup = bind_checkbox(QtWidgets.QCheckBox("启动时检查更新"), config.checkForUpdatesAtStartup)
layout = QtWidgets.QHBoxLayout()
layout.addWidget(check_do_on_startup)
@@ -88,7 +89,7 @@ def show(parent, silent_mode):
window = QtWidgets.QWidget(parent, Qt.Window | Qt.WindowTitleHint | Qt.CustomizeWindowHint)
window.resize(400 * scale_multiplier, 200 * scale_multiplier)
window.setAttribute(Qt.WA_DeleteOnClose)
- window.setWindowTitle("ngSkinTools2 version update")
+ window.setWindowTitle("ngSkinTools2 (中文) 版本更新")
layout = QtWidgets.QVBoxLayout()
window.setLayout(layout)
layout.setContentsMargins(0, 0, 0, 0)
@@ -106,14 +107,14 @@ def show(parent, silent_mode):
if info.update_available:
window.show()
else:
- log.info("not showing the window")
+ log.info("未显示窗口")
window.close()
cleanup.registerCleanupHandler(window.close)
@qt.on(window.destroyed)
def closed():
- log.info("deleting update window")
+ log.info("删除更新窗口")
versioncheck.download_update_info(success_callback=success_signal.emit, failure_callback=error_signal.emit)
@@ -129,4 +130,4 @@ def show_and_start_update(parent):
def build_action_check_for_updates(parent):
from ngSkinTools2.ui import actions
- return actions.define_action(parent, "Check for Updates...", callback=lambda: show_and_start_update(parent))
+ return actions.define_action(parent, "检查更新...", callback=lambda: show_and_start_update(parent))
diff --git a/2025/scripts/rigging_tools/ngskintools2/version.py b/2025/scripts/rigging_tools/ngskintools2/version.py
index 29a258a..d279d88 100644
--- a/2025/scripts/rigging_tools/ngskintools2/version.py
+++ b/2025/scripts/rigging_tools/ngskintools2/version.py
@@ -66,7 +66,7 @@ class SemanticVersion(Object):
result = pattern.match(stringVersion)
if result is None:
- raise Exception("Invalid version string: '{0}'".format(stringVersion))
+ raise Exception("无效的版本字符串: '{0}'".format(stringVersion))
self.major = toInt(result.group(1))
self.minor = toInt(result.group(3))
diff --git a/2025/scripts/userSetup.py b/2025/scripts/userSetup.py
index e0d7402..676b94d 100644
--- a/2025/scripts/userSetup.py
+++ b/2025/scripts/userSetup.py
@@ -13,37 +13,20 @@ Features:
- Maya 2018+ compatible
"""
-import maya.cmds as cmds
-import maya.mel as mel
-import maya.utils
+# Standard library imports
import atexit
import os
import sys
import re
-# Set MAYA_MODULE_PATH environment variable for external tools
+# Maya imports with error handling
try:
- _current_file = os.path.abspath(__file__)
- _script_dir = os.path.dirname(_current_file)
- _project_root = os.path.dirname(os.path.dirname(_script_dir))
- _modules_dir = os.path.join(_project_root, 'modules')
-
- if os.path.exists(_modules_dir):
- _modules_dir_normalized = os.path.normpath(_modules_dir)
- _current_module_path = os.environ.get('MAYA_MODULE_PATH', '')
-
- # Check if already in path
- _paths = [p.strip() for p in _current_module_path.split(os.pathsep) if p.strip()]
- _normalized_paths = [os.path.normpath(p) for p in _paths]
-
- if _modules_dir_normalized not in _normalized_paths:
- if _current_module_path:
- os.environ['MAYA_MODULE_PATH'] = f"{_modules_dir_normalized}{os.pathsep}{_current_module_path}"
- else:
- os.environ['MAYA_MODULE_PATH'] = _modules_dir_normalized
- print(f"[Tool] MAYA_MODULE_PATH set to: {_modules_dir_normalized}")
-except Exception as e:
- print(f"[Tool] Warning: Could not set MAYA_MODULE_PATH: {e}")
+ import maya.cmds as cmds
+ import maya.mel as mel
+ import maya.utils
+except ImportError as e:
+ print(f"[Tool] ERROR: Failed to import Maya modules: {e}")
+ raise
# Silently try to open default commandPort to avoid startup error if it's already in use
try:
@@ -51,6 +34,19 @@ try:
except Exception:
pass
+# =============================================================================
+# Constants
+# =============================================================================
+
+# Command port name
+COMMAND_PORT_NAME = "commandportDefault"
+
+# Log levels
+LOG_DEBUG = 0
+LOG_INFO = 1
+LOG_WARNING = 2
+LOG_ERROR = 3
+
# =============================================================================
# Configuration
# =============================================================================
@@ -58,6 +54,9 @@ except Exception:
# Shelves to load
SHELF_NAMES = ["Nexus_Manage", "Nexus_Modeling", "Nexus_Rigging", "Nexus_Animation", "Nexus_DevTools"]
+# User configuration file path (optional override)
+USER_CONFIG_FILE = os.path.join(os.path.expanduser("~"), ".nexus_maya_config.py")
+
# Tool packages configuration
TOOL_CONFIG = {
'scripts': [
@@ -67,12 +66,10 @@ TOOL_CONFIG = {
{'name': 'manage_tools', 'path': 'manage_tools'},
],
'plugins': [
- {'name': 'cv_manip.mll', 'path': 'modeling_tools/gs_curvetools/plugins/2025'},
{'name': 'ngskintools2.mll', 'path': 'rigging_tools/ngskintools2/plug-ins/2025'},
{'name': 'MGPicker_2025x64.mll', 'path': 'animation_tools/mgpicker/MGPicker_Program/Plug-ins'},
],
'icons': [
- {'name': 'gs_curvetools', 'path': 'modeling_tools/gs_curvetools/icons'},
{'name': 'gs_toolbox', 'path': 'modeling_tools/gs_toolbox/icons'},
{'name': 'modit', 'path': 'modeling_tools/ModIt/Icons/Theme_Classic'},
{'name': 'creaseplus', 'path': 'modeling_tools/creaseplus/icons'},
@@ -107,14 +104,41 @@ _ADDED_SCRIPT_PATHS = []
# Utility Functions
# =============================================================================
+def _log(msg, level=LOG_INFO):
+ """
+ Print log message with level control
+
+ Args:
+ msg: Message to print
+ level: LOG_DEBUG, LOG_INFO, LOG_WARNING, or LOG_ERROR
+ """
+ if level == LOG_DEBUG and not TOOL_DEBUG:
+ return
+
+ prefix_map = {
+ LOG_DEBUG: "[Tool:DEBUG]",
+ LOG_INFO: "[Tool]",
+ LOG_WARNING: "[Tool:WARNING]",
+ LOG_ERROR: "[Tool:ERROR]"
+ }
+ prefix = prefix_map.get(level, "[Tool]")
+ print(f"{prefix} {msg}")
+
def _tool_log(msg):
"""Print debug message if TOOL_DEBUG is enabled"""
- if TOOL_DEBUG:
- print(msg)
+ _log(msg, LOG_DEBUG)
def _tool_print(msg):
"""Print info message"""
- print(msg)
+ _log(msg, LOG_INFO)
+
+def _tool_warning(msg):
+ """Print warning message"""
+ _log(msg, LOG_WARNING)
+
+def _tool_error(msg):
+ """Print error message"""
+ _log(msg, LOG_ERROR)
def _get_script_dir():
"""Get the directory containing this script (with fallback)"""
@@ -157,16 +181,25 @@ def _check_maya_version():
try:
maya_version = int(cmds.about(version=True).split()[0])
if maya_version < MAYA_MIN_VERSION:
- _tool_print(f"[Tool] Warning: Maya {maya_version} detected. Minimum supported version is {MAYA_MIN_VERSION}")
+ _tool_warning(f"Maya {maya_version} detected. Minimum supported version is {MAYA_MIN_VERSION}")
return False
- _tool_log(f"[Tool] Maya version: {maya_version}")
+ _tool_log(f"Maya version: {maya_version}")
return True
except Exception as e:
- _tool_print(f"[Tool] Warning: Could not determine Maya version: {e}")
+ _tool_warning(f"Could not determine Maya version: {e}")
return True # Continue anyway
def _find_file_in_paths(filename, search_paths):
- """Find file in a list of search paths"""
+ """
+ Find file in a list of search paths
+
+ Args:
+ filename: Name of file to find
+ search_paths: List of directory paths to search
+
+ Returns:
+ Full path to file if found, None otherwise
+ """
for p in search_paths:
if not p:
continue
@@ -175,6 +208,45 @@ def _find_file_in_paths(filename, search_paths):
return candidate
return None
+def _validate_tool_config():
+ """
+ Validate TOOL_CONFIG structure
+
+ Returns:
+ True if valid, False otherwise
+ """
+ try:
+ required_keys = ['scripts', 'plugins', 'icons']
+ for key in required_keys:
+ if key not in TOOL_CONFIG:
+ _tool_error(f"Missing required key in TOOL_CONFIG: {key}")
+ return False
+
+ if not isinstance(TOOL_CONFIG[key], list):
+ _tool_error(f"TOOL_CONFIG['{key}'] must be a list")
+ return False
+
+ # Validate each item has required fields
+ for idx, item in enumerate(TOOL_CONFIG[key]):
+ if not isinstance(item, dict):
+ _tool_error(f"TOOL_CONFIG['{key}'][{idx}] must be a dict")
+ return False
+
+ if 'name' not in item:
+ _tool_error(f"TOOL_CONFIG['{key}'][{idx}] missing 'name' field")
+ return False
+
+ if 'path' not in item:
+ _tool_error(f"TOOL_CONFIG['{key}'][{idx}] missing 'path' field")
+ return False
+
+ _tool_log("TOOL_CONFIG validation passed")
+ return True
+
+ except Exception as e:
+ _tool_error(f"Error validating TOOL_CONFIG: {e}")
+ return False
+
def _verify_shelf_icon_references(search_paths):
"""Verify that shelf icon references can be resolved"""
if not TOOL_DEBUG:
@@ -198,9 +270,9 @@ def _verify_shelf_icon_references(search_paths):
for img in imgs:
found = any(os.path.exists(os.path.join(p, img).replace('\\', '/')) for p in search_paths)
if not found:
- _tool_log(f"[Tool] Warning: Icon '{img}' not found for shelf '{shelf_name}'")
+ _tool_warning(f"Icon '{img}' not found for shelf '{shelf_name}'")
except Exception as e:
- _tool_log(f"[Tool] Icon verification error: {e}")
+ _tool_log(f"Icon verification error: {e}")
def _remove_shelf_config(shelf_name):
"""Remove shelf config from Maya prefs to force reload"""
@@ -239,7 +311,7 @@ def setup_icon_paths():
if os.path.exists(full_path):
icon_paths[name] = full_path
else:
- _tool_print(f"[Tool] Warning: Icon path not found: {full_path}")
+ _tool_warning(f"Icon path not found: {full_path}")
# Check if already configured
global _ICONS_PATHS
@@ -273,7 +345,7 @@ def setup_icon_paths():
_verify_shelf_icon_references(paths)
except Exception as e:
- _tool_print(f"[Tool] Error setting up icon paths: {e}")
+ _tool_error(f"Error setting up icon paths: {e}")
def load_tool_shelves():
"""Load Nexus shelves into Maya"""
@@ -284,7 +356,7 @@ def load_tool_shelves():
script_dir = _get_script_dir()
shelf_paths = os.path.join(os.path.dirname(script_dir), "shelves")
if not os.path.exists(shelf_paths):
- _tool_print("[Tool] Shelf directory not found, skipping")
+ _tool_warning("Shelf directory not found, skipping")
return
shelf_path_list = [p.strip() for p in shelf_paths.split(os.pathsep) if p.strip()]
@@ -302,7 +374,7 @@ def load_tool_shelves():
break
if not shelf_file_found:
- _tool_print(f"[Tool] Shelf not found: shelf_{shelf_name}.mel")
+ _tool_warning(f"Shelf not found: shelf_{shelf_name}.mel")
continue
# Remove existing shelf
@@ -350,12 +422,12 @@ def load_tool_shelves():
_remove_shelf_config(shelf_name)
except Exception as e:
- _tool_print(f"[Tool] Error loading shelf {shelf_name}: {e}")
+ _tool_error(f"Error loading shelf {shelf_name}: {e}")
_tool_log(f"[Tool] ✓ Shelves: {loaded_count}/{len(SHELF_NAMES)} loaded")
except Exception as e:
- _tool_print(f"[Tool] Error loading shelves: {e}")
+ _tool_error(f"Error loading shelves: {e}")
def load_tool_plugins():
"""Load Nexus plugins"""
@@ -398,7 +470,7 @@ def load_tool_plugins():
plugin_path = _find_file_in_paths(plugin_name, search_dirs)
if not plugin_path:
- _tool_print(f"[Tool] Plugin not found: {plugin_name}")
+ _tool_warning(f"Plugin not found: {plugin_name}")
continue
# Add plugin directory to environment
@@ -435,12 +507,12 @@ def load_tool_plugins():
loaded_count += 1
_LOADED_PLUGINS[plugin_basename] = plugin_path
except Exception as e:
- _tool_print(f"[Tool] Error loading plugin {plugin_basename}: {e}")
+ _tool_error(f"Error loading plugin {plugin_basename}: {e}")
_tool_log(f"[Tool] ✓ Plugins: {loaded_count}/{len(plugin_configs)} loaded")
except Exception as e:
- _tool_print(f"[Tool] Error loading plugins: {e}")
+ _tool_error(f"Error loading plugins: {e}")
def load_tool_scripts():
"""Add Nexus script paths to sys.path"""
@@ -460,7 +532,7 @@ def load_tool_scripts():
full_path = os.path.normpath(os.path.join(script_dir, path))
if not os.path.exists(full_path):
- _tool_print(f"[Tool] Script path not found: {full_path}")
+ _tool_warning(f"Script path not found: {full_path}")
continue
if full_path not in sys.path:
@@ -472,7 +544,219 @@ def load_tool_scripts():
_tool_log(f"[Tool] ✓ Script paths: {loaded}/{len(script_configs)} added")
except Exception as e:
- _tool_print(f"[Tool] Error loading scripts: {e}")
+ _tool_error(f"Error loading scripts: {e}")
+
+def _parse_mod_file_line(line, maya_version, modules_dir, module_name):
+ """
+ Parse a single line from .mod file
+
+ Args:
+ line: Line to parse
+ maya_version: Current Maya version
+ modules_dir: Modules directory path
+ module_name: Name of the module
+
+ Returns:
+ Tuple of (in_correct_version, current_module_root) or None
+ """
+ parts = line.split()
+
+ if len(parts) < 4:
+ return None
+
+ # Detect current platform
+ current_platform = 'win64' if os.name == 'nt' else ('linux' if sys.platform.startswith('linux') else 'mac')
+
+ # Check for version and platform restrictions
+ has_version_requirement = False
+ version_matches = False
+ platform_matches = True # Assume match if no platform specified
+
+ for part in parts:
+ if part.startswith('MAYAVERSION:'):
+ has_version_requirement = True
+ required_version = int(part.split(':')[1])
+ version_matches = (required_version == maya_version)
+
+ if part.startswith('PLATFORM:'):
+ required_platform = part.split(':')[1].lower()
+ platform_matches = (required_platform == current_platform)
+
+ # Both version and platform must match (or not be specified)
+ if has_version_requirement:
+ if version_matches and platform_matches:
+ # Get the module root path (last parameter)
+ current_module_root = parts[-1]
+ if current_module_root.startswith('..'):
+ current_module_root = _norm_path(os.path.join(modules_dir, current_module_root))
+ _tool_print(f"{module_name}: Maya {maya_version} {current_platform} matched, root: {current_module_root}")
+ return (True, current_module_root)
+ else:
+ return (False, None)
+
+ # If there are no version restrictions, it works for all versions (but still check platform)
+ if platform_matches:
+ current_module_root = parts[-1]
+ if current_module_root.startswith('..'):
+ current_module_root = _norm_path(os.path.join(modules_dir, current_module_root))
+ _tool_print(f"{module_name}: No version restriction, root: {current_module_root}")
+ return (True, current_module_root)
+
+ return (False, None)
+
+def _load_plugins_from_directory(plugins_dir, mod_file):
+ """
+ Load all plugins from a directory
+
+ Args:
+ plugins_dir: Directory containing plugins
+ mod_file: Name of .mod file for logging
+
+ Returns:
+ Number of plugins loaded
+ """
+ plugins_loaded = 0
+
+ if not os.path.exists(plugins_dir):
+ _tool_log(f"Plugin dir not found: {plugins_dir}")
+ return 0
+
+ _tool_log(f"Checking plugin dir: {plugins_dir}")
+
+ for plugin_file in os.listdir(plugins_dir):
+ if not plugin_file.endswith(('.mll', '.so', '.bundle', '.py')):
+ continue
+
+ plugin_name = os.path.splitext(plugin_file)[0]
+ plugin_full_path = _norm_path(os.path.join(plugins_dir, plugin_file))
+
+ # Check if already tracked
+ if plugin_name in _LOADED_PLUGINS:
+ _tool_log(f"Plugin already tracked: {plugin_name}")
+ continue
+
+ # Check if already loaded
+ try:
+ is_loaded = cmds.pluginInfo(plugin_name, query=True, loaded=True)
+ except:
+ is_loaded = False
+
+ if not is_loaded:
+ try:
+ cmds.loadPlugin(plugin_full_path, quiet=False)
+ _tool_print(f"✓ Plugin loaded: {plugin_name} (from {mod_file})")
+ plugins_loaded += 1
+ _LOADED_PLUGINS[plugin_name] = plugin_full_path
+ except Exception as e:
+ _tool_error(f"Failed to load {plugin_name}: {e}")
+ else:
+ _tool_log(f"Plugin already loaded: {plugin_name}")
+ _LOADED_PLUGINS[plugin_name] = plugin_full_path
+
+ return plugins_loaded
+
+def _add_path_to_environment(env_var, path):
+ """
+ Add a path to an environment variable
+
+ Args:
+ env_var: Environment variable name (e.g., 'MAYA_SCRIPT_PATH')
+ path: Path to add
+
+ Returns:
+ True if added, False if already exists
+ """
+ if not os.path.exists(path):
+ _tool_warning(f"Path not found for {env_var}: {path}")
+ return False
+
+ # Get current paths
+ current_value = os.environ.get(env_var, '')
+ current_paths = [p.strip() for p in current_value.split(os.pathsep) if p.strip()]
+
+ # Normalize the new path
+ norm_path = _norm_path(path)
+
+ # Check if already in path
+ if norm_path in [_norm_path(p) for p in current_paths]:
+ _tool_log(f"{env_var} already contains: {norm_path}")
+ return False
+
+ # Add to front of path list
+ current_paths.insert(0, norm_path)
+ new_value = os.pathsep.join(current_paths)
+ os.environ[env_var] = new_value
+
+ # Update MEL environment if needed
+ if env_var in ['XBMLANGPATH', 'MAYA_SCRIPT_PATH', 'MAYA_PLUG_IN_PATH']:
+ try:
+ safe_value = new_value.replace('\\', '/').replace('"', '\\"')
+ mel.eval(f'putenv "{env_var}" "{safe_value}";')
+ except Exception as e:
+ _tool_warning(f"Could not update MEL environment for {env_var}: {e}")
+
+ # Also add PYTHONPATH to sys.path for Python imports
+ if env_var == 'PYTHONPATH':
+ if norm_path not in sys.path:
+ sys.path.insert(0, norm_path)
+ _tool_log(f"Added to sys.path: {norm_path}")
+
+ _tool_print(f"✓ Added to {env_var}: {os.path.basename(norm_path)}")
+ return True
+
+def _load_user_config():
+ """
+ Load user configuration from optional config file
+ Allows users to override default TOOL_CONFIG settings
+ """
+ global TOOL_CONFIG, SHELF_NAMES
+
+ if not os.path.exists(USER_CONFIG_FILE):
+ _tool_log(f"No user config file found at: {USER_CONFIG_FILE}")
+ return
+
+ try:
+ _tool_print(f"Loading user configuration from: {USER_CONFIG_FILE}")
+
+ # Create a namespace for user config
+ user_namespace = {}
+
+ # Execute user config file
+ with open(USER_CONFIG_FILE, 'r', encoding='utf-8') as f:
+ exec(f.read(), user_namespace)
+
+ # Override TOOL_CONFIG if provided
+ if 'TOOL_CONFIG' in user_namespace:
+ user_config = user_namespace['TOOL_CONFIG']
+
+ # Merge configurations
+ for key in ['scripts', 'plugins', 'icons']:
+ if key in user_config:
+ if key in TOOL_CONFIG:
+ # Extend existing config
+ TOOL_CONFIG[key].extend(user_config[key])
+ else:
+ # Add new key
+ TOOL_CONFIG[key] = user_config[key]
+
+ _tool_print("✓ User TOOL_CONFIG loaded and merged")
+
+ # Override SHELF_NAMES if provided
+ if 'SHELF_NAMES' in user_namespace:
+ user_shelves = user_namespace['SHELF_NAMES']
+ if isinstance(user_shelves, list):
+ # Extend shelf list
+ for shelf in user_shelves:
+ if shelf not in SHELF_NAMES:
+ SHELF_NAMES.append(shelf)
+ _tool_print(f"✓ User SHELF_NAMES loaded: {user_shelves}")
+
+ _tool_print("✓ User configuration applied successfully")
+
+ except Exception as e:
+ _tool_error(f"Error loading user config: {e}")
+ import traceback
+ traceback.print_exc()
def load_project_modules():
"""Load plugins defined in .mod files from the modules directory."""
@@ -486,27 +770,33 @@ def load_project_modules():
modules_dir = _norm_path(os.path.join(project_root, "modules"))
if not os.path.exists(modules_dir):
- _tool_log(f"[Tool] Modules directory not found: {modules_dir}")
+ _tool_log(f"Modules directory not found: {modules_dir}")
return
# Find all .mod files
mod_files = [f for f in os.listdir(modules_dir) if f.endswith('.mod')]
if not mod_files:
- _tool_log(f"[Tool] No .mod files found in: {modules_dir}")
+ _tool_log(f"No .mod files found in: {modules_dir}")
return
- _tool_print(f"[Tool] Found {len(mod_files)} module(s): {', '.join(mod_files)}")
+ _tool_print(f"Found {len(mod_files)} module(s): {', '.join(mod_files)}")
+
+ # TWO-PASS APPROACH: First configure all environment variables, then load plugins
+ # This ensures dependencies are available before plugins initialize
+
+ # PASS 1: Configure all environment variables (including MAYA_PLUG_IN_PATH paths)
+ # Track processed modules to avoid duplicates
+ processed_modules = set()
- # Parse .mod files and load plugins
- plugins_loaded = 0
for mod_file in mod_files:
mod_path = os.path.join(modules_dir, mod_file)
- _tool_log(f"[Tool] Processing: {mod_file}")
+ module_name = os.path.splitext(mod_file)[0]
try:
current_module_root = None
in_correct_version = False
+ module_key = None
with open(mod_path, 'r', encoding='utf-8') as f:
for line in f:
@@ -518,80 +808,117 @@ def load_project_modules():
# Parse module definition lines (starting with +)
if line.startswith('+'):
- parts = line.split()
- in_correct_version = False
- current_module_root = None
-
- if len(parts) >= 4:
- # Check for version restrictions
- has_version_requirement = False
- for part in parts:
- if part.startswith('MAYAVERSION:'):
- has_version_requirement = True
- required_version = int(part.split(':')[1])
- if required_version == maya_version:
- in_correct_version = True
- # Get the module root path (last parameter)
- current_module_root = parts[-1]
- if current_module_root.startswith('..'):
- current_module_root = _norm_path(os.path.join(modules_dir, current_module_root))
- _tool_log(f"[Tool] Version matched for Maya {maya_version}: {current_module_root}")
- break
+ result = _parse_mod_file_line(line, maya_version, modules_dir, module_name)
+ if result:
+ in_correct_version, current_module_root = result
+ # Create unique key for this module version
+ module_key = f"{module_name}:{maya_version}:{current_module_root}"
- # If there are no version restrictions, it works for all versions.
- if not has_version_requirement:
- in_correct_version = True
- current_module_root = parts[-1]
- if current_module_root.startswith('..'):
- current_module_root = _norm_path(os.path.join(modules_dir, current_module_root))
- _tool_log(f"[Tool] Module without version restriction loaded: {current_module_root}")
+ # Skip if already processed
+ if module_key in processed_modules:
+ _tool_log(f"Skipping duplicate module definition: {module_key}")
+ in_correct_version = False
+ current_module_root = None
+ continue
+
+ processed_modules.add(module_key)
+ else:
+ in_correct_version = False
+ current_module_root = None
+ module_key = None
- # Only process MAYA_PLUG_IN_PATH that matches the version.
+ # Process ALL environment variables in first pass (including MAYA_PLUG_IN_PATH to env, but don't load plugins)
+ elif in_correct_version and current_module_root and ('+:=' in line or '+=' in line):
+ if line.startswith('MAYA_PLUG_IN_PATH'):
+ # Add plugin directory to MAYA_PLUG_IN_PATH environment, but don't load plugins yet
+ plugin_path_relative = line.split('+:=')[-1].strip() if '+:=' in line else line.split('+=')[-1].strip()
+ plugins_dir = _norm_path(os.path.join(current_module_root, plugin_path_relative))
+ _add_path_to_environment('MAYA_PLUG_IN_PATH', plugins_dir)
+
+ elif line.startswith('MAYA_SCRIPT_PATH'):
+ script_path_relative = line.split('+:=')[-1].strip() if '+:=' in line else line.split('+=')[-1].strip()
+ script_path = _norm_path(os.path.join(current_module_root, script_path_relative))
+ _add_path_to_environment('MAYA_SCRIPT_PATH', script_path)
+ if script_path not in sys.path:
+ sys.path.insert(0, script_path)
+
+ elif line.startswith('XBMLANGPATH'):
+ icon_path_relative = line.split('+:=')[-1].strip() if '+:=' in line else line.split('+=')[-1].strip()
+ icon_path = _norm_path(os.path.join(current_module_root, icon_path_relative))
+ _add_path_to_environment('XBMLANGPATH', icon_path)
+
+ else:
+ # Handle PATH, PYTHONPATH, and other environment variables
+ try:
+ env_var = line.split('+')[0].strip()
+ rel_path = line.split('+:=')[-1].strip() if '+:=' in line else line.split('+=')[-1].strip()
+ full_path = _norm_path(os.path.join(current_module_root, rel_path))
+ _add_path_to_environment(env_var, full_path)
+ except Exception as e:
+ _tool_log(f"Could not process environment variable line: {line}, error: {e}")
+
+ except Exception as e:
+ _tool_error(f"Error processing environment variables in {mod_file}: {e}")
+
+ # PASS 2: Now load plugins with all dependencies configured
+ _tool_log("Environment variables configured, now loading plugins...")
+ plugins_loaded = 0
+ processed_modules.clear() # Reset for second pass
+
+ for mod_file in mod_files:
+ mod_path = os.path.join(modules_dir, mod_file)
+ module_name = os.path.splitext(mod_file)[0]
+
+ try:
+ current_module_root = None
+ in_correct_version = False
+ module_key = None
+
+ with open(mod_path, 'r', encoding='utf-8') as f:
+ for line in f:
+ line = line.strip()
+
+ if not line or line.startswith('#') or line.startswith('//'):
+ continue
+
+ if line.startswith('+'):
+ result = _parse_mod_file_line(line, maya_version, modules_dir, module_name)
+ if result:
+ in_correct_version, current_module_root = result
+ module_key = f"{module_name}:{maya_version}:{current_module_root}"
+
+ # Skip if already processed
+ if module_key in processed_modules:
+ _tool_log(f"Skipping duplicate module definition for plugin loading: {module_key}")
+ in_correct_version = False
+ current_module_root = None
+ continue
+
+ processed_modules.add(module_key)
+ else:
+ in_correct_version = False
+ current_module_root = None
+ module_key = None
+
+ # Now load plugins
elif line.startswith('MAYA_PLUG_IN_PATH') and in_correct_version and current_module_root:
if '+:=' in line or '+=' in line:
- plugin_path_relative = line.split('=')[-1].strip()
+ plugin_path_relative = line.split('+:=')[-1].strip() if '+:=' in line else line.split('+=')[-1].strip()
plugins_dir = _norm_path(os.path.join(current_module_root, plugin_path_relative))
-
- if os.path.exists(plugins_dir):
- _tool_log(f"[Tool] Checking plugin dir: {plugins_dir}")
-
- for plugin_file in os.listdir(plugins_dir):
- if plugin_file.endswith(('.mll', '.so', '.bundle', '.py')):
- plugin_name = os.path.splitext(plugin_file)[0]
- plugin_full_path = os.path.join(plugins_dir, plugin_file)
-
- # Check if already loaded
- if plugin_name in _LOADED_PLUGINS:
- continue
-
- try:
- is_loaded = cmds.pluginInfo(plugin_name, query=True, loaded=True)
- except:
- is_loaded = False
-
- if not is_loaded:
- try:
- cmds.loadPlugin(plugin_full_path, quiet=True)
- _tool_print(f"[Tool] ✓ Plugin loaded: {plugin_name} (from {mod_file})")
- plugins_loaded += 1
- _LOADED_PLUGINS[plugin_name] = plugin_full_path
- except Exception as e:
- _tool_print(f"[Tool] Failed to load {plugin_name}: {e}")
- else:
- _tool_log(f"[Tool] Plugin dir not found: {plugins_dir}")
+ plugins_loaded += _load_plugins_from_directory(plugins_dir, mod_file)
except Exception as e:
- _tool_print(f"[Tool] Error processing {mod_file}: {e}")
+ _tool_error(f"Error processing {mod_file}: {e}")
import traceback
traceback.print_exc()
if plugins_loaded > 0:
- _tool_print(f"[Tool] ✓ Total {plugins_loaded} module plugin(s) loaded")
+ _tool_print(f"✓ Total {plugins_loaded} module plugin(s) loaded")
else:
- _tool_print(f"[Tool] No module plugins loaded")
+ _tool_print("No module plugins loaded")
except Exception as e:
- _tool_print(f"[Tool] Error loading modules: {e}")
+ _tool_error(f"Error loading modules: {e}")
import traceback
traceback.print_exc()
@@ -601,18 +928,18 @@ def setup_command_port():
try:
# Check if already open
try:
- port_exists = bool(mel.eval('commandPort -q -name "commandportDefault"'))
+ port_exists = bool(mel.eval(f'commandPort -q -name "{COMMAND_PORT_NAME}"'))
except Exception:
port_exists = False
if port_exists:
- _tool_log("[Tool] Command port already open")
+ _tool_log("Command port already open")
_COMMAND_PORT_OPENED = True
return
# Open command port
- mel.eval('commandPort -securityWarning -name "commandportDefault";')
- _tool_log("[Tool] ✓ Command port opened")
+ mel.eval(f'commandPort -securityWarning -name "{COMMAND_PORT_NAME}";')
+ _tool_log("✓ Command port opened")
_COMMAND_PORT_OPENED = True
except Exception as e:
@@ -629,9 +956,13 @@ def initialize_tool():
print("[Tool] Nexus Plugin System - Initializing...")
print("=" * 80)
+ # Validate configuration
+ if not _validate_tool_config():
+ _tool_error("Configuration validation failed, continuing with caution...")
+
# Check Maya version compatibility
if not _check_maya_version():
- print("[Tool] Warning: Running on unsupported Maya version")
+ _tool_warning("Running on unsupported Maya version")
# First, set the icon path so that the shelf can find the icon when it loads.
setup_icon_paths()
@@ -672,11 +1003,11 @@ def cleanup_on_exit():
global _COMMAND_PORT_OPENED
if _COMMAND_PORT_OPENED:
try:
- if mel.eval('commandPort -q -name "commandportDefault"'):
- mel.eval('commandPort -cl "commandportDefault"')
- _tool_log("[Tool] ✓ Command port closed")
+ if mel.eval(f'commandPort -q -name "{COMMAND_PORT_NAME}"'):
+ mel.eval(f'commandPort -cl "{COMMAND_PORT_NAME}"')
+ _tool_log("✓ Command port closed")
except Exception as e:
- _tool_log(f"[Tool] Could not close command port: {e}")
+ _tool_log(f"Could not close command port: {e}")
# Unload plugins
if _LOADED_PLUGINS:
diff --git a/2025/shelves/shelf_Nexus_Modeling.mel b/2025/shelves/shelf_Nexus_Modeling.mel
index 51da4c7..f72fdf6 100644
--- a/2025/shelves/shelf_Nexus_Modeling.mel
+++ b/2025/shelves/shelf_Nexus_Modeling.mel
@@ -109,111 +109,6 @@ global proc shelf_Nexus_Modeling () {
-commandRepeatable 1
-flat 1
;
- shelfButton
- -enableCommandRepeat 1
- -flexibleWidthType 3
- -flexibleWidthValue 36
- -enable 1
- -width 39
- -height 34
- -manage 1
- -visible 1
- -preventOverride 0
- -annotation "GS Curvetools - Open UI"
- -enableBackground 0
- -backgroundColor 0 0 0
- -highlightColor 0.321569 0.521569 0.65098
- -align "center"
- -label "GSCurve"
- -labelOffset 0
- -rotation 0
- -flipX 0
- -flipY 0
- -useAlpha 1
- -font "plainLabelFont"
- -imageOverlayLabel "UI"
- -overlayLabelColor 0.8 0.8 0.8
- -overlayLabelBackColor 0 0 0 0.5
- -image "gsCurveToolsIcon_ui.png"
- -image1 "gsCurveToolsIcon_ui.png"
- -style "iconOnly"
- -marginWidth 0
- -marginHeight 1
- -command "import gs_curvetools.main as gs_curvetools_main; gs_curvetools_main.main();"
- -sourceType "python"
- -commandRepeatable 1
- -flat 1
- ;
- shelfButton
- -enableCommandRepeat 1
- -flexibleWidthType 3
- -flexibleWidthValue 36
- -enable 1
- -width 39
- -height 34
- -manage 1
- -visible 1
- -preventOverride 0
- -annotation "GS Curvetools - Reset"
- -enableBackground 0
- -backgroundColor 0 0 0
- -highlightColor 0.321569 0.521569 0.65098
- -align "center"
- -label "GSCReset"
- -labelOffset 0
- -rotation 0
- -flipX 0
- -flipY 0
- -useAlpha 1
- -font "plainLabelFont"
- -imageOverlayLabel "Reset"
- -overlayLabelColor 0.8 0.8 0.8
- -overlayLabelBackColor 0 0 0 0.5
- -image "gsCurveToolsIcon_reset.png"
- -image1 "gsCurveToolsIcon_reset.png"
- -style "iconOnly"
- -marginWidth 0
- -marginHeight 1
- -command "import gs_curvetools.core.utils as gs_curvetools_utils; gs_curvetools_utils.reset_ui(); del gs_curvetools_utils"
- -sourceType "python"
- -commandRepeatable 1
- -flat 1
- ;
- shelfButton
- -enableCommandRepeat 1
- -flexibleWidthType 3
- -flexibleWidthValue 36
- -enable 1
- -width 39
- -height 34
- -manage 1
- -visible 1
- -preventOverride 0
- -annotation "GS Curvetools - Stop/Close"
- -enableBackground 0
- -backgroundColor 0 0 0
- -highlightColor 0.321569 0.521569 0.65098
- -align "center"
- -label "GSCStop"
- -labelOffset 0
- -rotation 0
- -flipX 0
- -flipY 0
- -useAlpha 1
- -font "plainLabelFont"
- -imageOverlayLabel "Stop"
- -overlayLabelColor 0.8 0.8 0.8
- -overlayLabelBackColor 0 0 0 0.5
- -image "gsCurveToolsIcon_stop.png"
- -image1 "gsCurveToolsIcon_stop.png"
- -style "iconOnly"
- -marginWidth 0
- -marginHeight 1
- -command "import gs_curvetools.core.utils as gs_curvetools_utils; gs_curvetools_utils.stop_ui(); del gs_curvetools_utils"
- -sourceType "python"
- -commandRepeatable 1
- -flat 1
- ;
shelfButton
-enableCommandRepeat 1
-flexibleWidthType 3
diff --git a/CleanCache.bat b/CleanCache.bat
index f8b1b79..43516ce 100644
--- a/CleanCache.bat
+++ b/CleanCache.bat
@@ -8,11 +8,11 @@ echo.
echo Starting cache cleanup...
echo.
-REM 计数器初始化
+@REM Counter initialization
set "pycache_count=0"
set "temp_count=0"
-REM 清理 Python __pycache__ 目录
+REM Clean up the Python __pycache__ directory
echo [1/2] Cleaning Python cache files...
for /f "delims=" %%d in ('dir /s /b /ad __pycache__ 2^>nul') do (
echo Deleting: %%d
@@ -22,10 +22,10 @@ for /f "delims=" %%d in ('dir /s /b /ad __pycache__ 2^>nul') do (
)
)
-REM 清理临时文件
+REM Clean up temporary files
echo [2/2] Cleaning temporary files...
-for %%ext in (*.tmp *.temp *.pyo) do (
- for /f "delims=" %%f in ('dir /s /b "%%ext" 2^>nul') do (
+for %%e in (tmp temp pyo) do (
+ for /f "delims=" %%f in ('dir /s /b "*.%%e" 2^>nul') do (
echo Deleting: %%f
del /f /q "%%f" 2>nul
if !errorlevel! equ 0 (
diff --git a/modules/ARTv1.mod b/modules/ARTv1.mod
new file mode 100644
index 0000000..77c77f0
--- /dev/null
+++ b/modules/ARTv1.mod
@@ -0,0 +1,32 @@
++ MAYAVERSION:2023 PLATFORM:win64 ARTv1 3.1.0 ../plug-ins/ARTv1
+MAYA_PLUG_IN_PATH+:=plug-ins
+MAYA_SCRIPT_PATH+:=Scripts
+MAYA_SCRIPT_PATH+:=Scripts/art_v1
+MAYA_SCRIPT_PATH+:=Scripts/epic
+MAYA_SCRIPT_PATH+:=Scripts/Modules
+PYTHONPATH+:=Scripts
+PYTHONPATH+:=Scripts/art_v1
+PYTHONPATH+:=Scripts/epic
+XBMLANGPATH+:=Icons/ART
+
++ MAYAVERSION:2024 PLATFORM:win64 ARTv1 3.1.0 ../plug-ins/ARTv1
+MAYA_PLUG_IN_PATH+:=plug-ins
+MAYA_SCRIPT_PATH+:=Scripts
+MAYA_SCRIPT_PATH+:=Scripts/art_v1
+MAYA_SCRIPT_PATH+:=Scripts/epic
+MAYA_SCRIPT_PATH+:=Scripts/Modules
+PYTHONPATH+:=Scripts
+PYTHONPATH+:=Scripts/art_v1
+PYTHONPATH+:=Scripts/epic
+XBMLANGPATH+:=Icons/ART
+
++ MAYAVERSION:2025 PLATFORM:win64 ARTv1 3.1.0 ../plug-ins/ARTv1
+MAYA_PLUG_IN_PATH+:=plug-ins
+MAYA_SCRIPT_PATH+:=Scripts
+MAYA_SCRIPT_PATH+:=Scripts/art_v1
+MAYA_SCRIPT_PATH+:=Scripts/epic
+MAYA_SCRIPT_PATH+:=Scripts/Modules
+PYTHONPATH+:=Scripts
+PYTHONPATH+:=Scripts/art_v1
+PYTHONPATH+:=Scripts/epic
+XBMLANGPATH+:=Icons/ART
\ No newline at end of file
diff --git a/modules/MetaHumanForMaya.mod b/modules/MetaHumanForMaya.mod
index f20e245..1e3ae0b 100644
--- a/modules/MetaHumanForMaya.mod
+++ b/modules/MetaHumanForMaya.mod
@@ -334,4 +334,4 @@ MAYA_PLUG_IN_PATH+:=lib/MayaUERBFPlugin/2.0.4/platform-linux/maya-2026/lib
MAYA_PLUG_IN_PATH+:=lib/PreviewRigLogic/2.3.3/platform-linux/maya-2026/lib
MAYA_PLUG_IN_PATH+:=lib/SwingTwistEvaluatorPlugin/1.3.2/platform-linux/maya-2026/lib
ML_MODEL_ROOT+:=lib/ml_jm_model/1.2.2
-LOD_GENERATION_ROOT+:=lib/lod_generation_model/1.0.0
\ No newline at end of file
+LOD_GENERATION_ROOT+:=lib/lod_generation_model/1.0.0
diff --git a/modules/QuadRemesher.mod b/modules/QuadRemesher.mod
index dd45b34..f48e8e6 100644
--- a/modules/QuadRemesher.mod
+++ b/modules/QuadRemesher.mod
@@ -1,41 +1,41 @@
+ MAYAVERSION:2020 PLATFORM:win64 QuadRemesher 1.0.1 ../plug-ins/QuadRemesher
-PATH +:= QuadRemesher
-MAYA_PLUG_IN_PATH +:= plug-ins
-MAYA_SCRIPT_PATH +:= scripts
-MAYA_SHELF_PATH +:= shelves
+PATH+:=QuadRemesher
+MAYA_PLUG_IN_PATH+:=plug-ins
+MAYA_SCRIPT_PATH+:=scripts
+MAYA_SHELF_PATH+:=shelves
XBMLANGPATH+:=icons
+ MAYAVERSION:2021 PLATFORM:win64 QuadRemesher 1.0.1 ../plug-ins/QuadRemesher
-PATH +:= QuadRemesher
-MAYA_PLUG_IN_PATH +:= plug-ins
-MAYA_SCRIPT_PATH +:= scripts
-MAYA_SHELF_PATH +:= shelves
+PATH+:=QuadRemesher
+MAYA_PLUG_IN_PATH+:=plug-ins
+MAYA_SCRIPT_PATH+:=scripts
+MAYA_SHELF_PATH+:=shelves
XBMLANGPATH+:=icons
+ MAYAVERSION:2022 PLATFORM:win64 QuadRemesher 1.0.1 ../plug-ins/QuadRemesher
-PATH +:= QuadRemesher
-MAYA_PLUG_IN_PATH +:= plug-ins
-MAYA_SCRIPT_PATH +:= scripts
-MAYA_SHELF_PATH +:= shelves
+PATH+:=QuadRemesher
+MAYA_PLUG_IN_PATH+:=plug-ins
+MAYA_SCRIPT_PATH+:=scripts
+MAYA_SHELF_PATH+:=shelves
XBMLANGPATH+:=icons
+ MAYAVERSION:2023 PLATFORM:win64 QuadRemesher 1.0.1 ../plug-ins/QuadRemesher
-PATH +:= QuadRemesher
-MAYA_PLUG_IN_PATH +:= plug-ins
-MAYA_SCRIPT_PATH +:= scripts
-MAYA_SHELF_PATH +:= shelves
+PATH+:=QuadRemesher
+MAYA_PLUG_IN_PATH+:=plug-ins
+MAYA_SCRIPT_PATH+:=scripts
+MAYA_SHELF_PATH+:=shelves
XBMLANGPATH+:=icons
+ MAYAVERSION:2024 PLATFORM:win64 QuadRemesher 1.0.1 ../plug-ins/QuadRemesher
-PATH +:= QuadRemesher
-MAYA_PLUG_IN_PATH +:= plug-ins
-MAYA_SCRIPT_PATH +:= scripts
-MAYA_SHELF_PATH +:= shelves
+PATH+:=QuadRemesher
+MAYA_PLUG_IN_PATH+:=plug-ins
+MAYA_SCRIPT_PATH+:=scripts
+MAYA_SHELF_PATH+:=shelves
XBMLANGPATH+:=icons
+ MAYAVERSION:2025 PLATFORM:win64 QuadRemesher 1.0.1 ../plug-ins/QuadRemesher
-PATH +:= QuadRemesher
-MAYA_PLUG_IN_PATH +:= plug-ins
-MAYA_SCRIPT_PATH +:= scripts
-MAYA_SHELF_PATH +:= shelves
+PATH+:=QuadRemesher
+MAYA_PLUG_IN_PATH+:=plug-ins
+MAYA_SCRIPT_PATH+:=scripts
+MAYA_SHELF_PATH+:=shelves
XBMLANGPATH+:=icons
\ No newline at end of file