Repository: FelisCatus/SwitchyOmega Branch: master Commit: 19f9d73f2012 Files: 198 Total size: 1.5 MB Directory structure: gitextract_3lnnenxm/ ├── .circleci/ │ └── config.yml ├── .github/ │ ├── ISSUE_TEMPLATE.md │ └── PULL_REQUEST_TEMPLATE.md ├── .gitignore ├── .tern-project ├── AUTHORS ├── COPYING ├── README.md ├── omega-build/ │ ├── Gruntfile.coffee │ └── package.json ├── omega-locales/ │ ├── ach/ │ │ └── LC_MESSAGES/ │ │ └── omega-web.po │ ├── cs/ │ │ └── LC_MESSAGES/ │ │ └── omega-web.po │ ├── de/ │ │ └── LC_MESSAGES/ │ │ └── omega-web.po │ ├── en_US/ │ │ └── LC_MESSAGES/ │ │ └── omega-web.po │ ├── es/ │ │ └── LC_MESSAGES/ │ │ └── omega-web.po │ ├── es_AR/ │ │ └── LC_MESSAGES/ │ │ └── omega-web.po │ ├── fa/ │ │ └── LC_MESSAGES/ │ │ └── omega-web.po │ ├── fr/ │ │ └── LC_MESSAGES/ │ │ └── omega-web.po │ ├── he_IL/ │ │ └── LC_MESSAGES/ │ │ └── omega-web.po │ ├── id/ │ │ └── LC_MESSAGES/ │ │ └── omega-web.po │ ├── is/ │ │ └── LC_MESSAGES/ │ │ └── omega-web.po │ ├── it/ │ │ └── LC_MESSAGES/ │ │ └── omega-web.po │ ├── ja/ │ │ └── LC_MESSAGES/ │ │ └── omega-web.po │ ├── lzh/ │ │ └── LC_MESSAGES/ │ │ └── omega-web.po │ ├── nb_NO/ │ │ └── LC_MESSAGES/ │ │ └── omega-web.po │ ├── nl/ │ │ └── LC_MESSAGES/ │ │ └── omega-web.po │ ├── pl/ │ │ └── LC_MESSAGES/ │ │ └── omega-web.po │ ├── pt/ │ │ └── LC_MESSAGES/ │ │ └── omega-web.po │ ├── pt_BR/ │ │ └── LC_MESSAGES/ │ │ └── omega-web.po │ ├── ru/ │ │ └── LC_MESSAGES/ │ │ └── omega-web.po │ ├── si/ │ │ └── LC_MESSAGES/ │ │ └── omega-web.po │ ├── sk/ │ │ └── LC_MESSAGES/ │ │ └── omega-web.po │ ├── sl/ │ │ └── LC_MESSAGES/ │ │ └── omega-web.po │ ├── tr/ │ │ └── LC_MESSAGES/ │ │ └── omega-web.po │ ├── uk/ │ │ └── LC_MESSAGES/ │ │ └── omega-web.po │ ├── zh_CN/ │ │ └── LC_MESSAGES/ │ │ └── omega-web.po │ ├── zh_Hant/ │ │ └── LC_MESSAGES/ │ │ └── omega-web.po │ └── zh_TW/ │ └── LC_MESSAGES/ │ └── omega-web.po ├── omega-pac/ │ ├── .gitattributes │ ├── .gitignore │ ├── Gruntfile.coffee │ ├── grunt/ │ │ ├── aliases.coffee │ │ ├── browserify.coffee │ │ ├── coffeelint.coffee │ │ ├── mochaTest.coffee │ │ └── watch.coffee │ ├── index.coffee │ ├── package.json │ ├── src/ │ │ ├── conditions.coffee │ │ ├── pac_generator.coffee │ │ ├── profiles.coffee │ │ ├── rule_list.coffee │ │ ├── shexp_utils.coffee │ │ └── utils.coffee │ ├── test/ │ │ ├── conditions.coffee │ │ ├── pac_generator.coffee │ │ ├── profiles.coffee │ │ ├── rule_list.coffee │ │ ├── shexp_utils.coffee │ │ └── utils.coffee │ ├── uglifyjs-shim.js │ └── uglifyjs.js ├── omega-target/ │ ├── .gitignore │ ├── Gruntfile.coffee │ ├── grunt/ │ │ ├── aliases.coffee │ │ ├── browserify.coffee │ │ ├── coffeelint.coffee │ │ ├── mochaTest.coffee │ │ └── watch.coffee │ ├── index.coffee │ ├── omega_pac_shim.js │ ├── package.json │ ├── src/ │ │ ├── browser_storage.coffee │ │ ├── default_options.coffee │ │ ├── errors.coffee │ │ ├── log.coffee │ │ ├── options.coffee │ │ ├── options_sync.coffee │ │ ├── storage.coffee │ │ └── utils.coffee │ └── test/ │ └── options_sync.coffee ├── omega-target-chromium-extension/ │ ├── .gitignore │ ├── Gruntfile.coffee │ ├── grunt/ │ │ ├── aliases.coffee │ │ ├── browserify.coffee │ │ ├── coffee.coffee │ │ ├── coffeelint.coffee │ │ ├── compress.coffee │ │ ├── copy.coffee │ │ ├── mochaTest.coffee │ │ ├── po2crx.coffee │ │ └── watch.coffee │ ├── grunt-po2crx.coffee │ ├── index.coffee │ ├── omega_target_shim.js │ ├── overlay/ │ │ ├── background.html │ │ └── manifest.json │ ├── package.json │ └── src/ │ ├── coffee/ │ │ ├── background.coffee │ │ ├── background_preload.coffee │ │ ├── omega_debug.coffee │ │ └── omega_target_web.coffee │ ├── js/ │ │ ├── omega_target_popup.js │ │ └── omega_webext_proxy_script.js │ └── module/ │ ├── chrome_api.coffee │ ├── chrome_port.coffee │ ├── external_api.coffee │ ├── fetch_url.coffee │ ├── index.coffee │ ├── inspect.coffee │ ├── options.coffee │ ├── proxy/ │ │ ├── index.coffee │ │ ├── proxy_auth.coffee │ │ ├── proxy_impl.coffee │ │ ├── proxy_impl_listener.coffee │ │ ├── proxy_impl_script.coffee │ │ └── proxy_impl_settings.coffee │ ├── storage.coffee │ ├── switchysharp.coffee │ ├── tabs.coffee │ ├── upgrade.coffee │ └── web_request_monitor.coffee └── omega-web/ ├── .gitattributes ├── .gitignore ├── Gruntfile.coffee ├── bower.json ├── grunt/ │ ├── aliases.coffee │ ├── autoprefixer.coffee │ ├── bower.coffee │ ├── coffee.coffee │ ├── coffeelint.coffee │ ├── copy.coffee │ ├── jade.coffee │ ├── less.coffee │ ├── mochaTest.coffee │ ├── ngAnnotate.coffee │ └── watch.coffee ├── img/ │ └── icons/ │ └── draw_omega.js ├── package.json └── src/ ├── coffee/ │ ├── log_error.coffee │ ├── omega_decoration.coffee │ ├── options.coffee │ ├── options_guide.coffee │ ├── popup.coffee │ └── switch_profile_guide.coffee ├── less/ │ ├── common.less │ ├── options.less │ └── popup.less ├── omega/ │ ├── app.coffee │ ├── controllers/ │ │ ├── about.coffee │ │ ├── fixed_profile.coffee │ │ ├── io.coffee │ │ ├── master.coffee │ │ ├── pac_profile.coffee │ │ ├── profile.coffee │ │ ├── quick_switch.coffee │ │ ├── rule_list_profile.coffee │ │ └── switch_profile.coffee │ ├── directives.coffee │ └── filters.coffee ├── options.jade ├── partials/ │ ├── about.jade │ ├── apply_options_confirm.jade │ ├── cannot_delete_profile.jade │ ├── delete_attached.jade │ ├── delete_profile.jade │ ├── fixed_auth_edit.jade │ ├── general.jade │ ├── input_group_clear.jade │ ├── io.jade │ ├── new_profile.jade │ ├── omega_profile_select.jade │ ├── options_welcome.jade │ ├── profile.jade │ ├── profile_fixed.jade │ ├── profile_pac.jade │ ├── profile_rule_list.jade │ ├── profile_switch.jade │ ├── profile_unsupported.jade │ ├── profile_virtual.jade │ ├── rename_profile.jade │ ├── replace_profile.jade │ ├── reset_options_confirm.jade │ ├── rule_remove_confirm.jade │ ├── rule_reset_confirm.jade │ └── ui.jade ├── popup/ │ ├── css/ │ │ ├── dialog.css │ │ └── index.css │ ├── index.html │ ├── js/ │ │ ├── i18n.js │ │ ├── index.js │ │ ├── keyboard.js │ │ ├── keyboard_help.js │ │ ├── loader.js │ │ ├── profiles.js │ │ └── proxy_not_controllable.js │ └── proxy_not_controllable.html └── popup.jade ================================================ FILE CONTENTS ================================================ ================================================ FILE: .circleci/config.yml ================================================ version: 2 jobs: build: docker: - image: circleci/node:7.10 working_directory: ~/repo steps: - checkout - restore_cache: keys: - v2-dependencies-build-{{ checksum "omega-build/package.json" }} - v2-dependencies-build - restore_cache: keys: - v2-dependencies-pac-{{ checksum "omega-pac/package.json" }} - v2-dependencies-pac - restore_cache: keys: - v2-dependencies-target-{{ checksum "omega-target/package.json" }} - v2-dependencies-target - restore_cache: keys: - v2-dependencies-web-{{ checksum "omega-web/package.json" }} - v2-dependencies-web - restore_cache: keys: - v2-dependencies-webbower-{{ checksum "omega-web/bower.json" }} - v2-dependencies-webbower - restore_cache: keys: - v2-dependencies-targetchromium-{{ checksum "omega-target-chromium-extension/package.json" }} - v2-dependencies-targetchromium - run: sudo npm install -g grunt-cli@1.2.0 bower web-ext json - run: (cd omega-build && npm run deps) - save_cache: paths: - omega-build/node_modules key: v2-dependencies-build-{{ checksum "omega-build/package.json" }} - save_cache: paths: - omega-pac/node_modules key: v2-dependencies-pac-{{ checksum "omega-pac/package.json" }} - save_cache: paths: - omega-web/node_modules key: v2-dependencies-web-{{ checksum "omega-web/package.json" }} - save_cache: paths: - omega-web/bower_components key: v2-dependencies-webbower-{{ checksum "omega-web/bower.json" }} - save_cache: paths: - omega-target-chromium-extension/node_modules key: v2-dependencies-targetchromium-{{ checksum "omega-target-chromium-extension/package.json" }} - run: (cd omega-build && sudo npm run dev) - run: (cd omega-pac && npm test) - run: (cd omega-target && npm test) - run: (cd omega-build && grunt) - run: name: Prepare for package builds command: | cd omega-target-chromium-extension mkdir packages base_ver=$(json -f "overlay/manifest.json" version) commit_rev=$(git rev-parse --short HEAD) FULL_VER="${base_ver}-${CIRCLE_BUILD_NUM}.ci.${commit_rev}" echo "export FULL_VER='$FULL_VER'" >> $BASH_ENV cd .. - run: name: Build unsigned ZIP package for Chromium command: | cd omega-target-chromium-extension grunt release dest_file="packages/SwitchyOmega_${FULL_VER}_Chromium_UNSIGNED.zip" mv release.zip "$dest_file" cd .. - run: (cd omega-target-chromium-extension && web-ext -s build lint) - run: name: Build unsigned ZIP package for Firefox command: | cd omega-target-chromium-extension web-ext -s build build dest_file="packages/SwitchyOmega_${FULL_VER}_Firefox_UNSIGNED.xpi" mv web-ext-artifacts/*.zip "$dest_file" cd .. - store_artifacts: path: omega-target-chromium-extension/packages destination: packages ================================================ FILE: .github/ISSUE_TEMPLATE.md ================================================ ### SwitchyOmega version / SwitchyOmega 版本 ### Browser version & OS version / 浏览器名称、版本及操作系统版本 ### Problem description / 问题描述 (Please provide as much detail as possible. We recommend the following format.) (请尽可能多提供一些细节。我们推荐使用下面的格式。) #### Steps to reproduce issue / 重现错误所需步骤 (What did you do? / 你做了什么?) 1. 2. 3. #### Expected behavior / 期望发生的情况 #### Actual (or suggested) behavior / 实际发生的情况(或建议修改后的行为) ================================================ FILE: .github/PULL_REQUEST_TEMPLATE.md ================================================ ### What does this PR do? - [ ] Bug fix - [ ] Improvement - [ ] New feature (Note: Translations and typo fixes should be done on https://hosted.weblate.org/projects/switchyomega/ instead of PR.) Please explain the changes in details here... #### Compatibility Is this PR compatible with old versions? Can users simply upgrade the extension? Please describe any possible breaking changes (or surprising UX differences). #### Screenshots (if applicable) --- After creating the PR: - Please make sure the CircleCI test passes. Feel free to add more commits for bug or style fixes. - Any merge conflicts should be fixed on *your* side. Prefer rebasing to merging. - Allow some time for project maintainers to review and merge the change. - New features & behavior changes are subject to discussion. Please understand that project maintainers may reject new features, or request changes. ================================================ FILE: .gitignore ================================================ node_modules bower_components ================================================ FILE: .tern-project ================================================ { "libs": [ "chai" ], "plugins": { "node": {}, "coffee": {} } } ================================================ FILE: AUTHORS ================================================ # SwitchyOmega authors: FelisCatus # SwitchyOmega translators: Filip Michal Čihař masoud Rahmani # SwitchyOmega includes or links to (unchanged): # * jQuery UI (custom build) # => omega-web/lib/jquery-ui-*.js # => Copyright 2014 jQuery Foundation and other contributors; Licensed MIT # * Many npm packages and bower packages # => **/node_modules, **/bower_components # => Please refer to their project homepages or npm package pages for the # copyright and license information of each package. ================================================ FILE: COPYING ================================================ GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The GNU General Public License is a free, copyleft license for software and other kinds of works. The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things. To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others. For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. Developers that use the GNU GPL protect your rights with two steps: (1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it. For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions. Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users. Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free. The precise terms and conditions for copying, distribution and modification follow. TERMS AND CONDITIONS 0. Definitions. "This License" refers to version 3 of the GNU General Public License. "Copyright" also means copyright-like laws that apply to other kinds of works, such as semiconductor masks. "The Program" refers to any copyrightable work licensed under this License. Each licensee is addressed as "you". "Licensees" and "recipients" may be individuals or organizations. To "modify" a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a "modified version" of the earlier work or a work "based on" the earlier work. A "covered work" means either the unmodified Program or a work based on the Program. To "propagate" a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well. To "convey" a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying. An interactive user interface displays "Appropriate Legal Notices" to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion. 1. Source Code. The "source code" for a work means the preferred form of the work for making modifications to it. "Object code" means any non-source form of a work. A "Standard Interface" means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language. The "System Libraries" of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A "Major Component", in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it. The "Corresponding Source" for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work. The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source. The Corresponding Source for a work in source code form is that same work. 2. Basic Permissions. All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law. You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you. Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary. 3. Protecting Users' Legal Rights From Anti-Circumvention Law. No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures. When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures. 4. Conveying Verbatim Copies. You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program. You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee. 5. Conveying Modified Source Versions. You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions: a) The work must carry prominent notices stating that you modified it, and giving a relevant date. b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to "keep intact all notices". c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it. d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so. A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an "aggregate" if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate. 6. Conveying Non-Source Forms. You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways: a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange. b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge. c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b. d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements. e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d. A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work. A "User Product" is either (1) a "consumer product", which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, "normally used" refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product. "Installation Information" for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made. If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM). The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network. Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying. 7. Additional Terms. "Additional permissions" are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions. When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission. Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms: a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or d) Limiting the use for publicity purposes of names of licensors or authors of the material; or e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors. All other non-permissive additional terms are considered "further restrictions" within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying. If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms. Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way. 8. Termination. You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11). However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation. Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice. Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10. 9. Acceptance Not Required for Having Copies. You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so. 10. Automatic Licensing of Downstream Recipients. Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License. An "entity transaction" is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts. You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it. 11. Patents. A "contributor" is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's "contributor version". A contributor's "essential patent claims" are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, "control" includes the right to grant patent sublicenses in a manner consistent with the requirements of this License. Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version. In the following three paragraphs, a "patent license" is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To "grant" such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party. If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. "Knowingly relying" means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid. If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it. A patent license is "discriminatory" if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007. Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law. 12. No Surrender of Others' Freedom. If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program. 13. Use with the GNU Affero General Public License. Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such. 14. Revised Versions of this License. The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation. If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program. Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version. 15. Disclaimer of Warranty. THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. Limitation of Liability. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 17. Interpretation of Sections 15 and 16. If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively state the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . Also add information on how to contact you by electronic and paper mail. If the program does terminal interaction, make it output a short notice like this when it starts in an interactive mode: Copyright (C) This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, your program's commands might be different; for a GUI interface, you would use an "about box". You should also get your employer (if you work as a programmer) or school, if any, to sign a "copyright disclaimer" for the program, if necessary. For more information on this, and how to apply and follow the GNU GPL, see . The GNU General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. But first, please read . ================================================ FILE: README.md ================================================ SwitchyOmega ============ Manage and switch between multiple proxies quickly & easily. [![Translation status](https://hosted.weblate.org/widgets/switchyomega/-/svg-badge.svg)](https://hosted.weblate.org/engage/switchyomega/?utm_source=widget) Chromium Extension ------------------ The project is available as a Chromium Extension. You can try it on [Chrome Web Store](https://chrome.google.com/webstore/detail/padekgcemlokbadohgkifijomclgjgif), or grab a packaged extension file (CRX) for offline installation on the [Releases page](https://github.com/FelisCatus/SwitchyOmega/releases). Please [report issues on the issue tracker.](https://github.com/FelisCatus/SwitchyOmega/issues) Firefox Addon (Experimental) ---------------------------- There is also an experimental WebExtension port, which allows installing in **Firefox Nightly Version >= 56**. **Since the WebExtensions API is still under heavy development on Mozilla's side, we strongly recommended using the Nightly channel (>= 56.0) and update frequently.** The Developer Edition and Beta channels will not receive fixes as often and therefore unsupported by SwitchyOmega. Some users report that it works with the Firefox Developer Edition (>= 55) as well, but we strongly advise against doing so. It won't work at all in Firefox 54 Stable. You can try it on [Mozilla Add-ons](https://addons.mozilla.org/en-US/firefox/addon/switchyomega/), or grab a packaged extension file (XPI) for offline installation on the [Releases page](https://github.com/FelisCatus/SwitchyOmega/releases). Please make sure that you are using the latest Nightly build before you [report issues](https://github.com/FelisCatus/SwitchyOmega/issues). Build number AND build date should be mentioned somewhere in the issue. NOTE: PAC Profiles DO NOT work on Firefox due to AMO review policies. We will see what we can do. Development status ------------------ ## PAC generator This project contains a PAC generating module called `omega-pac`, which handles the profiles model and compile profiles into PAC scripts. This module is standalone and can be published to npm when the documentation is ready. ## Options manager The folder `omega-target` contains browser-independent logic for managing the options and applying profiles. Every public method is well documented in the comments. Functions related to browser are not included, and shall be implemented in subclasses of the `omega-target` classes. `omega-web` is a web-based configuration interface for various options and profiles. The interface works great with `omega-target` as the back-end. `omega-web` alone is incomplete and requires a file named `omega_target_web.js` containing an angular module `omegaTarget`. The module contains browser-dependent code to communicate with `omega-target` back-end, and other code retrieving browser-related state and information. See the `omega-target-chromium-extension/omega_target_web.coffee` file for an example of such module. ## Targets The `omega-target-*` folders should contain environment-dependent code such as browser API calls. Each target folder should contain an extended `OmegaTarget` object, which contains subclasses of the abstract base classes like `Options`. The classes contains implementation of the abstract methods, and can override other methods at will. A target can copy the files in `omega-web` into its build to provide a web-based configuration interface. If so, the target must provide the `omega_target_web.js` file as described in the Options manager section. Additionally, each target can contain other files and resources required for the target, such as background pages and extension manifests. For now, only one target has been implemented: The WebExtension target. This target allows the project to be used as a Chromium extension in most Chromium-based browsers and also as a Firefox Addon as mentioned above. ## Translation Translation is hosted on Weblate. If you want to help improve the translated text or start translation for your language, please follow the link of the picture below. 本项目翻译由Weblate托管。如果您希望帮助改进翻译,或将本项目翻译成一种新的语言,请 点击下方图片链接进入翻译。 [![Translation status](https://hosted.weblate.org/widgets/switchyomega/-/287x66-white.png)](https://hosted.weblate.org/engage/switchyomega/?utm_source=widget) ## Building the project SwitchyOmega has migrated to use npm and grunt for building. Please note that npm 2.x is required for this project. To build the project: # Install node and npm first (make sure npm --version > 2.0), then: sudo npm install -g grunt-cli@1.2.0 bower # In the project folder: cd omega-build npm run deps # This runs npm install in every module. npm run dev # This runs npm link to aid local development. # Note: the previous command may require sudo in some environments. # The modules are now working. We can build now: grunt # After building, a folder will be generated: cd .. # Return to project root. ls omega-chromium-extension/build/ # The folder above can be loaded as an unpacked extension in Chromium now. To enable `grunt watch`, run `grunt watch` once in the `omega-build` directory. This will effectively run `grunt watch` in every module in this project. License ------- ![GPLv3](https://www.gnu.org/graphics/gplv3-127x51.png) SwitchyOmega is licensed under [GNU General Public License](https://www.gnu.org/licenses/gpl.html) Version 3 or later. SwitchyOmega is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. SwitchyOmega is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with SwitchyOmega. If not, see . Notice ------ SwitchyOmega currently does not have a dedicated project homepage. `switchyomega.com` and similar webites are NOT affiliated with the SwitchyOmega project in any way, nor are they maintained by SwitchyOmega project members. Please refer to this Github repository and wiki for official information. SwitchyOmega is not cooperating with any proxy providers, VPN providers or ISPs at the moment. No advertisement is displayed in SwitchyOmega project or software. Proxy providers are welcome to recommend SwitchyOmega as part of the solution in tutorials, but it must be made clear that SwitchyOmega is an independent project, is not affiliated with the provider and therefore cannot provide any support on network connections or proxy technology. 重要声明 -------- SwitchyOmega 目前没有专门的项目主页。 `switchyomega.com` 等网站与 SwitchyOmega 项目并无任何关联,也并非由 SwitchyOmega 项目成员维护。一切信息请以 Github 上的项目和 wiki 为准。 SwitchyOmega 目前未与任何代理提供商、VPN提供商或 ISP 达成任何合作协议,项目或软件中不包含任何此类广告。欢迎代理提供商在教程或说明中推荐 SwitchyOmega ,但请明确说明此软件是独立项目,与代理提供商无关,且不提供任何关于网络连接或代理技术的支持。 ================================================ FILE: omega-build/Gruntfile.coffee ================================================ module.exports = (grunt) -> submodules = ['omega-pac', 'omega-target', 'omega-web', 'omega-target-*'] hubConfig = all: options: concurrent: Infinity src: "../*/Gruntfile.*" for module in submodules hubConfig[module] = src: "../#{module}/Gruntfile.*" hubAll = (task) -> "hub:#{module}:#{task}" for module in submodules grunt.initConfig { hub: hubConfig } grunt.loadNpmTasks 'grunt-hub' grunt.registerTask 'default', hubAll('default') grunt.registerTask 'test', hubAll('test') grunt.registerTask 'watch', ['hub:all:watch'] ================================================ FILE: omega-build/package.json ================================================ { "name": "omega-build", "version": "0.0.1", "private": true, "devDependencies": { "grunt": "~0.4.1", "grunt-hub": "^0.7.0" }, "scripts": { "deps": "npm install && (cd ../omega-pac && npm install) && (cd ../omega-target && npm install) && (cd ../omega-web && npm install && bower install) && (cd ../omega-target-chromium-extension/ && npm install)", "dev": "(cd ../omega-pac && npm run dev) && (cd ../omega-target && npm run dev) && (cd ../omega-web && npm run dev) && (cd ../omega-target-chromium-extension/ && npm run dev)" } } ================================================ FILE: omega-locales/ach/LC_MESSAGES/omega-web.po ================================================ msgid "" msgstr "" "Project-Id-Version: SwitchyOmega 2.3.3\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2015-02-13 10:29+0000\n" "PO-Revision-Date: 2015-02-13 10:29+0000\n" "Last-Translator: Automatically generated\n" "Language-Team: none\n" "Language: ach\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Generator: Weblate 2.2-dev\n" msgid "appNameShort" msgstr "SwitchyOmega" msgid "manifest_app_name" msgstr "Proxy SwitchyOmega" msgid "manifest_app_description" msgstr "Manage and switch between multiple proxies quickly & easily." msgid "manifest_icon_default_title" msgstr "Loading…" msgid "upgrade_profile_auto" msgstr "Auto Switch" msgid "profile_direct" msgstr "[Direct]" msgid "profile_system" msgstr "[System Proxy]" msgid "condition_HostWildcardCondition" msgstr "Host wildcard" msgid "condition_help_HostWildcardCondition" msgstr "" "Matches hosts (domain names) by wildcard.
The asterisk * matches zero or more characters.
The question mark ? matches exactly one character.

Note that rules beginning with " "*. are specially treated only in Host wildcard conditions." "
Example: *.example.com will match www.example.com AND " "example.com as well.
To match subdomains only, use two " "asterisks like **.example.com." msgid "condition_HostRegexCondition" msgstr "Host regex" msgid "condition_help_HostRegexCondition" msgstr "" "Like Host wildcard condition, but matches hosts (domain names) by regular " "expression.
Regular expressions can be hard to construct (and read)." "
It is recommended to use wildcards for most cases and only use regex for " "conditions that cannot be achieved by any other condition type." msgid "condition_HostLevelsCondition" msgstr "Host levels" msgid "condition_help_HostLevelsCondition" msgstr "" "Matches the request if and only if the host level in within the given range." "
Host level is defined as the number of dot-separated segments of " "the host (domain name).
Example: www.example.com is with a " "host level of 3, while internal is of host level 1." msgid "condition_IpCondition" msgstr "IP Literals" msgid "condition_help_IpCondition" msgstr "" "Matches the request if and only if the host is a literal IP address and" " in the subnet as specified by " "CIDR notation.
For example, given the rule 127.0.0.1/16, " "it matches all IP addresses like 127.0.*.*.
" "So 127.0.0.1 matches while 127.1.0.0 does not. " "Host names like localhost will never match because they are " "not IP literals." msgid "condition_UrlWildcardCondition" msgstr "URL wildcard" msgid "condition_help_UrlWildcardCondition" msgstr "" "Matches URLs of the request by wildcard.
See the Host wildcard section " "above for a quick wildcard reference.
Note that URL wildcards are not " "specially treated (no subdomain magic as in Host wildcard).
So *://" "*.example.com/* matches http://www.example.com/ but does not " "match http://example.com/." msgid "condition_UrlRegexCondition" msgstr "URL regex" msgid "condition_help_UrlRegexCondition" msgstr "" "Matches URL by extremely powerful regular expression.
However, regular " "expressions can be hard to construct (and read).
It is recommended to use " "wildcards for most cases and only use regex for conditions that cannot be " "achieved by any other condition type." msgid "condition_KeywordCondition" msgstr "Keyword" msgid "condition_help_KeywordCondition" msgstr "" "A keyword condition matches if the URL protocol is HTTP, and the pattern is " "an exact sub-string of the URL.
It behaves like the URL wildcard pattern " "http://*pattern*, where pattern is the keyword " "pattern.
Keyword conditions are useful if you want to bypass a firewall " "blocking some keywords in the URL, by requesting such URLs through a proxy." msgid "condition_FalseCondition" msgstr "(Disabled)" msgid "condition_details_FalseCondition" msgstr "(Condition ignored when matching)" msgid "condition_help_FalseCondition" msgstr "" "You can disable a condition by setting its type to (Disabled). " "A Disabled condition act as if it does not exist.
This feature can be " "used to disable conditions temporarily.
Disabled conditions still hold " "the previous information (like patterns) and can be re-enabled by setting " "the condition type back to the previous type." msgid "condition_TimeCondition" msgstr "Current Time" msgid "condition_help_TimeCondition" msgstr "" "Matches if the current local time is in the range defined by " "starting hour and ending hour, both inclusive.
" "Local time, starting hour and ending hour are all calculated in " "24-hour format (from 0 to 23).
" "The calculation happens roughly at the moment when the request is sent." msgid "condition_WeekdayCondition" msgstr "Day of the Week" msgid "condition_help_WeekdayCondition" msgstr "" "Matches if the current day of week is selected in condition details. " "Day is calculated according to local timezone.
" "The request and its URL don't matter to this condition. " "The result is solely based on the day of the week when the request is sent." msgid "condition_alert_fullUrlLimitation" msgstr "" "Full URL matching is no longer possible for https:// " "URLs as of Chrome 52. " "" "Learn more..." msgid "condition_alert_fullUrlLimitationLink" msgstr "https://github.com/FelisCatus/SwitchyOmega/wiki/Chromium-Full-URL-Limitation" msgid "condition_group_default" msgstr " " msgid "condition_group_host" msgstr "Host" msgid "condition_group_url" msgstr "Url" msgid "condition_group_special" msgstr "Special" msgid "ruleListFormat_Switchy" msgstr "Switchy" msgid "ruleListFormat_AutoProxy" msgstr "AutoProxy" msgid "ruleList_usageUrl" msgstr "https://github.com/FelisCatus/SwitchyOmega/wiki/RuleListUsage" msgid "ruleList_error_resultNotEnabled" msgstr "Missing '@with result' directive!" msgid "ruleList_error_unknownProfile" msgstr "Unknown profile: $PROFILE$" msgid "ruleList_error_missingResultProfile" msgstr "Missing result profile name at Line $LNO$: $SOURCE$" msgid "ruleList_error_invalidRule" msgstr "Invalid rule at Line $LNO$: $SOURCE$" msgid "ruleList_error_noDefaultRule" msgstr "Missing default rule with catch-all '*' condition!" msgid "dialog_close" msgstr "Close" msgid "dialog_save" msgstr "Save changes" msgid "dialog_ok" msgstr "OK" msgid "dialog_cancel" msgstr "Cancel" msgid "inputClear_clear" msgstr "Clear" msgid "inputClear_restore" msgstr "Restore" msgid "options_title" msgstr "SwitchyOmega Options" msgid "options_experimental_badge" msgstr "α" msgid "options_navHeader_setting" msgstr "Settings" msgid "options_navHeader_profiles" msgstr "Profiles" msgid "options_navHeader_actions" msgstr "Actions" msgid "options_tab_ui" msgstr "Interface" msgid "options_tab_general" msgstr "General" msgid "options_tab_importExport" msgstr "Import/Export" msgid "options_newProfile" msgstr "New profile…" msgid "options_apply" msgstr "Apply changes" msgid "options_discard" msgstr "Discard changes" msgid "options_reset" msgstr "Reset options" msgid "options_group_miscOptions" msgstr "Misc Options" msgid "options_confirmDeletion" msgstr "Confirm on condition deletion." msgid "options_refreshOnProfileChange" msgstr "Refresh current tab on profile change." msgid "options_showInspectMenu" msgstr "Allow inspecting proxy used for page elements via context menu." msgid "options_addConditionsToBottom" msgstr "Put new conditions added using the popup to the bottom of the list." msgid "options_group_keyboardShortcut" msgstr "Keyboard Shortcut" msgid "options_menuShortcutHelp" msgstr "" "Pressing the shortcut will open the switch popup menu. (Defaults to Alt+Shift" "+O)." msgid "options_menuShortcutMore" msgstr "" "The items in the popup menu can also be accessed using the keyboard. Press ? " "(or /) in the menu to learn more." msgid "options_menuShortcutConfigure" msgstr "Configure shortcut" msgid "options_group_switchOptions" msgstr "Switch Options" msgid "options_startupProfile" msgstr "Startup Profile" msgid "options_startupProfile_none" msgstr "(Current profile)" msgid "options_showConditionTypesAdvanced" msgstr "Show advanced condition types" msgid "options_showConditionTypesAdvancedHelp" msgstr "" "Unlocks new types of advanced but complicated switch conditions. For most " "senarios, the basic condition types should be enough, so this option is not " "recommended." msgid "options_quickSwitch" msgstr "Quick Switch" msgid "options_cycledProfiles" msgstr "Cycled Profiles" msgid "options_cycledProfilesHelp" msgstr "" "When you click on the icon (or use the shortcut above), the following " "profiles will be applied in their order." msgid "options_cycledProfilesTooFew" msgstr "" "You need to select at least 2 profiles to enable this function! You can drag " "them from the box below." msgid "options_notCycledProfiles" msgstr "Not Cycled Profiles" msgid "options_group_proxyChanges" msgstr "Proxy Changes" msgid "options_revertProxyChanges" msgstr "Revert proxy changes done by other apps." msgid "options_group_conflicts" msgstr "Conflicts" msgid "options_conflicts_introduction" msgstr "" "Sometimes, other apps will also try to control the proxy settings, resulting " "in conflicts. Note that ad blockers and other extensions may also use proxy " "settings under the hood. Such conflicts cannot be avoided due to how the " "browser works." msgid "options_conflicts_lowerPriority" msgstr "" "A red badge like this on the SwitchyOmega icon indicates that another app has " "higher priority so SwitchyOmega cannot control the settings. Please try to " "uninstall SwitchyOmega and reinstall, which should raise SwitchyOmega's " "priority. If you still see conflicts after reinstallation, please consider " "removing the other app causing the conflict." msgid "options_conflicts_higherPriority" msgstr "" "If SwitchyOmega has higher priority, you can give the control back to other " "apps or system settings by selecting $SYSTEMPROFILE$ in the popup menu." msgid "options_showExternalProfile" msgstr "Show popup menu item to import proxy settings from other apps." msgid "options_showExternalProfileHelp" msgstr "" "When $SYSTEMPROFILE$ is selected, you can import the effective proxy settings " "from other apps by selecting $EXTERNALPROFILE$ on the popup menu. " "The settings will be imported as a profile using the name you provide. " "Please note that the imported profile is a snapshot and will not reflect " "any changes from the source app thereafter." msgid "options_group_networkRequests" msgstr "Network Requests" msgid "options_monitorWebRequests" msgstr "Show count of failed web requests for resources in the current tab." msgid "options_monitorWebRequestsHelp" msgstr "" "A yellow badge will be displayed on the icon if some resources fail to load," "
and you can set the profile for such resources conveniently via the " "popup menu." msgid "options_downloadOptions" msgstr "Download Options" msgid "options_downloadOptionsHelp" msgstr "Configure the update frequency of online rule lists and PAC scripts." msgid "options_downloadInterval" msgstr "Download Interval" msgid "options_downloadInterval_15" msgstr "15 Minutes" msgid "options_downloadInterval_60" msgstr "1 Hour" msgid "options_downloadInterval_180" msgstr "3 Hours" msgid "options_downloadInterval_360" msgstr "6 Hours" msgid "options_downloadInterval_720" msgstr "12 Hours" msgid "options_downloadInterval_1440" msgstr "Every day" msgid "options_downloadInterval_never" msgstr "Never" msgid "options_group_importExportProfile" msgstr "Profile" msgid "options_exportPacFile" msgstr "Export as PAC File" msgid "options_exportPacFileHelp" msgstr "" "Export the current profile as a PAC file, so you can use it in other " "browsers." msgid "options_exportProfileHelp" msgstr "To export a profile, use the top-right action bar on the profile page." msgid "options_exportLegacyRuleList" msgstr "" "Export rule lists using Proxy Switchy!/SwitchyPlus/SwitchySharp compatible " "format when possible." msgid "options_exportLegacyRuleListHelp" msgstr "" "Enable this option only if you publish rule lists for users of those " "projects.
Please consider advising your audience to upgrade to " "SwitchyOmega for the improvements." msgid "options_group_importExportSettings" msgstr "Settings" msgid "options_makeBackup" msgstr "Make backup" msgid "options_makeBackupHelp" msgstr "" "Make a full backup of your options (including profiles and all other " "options)." msgid "options_restoreLocal" msgstr "Restore from file" msgid "options_restoreLocalHelp" msgstr "Restore your SwitchyOmega options from a local file." msgid "options_restoreOnline" msgstr "Restore from online" msgid "options_restoreOnlinePlaceholder" msgstr "Options file URL (e.g. 'http://example.com/switchy.bak')" msgid "options_restoreOnlineSubmit" msgstr "Restore" msgid "options_group_syncing" msgstr "Syncing (Experimental)" msgid "options_syncEnable" msgstr "Enable Syncing" msgid "options_syncEnableForce" msgstr "Download from Syncing" msgid "options_syncDisable" msgstr "Disable syncing" msgid "options_syncReset" msgstr "Clear remote copy" msgid "options_syncPristineHelp" msgstr "" "You can now automatically synchronize your settings and profiles across all " "your desktop devices running Chrome browser." msgid "options_syncSyncAlert" msgstr "Your options are automatically synchronized with your other devices." msgid "options_syncSyncHelp" msgstr "" "Please note that you must sign in to Chrome on each of your devices " "(including this one) for the syncing to actually work.
You may check " "this section on other devices to ensure that it is working." msgid "options_syncConflictAlert" msgstr "" "You have uploaded a copy of your options on another device via syncing." msgid "options_syncConflictHelp" msgstr "" "You may download the remote copy to your device if you like.
However, " "doing so would overwrite your existing settings and profiles on this " "device." msgid "options_syncUnsupportedHelp" msgstr "" "Options syncing is not supported on your platform or browser. For now, only " "Chrome browser on desktop is supported." msgid "options_profileSyncDisabled" msgstr "Syncing is disabled for this profile." msgid "options_profileSyncDisabled_quotaPerItem" msgstr "Syncing is disabled for this profile for using too much storage space." msgid "options_profileTabPrefix" msgstr "Profile :: " msgid "options_renameProfile" msgstr "Rename" msgid "options_deleteProfile" msgstr "Delete" msgid "options_profileExportRuleList" msgstr "Publish rule list" msgid "options_profileExportRuleListHelp" msgstr "Export Switch Rules as text format for publishing." msgid "options_profileExportPac" msgstr "Export PAC" msgid "options_profileUnsupported" msgstr "Unsupported profile type $TYPE$!" msgid "options_profileUnsupportedHelp" msgstr "The options could be broken, or from a newer version of this program." msgid "options_profileEditSource" msgstr "Edit source code" msgid "options_profileEditSourceHelp" msgstr "Show help about the source code format" msgid "options_profileEditSourceHelpUrl" msgstr "" "https://github.com/FelisCatus/SwitchyOmega/wiki/SwitchyOmega-conditions-" "format#result-profile" msgid "options_group_proxyServers" msgstr "Proxy servers" msgid "options_proxy_scheme" msgstr "Scheme" msgid "options_proxy_protocol" msgstr "Protocol" msgid "options_proxy_server" msgstr "Server" msgid "options_proxy_port" msgstr "Port" msgid "options_proxy_auth" msgstr "Authentication" msgid "options_proxy_authNotSupported" msgstr "Your browser DOES NOT support $PROTOCOLDISP$ proxy authentication! " "Please do not report this issue to SwitchyOmega. Contact the support for " "your browser instead." msgid "options_proxy_authAllWarningPac" msgstr "" "Warning: The username/password may be sent to unexpected servers returned by " "the PAC script." msgid "options_proxy_authAllWarningPacUrl" msgstr "" "Please make sure that you trust the script provided via the URL above before " "entering sensitive credentials." msgid "options_proxy_authAllWarningPacScript" msgstr "" "Please make sure that you trust the script below before providing sensitive " "credentials." msgid "options_proxy_authReferencedWarning" msgstr "" "Additionally, using this profile in other profiles (e.g. Switch Profile) may " "cause the username/password to be sent to proxy servers configured in other " "profiles." msgid "options_scheme_default" msgstr "(default)" msgid "options_protocol_direct" msgstr "DIRECT" msgid "options_protocol_useDefault" msgstr "(use default)" msgid "options_proxy_single" msgstr "Use the proxy above for all protocols." msgid "options_proxy_expand" msgstr "Show Advanced" msgid "options_group_bypassList" msgstr "Bypass List" msgid "options_bypassListHelp" msgstr "" "Servers for which you do not want to use any proxy: (One server on each " "line.)" msgid "options_bypassListHelpLinkText" msgstr "(Wildcards and more available…)" msgid "options_group_pacUrl" msgstr "PAC URL" msgid "options_pacUrlHelp" msgstr "" "The PAC script will be updated from this URL. If it is left blank, the " "following script will be used directly instead." msgid "options_pacUrlFile" msgstr "" "PAC profiles with file: URLs can only be applied directly. They cannot be " "used as result profiles because local files cannot be accessed due to " "browser limitation." msgid "options_pacUrlFileDisabled" msgstr "" "Therefore, you cannot use local PAC file for this profile. You can create a " "new PAC profile for that if you really want that." msgid "options_group_pacScript" msgstr "PAC Script" msgid "options_pacScriptLastUpdate" msgstr "PAC script downloaded at $TIME$:" msgid "options_pacScriptObsolete" msgstr "" "PAC script is obsolete due to URL change. Press the download button above to " "update." msgid "options_group_virtualProfile" msgstr "Virtual Profile" msgid "options_virtualProfileTarget" msgstr "Target" msgid "options_virtualProfileTargetHelp" msgstr "" "When this profile is applied, it acts exactly the same as the profile " "selected below." msgid "options_group_virtualProfileReplace" msgstr "Migrate to Virtual Profile" msgid "options_virtualProfileReplace" msgstr "Replace target profile" msgid "options_virtualProfileReplaceHelp" msgstr "" "You can migrate existing options to use this virtual profile instead of " "$PROFILE$. Doing so will update all existing rules concerning $PROFILE$ and " "point them to this virtual profile, so that their result profile can be " "controlled here." msgid "options_group_ruleListConfig" msgstr "Rule List Config" msgid "options_ruleListFormat" msgstr "Rule List Format" msgid "options_group_ruleListResult" msgstr "Rule list result profiles" msgid "options_ruleListMatchProfile" msgstr "Match profile" msgid "options_ruleListDefaultProfile" msgstr "Default profile" msgid "options_group_ruleListUrl" msgstr "Rule List URL" msgid "options_ruleListUrlHelp" msgstr "" "The rule list will be updated from this URL. If it is left blank, the " "following text will be parsed instead." msgid "options_group_ruleListText" msgstr "Rule List Text" msgid "options_ruleListLastUpdate" msgstr "Rule list downloaded at $TIME$:" msgid "options_ruleListObsolete" msgstr "" "Rule list is obsolete due to URL change. Press the download button above to " "update." msgid "options_group_switchRules" msgstr "Switch rules" msgid "options_sort" msgstr "Sort" msgid "options_conditionType" msgstr "Condition Type" msgid "options_showConditionTypeHelp" msgstr "Show help" msgid "options_conditionDetails" msgstr "Condition Details" msgid "options_resultProfile" msgstr "Profile" msgid "options_conditionActions" msgstr "Actions" msgid "options_addCondition" msgstr "Add condition" msgid "options_cloneRule" msgstr "Clone" msgid "options_ruleNote" msgstr "Note" msgid "options_switchAttachedProfileInCondition" msgstr "Rule list rules" msgid "options_switchAttachedProfileInConditionDetails" msgstr "(Any request matching the rule list below)" msgid "options_switchAttachedProfileInConditionDisabled" msgstr "(Rule list rules are DISABLED)" msgid "options_switchDefaultProfile" msgstr "Default" msgid "options_hostLevelsBetween" msgstr "≤ host levels ≤" msgid "options_hourBetween" msgstr "≤ current hour ≤" msgid "options_weekDayShort_0" msgstr "Su" msgid "options_weekDayShort_1" msgstr "Mo" msgid "options_weekDayShort_2" msgstr "Tu" msgid "options_weekDayShort_3" msgstr "We" msgid "options_weekDayShort_4" msgstr "Th" msgid "options_weekDayShort_5" msgstr "Fr" msgid "options_weekDayShort_6" msgstr "Sa" msgid "options_group_conditionHelp" msgstr "About Condition Types" msgid "options_group_attachProfile" msgstr "Import online rule lists" msgid "options_attachProfile" msgstr "Add a rule list" msgid "options_attachProfileHelp" msgstr "" "You can reuse an online collection of conditions published by others by " "adding a rule list." msgid "options_modalHeader_welcome" msgstr "Welcome to SwitchyOmega" msgid "options_welcomeNormal" msgstr "" "You have successfully installed SwitchyOmega, the ultimate proxy switcher." msgid "options_welcomeNormalGuide" msgstr "" "Please tell SwitchyOmega about your proxies through the options page. Let's " "see how." msgid "options_welcomeUpgrade" msgstr "" "You have successfully upgraded to SwitchyOmega. Don't panic, your existing " "options are fully preserved." msgid "options_welcomeUpgradeGuide" msgstr "Now let's go through a quick guide of the new options page." msgid "options_guideNext" msgstr "Next" msgid "options_guideDone" msgstr "Done" msgid "options_guideSkip" msgstr "Skip guide" msgid "options_modalHeader_applyOptions" msgstr "Apply Options" msgid "options_optionsNotSaved" msgstr "" "Your modifications to the options have not been saved and will be lost if " "you proceed!" msgid "options_applyOptionsRequired" msgstr "Your changes to the options must be applied before you proceed." msgid "options_applyOptionsConfirm" msgstr "Do you want to save and apply the options?" msgid "options_modalHeader_renameProfile" msgstr "Rename Profile" msgid "options_renameProfileName" msgstr "New profile name" msgid "options_profileNameConflict" msgstr "A profile with this name already exists." msgid "options_profileNameReserved" msgstr "Profile names beginning with double-underscore are reserved." msgid "options_profileNameHidden" msgstr "" "Profiles with names starting with underscore will be hidden on the popup " "menu. However, they can still be used in places like switch profile results." msgid "options_modalHeader_replaceProfile" msgstr "Replace Profile" msgid "options_replaceProfile" msgstr "Replace Profile" msgid "options_replaceProfileConfirm" msgstr "Do you really want to replace $FromProfile$ with $ToProfile$?" msgid "options_replaceProfileHelp" msgstr "" "If you proceed, all rules pointing to $FromProfile$ will be updated to use " "$ToProfile$ instead. Other options, such as startup profile and Quick Switch " "will also be modified as appropriate. However, the two profile themselves " "will NOT be changed or deleted." msgid "options_replaceProfileSuccess" msgstr "Options updated." msgid "options_modalHeader_deleteProfile" msgstr "Delete Profile" msgid "options_deleteProfileConfirm" msgstr "Do you really want to delete the following profile?" msgid "options_modalHeader_cannotDeleteProfile" msgstr "Unable to Delete Profile" msgid "options_profileReferredBy" msgstr "" "This profile cannot be deleted because it is referred by the following " "profiles:" msgid "options_modifyReferringProfiles" msgstr "" "You must modify these profiles and make them stop referring to this profile " "before you can delete it." msgid "options_profileNameEmpty" msgstr "The name of the profile must not be empty." msgid "popup_title" msgstr "SwitchyOmega Popup" msgid "options_modalHeader_proxyAuth" msgstr "Proxy Authentication" msgid "options_proxyAuthUsername" msgstr "Username" msgid "options_proxyAuthPassword" msgstr "Password" msgid "options_proxyAuthShowPassword" msgstr "Show password" msgid "options_proxyAuthHidePassword" msgstr "Hide password" msgid "options_proxyAuthNone" msgstr "No Authentication" msgid "options_modalHeader_deleteRule" msgstr "Delete Rule" msgid "options_deleteRuleConfirm" msgstr "Do you really want to delete the following rule?" msgid "options_deleteRule" msgstr "Delete" msgid "options_modalHeader_resetRules" msgstr "Reset rules" msgid "options_resetRulesConfirm" msgstr "" "Are you sure to set the result profile of ALL rules to the following profile?" msgid "options_resetRules" msgstr "Reset rules" msgid "options_resetRules_help" msgstr "Set profile for all rules" msgid "options_modalHeader_deleteAttached" msgstr "Remove Rule List" msgid "options_deleteAttachedConfirm" msgstr "Do you really want to remove the rule list from the current profile?" msgid "options_ruleListLineCount" msgstr "$COUNT$ line(s) of rules" msgid "options_deleteAttached" msgstr "Remove rule list" msgid "options_modalHeader_newProfile" msgstr "New Profile" msgid "options_newProfileName" msgstr "Profile name" msgid "options_profileType" msgstr "Please select the type of the profile:" msgid "options_profileTypeFixedProfile" msgstr "Proxy Profile" msgid "options_profileDescFixedProfile" msgstr "Tunneling traffic through proxy servers." msgid "options_profileTypePacProfile" msgstr "PAC Profile" msgid "options_profileDescPacProfile" msgstr "Choosing proxies using an online/local PAC script." msgid "options_profileDescMorePacProfile" msgstr "" "You will only need this if you have a PAC script or a URL to it. Don't try " "to create one unless you have knowledge about PAC." msgid "options_profileTypeSwitchProfile" msgstr "Switch Profile" msgid "options_profileDescSwitchProfile" msgstr "" "Applying different profiles automatically on various conditions such as " "domains or patterns.\n" " You can also import rules published online for easier switching. (Replaces " "AutoSwitch mode + Rule List.)" msgid "options_profileTypeRuleListProfile" msgstr "Rule List Profile" msgid "options_profileDescRuleListProfile" msgstr "Reusing an online collection of conditions published by others." msgid "options_profileTypeVirtualProfile" msgstr "Virtual Profile" msgid "options_profileDescVirtualProfile" msgstr "" "A virtual profile can act as any of the other profiles on demand. It works " "well with SwitchProfile, allowing you to change the result of multiple " "conditions by one click." msgid "options_createProfile" msgstr "Create" msgid "options_modalHeader_resetOptions" msgstr "Reset Options" msgid "options_resetOptionsConfirm" msgstr "" "Do you really want to reset the options? All profiles and settings will be " "LOST!" msgid "options_formInvalid" msgstr "Please correct the errors in this page." msgid "options_profileNotFound" msgstr "Profile $PROFILE$ does not exist! The options may be corrupted." msgid "options_resetSuccess" msgstr "Options reset." msgid "options_saveSuccess" msgstr "Options saved." msgid "options_importSuccess" msgstr "Options imported." msgid "options_importFormatError" msgstr "Invalid backup file!" msgid "options_importDownloadError" msgstr "Error downloading backup file!" msgid "options_profileDownloadSuccess" msgstr "Successfully updated profile." msgid "options_profileDownloadError" msgstr "Error downloading profile data!" msgid "options_profileDownloadError_NetworkError" msgstr "A network error occurred when updating." msgid "options_profileDownloadError_HttpError" msgstr "An HTTP error ($STATUS$) occurred when updating." msgid "options_profileDownloadError_HttpNotFoundError" msgstr "The Profile URL was not found on the server. Please double-check." msgid "options_profileDownloadError_HttpServerError" msgstr "The remote server responded with error ($STATUS$) when updating." msgid "options_profileDownloadError_ContentTypeRejectedError" msgstr "The downloaded data is invalid! " "You may open the Profile URL in your browser to inspect it." msgid "options_downloadProfileNow" msgstr "Download Profile Now" msgid "options_guide_fixedProfileStep" msgstr "" "A Proxy Profile contains settings like server ip & port for proxy." "
Profiles are the the basic configuration units in SwitchyOmega.
We " "have already created an example profile for you. Try opening it." msgid "options_guide_fixedServersStep" msgstr "" "You can fill in your proxy server and port here as you like.
SwitchyOmega " "does not come with any proxy servers.
Please consult your network " "provider or proxy software manual if you don't know what should be filled in " "here." msgid "options_guide_autoSwitchProfileStep" msgstr "" "You can tell SwitchyOmega to switch between proxies automatically through " "the mighty Switch Profile.
However, its features cannot be covered " "in this quick guide.
You can open this profile to unlock its power some " "time later." msgid "options_guide_addMoreProfilesStep" msgstr "" "Need more profiles? You can always add more Proxy, Switch and other " "profiles
for all your proxying needs.
Enjoy proxying!" msgid "options_guide_conditionStep" msgstr "" "SwitchyOmega can apply different profiles to requests based on " "conditions.
For example, the Host wildcard condition " "allows you to set the profile for all URLs in a domain." msgid "options_guide_conditionTypeStep" msgstr "" "You can use various condition types to match the host or full URL.
" "Click on the question mark to open the type reference." msgid "options_guide_conditionProfileStep" msgstr "" "SwitchyOmega applies the selected profile here to any request matching " "the condition.
The special \"[Direct]\" profile will cause " "the request to be sent without any proxy." msgid "options_guide_switchDefaultStep" msgstr "" "If no condition applies to some request, the \"Default\" profile will be " "used.
Conditions are always considered from top to bottom in " "order.
You can change their order by dragging the sort icon." msgid "options_guide_applySwitchProfileStep" msgstr "" "When you are done setting the switch profile, don't forget to switch to " "it in the popup menu.
The icon will show you the final result profile applied for the current tab.
Hovering on the icon " "will reveal a tooltip with details." msgid "popup_externalProfile" msgstr "(External Profile)" msgid "popup_externalProfileName" msgstr "profile name" msgid "popup_proxyNotControllable_app" msgstr "" "The proxy settings are controlled by other app(s) or extension(s). Please " "disable or uninstall the apps or extensions in conflict." msgid "popup_proxyNotControllable_policy" msgstr "" "The proxy settings are overruled by policies. Please contact your " "administrator." msgid "popup_proxyNotControllable_unknown" msgstr "" "The proxy settings cannot be controlled. Please check your system and " "browser settings." msgid "popup_proxyNotControllable_disabled" msgstr "" "The proxy settings are disabled by explicit request from other app(s) or " "extension(s)." msgid "popup_proxyNotControllable_upgrade" msgstr "Proxy settings are now controlled by a newer version of SwitchyOmega." msgid "popup_proxyNotControllableDetails" msgstr "" "You cannot switch profiles with SwitchyOmega unless you fix the problem " "above." msgid "popup_proxyNotControllableDetails_upgrade" msgstr "" "You can't enable two (or more) versions of SwitchyOmega at the same time. " "Please disable one of them." msgid "popup_proxyNotControllableManage" msgstr "Manage extensions" msgid "popup_addConditionTo" msgstr "Add condition to" msgid "popup_addCondition" msgstr "Add condition" msgid "popup_showOptions" msgstr "Options" msgid "popup_reportIssues" msgstr "Report issues" msgid "popup_errorLog" msgstr "Save error log" msgid "popup_requestErrorCount" msgstr "$COUNT$ failed resources" msgid "popup_requestErrorHeading" msgstr "Resources that failed to load" msgid "popup_requestErrorWarning" msgstr "" "A few resources failed to load due to issues with your network, proxy server " "or the webpage." msgid "popup_requestErrorWarningHelp" msgstr "" "SwitchyOmega is just the reporter of these issues, not the cause of them." msgid "popup_requestErrorAddCondition" msgstr "" "You can review the following domains and use proxy for them when appropriate." msgid "popup_requestErrorCannotAddCondition" msgstr "" "You can add switch conditions for them only when using a Switch Profile." msgid "popup_configureMonitorWebRequests" msgstr "Configure Network Monitor" msgid "options_resultProfileForSelectedDomains" msgstr "Use this profile for all selected domains" msgid "options_pac_profile_unsupported_moz" msgstr "PAC Profiles WILL NOT work in Mozilla Firefox due to technical limitations!" msgid "popup_issueTemplate" msgstr "" "\n" "\n" "\n" "\n" "SwitchyOmega $projectVersion$\n" "$userAgent$" msgid "browserAction_profileDetails_PacProfile" msgstr "(PAC script)" msgid "browserAction_profileDetails_SystemProfile" msgstr "(controlled by other extensions or environment)" msgid "browserAction_profileDetails_DirectProfile" msgstr "(not using any proxy)" msgid "browserAction_profileDetails_SwitchProfile" msgstr "(switching based on conditions)" msgid "browserAction_profileDetails_RuleListProfile" msgstr "(switching based on rule list)" msgid "browserAction_titleNormal" msgstr "SwitchyOmega:: $PROFILE$" msgid "browserAction_titleWithResult" msgstr "" "SwitchyOmega:: $1:PROFILE$\n" "$3:DETAILS$" msgid "browserAction_titleNewerOptions" msgstr "" "ERROR: A newer version of SwitchOmega is required to load the stored options." msgid "browserAction_titleOptionError" msgstr "ERROR: The stored options are corrupted. Click here to RESET OPTIONS." msgid "browserAction_titleDownloadFail" msgstr "Warning: Failed to download PAC scripts and/or rule lists." msgid "browserAction_titleExternalProxy" msgstr "Note: The proxy settings are currently controlled by other app(s)." msgid "browserAction_titleInspect" msgstr "[Inspect] $URL$" msgid "browserAction_defaultRuleDetails" msgstr "(default)" msgid "browserAction_directResult" msgstr "DIRECT" msgid "browserAction_attachedPrefix" msgstr "(RL) " msgid "browserAction_tempRulePrefix" msgstr "(TEMP) " msgid "contextMenu_inspectPage" msgstr "Inspect proxy used for this page" msgid "contextMenu_inspectFrame" msgstr "Inspect proxy used for this Frame" msgid "contextMenu_inspectLink" msgstr "Inspect proxy to be used if this Link is opened" msgid "contextMenu_inspectElement" msgstr "Inspect proxy used for this Element" msgid "contextMenu_enableQuickSwitch" msgstr "Enable Quick Switch" msgid "about_title" msgstr "About" msgid "about_app_description" msgstr "A proxy configuration tool" msgid "about_version" msgstr "Version $VERSION$" msgid "about_experimental_warning_moz" msgstr "Mozilla Firefox support is highly experimental! If you encounter issues, please report using the buttons below." msgid "about_disclaimer_networkService" msgstr "SwitchyOmega does not provide proxies, VPNs, or other network services." msgid "about_disclaimer_privacy" msgstr "SwitchyOmega does not track you or insert ads into webpages. Please see" " our privacy policy." msgid "about_help" msgstr "Other questions? Need help with using SwitchyOmega? Please see our " "FAQ." msgid "about_copyright" msgstr "Copyright 2012-2017 The SwitchyOmega Authors. All rights reserved." msgid "about_credits" msgstr "SwitchyOmega is made possible by the SwitchyOmega open source project and other open source software." msgid "about_license" msgstr "SwitchyOmega is free software licensed under GNU General Public License Version 3 or later." ================================================ FILE: omega-locales/cs/LC_MESSAGES/omega-web.po ================================================ msgid "" msgstr "" "Project-Id-Version: SwitchyOmega 2.3.3\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2015-02-13 10:29+0000\n" "PO-Revision-Date: 2020-08-19 11:32+0000\n" "Last-Translator: WXC \n" "Language-Team: Czech \n" "Language: cs\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n" "X-Generator: Weblate 4.2-dev\n" msgid "appNameShort" msgstr "SwitchyOmega" msgid "manifest_app_name" msgstr "Proxy přepínač SwitchyOmega" msgid "manifest_app_description" msgstr "Správa a přepínání mezi více proxy servery ." msgid "manifest_icon_default_title" msgstr "Načítám…" msgid "upgrade_profile_auto" msgstr "Automatický přepínač" msgid "profile_direct" msgstr "[Přímé připojení]" msgid "profile_system" msgstr "[Systémová Proxy]" msgid "condition_HostWildcardCondition" msgstr "Host wildcard" msgid "condition_help_HostWildcardCondition" msgstr "" "Zápasy hostitelé (názvy domén) od zástupný znak.
Hvězdičky " "* odpovídá žádnému nebo více znakům.
Otazník " "? odpovídá právě jeden znak.

Poznámka, že pravidla s " "*. jsou speciálně ošetřeny pouze v podmínkách hostitele " "zástupné.
Příklad: *. priklad.cz bude odpovídat " "www.example.com a example.com stejně.
Subdomény pouze " "zápas, použijte dvě hvězdičky jako **. example.com." msgid "condition_HostRegexCondition" msgstr "Regulární výraz host" msgid "condition_help_HostRegexCondition" msgstr "" "Jako hostitele zástupné stav, ale zápasy hostí (názvy domén) regulární " "výraz.
Regulární výrazy mohou být těžké sestavit (a číst).
Se " "doporučuje použít zástupné znaky pro většinu případů a pouze používat regex " "pro podmínky, které nelze dosáhnout jiným typ podmínky." msgid "condition_HostLevelsCondition" msgstr "Host úrovně" msgid "condition_help_HostLevelsCondition" msgstr "" "Odpovídá žádosti pokud úroveň hostitele v v daném rozsahu.Úroveň hostitele " "
je definována jako počet segmentů oddělených tečkou hostitele (" "název domény).
Příklad: www.example.com je na úrovni " "hostitele 3, zatímco vnitřní hostitele úrovně 1." msgid "condition_IpCondition" msgstr "IP Literals" msgid "condition_help_IpCondition" msgstr "" "Matches the request if and only if the host is a literal IP address and" " in the subnet as specified by " "CIDR notation.
For example, given the rule 127.0.0.1/16, " "it matches all IP addresses like 127.0.*.*.
" "So 127.0.0.1 matches while 127.1.0.0 does not. " "Host names like localhost will never match because they are " "not IP literals." msgid "condition_UrlWildcardCondition" msgstr "URL wildcard" msgid "condition_help_UrlWildcardCondition" msgstr "" "Odpovídá URL požadavku pomocí zástupných znaků.
Viz hostitele zástupné " "sekce výše pro rychlé zástupných.
Všimněte si, že URL zástupné znaky " "nejsou speciálně ošetřené (bez subdomény magic jako v hostitele " "zástupné).
Tak *://*.example.com/* zápasy " "http://www.example.com/ ale není odpovídat http://example.com/." msgid "condition_UrlRegexCondition" msgstr "URL regulární výraz" msgid "condition_help_UrlRegexCondition" msgstr "" "Adresa URL odpovídá mimořádně mocné regulární " "výraz.
Však může být obtížné sestavit (a číst) regulární výrazy.
" "Se doporučuje použít zástupné znaky pro většinu případů a pouze používat " "regex pro podmínky, které nelze dosáhnout jiným typ podmínky." msgid "condition_KeywordCondition" msgstr "Klíčové slovo" msgid "condition_help_KeywordCondition" msgstr "" "Klíčové slovo stav odpovídá, pokud je adresa URL protokol HTTP a vzorek je " "přesný dílčí řetězec adresy URL.
Se chová jako maska zástupných znaků " "adresy URL http://* vzor *, kde vzorek je vzorek " "klíčové slovo.
Klíčové podmínky jsou užitečné, pokud chcete obejít " "firewall blokuje některá klíčová slova v URL, vyžádáním takových URL " "prostřednictvím serveru proxy." msgid "condition_FalseCondition" msgstr "(Vypnuto)" msgid "condition_details_FalseCondition" msgstr "(Podmínky ignorovány při porovnání)" msgid "condition_help_FalseCondition" msgstr "" "Podmínku můžete zakázat nastavením jeho typ ( zakázáno). Stav " "zakázáno chovat, jako by již neexistuje.
Tuto funkci lze použít k " "zakázání podmínky dočasně.
Zakázáno podmínky stále drží předchozí " "informace (např modely) a lze znovu povolit nastavením podmínky typ zpět do " "předchozího typu." msgid "condition_TimeCondition" msgstr "Aktuální čas" msgid "condition_help_TimeCondition" msgstr "" "Matches if the current local time is in the range defined by " "starting hour and ending hour, both inclusive.
" "Local time, starting hour and ending hour are all calculated in " "24-hour format (from 0 to 23).
" "The calculation happens roughly at the moment when the request is sent." msgid "condition_WeekdayCondition" msgstr "Den v týdnu" msgid "condition_help_WeekdayCondition" msgstr "" "Matches if the current day of week is selected in condition details. " "Day is calculated according to local timezone.
" "The request and its URL don't matter to this condition. " "The result is solely based on the day of the week when the request is sent." msgid "condition_alert_fullUrlLimitation" msgstr "" "Full URL matching is no longer possible for https:// " "URLs as of Chrome 52. " "" "Learn more..." msgid "condition_alert_fullUrlLimitationLink" msgstr "https://github.com/FelisCatus/SwitchyOmega/wiki/Chromium-Full-URL-Limitation" msgid "condition_group_default" msgstr " " msgid "condition_group_host" msgstr "Host" msgid "condition_group_url" msgstr "Url" msgid "condition_group_special" msgstr "Speciální" msgid "ruleListFormat_Switchy" msgstr "Přepínač" msgid "ruleListFormat_AutoProxy" msgstr "Automatická Proxy" msgid "ruleList_usageUrl" msgstr "https://github.com/FelisCatus/SwitchyOmega/wiki/RuleListUsage" msgid "ruleList_error_resultNotEnabled" msgstr "Schází '@s výsledkem' directive!" msgid "ruleList_error_unknownProfile" msgstr "Neznámý profil: $PROFILE$" msgid "ruleList_error_missingResultProfile" msgstr "Schází výsledný profil na řádce $LNO$: $SOURCE$" msgid "ruleList_error_invalidRule" msgstr "Nesprávná podmínka na řádku $LNO$: $SOURCE$" msgid "ruleList_error_noDefaultRule" msgstr "Chybí výchozí pravidlo s catch-all '*' podmínkou!" msgid "dialog_close" msgstr "Zavřít" msgid "dialog_save" msgstr "Uložit změny" msgid "dialog_ok" msgstr "OK" msgid "dialog_cancel" msgstr "Storno" msgid "inputClear_clear" msgstr "Vymazat" msgid "inputClear_restore" msgstr "Obnovit" msgid "options_title" msgstr "SwitchyOmega Nastavení" msgid "options_experimental_badge" msgstr "α" msgid "options_navHeader_setting" msgstr "Nastavení" msgid "options_navHeader_profiles" msgstr "Profily" msgid "options_navHeader_actions" msgstr "Akce" msgid "options_tab_ui" msgstr "Rozhraní" msgid "options_tab_general" msgstr "Obecné" msgid "options_tab_importExport" msgstr "Import/Export" msgid "options_newProfile" msgstr "Nový profil…" msgid "options_apply" msgstr "Použít změny" msgid "options_discard" msgstr "Zahodit změny" msgid "options_reset" msgstr "Obnovit nastavení" msgid "options_group_miscOptions" msgstr "Ostatní nastavení" msgid "options_confirmDeletion" msgstr "Potvrdit smazání podmínky." msgid "options_refreshOnProfileChange" msgstr "Obnovit aktuální záložku při změnu profilu." msgid "options_showInspectMenu" msgstr "Povolit kontrolu proxy pro prvky stránky přes kontextové menu." msgid "options_addConditionsToBottom" msgstr "Put new conditions added using the popup to the bottom of the list." msgid "options_group_keyboardShortcut" msgstr "Klávesové zkratky" msgid "options_menuShortcutHelp" msgstr "Stisknutím zástupce aktivujete místní nabídku. (Výchozí Alt+Shift+O)." msgid "options_menuShortcutMore" msgstr "" "Položky v kontextovém menu jsou také přistupné pomocí klávesnice. Stisknutím " "? (nebo /) v menu se dozvíte více." msgid "options_menuShortcutConfigure" msgstr "Konfigurovat zástupce" msgid "options_group_switchOptions" msgstr "Nastavení přepínání" msgid "options_startupProfile" msgstr "Profil při spuštění" msgid "options_startupProfile_none" msgstr "(Aktuální profil)" msgid "options_showConditionTypesAdvanced" msgstr "Zobrazit pokročilé typy podmínek" msgid "options_showConditionTypesAdvancedHelp" msgstr "" "Odemknout nové typy pokročilých, ale komplikovaných přepínačů. Pro běžnou " "práci stačí základní nastavení, proto se tato možnost nedoporučuje." msgid "options_quickSwitch" msgstr "Rychlé přepínání" msgid "options_cycledProfiles" msgstr "Opakované profily" msgid "options_cycledProfilesHelp" msgstr "" "Pokud kliknete na ikonu (nebo použijte klávesovou zkratku), následující " "profily budou řazeny dle jejich pořadí." msgid "options_cycledProfilesTooFew" msgstr "" "Pro tuto funkci musíte vybrat alespoň 2 profily! Můžete je přetáhnout z níže " "uvedeného pole." msgid "options_notCycledProfiles" msgstr "Ne-opakované profily" msgid "options_group_proxyChanges" msgstr "Změny proxy" msgid "options_revertProxyChanges" msgstr "Reverzní proxy změněné jinou aplikací." msgid "options_group_conflicts" msgstr "Konflikty" msgid "options_conflicts_introduction" msgstr "" "Sometimes, other apps will also try to control the proxy settings, resulting " "in conflicts. Note that ad blockers and other extensions may also use proxy " "settings under the hood. Such conflicts cannot be avoided due to how the " "browser works." msgid "options_conflicts_lowerPriority" msgstr "" "A red badge like this on the SwitchyOmega icon indicates that another app has " "higher priority so SwitchyOmega cannot control the settings. Please try to " "uninstall SwitchyOmega and reinstall, which should raise SwitchyOmega's " "priority. If you still see conflicts after reinstallation, please consider " "removing the other app causing the conflict." msgid "options_conflicts_higherPriority" msgstr "" "If SwitchyOmega has higher priority, you can give the control back to other " "apps or system settings by selecting $SYSTEMPROFILE$ in the popup menu." msgid "options_showExternalProfile" msgstr "Show popup menu item to import proxy settings from other apps." msgid "options_showExternalProfileHelp" msgstr "" "When $SYSTEMPROFILE$ is selected, you can import the effective proxy settings " "from other apps by selecting $EXTERNALPROFILE$ on the popup menu. " "The settings will be imported as a profile using the name you provide. " "Please note that the imported profile is a snapshot and will not reflect " "any changes from the source app thereafter." msgid "options_group_networkRequests" msgstr "Síťové požadavky" msgid "options_monitorWebRequests" msgstr "" "Zobrazit počet neúspěšných webových žádostí o prostředky na aktuální kartě." msgid "options_monitorWebRequestsHelp" msgstr "" "Žlutý odznak se zobrazí na ikoně Pokud některé zdroje selhání načtení,
a " "můžete nastavit profil pro tyto zdroje přes místní nabídku." msgid "options_downloadOptions" msgstr "Nastavení stahování" msgid "options_downloadOptionsHelp" msgstr "Konfigurace četnosti aktualizace online pravidla seznamů a PAC skriptů." msgid "options_downloadInterval" msgstr "Interval stahování" msgid "options_downloadInterval_15" msgstr "15 minut" msgid "options_downloadInterval_60" msgstr "1 Hodina" msgid "options_downloadInterval_180" msgstr "3 Hodiny" msgid "options_downloadInterval_360" msgstr "6 Hodin" msgid "options_downloadInterval_720" msgstr "12 Hodin" msgid "options_downloadInterval_1440" msgstr "Každý den" msgid "options_downloadInterval_never" msgstr "Nikdy" msgid "options_group_importExportProfile" msgstr "Profil" msgid "options_exportPacFile" msgstr "Exportovat jako PAC soubor" msgid "options_exportPacFileHelp" msgstr "" "Exportujte aktuální profil jako soubor PAC, takže můžete použít v jiných " "prohlížečích." msgid "options_exportProfileHelp" msgstr "" "Chcete-li exportovat profil, pomocí panelu Akce shora zprava na stránce " "profil." msgid "options_exportLegacyRuleList" msgstr "" "Exportovat pravidla seznamy pomocí Proxy Switchy!/SwitchyPlus/SwitchySharp " "kompatibilní formát pokud je to možné." msgid "options_exportLegacyRuleListHelp" msgstr "" "Tuto možnost použijte, pouze v případě, že publikujete pravidlo seznamy pro " "uživatele těchto projektů.
Prosím zvažte aktualizovat na SwitchyOmega " "pro zlepšení." msgid "options_group_importExportSettings" msgstr "Nastavení" msgid "options_makeBackup" msgstr "Provést zálohu" msgid "options_makeBackupHelp" msgstr "" "Provést plnou záloho Vašeho nastavení (obsahuje profily a veškeré další " "nastavení)." msgid "options_restoreLocal" msgstr "Obnovit ze souboru" msgid "options_restoreLocalHelp" msgstr "Obnovit Vaše SwitchyOmega nastavení z lokálního souboru." msgid "options_restoreOnline" msgstr "Obnovit z online" msgid "options_restoreOnlinePlaceholder" msgstr "URL souboru nastavení (e.g. 'http://example.com/switchy.bak')" msgid "options_restoreOnlineSubmit" msgstr "Obnovit" msgid "options_group_syncing" msgstr "Synchronizace (Experimentální)" msgid "options_syncEnable" msgstr "Povolit synchronizaci" msgid "options_syncEnableForce" msgstr "Stáhnout ze synchronizace" msgid "options_syncDisable" msgstr "Zrušit synchronizaci" msgid "options_syncReset" msgstr "Odstranit vzdálenou kopii" msgid "options_syncPristineHelp" msgstr "" "Vy můžete nyní automaticky synchronizovat Vaše nastavení, profily napříč " "všemi desktop spuštěnými Chrome prohlížeči." msgid "options_syncSyncAlert" msgstr "Vaše nastavení jsou automaticky synchronizování s dalšími zařízeními." msgid "options_syncSyncHelp" msgstr "" "Vezměte prosím na vědomí, že musíte se přihlásit k Chrome na každém zařízení " "(včetně této) pro synchronizaci skutečně pracovat.
Můžete zkontrolovat " "tuto sekci na jiných zařízeních, aby bylo zajištěno, že to funguje." msgid "options_syncConflictAlert" msgstr "" "Načetli jste kopii svých nastavení/možností na jiném zařízení " "prostřednictvím synchronizace." msgid "options_syncConflictHelp" msgstr "" "Pokud budete chtít můžete stáhnout vzdálenou kopii do zařízení.
To tak " "by však přepsat stávající nastavení a profily v tomto zařízení." msgid "options_syncUnsupportedHelp" msgstr "" "Možnosti synchronizace není podporována na platformě nebo prohlížeče. Pro " "tuto chvíli je podporován pouze prohlížeč Chrome na desktopu." msgid "options_profileSyncDisabled" msgstr "Synchronizace je vypnutá pro tento profil." msgid "options_profileSyncDisabled_quotaPerItem" msgstr "" "Synchronizace je zakázána pro tento profil pro použití příliš mnoho úložného " "prostoru." msgid "options_profileTabPrefix" msgstr "Profil :: " msgid "options_renameProfile" msgstr "Přejmenovat" msgid "options_deleteProfile" msgstr "Smazat" msgid "options_profileExportRuleList" msgstr "Publikovat tento seznam podmínek" msgid "options_profileExportRuleListHelp" msgstr "Exportovat podmínky jako prostý text pro publikování." msgid "options_profileExportPac" msgstr "Exportovat PAC" msgid "options_profileUnsupported" msgstr "Nepodporovaný profil typu $TYPE$!" msgid "options_profileUnsupportedHelp" msgstr "Tato možnost může zlobit s novější verzí tohoto programu." msgid "options_profileEditSource" msgstr "Editovat zdrojový kód" msgid "options_profileEditSourceHelp" msgstr "Zobraz nápovědu o formátování zdrojového kódu" msgid "options_profileEditSourceHelpUrl" msgstr "" "https://github.com/FelisCatus/SwitchyOmega/wiki/SwitchyOmega-conditions-" "format#result-profile" msgid "options_group_proxyServers" msgstr "Proxy servery" msgid "options_proxy_scheme" msgstr "Schéma" msgid "options_proxy_protocol" msgstr "Protokol" msgid "options_proxy_server" msgstr "Server" msgid "options_proxy_port" msgstr "Port" msgid "options_proxy_auth" msgstr "Ověřování" msgid "options_proxy_authNotSupported" msgstr "Your browser DOES NOT support $PROTOCOLDISP$ proxy authentication! " "Please do not report this issue to SwitchyOmega. Contact the support for " "your browser instead." msgid "options_proxy_authAllWarningPac" msgstr "" "Varování: Uživatelské jméno a heslo může být nečekané serverům zaslána " "vrácenou skriptem PAC." msgid "options_proxy_authAllWarningPacUrl" msgstr "" "Ujistěte se prosím, důvěryhodných skriptů poskytované prostřednictvím adresy " "URL nad před vstupem do citlivých pověření." msgid "options_proxy_authAllWarningPacScript" msgstr "" "Přesvědčte se, zda důvěřovat skript níže než poskytnutí citlivých pověření." msgid "options_proxy_authReferencedWarning" msgstr "" "Navíc použití tohoto profilu v jiných profilech (např. profil Switch) může " "způsobit uživatelské jméno a heslo k odeslání k serverům proxy, které jsou " "nakonfigurovány v jiných profilech." msgid "options_scheme_default" msgstr "(výchozí)" msgid "options_protocol_direct" msgstr "PŘÍMÉ" msgid "options_protocol_useDefault" msgstr "(použít výchozí)" msgid "options_proxy_single" msgstr "Používejte proxy výše pro všechny protokoly." msgid "options_proxy_expand" msgstr "Zobraz pokročilé" msgid "options_group_bypassList" msgstr "Seznam vynechaných serverů" msgid "options_bypassListHelp" msgstr "" "Servery, které chcete použít při proxy: (jeden server na každém řádku.)" msgid "options_bypassListHelpLinkText" msgstr "(Wildcards and more available...)" msgid "options_group_pacUrl" msgstr "PAC URL" msgid "options_pacUrlHelp" msgstr "" "PAC skript bude aktualizován z této adresy URL. Pokud je ponechán prázdný, " "následující skript bude použit přímo." msgid "options_pacUrlFile" msgstr "" "PAC profily s souboru: adresy URL lze použít pouze přímo. Jejich nelze " "použít jako výsledek profily, protože místní soubory není přístupná z důvodu " "omezení prohlížeče." msgid "options_pacUrlFileDisabled" msgstr "" "Proto nelze použít místní soubor PAC pro tento profil. Pokud opravdu chcete, " "můžete vytvořit nový profil PAC." msgid "options_group_pacScript" msgstr "PAC Skript" msgid "options_pacScriptLastUpdate" msgstr "PAC skript stažený v $TIME$:" msgid "options_pacScriptObsolete" msgstr "" "PAC skript je zastaralá kvůli změně adresy URL. Stiskněte tlačítko Stáhnout " "výše k aktualizaci." msgid "options_group_virtualProfile" msgstr "Virtuální profil" msgid "options_virtualProfileTarget" msgstr "Cíl" msgid "options_virtualProfileTargetHelp" msgstr "Při použití tohoto profilu, funguje stejně jako profilu vybraný níže." msgid "options_group_virtualProfileReplace" msgstr "Migrovat do virtuálního profilu" msgid "options_virtualProfileReplace" msgstr "Nahradit cílový profil" msgid "options_virtualProfileReplaceHelp" msgstr "" "Můžete migrovat existující možnosti používat tento virtuální profil namísto " "$PROFILE$. Tak bude aktualizovat všechny existující pravidla týkající se " "$PROFILE$ a nasměrovat do tohoto virtuálního profilu tak, aby jejich " "výsledek profil je možné ovládat zde." msgid "options_group_ruleListConfig" msgstr "Konfigurace seznamu pravidel" msgid "options_ruleListFormat" msgstr "Formát seznamu podmínek" msgid "options_group_ruleListResult" msgstr "Seznam pravidel výsledků profilů" msgid "options_ruleListMatchProfile" msgstr "Porovnat profil" msgid "options_ruleListDefaultProfile" msgstr "Výchozí profil" msgid "options_group_ruleListUrl" msgstr "Adresa URL podmínek" msgid "options_ruleListUrlHelp" msgstr "" "Seznam pravidel bude aktualizován z této adresy URL. Pokud je ponechán " "prázdný, bude následující text analyzován." msgid "options_group_ruleListText" msgstr "Text seznamu pravidel" msgid "options_ruleListLastUpdate" msgstr "Seznam pravidel stažen $TIME$:" msgid "options_ruleListObsolete" msgstr "" "Seznam pravidel je zastaralá kvůli změně adresy URL. Stiskněte tlačítko " "Stáhnout výše k aktualizaci." msgid "options_group_switchRules" msgstr "Přepínač pravidel" msgid "options_sort" msgstr "Řadit" msgid "options_conditionType" msgstr "Typ podmínek" msgid "options_showConditionTypeHelp" msgstr "Zobrazit nápovědu" msgid "options_conditionDetails" msgstr "Podrobnosti o podmínce" msgid "options_resultProfile" msgstr "Profil" msgid "options_conditionActions" msgstr "Akce" msgid "options_addCondition" msgstr "Přidat podmínku" msgid "options_cloneRule" msgstr "Klonovat" msgid "options_ruleNote" msgstr "Note" msgid "options_switchAttachedProfileInCondition" msgstr "Pravidlo seznamu pravidel" msgid "options_switchAttachedProfileInConditionDetails" msgstr "(Každá žádost odpovídající pravidlo seznam níže)" msgid "options_switchAttachedProfileInConditionDisabled" msgstr "(Seznam pravidel je ZAKÁZÁN)" msgid "options_switchDefaultProfile" msgstr "Výchozí" msgid "options_hostLevelsBetween" msgstr "≤ host úrovně ≤" msgid "options_hourBetween" msgstr "≤ current hour ≤" msgid "options_weekDayShort_0" msgstr "Su" msgid "options_weekDayShort_1" msgstr "Mo" msgid "options_weekDayShort_2" msgstr "Tu" msgid "options_weekDayShort_3" msgstr "We" msgid "options_weekDayShort_4" msgstr "Th" msgid "options_weekDayShort_5" msgstr "Fr" msgid "options_weekDayShort_6" msgstr "Sa" msgid "options_group_conditionHelp" msgstr "O typech podmínek" msgid "options_group_attachProfile" msgstr "Importovat seznamy online pravidla" msgid "options_attachProfile" msgstr "Přidat seznam pravidel" msgid "options_attachProfileHelp" msgstr "" "Můžete použít on-line sbírku podmínek vydané ostatními a přidáním do seznamu " "pravidel." msgid "options_modalHeader_welcome" msgstr "Vítejte v SwitchyOmega" msgid "options_welcomeNormal" msgstr "Úspěšně jste nainstalovali SwitchyOmega, ultimate proxy přepínač." msgid "options_welcomeNormalGuide" msgstr "" "Prosím, řekněte SwitchyOmega o vaší proxy prostřednictvím stránky možnosti. " "Podívejme se, jak." msgid "options_welcomeUpgrade" msgstr "" "Úspěšně jste inovovali na SwitchyOmega. Buďte v klidu, vaše stávající " "možnosti jsou plně zachovány." msgid "options_welcomeUpgradeGuide" msgstr "Teď pojďme projít stručného průvodce a nové možnosti stránky." msgid "options_guideNext" msgstr "Další" msgid "options_guideDone" msgstr "Hotovo" msgid "options_guideSkip" msgstr "Přeskočit průvodce" msgid "options_modalHeader_applyOptions" msgstr "Použít možnosti" msgid "options_optionsNotSaved" msgstr "Vaše změny nebyly uloženy a budou ztracena, pokud budete pokračovat!" msgid "options_applyOptionsRequired" msgstr "Než budete pokračovat, je třeba použít vaše změny možností." msgid "options_applyOptionsConfirm" msgstr "Přejete si uložit a aplikovat nastavení?" msgid "options_modalHeader_renameProfile" msgstr "Přejmenovat profil" msgid "options_renameProfileName" msgstr "Název nového profilu" msgid "options_profileNameConflict" msgstr "Profil s tímto názvem již existuje." msgid "options_profileNameReserved" msgstr "Profil názvy začínající dvojité podtržítko, jsou vyhrazena." msgid "options_profileNameHidden" msgstr "" "Profily s názvy začínají podtržítkem skrytý v místní nabídce. Však stále " "používají se v místech, jako je přepnutí profilu výsledky." msgid "options_modalHeader_replaceProfile" msgstr "Nahradit profil" msgid "options_replaceProfile" msgstr "Nahradit profil" msgid "options_replaceProfileConfirm" msgstr "Opravdu chcete nahradit $FromProfile$ s $ToProfile$?" msgid "options_replaceProfileHelp" msgstr "" "Budete-li pokračovat, všechna pravidla, směřující na $FromProfile$ bude " "aktualizován tak, místo toho použít $ToProfile$. Další možnosti, například " "při spuštění profilu a rychlé přepínače budou také změněny podle potřeby. " "Však sami dva profil nebude být změněn nebo odstraněn." msgid "options_replaceProfileSuccess" msgstr "Nastavení aktualizováno." msgid "options_modalHeader_deleteProfile" msgstr "Odstranit profil" msgid "options_deleteProfileConfirm" msgstr "Opravdu chcete odstranit tento profil?" msgid "options_modalHeader_cannotDeleteProfile" msgstr "Nelze odstranit profil" msgid "options_profileReferredBy" msgstr "Tento profil nelze odstranit, protože se označuje následující profily:" msgid "options_modifyReferringProfiles" msgstr "" "Je třeba upravit tyto profily a zastavit, odkazující k tomuto profilu " "předtím, než můžete odstranit." msgid "options_profileNameEmpty" msgstr "Název profilu nesmí být prázdný." msgid "popup_title" msgstr "SwitchyOmega Vyskakovací okno" msgid "options_modalHeader_proxyAuth" msgstr "Ověřování proxy serveru" msgid "options_proxyAuthUsername" msgstr "Uživatelské jméno" msgid "options_proxyAuthPassword" msgstr "Heslo" msgid "options_proxyAuthShowPassword" msgstr "Show password" msgid "options_proxyAuthHidePassword" msgstr "Hide password" msgid "options_proxyAuthNone" msgstr "Bez ověřování" msgid "options_modalHeader_deleteRule" msgstr "Odstranit pravidlo" msgid "options_deleteRuleConfirm" msgstr "Opravdu chcete odstranit toto pravidlo?" msgid "options_deleteRule" msgstr "Odstranit" msgid "options_modalHeader_resetRules" msgstr "Obnovit pravidla" msgid "options_resetRulesConfirm" msgstr "" "Jste si jisti, nastavte profil výsledek všech pravidel pro tento profil?" msgid "options_resetRules" msgstr "Obnovit pravidla" msgid "options_resetRules_help" msgstr "Nastavit profil pro všechna pravidla" msgid "options_modalHeader_deleteAttached" msgstr "Odstranit seznam pravidel" msgid "options_deleteAttachedConfirm" msgstr "Opravdu chcete odstranit seznam pravidel z aktuálního profilu?" msgid "options_ruleListLineCount" msgstr "$COUNT$ řádky pravidel" msgid "options_deleteAttached" msgstr "Odstranit seznam pravidel" msgid "options_modalHeader_newProfile" msgstr "Nový profil" msgid "options_newProfileName" msgstr "Název profilu" msgid "options_profileType" msgstr "Vyberte prosím typ profilu:" msgid "options_profileTypeFixedProfile" msgstr "Profil serveru proxy" msgid "options_profileDescFixedProfile" msgstr "Tunelování provozu přes proxy servery." msgid "options_profileTypePacProfile" msgstr "PAC Profil" msgid "options_profileDescPacProfile" msgstr "Volba proxy pomocí skriptu PAC online nebo místní." msgid "options_profileDescMorePacProfile" msgstr "" "Budete potřebovat pouze to máte PAC skript nebo URL k němu. Nesnažte se " "vytvořit jeden, pokud nemáte znalosti o PAC." msgid "options_profileTypeSwitchProfile" msgstr "Přepnout profil" msgid "options_profileDescSwitchProfile" msgstr "" "Použití různých profilů automaticky na různých podmínkách domén nebo vzory.\n" " Můžete také importovat pravidla zveřejněny online pro snadnější přepínání. (" "Nahrazuje automatické přepínání režimu + seznam pravidlo.)" msgid "options_profileTypeRuleListProfile" msgstr "Pravidla seznamu profilu" msgid "options_profileDescRuleListProfile" msgstr "Opětovné použití on-line sbírku podmínek vydané ostatní." msgid "options_profileTypeVirtualProfile" msgstr "Virtuální profil" msgid "options_profileDescVirtualProfile" msgstr "" "Virtuální profil mohou působit jako kterýkoli z ostatních profilů na " "požádání. To funguje dobře s SwitchProfile, což umožňuje změnit výsledek " "více podmínek jedním kliknutím." msgid "options_createProfile" msgstr "Vytvořit" msgid "options_modalHeader_resetOptions" msgstr "Obnovit nastavení" msgid "options_resetOptionsConfirm" msgstr "" "Opravdu chcete obnovit možnosti? Všechny profily a nastavení bude ztraceno!" msgid "options_formInvalid" msgstr "Opravte chyby na této stránce." msgid "options_profileNotFound" msgstr "Profil $PROFILE$ neexistuje! Nastavení může být špatné." msgid "options_resetSuccess" msgstr "Obnovit nastavení." msgid "options_saveSuccess" msgstr "Nastavení uloženo." msgid "options_importSuccess" msgstr "Nastavení importováno." msgid "options_importFormatError" msgstr "Soubor ze zálohy je neplatný!" msgid "options_importDownloadError" msgstr "Chyba při stahování zálohovaného souboru!" msgid "options_profileDownloadSuccess" msgstr "Profil byl úspěšně aktualizován." msgid "options_profileDownloadError" msgstr "Chyba při stahování dat profilu!" msgid "options_profileDownloadError_NetworkError" msgstr "A network error occurred when updating." msgid "options_profileDownloadError_HttpError" msgstr "An HTTP error ($STATUS$) occurred when updating." msgid "options_profileDownloadError_HttpNotFoundError" msgstr "The Profile URL was not found on the server. Please double-check." msgid "options_profileDownloadError_HttpServerError" msgstr "The remote server responded with error ($STATUS$) when updating." msgid "options_profileDownloadError_ContentTypeRejectedError" msgstr "The downloaded data is invalid! " "You may open the Profile URL in your browser to inspect it." msgid "options_downloadProfileNow" msgstr "Stáhnout profil" msgid "options_guide_fixedProfileStep" msgstr "" "Proxy profil obsahuje nastavení jako server ip a port serveru " "proxy.
Profily jsou základní konfiguraci jednotky v SwitchyOmega.
Jsme " "již vytvořili příklad profil pro vás. Pokuste se jej otevřít." msgid "options_guide_fixedServersStep" msgstr "" "Můžete vyplnit serveru proxy a portu zde jak se vám líbí.
, SwitchyOmega, " "nepřichází s proxy servery.
Prosím poraďte se s poskytovatelem " "sítě nebo server proxy software manuál Pokud nevíte, co by mělo být vyplněno " "zde." msgid "options_guide_autoSwitchProfileStep" msgstr "" "Poznáte SwitchyOmega přepínat mezi proxy automaticky prostřednictvím mohutné " "Přepnutí profilu.
Však nelze pokrýt jeho rysy v tomto rychlém " "průvodci.
Můžete otevřít tento profil odemknout její moci nějaký čas " "později." msgid "options_guide_addMoreProfilesStep" msgstr "" "Potřebujete další profily? Pro potřeby vaší proxy, můžete vždy přidat více " "Proxy, Switch a další profily
.
Užijte si proxy!" msgid "options_guide_conditionStep" msgstr "" "SwitchyOmega profily je možné použít různé žádosti na základě " "podmínek.
Například hostitele zástupné stavu umožňuje " "nastavit profil pro všechny adresy URL v doméně." msgid "options_guide_conditionTypeStep" msgstr "" "Můžete použít různé typy podmínek hostitele nebo úplnou adresu URL.
" "Klepněte na otazník zobrazíte typ odkazu." msgid "options_guide_conditionProfileStep" msgstr "" "SwitchyOmega použije vybraný profil zde na žádost odpovídající " "podmínky.
Speciální \"[]\" profilu způsobí požadavek na " "odeslání bez jakékoli proxy." msgid "options_guide_switchDefaultStep" msgstr "" "Pokud žádná podmínka se vztahuje na některé žádosti, bude použit profil \"" "Výchozí\".
Podmínky jsou vždy považovány za shora dolů v " "pořadí.
Jejich pořadí můžete změnit přetažením ikony řazení." msgid "options_guide_applySwitchProfileStep" msgstr "" "Po dokončení nastavení přepínače profilu, nezapomeňte Přepněte do ní v " "kontextovém menu.
Ikona se zobrazí konečný výsledek profilu " "použité pro aktuální kartu
Hovering na ikonu odhalí tooltip s " "detaily." msgid "popup_externalProfile" msgstr "(Externí profil)" msgid "popup_externalProfileName" msgstr "název profilu" msgid "popup_proxyNotControllable_app" msgstr "" "Nastavení serveru proxy jsou řízeny jinými app(s) nebo přípony. Zakázat nebo " "odinstalovat aplikace nebo rozšíření v konfliktu." msgid "popup_proxyNotControllable_policy" msgstr "" "Nastavení serveru proxy byly přepsány politikou. Obraťte se na správce " "systému." msgid "popup_proxyNotControllable_unknown" msgstr "" "Nastavení serveru proxy nelze ovládat. Zkontrolujte nastavení systému a " "prohlížeče." msgid "popup_proxyNotControllable_disabled" msgstr "" "Nastavení serveru proxy jsou zakázány výslovný požadavek od jiných app(s) " "nebo rozšířeními." msgid "popup_proxyNotControllable_upgrade" msgstr "" "Nastavení serveru proxy jsou nyní řízeny pomocí novější verze SwitchyOmega." msgid "popup_proxyNotControllableDetails" msgstr "Dokud nevyřešíte problém výše, nelze přepnout profily s SwitchyOmega." msgid "popup_proxyNotControllableDetails_upgrade" msgstr "" "Současně nelze povolit dvě (nebo více) verze SwitchyOmega. Zakažte jednu z " "nich." msgid "popup_proxyNotControllableManage" msgstr "Správa rozšíření" msgid "popup_addConditionTo" msgstr "Přidat podmínku do" msgid "popup_addCondition" msgstr "Přidat podmínku" msgid "popup_showOptions" msgstr "Možnosti" msgid "popup_reportIssues" msgstr "Report problémů" msgid "popup_errorLog" msgstr "Uložit protokol chyb" msgid "popup_requestErrorCount" msgstr "$COUNT$ chybových požadavků" msgid "popup_requestErrorHeading" msgstr "Zdroje, které se nepodařilo načíst" msgid "popup_requestErrorWarning" msgstr "Několik zdrojů se nepodařilo načíst kvůli potížím se sítí." msgid "popup_requestErrorWarningHelp" msgstr "SwitchyOmega jen reportuje tyto chyby, ale není příčinou těchto chyb." msgid "popup_requestErrorAddCondition" msgstr "" "Můžete zkontrolovat následující domény a použít proxy server pro ně v " "případě potřeby." msgid "popup_requestErrorCannotAddCondition" msgstr "" "Můžete přidat podmínky, přepínač se použije pouze při použití Přepnout " "profil." msgid "popup_configureMonitorWebRequests" msgstr "Konfigurovat monitor sítě" msgid "options_resultProfileForSelectedDomains" msgstr "Použít tento profil pro všechny vybrané domény" msgid "options_pac_profile_unsupported_moz" msgstr "PAC Profiles WILL NOT work in Mozilla Firefox due to technical limitations!" msgid "popup_issueTemplate" msgstr "" "\n" "\n" "\n" "\n" "Přeložil Filip Havlin\n" "SwitchyOmega $projectVersion$\n" "$userAgent$" msgid "browserAction_profileDetails_PacProfile" msgstr "(PAC skript)" msgid "browserAction_profileDetails_SystemProfile" msgstr "(kontrolované jinými rozšířeními nebo prostředím)" msgid "browserAction_profileDetails_DirectProfile" msgstr "(nepoužívá žádné proxy)" msgid "browserAction_profileDetails_SwitchProfile" msgstr "(přepínání na základě podmínek)" msgid "browserAction_profileDetails_RuleListProfile" msgstr "(přepínání na základě seznamu pravidel)" msgid "browserAction_titleNormal" msgstr "Switchy Omega:: $PROFILE$" msgid "browserAction_titleWithResult" msgstr "" "Switchy Omega:: $1:PROFILE$\n" "$3:DETAILS$" msgid "browserAction_titleNewerOptions" msgstr "" "Chyba: Novější verze SwitchOmega je potřeba pro uložené nastavení/možnosti." msgid "browserAction_titleOptionError" msgstr "" "Chyba: Uložené volby jsou poškozeny. Chcete-li obnovit možnosti klikněte zde." msgid "browserAction_titleDownloadFail" msgstr "Upozornění: Nepodařilo se stáhnout PAC skripty nebo seznam pravidel." msgid "browserAction_titleExternalProxy" msgstr "" "Poznámka: Nastavení serveru proxy jsou v současnosti řízena jinými " "aplikacemi." msgid "browserAction_titleInspect" msgstr "[Prohlédnout] $URL$" msgid "browserAction_defaultRuleDetails" msgstr "(výchozí)" msgid "browserAction_directResult" msgstr "PŘÍMÉ" msgid "browserAction_attachedPrefix" msgstr "(RL) " msgid "browserAction_tempRulePrefix" msgstr "(DOČASNÉ) " msgid "contextMenu_inspectPage" msgstr "Zkontrolujte proxy pro tuto stránku" msgid "contextMenu_inspectFrame" msgstr "Zkontrolujte proxy pro tento Frame" msgid "contextMenu_inspectLink" msgstr "Zkontrolujte, zda server proxy používaná tento prvek" msgid "contextMenu_inspectElement" msgstr "Zkontrolujte, zda server proxy používaná tento prvek" msgid "contextMenu_enableQuickSwitch" msgstr "Povolit rychlé přepínání" msgid "about_title" msgstr "About" msgid "about_app_description" msgstr "A proxy configuration tool" msgid "about_version" msgstr "Version $VERSION$" msgid "about_experimental_warning_moz" msgstr "Mozilla Firefox support is highly experimental! If you encounter issues, please report using the buttons below." msgid "about_disclaimer_networkService" msgstr "SwitchyOmega does not provide proxies, VPNs, or other network services." msgid "about_disclaimer_privacy" msgstr "SwitchyOmega does not track you or insert ads into webpages. Please see" " our privacy policy." msgid "about_help" msgstr "Other questions? Need help with using SwitchyOmega? Please see our " "FAQ." msgid "about_copyright" msgstr "Copyright 2012-2017 The SwitchyOmega Authors. All rights reserved." msgid "about_credits" msgstr "SwitchyOmega is made possible by the SwitchyOmega open source project and other open source software." msgid "about_license" msgstr "SwitchyOmega is free software licensed under GNU General Public License Version 3 or later." ================================================ FILE: omega-locales/de/LC_MESSAGES/omega-web.po ================================================ msgid "" msgstr "" "Project-Id-Version: SwitchyOmega 2.3.3\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2015-02-13 10:29+0000\n" "PO-Revision-Date: 2019-05-14 08:49+0000\n" "Last-Translator: ssantos \n" "Language-Team: German \n" "Language: de\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Generator: Weblate 3.7-dev\n" msgid "appNameShort" msgstr "SwitchyOmega" msgid "manifest_app_name" msgstr "Proxy SwitchyOmega" msgid "manifest_app_description" msgstr "" "Einfach & schnell mehrere Proxies verwalten und zwischen ihnen wechseln." msgid "manifest_icon_default_title" msgstr "Laden…" msgid "upgrade_profile_auto" msgstr "Automatisches Wechseln" msgid "profile_direct" msgstr "[Direkt]" msgid "profile_system" msgstr "[System Proxy]" msgid "condition_HostWildcardCondition" msgstr "Host wildcard" msgid "condition_help_HostWildcardCondition" msgstr "" "Übereinstimmungen mit Hosts (Domänennamen) per Wildcard.
Das Sternchen " "* entspricht null oder mehr Zeichen.
Das Fragezeichen " "? entspricht genau einem Zeichen.

Beachten Sie, dass " "Regeln, die mit *. beginnen, speziell nur in Hosts mit Wildcard " "behandelt werden.
Beispiel: *.example.com passt auch zu " "www.example.com UND auch example.com.
Zur Übereinstimmung " "nur von Subdomains, verwenden Sie zwei Sternchen wie " "**.example.com." msgid "condition_HostRegexCondition" msgstr "Host regex" msgid "condition_help_HostRegexCondition" msgstr "" "Wie die Host Platzhalter Bedingung, aber gleicht hosts (domain namen) bei Regulärer " "Ausdruck.
Regulärer Ausdruck können schwer zu erstellen und/oder zu " "lesen sein.
Es wird im Normalfall Platzhalter zu verwenden und Regulärer " "Ausdrücke nur für Bedingungen Typen die nicht mit anderen Bedingungen Typen " "möglich sind zu benutzen." msgid "condition_HostLevelsCondition" msgstr "Host levels" msgid "condition_help_HostLevelsCondition" msgstr "" "Matches the request if and only if the host level in within the given range." "
Host level is defined as the number of dot-separated segments of " "the host (domain name).
Example: www.example.com is with a " "host level of 3, while internal is of host level 1." msgid "condition_IpCondition" msgstr "IP Literals" msgid "condition_help_IpCondition" msgstr "" "Matches the request if and only if the host is a literal IP address and" " in the subnet as specified by " "CIDR notation.
For example, given the rule 127.0.0.1/16, " "it matches all IP addresses like 127.0.*.*.
" "So 127.0.0.1 matches while 127.1.0.0 does not. " "Host names like localhost will never match because they are " "not IP literals." msgid "condition_UrlWildcardCondition" msgstr "URL wildcard" msgid "condition_help_UrlWildcardCondition" msgstr "" "Matches URLs of the request by wildcard.
See the Host wildcard section " "above for a quick wildcard reference.
Note that URL wildcards are not " "specially treated (no subdomain magic as in Host wildcard).
So *://" "*.example.com/* matches http://www.example.com/ but does not " "match http://example.com/." msgid "condition_UrlRegexCondition" msgstr "URL regex" msgid "condition_help_UrlRegexCondition" msgstr "" "Matches URL by extremely powerful regular expression.
However, regular " "expressions can be hard to construct (and read).
It is recommended to use " "wildcards for most cases and only use regex for conditions that cannot be " "achieved by any other condition type." msgid "condition_KeywordCondition" msgstr "Schlüsselwort" msgid "condition_help_KeywordCondition" msgstr "" "A keyword condition matches if the URL protocol is HTTP, and the pattern is " "an exact sub-string of the URL.
It behaves like the URL wildcard pattern " "http://*pattern*, where pattern is the keyword " "pattern.
Keyword conditions are useful if you want to bypass a firewall " "blocking some keywords in the URL, by requesting such URLs through a proxy." msgid "condition_FalseCondition" msgstr "(Ausgeschaltet)" msgid "condition_details_FalseCondition" msgstr "(Bedingung wird ignoriert wenn zutreffend)" msgid "condition_help_FalseCondition" msgstr "" "You can disable a condition by setting its type to (Disabled). " "A Disabled condition act as if it does not exist.
This feature can be " "used to disable conditions temporarily.
Disabled conditions still hold " "the previous information (like patterns) and can be re-enabled by setting " "the condition type back to the previous type." msgid "condition_TimeCondition" msgstr "Current Time" msgid "condition_help_TimeCondition" msgstr "" "Matches if the current local time is in the range defined by " "starting hour and ending hour, both inclusive.
" "Local time, starting hour and ending hour are all calculated in " "24-hour format (from 0 to 23).
" "The calculation happens roughly at the moment when the request is sent." msgid "condition_WeekdayCondition" msgstr "Day of the Week" msgid "condition_help_WeekdayCondition" msgstr "" "Matches if the current day of week is selected in condition details. " "Day is calculated according to local timezone.
" "The request and its URL don't matter to this condition. " "The result is solely based on the day of the week when the request is sent." msgid "condition_alert_fullUrlLimitation" msgstr "" "Full URL matching is no longer possible for https:// " "URLs as of Chrome 52. " "" "Learn more..." msgid "condition_alert_fullUrlLimitationLink" msgstr "https://github.com/FelisCatus/SwitchyOmega/wiki/Chromium-Full-URL-Limitation" msgid "condition_group_default" msgstr " " msgid "condition_group_host" msgstr "Host" msgid "condition_group_url" msgstr "Url" msgid "condition_group_special" msgstr "Spezial" msgid "ruleListFormat_Switchy" msgstr "Switchy" msgid "ruleListFormat_AutoProxy" msgstr "AutoProxy" msgid "ruleList_usageUrl" msgstr "https://github.com/FelisCatus/SwitchyOmega/wiki/RuleListUsage" msgid "ruleList_error_resultNotEnabled" msgstr "Missing '@with result' directive!" msgid "ruleList_error_unknownProfile" msgstr "Unbekanntes Profil: $PROFILE$" msgid "ruleList_error_missingResultProfile" msgstr "Benötigt Ergebnis Profil Name in Line $LNO$: $SOURCE$" msgid "ruleList_error_invalidRule" msgstr "Invalid rule at Line $LNO$: $SOURCE$" msgid "ruleList_error_noDefaultRule" msgstr "Missing default rule with catch-all '*' condition!" msgid "dialog_close" msgstr "Close" msgid "dialog_save" msgstr "Save changes" msgid "dialog_ok" msgstr "OK" msgid "dialog_cancel" msgstr "Cancel" msgid "inputClear_clear" msgstr "Clear" msgid "inputClear_restore" msgstr "Restore" msgid "options_title" msgstr "SwitchyOmega Options" msgid "options_experimental_badge" msgstr "α" msgid "options_navHeader_setting" msgstr "Settings" msgid "options_navHeader_profiles" msgstr "Profiles" msgid "options_navHeader_actions" msgstr "Actions" msgid "options_tab_ui" msgstr "Interface" msgid "options_tab_general" msgstr "General" msgid "options_tab_importExport" msgstr "Import/Export" msgid "options_newProfile" msgstr "New profile…" msgid "options_apply" msgstr "Apply changes" msgid "options_discard" msgstr "Discard changes" msgid "options_reset" msgstr "Reset options" msgid "options_group_miscOptions" msgstr "Misc Options" msgid "options_confirmDeletion" msgstr "Confirm on condition deletion." msgid "options_refreshOnProfileChange" msgstr "Refresh current tab on profile change." msgid "options_showInspectMenu" msgstr "Allow inspecting proxy used for page elements via context menu." msgid "options_addConditionsToBottom" msgstr "Put new conditions added using the popup to the bottom of the list." msgid "options_group_keyboardShortcut" msgstr "Keyboard Shortcut" msgid "options_menuShortcutHelp" msgstr "" "Pressing the shortcut will open the switch popup menu. (Defaults to Alt+Shift" "+O)." msgid "options_menuShortcutMore" msgstr "" "The items in the popup menu can also be accessed using the keyboard. Press ? " "(or /) in the menu to learn more." msgid "options_menuShortcutConfigure" msgstr "Configure shortcut" msgid "options_group_switchOptions" msgstr "Switch Options" msgid "options_startupProfile" msgstr "Startup Profile" msgid "options_startupProfile_none" msgstr "(Current profile)" msgid "options_showConditionTypesAdvanced" msgstr "Show advanced condition types" msgid "options_showConditionTypesAdvancedHelp" msgstr "" "Erschließt neue Arten von fortgeschrittenen, aber komplizierten " "Schalterbedingungen. Für die meisten Szenarien sollten die " "Grundbedingungsarten ausreichen, so dass diese Option nicht empfohlen wird." msgid "options_quickSwitch" msgstr "Quick Switch" msgid "options_cycledProfiles" msgstr "Cycled Profiles" msgid "options_cycledProfilesHelp" msgstr "" "When you click on the icon (or use the shortcut above), the following " "profiles will be applied in their order." msgid "options_cycledProfilesTooFew" msgstr "" "You need to select at least 2 profiles to enable this function! You can drag " "them from the box below." msgid "options_notCycledProfiles" msgstr "Not Cycled Profiles" msgid "options_group_proxyChanges" msgstr "Proxy Changes" msgid "options_revertProxyChanges" msgstr "Revert proxy changes done by other apps." msgid "options_group_conflicts" msgstr "Conflicts" msgid "options_conflicts_introduction" msgstr "" "Sometimes, other apps will also try to control the proxy settings, resulting " "in conflicts. Note that ad blockers and other extensions may also use proxy " "settings under the hood. Such conflicts cannot be avoided due to how the " "browser works." msgid "options_conflicts_lowerPriority" msgstr "" "A red badge like this on the SwitchyOmega icon indicates that another app has " "higher priority so SwitchyOmega cannot control the settings. Please try to " "uninstall SwitchyOmega and reinstall, which should raise SwitchyOmega's " "priority. If you still see conflicts after reinstallation, please consider " "removing the other app causing the conflict." msgid "options_conflicts_higherPriority" msgstr "" "If SwitchyOmega has higher priority, you can give the control back to other " "apps or system settings by selecting $SYSTEMPROFILE$ in the popup menu." msgid "options_showExternalProfile" msgstr "Show popup menu item to import proxy settings from other apps." msgid "options_showExternalProfileHelp" msgstr "" "When $SYSTEMPROFILE$ is selected, you can import the effective proxy settings " "from other apps by selecting $EXTERNALPROFILE$ on the popup menu. " "The settings will be imported as a profile using the name you provide. " "Please note that the imported profile is a snapshot and will not reflect " "any changes from the source app thereafter." msgid "options_group_networkRequests" msgstr "Network Requests" msgid "options_monitorWebRequests" msgstr "Show count of failed web requests for resources in the current tab." msgid "options_monitorWebRequestsHelp" msgstr "" "A yellow badge will be displayed on the icon if some resources fail to load," "
and you can set the profile for such resources conveniently via the " "popup menu." msgid "options_downloadOptions" msgstr "Download Options" msgid "options_downloadOptionsHelp" msgstr "Configure the update frequency of online rule lists and PAC scripts." msgid "options_downloadInterval" msgstr "Download Interval" msgid "options_downloadInterval_15" msgstr "15 Minutes" msgid "options_downloadInterval_60" msgstr "1 Hour" msgid "options_downloadInterval_180" msgstr "3 Hours" msgid "options_downloadInterval_360" msgstr "6 Hours" msgid "options_downloadInterval_720" msgstr "12 Hours" msgid "options_downloadInterval_1440" msgstr "Every day" msgid "options_downloadInterval_never" msgstr "Never" msgid "options_group_importExportProfile" msgstr "Profile" msgid "options_exportPacFile" msgstr "Export as PAC File" msgid "options_exportPacFileHelp" msgstr "" "Export the current profile as a PAC file, so you can use it in other " "browsers." msgid "options_exportProfileHelp" msgstr "To export a profile, use the top-right action bar on the profile page." msgid "options_exportLegacyRuleList" msgstr "" "Export rule lists using Proxy Switchy!/SwitchyPlus/SwitchySharp compatible " "format when possible." msgid "options_exportLegacyRuleListHelp" msgstr "" "Enable this option only if you publish rule lists for users of those " "projects.
Please consider advising your audience to upgrade to " "SwitchyOmega for the improvements." msgid "options_group_importExportSettings" msgstr "Settings" msgid "options_makeBackup" msgstr "Make backup" msgid "options_makeBackupHelp" msgstr "" "Make a full backup of your options (including profiles and all other " "options)." msgid "options_restoreLocal" msgstr "Restore from file" msgid "options_restoreLocalHelp" msgstr "Restore your SwitchyOmega options from a local file." msgid "options_restoreOnline" msgstr "Restore from online" msgid "options_restoreOnlinePlaceholder" msgstr "Options file URL (e.g. 'http://example.com/switchy.bak')" msgid "options_restoreOnlineSubmit" msgstr "Restore" msgid "options_group_syncing" msgstr "Syncing (Experimental)" msgid "options_syncEnable" msgstr "Enable Syncing" msgid "options_syncEnableForce" msgstr "Download from Syncing" msgid "options_syncDisable" msgstr "Disable syncing" msgid "options_syncReset" msgstr "Clear remote copy" msgid "options_syncPristineHelp" msgstr "" "You can now automatically synchronize your settings and profiles across all " "your desktop devices running Chrome browser." msgid "options_syncSyncAlert" msgstr "Your options are automatically synchronized with your other devices." msgid "options_syncSyncHelp" msgstr "" "Please note that you must sign in to Chrome on each of your devices " "(including this one) for the syncing to actually work.
You may check " "this section on other devices to ensure that it is working." msgid "options_syncConflictAlert" msgstr "" "You have uploaded a copy of your options on another device via syncing." msgid "options_syncConflictHelp" msgstr "" "You may download the remote copy to your device if you like.
However, " "doing so would overwrite your existing settings and profiles on this " "device." msgid "options_syncUnsupportedHelp" msgstr "" "Options syncing is not supported on your platform or browser. For now, only " "Chrome browser on desktop is supported." msgid "options_profileSyncDisabled" msgstr "Syncing is disabled for this profile." msgid "options_profileSyncDisabled_quotaPerItem" msgstr "Syncing is disabled for this profile for using too much storage space." msgid "options_profileTabPrefix" msgstr "Profile :: " msgid "options_renameProfile" msgstr "Rename" msgid "options_deleteProfile" msgstr "Delete" msgid "options_profileExportRuleList" msgstr "Publish rule list" msgid "options_profileExportRuleListHelp" msgstr "Export Switch Rules as text format for publishing." msgid "options_profileExportPac" msgstr "Export PAC" msgid "options_profileUnsupported" msgstr "Unsupported profile type $TYPE$!" msgid "options_profileUnsupportedHelp" msgstr "The options could be broken, or from a newer version of this program." msgid "options_profileEditSource" msgstr "Edit source code" msgid "options_profileEditSourceHelp" msgstr "Show help about the source code format" msgid "options_profileEditSourceHelpUrl" msgstr "" "https://github.com/FelisCatus/SwitchyOmega/wiki/SwitchyOmega-conditions-" "format#result-profile" msgid "options_group_proxyServers" msgstr "Proxy servers" msgid "options_proxy_scheme" msgstr "Scheme" msgid "options_proxy_protocol" msgstr "Protocol" msgid "options_proxy_server" msgstr "Server" msgid "options_proxy_port" msgstr "Port" msgid "options_proxy_auth" msgstr "Authentication" msgid "options_proxy_authNotSupported" msgstr "Your browser DOES NOT support $PROTOCOLDISP$ proxy authentication! " "Please do not report this issue to SwitchyOmega. Contact the support for " "your browser instead." msgid "options_proxy_authAllWarningPac" msgstr "" "Warning: The username/password may be sent to unexpected servers returned by " "the PAC script." msgid "options_proxy_authAllWarningPacUrl" msgstr "" "Please make sure that you trust the script provided via the URL above before " "entering sensitive credentials." msgid "options_proxy_authAllWarningPacScript" msgstr "" "Please make sure that you trust the script below before providing sensitive " "credentials." msgid "options_proxy_authReferencedWarning" msgstr "" "Additionally, using this profile in other profiles (e.g. Switch Profile) may " "cause the username/password to be sent to proxy servers configured in other " "profiles." msgid "options_scheme_default" msgstr "(default)" msgid "options_protocol_direct" msgstr "DIRECT" msgid "options_protocol_useDefault" msgstr "(use default)" msgid "options_proxy_single" msgstr "Use the proxy above for all protocols." msgid "options_proxy_expand" msgstr "Show Advanced" msgid "options_group_bypassList" msgstr "Bypass List" msgid "options_bypassListHelp" msgstr "" "Servers for which you do not want to use any proxy: (One server on each " "line.)" msgid "options_bypassListHelpLinkText" msgstr "(Wildcards and more available…)" msgid "options_group_pacUrl" msgstr "PAC URL" msgid "options_pacUrlHelp" msgstr "" "The PAC script will be updated from this URL. If it is left blank, the " "following script will be used directly instead." msgid "options_pacUrlFile" msgstr "" "PAC profiles with file: URLs can only be applied directly. They cannot be " "used as result profiles because local files cannot be accessed due to " "browser limitation." msgid "options_pacUrlFileDisabled" msgstr "" "Therefore, you cannot use local PAC file for this profile. You can create a " "new PAC profile for that if you really want that." msgid "options_group_pacScript" msgstr "PAC Script" msgid "options_pacScriptLastUpdate" msgstr "PAC script downloaded at $TIME$:" msgid "options_pacScriptObsolete" msgstr "" "PAC script is obsolete due to URL change. Press the download button above to " "update." msgid "options_group_virtualProfile" msgstr "Virtual Profile" msgid "options_virtualProfileTarget" msgstr "Target" msgid "options_virtualProfileTargetHelp" msgstr "" "When this profile is applied, it acts exactly the same as the profile " "selected below." msgid "options_group_virtualProfileReplace" msgstr "Migrate to Virtual Profile" msgid "options_virtualProfileReplace" msgstr "Replace target profile" msgid "options_virtualProfileReplaceHelp" msgstr "" "You can migrate existing options to use this virtual profile instead of " "$PROFILE$. Doing so will update all existing rules concerning $PROFILE$ and " "point them to this virtual profile, so that their result profile can be " "controlled here." msgid "options_group_ruleListConfig" msgstr "Rule List Config" msgid "options_ruleListFormat" msgstr "Rule List Format" msgid "options_group_ruleListResult" msgstr "Rule list result profiles" msgid "options_ruleListMatchProfile" msgstr "Match profile" msgid "options_ruleListDefaultProfile" msgstr "Default profile" msgid "options_group_ruleListUrl" msgstr "Rule List URL" msgid "options_ruleListUrlHelp" msgstr "" "The rule list will be updated from this URL. If it is left blank, the " "following text will be parsed instead." msgid "options_group_ruleListText" msgstr "Rule List Text" msgid "options_ruleListLastUpdate" msgstr "Rule list downloaded at $TIME$:" msgid "options_ruleListObsolete" msgstr "" "Rule list is obsolete due to URL change. Press the download button above to " "update." msgid "options_group_switchRules" msgstr "Switch rules" msgid "options_sort" msgstr "Sort" msgid "options_conditionType" msgstr "Condition Type" msgid "options_showConditionTypeHelp" msgstr "Show help" msgid "options_conditionDetails" msgstr "Condition Details" msgid "options_resultProfile" msgstr "Profile" msgid "options_conditionActions" msgstr "Actions" msgid "options_addCondition" msgstr "Add condition" msgid "options_cloneRule" msgstr "Clone" msgid "options_ruleNote" msgstr "Note" msgid "options_switchAttachedProfileInCondition" msgstr "Rule list rules" msgid "options_switchAttachedProfileInConditionDetails" msgstr "(Any request matching the rule list below)" msgid "options_switchAttachedProfileInConditionDisabled" msgstr "(Rule list rules are DISABLED)" msgid "options_switchDefaultProfile" msgstr "Default" msgid "options_hostLevelsBetween" msgstr "≤ host levels ≤" msgid "options_hourBetween" msgstr "≤ current hour ≤" msgid "options_weekDayShort_0" msgstr "Su" msgid "options_weekDayShort_1" msgstr "Mo" msgid "options_weekDayShort_2" msgstr "Tu" msgid "options_weekDayShort_3" msgstr "We" msgid "options_weekDayShort_4" msgstr "Th" msgid "options_weekDayShort_5" msgstr "Fr" msgid "options_weekDayShort_6" msgstr "Sa" msgid "options_group_conditionHelp" msgstr "About Condition Types" msgid "options_group_attachProfile" msgstr "Import online rule lists" msgid "options_attachProfile" msgstr "Add a rule list" msgid "options_attachProfileHelp" msgstr "" "You can reuse an online collection of conditions published by others by " "adding a rule list." msgid "options_modalHeader_welcome" msgstr "Welcome to SwitchyOmega" msgid "options_welcomeNormal" msgstr "" "You have successfully installed SwitchyOmega, the ultimate proxy switcher." msgid "options_welcomeNormalGuide" msgstr "" "Please tell SwitchyOmega about your proxies through the options page. Let's " "see how." msgid "options_welcomeUpgrade" msgstr "" "You have successfully upgraded to SwitchyOmega. Don't panic, your existing " "options are fully preserved." msgid "options_welcomeUpgradeGuide" msgstr "Now let's go through a quick guide of the new options page." msgid "options_guideNext" msgstr "Next" msgid "options_guideDone" msgstr "Done" msgid "options_guideSkip" msgstr "Skip guide" msgid "options_modalHeader_applyOptions" msgstr "Apply Options" msgid "options_optionsNotSaved" msgstr "" "Your modifications to the options have not been saved and will be lost if " "you proceed!" msgid "options_applyOptionsRequired" msgstr "Your changes to the options must be applied before you proceed." msgid "options_applyOptionsConfirm" msgstr "Do you want to save and apply the options?" msgid "options_modalHeader_renameProfile" msgstr "Rename Profile" msgid "options_renameProfileName" msgstr "New profile name" msgid "options_profileNameConflict" msgstr "A profile with this name already exists." msgid "options_profileNameReserved" msgstr "Profile names beginning with double-underscore are reserved." msgid "options_profileNameHidden" msgstr "" "Profiles with names starting with underscore will be hidden on the popup " "menu. However, they can still be used in places like switch profile results." msgid "options_modalHeader_replaceProfile" msgstr "Replace Profile" msgid "options_replaceProfile" msgstr "Replace Profile" msgid "options_replaceProfileConfirm" msgstr "Do you really want to replace $FromProfile$ with $ToProfile$?" msgid "options_replaceProfileHelp" msgstr "" "If you proceed, all rules pointing to $FromProfile$ will be updated to use " "$ToProfile$ instead. Other options, such as startup profile and Quick Switch " "will also be modified as appropriate. However, the two profile themselves " "will NOT be changed or deleted." msgid "options_replaceProfileSuccess" msgstr "Options updated." msgid "options_modalHeader_deleteProfile" msgstr "Delete Profile" msgid "options_deleteProfileConfirm" msgstr "Do you really want to delete the following profile?" msgid "options_modalHeader_cannotDeleteProfile" msgstr "Unable to Delete Profile" msgid "options_profileReferredBy" msgstr "" "This profile cannot be deleted because it is referred by the following " "profiles:" msgid "options_modifyReferringProfiles" msgstr "" "You must modify these profiles and make them stop referring to this profile " "before you can delete it." msgid "options_profileNameEmpty" msgstr "The name of the profile must not be empty." msgid "popup_title" msgstr "SwitchyOmega Popup" msgid "options_modalHeader_proxyAuth" msgstr "Proxy Authentication" msgid "options_proxyAuthUsername" msgstr "Username" msgid "options_proxyAuthPassword" msgstr "Password" msgid "options_proxyAuthShowPassword" msgstr "Show password" msgid "options_proxyAuthHidePassword" msgstr "Hide password" msgid "options_proxyAuthNone" msgstr "No Authentication" msgid "options_modalHeader_deleteRule" msgstr "Delete Rule" msgid "options_deleteRuleConfirm" msgstr "Do you really want to delete the following rule?" msgid "options_deleteRule" msgstr "Delete" msgid "options_modalHeader_resetRules" msgstr "Reset rules" msgid "options_resetRulesConfirm" msgstr "" "Are you sure to set the result profile of ALL rules to the following profile?" msgid "options_resetRules" msgstr "Reset rules" msgid "options_resetRules_help" msgstr "Set profile for all rules" msgid "options_modalHeader_deleteAttached" msgstr "Remove Rule List" msgid "options_deleteAttachedConfirm" msgstr "Do you really want to remove the rule list from the current profile?" msgid "options_ruleListLineCount" msgstr "$COUNT$ line(s) of rules" msgid "options_deleteAttached" msgstr "Remove rule list" msgid "options_modalHeader_newProfile" msgstr "New Profile" msgid "options_newProfileName" msgstr "Profile name" msgid "options_profileType" msgstr "Please select the type of the profile:" msgid "options_profileTypeFixedProfile" msgstr "Proxy Profile" msgid "options_profileDescFixedProfile" msgstr "Tunneling traffic through proxy servers." msgid "options_profileTypePacProfile" msgstr "PAC Profile" msgid "options_profileDescPacProfile" msgstr "Choosing proxies using an online/local PAC script." msgid "options_profileDescMorePacProfile" msgstr "" "You will only need this if you have a PAC script or a URL to it. Don't try " "to create one unless you have knowledge about PAC." msgid "options_profileTypeSwitchProfile" msgstr "Switch Profile" msgid "options_profileDescSwitchProfile" msgstr "" "Applying different profiles automatically on various conditions such as " "domains or patterns.\n" " You can also import rules published online for easier switching. (Replaces " "AutoSwitch mode + Rule List.)" msgid "options_profileTypeRuleListProfile" msgstr "Rule List Profile" msgid "options_profileDescRuleListProfile" msgstr "Reusing an online collection of conditions published by others." msgid "options_profileTypeVirtualProfile" msgstr "Virtual Profile" msgid "options_profileDescVirtualProfile" msgstr "" "A virtual profile can act as any of the other profiles on demand. It works " "well with SwitchProfile, allowing you to change the result of multiple " "conditions by one click." msgid "options_createProfile" msgstr "Create" msgid "options_modalHeader_resetOptions" msgstr "Reset Options" msgid "options_resetOptionsConfirm" msgstr "" "Do you really want to reset the options? All profiles and settings will be " "LOST!" msgid "options_formInvalid" msgstr "Please correct the errors in this page." msgid "options_profileNotFound" msgstr "Profile $PROFILE$ does not exist! The options may be corrupted." msgid "options_resetSuccess" msgstr "Options reset." msgid "options_saveSuccess" msgstr "Options saved." msgid "options_importSuccess" msgstr "Options imported." msgid "options_importFormatError" msgstr "Invalid backup file!" msgid "options_importDownloadError" msgstr "Error downloading backup file!" msgid "options_profileDownloadSuccess" msgstr "Successfully updated profile." msgid "options_profileDownloadError" msgstr "Error downloading profile data!" msgid "options_profileDownloadError_NetworkError" msgstr "A network error occurred when updating." msgid "options_profileDownloadError_HttpError" msgstr "An HTTP error ($STATUS$) occurred when updating." msgid "options_profileDownloadError_HttpNotFoundError" msgstr "The Profile URL was not found on the server. Please double-check." msgid "options_profileDownloadError_HttpServerError" msgstr "The remote server responded with error ($STATUS$) when updating." msgid "options_profileDownloadError_ContentTypeRejectedError" msgstr "The downloaded data is invalid! " "You may open the Profile URL in your browser to inspect it." msgid "options_downloadProfileNow" msgstr "Download Profile Now" msgid "options_guide_fixedProfileStep" msgstr "" "A Proxy Profile contains settings like server ip & port for proxy." "
Profiles are the the basic configuration units in SwitchyOmega.
We " "have already created an example profile for you. Try opening it." msgid "options_guide_fixedServersStep" msgstr "" "You can fill in your proxy server and port here as you like.
SwitchyOmega " "does not come with any proxy servers.
Please consult your network " "provider or proxy software manual if you don't know what should be filled in " "here." msgid "options_guide_autoSwitchProfileStep" msgstr "" "You can tell SwitchyOmega to switch between proxies automatically through " "the mighty Switch Profile.
However, its features cannot be covered " "in this quick guide.
You can open this profile to unlock its power some " "time later." msgid "options_guide_addMoreProfilesStep" msgstr "" "Need more profiles? You can always add more Proxy, Switch and other " "profiles
for all your proxying needs.
Enjoy proxying!" msgid "options_guide_conditionStep" msgstr "" "SwitchyOmega can apply different profiles to requests based on " "conditions.
For example, the Host wildcard condition " "allows you to set the profile for all URLs in a domain." msgid "options_guide_conditionTypeStep" msgstr "" "You can use various condition types to match the host or full URL.
" "Click on the question mark to open the type reference." msgid "options_guide_conditionProfileStep" msgstr "" "SwitchyOmega applies the selected profile here to any request matching " "the condition.
The special \"[Direct]\" profile will cause " "the request to be sent without any proxy." msgid "options_guide_switchDefaultStep" msgstr "" "If no condition applies to some request, the \"Default\" profile will be " "used.
Conditions are always considered from top to bottom in " "order.
You can change their order by dragging the sort icon." msgid "options_guide_applySwitchProfileStep" msgstr "" "When you are done setting the switch profile, don't forget to switch to " "it in the popup menu.
The icon will show you the final result profile applied for the current tab.
Hovering on the icon " "will reveal a tooltip with details." msgid "popup_externalProfile" msgstr "(External Profile)" msgid "popup_externalProfileName" msgstr "profile name" msgid "popup_proxyNotControllable_app" msgstr "" "The proxy settings are controlled by other app(s) or extension(s). Please " "disable or uninstall the apps or extensions in conflict." msgid "popup_proxyNotControllable_policy" msgstr "" "The proxy settings are overruled by policies. Please contact your " "administrator." msgid "popup_proxyNotControllable_unknown" msgstr "" "The proxy settings cannot be controlled. Please check your system and " "browser settings." msgid "popup_proxyNotControllable_disabled" msgstr "" "The proxy settings are disabled by explicit request from other app(s) or " "extension(s)." msgid "popup_proxyNotControllable_upgrade" msgstr "Proxy settings are now controlled by a newer version of SwitchyOmega." msgid "popup_proxyNotControllableDetails" msgstr "" "You cannot switch profiles with SwitchyOmega unless you fix the problem " "above." msgid "popup_proxyNotControllableDetails_upgrade" msgstr "" "You can't enable two (or more) versions of SwitchyOmega at the same time. " "Please disable one of them." msgid "popup_proxyNotControllableManage" msgstr "Manage extensions" msgid "popup_addConditionTo" msgstr "Add condition to" msgid "popup_addCondition" msgstr "Add condition" msgid "popup_showOptions" msgstr "Options" msgid "popup_reportIssues" msgstr "Report issues" msgid "popup_errorLog" msgstr "Save error log" msgid "popup_requestErrorCount" msgstr "$COUNT$ failed resources" msgid "popup_requestErrorHeading" msgstr "Resources that failed to load" msgid "popup_requestErrorWarning" msgstr "" "A few resources failed to load due to issues with your network, proxy server " "or the webpage." msgid "popup_requestErrorWarningHelp" msgstr "" "SwitchyOmega is just the reporter of these issues, not the cause of them." msgid "popup_requestErrorAddCondition" msgstr "" "You can review the following domains and use proxy for them when appropriate." msgid "popup_requestErrorCannotAddCondition" msgstr "" "You can add switch conditions for them only when using a Switch Profile." msgid "popup_configureMonitorWebRequests" msgstr "Configure Network Monitor" msgid "options_resultProfileForSelectedDomains" msgstr "Use this profile for all selected domains" msgid "options_pac_profile_unsupported_moz" msgstr "PAC Profiles WILL NOT work in Mozilla Firefox due to technical limitations!" msgid "popup_issueTemplate" msgstr "" "\n" "\n" "\n" "\n" "SwitchyOmega $projectVersion$\n" "$userAgent$" msgid "browserAction_profileDetails_PacProfile" msgstr "(PAC script)" msgid "browserAction_profileDetails_SystemProfile" msgstr "(controlled by other extensions or environment)" msgid "browserAction_profileDetails_DirectProfile" msgstr "(not using any proxy)" msgid "browserAction_profileDetails_SwitchProfile" msgstr "(switching based on conditions)" msgid "browserAction_profileDetails_RuleListProfile" msgstr "(switching based on rule list)" msgid "browserAction_titleNormal" msgstr "SwitchyOmega:: $PROFILE$" msgid "browserAction_titleWithResult" msgstr "" "SwitchyOmega:: $1:PROFILE$\n" "$3:DETAILS$" msgid "browserAction_titleNewerOptions" msgstr "" "ERROR: A newer version of SwitchOmega is required to load the stored options." msgid "browserAction_titleOptionError" msgstr "ERROR: The stored options are corrupted. Click here to RESET OPTIONS." msgid "browserAction_titleDownloadFail" msgstr "Warning: Failed to download PAC scripts and/or rule lists." msgid "browserAction_titleExternalProxy" msgstr "Note: The proxy settings are currently controlled by other app(s)." msgid "browserAction_titleInspect" msgstr "[Inspect] $URL$" msgid "browserAction_defaultRuleDetails" msgstr "(default)" msgid "browserAction_directResult" msgstr "DIRECT" msgid "browserAction_attachedPrefix" msgstr "(RL) " msgid "browserAction_tempRulePrefix" msgstr "(TEMP) " msgid "contextMenu_inspectPage" msgstr "Inspect proxy used for this page" msgid "contextMenu_inspectFrame" msgstr "Inspect proxy used for this Frame" msgid "contextMenu_inspectLink" msgstr "Inspect proxy to be used if this Link is opened" msgid "contextMenu_inspectElement" msgstr "Inspect proxy used for this Element" msgid "contextMenu_enableQuickSwitch" msgstr "Enable Quick Switch" msgid "about_title" msgstr "About" msgid "about_app_description" msgstr "A proxy configuration tool" msgid "about_version" msgstr "Version $VERSION$" msgid "about_experimental_warning_moz" msgstr "Mozilla Firefox support is highly experimental! If you encounter issues, please report using the buttons below." msgid "about_disclaimer_networkService" msgstr "SwitchyOmega does not provide proxies, VPNs, or other network services." msgid "about_disclaimer_privacy" msgstr "SwitchyOmega does not track you or insert ads into webpages. Please see" " our privacy policy." msgid "about_help" msgstr "Other questions? Need help with using SwitchyOmega? Please see our " "FAQ." msgid "about_copyright" msgstr "Copyright 2012-2017 The SwitchyOmega Authors. All rights reserved." msgid "about_credits" msgstr "SwitchyOmega is made possible by the SwitchyOmega open source project and other open source software." msgid "about_license" msgstr "SwitchyOmega is free software licensed under GNU General Public License Version 3 or later." ================================================ FILE: omega-locales/en_US/LC_MESSAGES/omega-web.po ================================================ msgid "" msgstr "" "Project-Id-Version: SwitchyOmega 2.3.3\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2015-02-13 10:29+0000\n" "PO-Revision-Date: 2018-06-13 01:52+0000\n" "Last-Translator: Joost-Wim Boekesteijn \n" "Language-Team: English (United States) \n" "Language: en_US\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Generator: Weblate 3.0.1\n" msgid "appNameShort" msgstr "SwitchyOmega" msgid "manifest_app_name" msgstr "Proxy SwitchyOmega" msgid "manifest_app_description" msgstr "Manage and switch between multiple proxies quickly & easily." msgid "manifest_icon_default_title" msgstr "Loading…" msgid "upgrade_profile_auto" msgstr "Auto Switch" msgid "profile_direct" msgstr "[Direct]" msgid "profile_system" msgstr "[System Proxy]" msgid "condition_HostWildcardCondition" msgstr "Host wildcard" msgid "condition_help_HostWildcardCondition" msgstr "" "Matches hosts (domain names) by wildcard.
The asterisk * matches zero or more characters.
The question mark ? " "matches exactly one character.

Note that rules beginning with *. are specially treated only in Host wildcard conditions.
Example: <" "code>*.example.com
will match www.example.com AND example.com as " "well.
To match subdomains only, use two asterisks like <" "code>**.example.com." msgid "condition_HostRegexCondition" msgstr "Host regex" msgid "condition_help_HostRegexCondition" msgstr "" "Like Host wildcard condition, but matches hosts (domain names) by regular expression.<" "br>Regular expressions can be hard to construct (and read).
It is " "recommended to use wildcards for most cases and only use regex for conditions " "that cannot be achieved by any other condition type." msgid "condition_HostLevelsCondition" msgstr "Host levels" msgid "condition_help_HostLevelsCondition" msgstr "" "Matches the request if and only if the host level in within the given range.<" "br>Host level is defined as the number of dot-separated segments of " "the host (domain name).
Example: www.example.com is with a " "host level of 3, while internal is of host level 1." msgid "condition_IpCondition" msgstr "IP Literals" msgid "condition_help_IpCondition" msgstr "" "Matches the request if and only if the host is a literal IP address and" " in the subnet as specified by " "CIDR notation.
For example, given the rule 127.0.0.1/16, " "it matches all IP addresses like 127.0.*.*.
" "So 127.0.0.1 matches while 127.1.0.0 does not. " "Host names like localhost will never match because they are " "not IP literals." msgid "condition_UrlWildcardCondition" msgstr "URL wildcard" msgid "condition_help_UrlWildcardCondition" msgstr "" "Matches URLs of the request by wildcard.
See the Host wildcard section " "above for a quick wildcard reference.
Note that URL wildcards are not " "specially treated (no subdomain magic as in Host wildcard).
So *://*." "example.com/* matches http://www.example.com/ but does not " "match http://example.com/." msgid "condition_UrlRegexCondition" msgstr "URL regex" msgid "condition_help_UrlRegexCondition" msgstr "" "Matches URL by extremely powerful regular expression.
However, regular expressions " "can be hard to construct (and read).
It is recommended to use wildcards " "for most cases and only use regex for conditions that cannot be achieved by " "any other condition type." msgid "condition_KeywordCondition" msgstr "Keyword" msgid "condition_help_KeywordCondition" msgstr "" "A keyword condition matches if the URL protocol is HTTP, and the pattern is " "an exact sub-string of the URL.
It behaves like the URL wildcard pattern <" "code>http://*pattern*, where pattern is the keyword " "pattern.
Keyword conditions are useful if you want to bypass a firewall " "blocking some keywords in the URL, by requesting such URLs through a proxy." msgid "condition_FalseCondition" msgstr "(Disabled)" msgid "condition_details_FalseCondition" msgstr "(Condition ignored when matching)" msgid "condition_help_FalseCondition" msgstr "" "You can disable a condition by setting its type to (Disabled). A " "Disabled condition act as if it does not exist.
This feature can be used " "to disable conditions temporarily.
Disabled conditions still hold the " "previous information (like patterns) and can be re-enabled by setting the " "condition type back to the previous type." msgid "condition_TimeCondition" msgstr "Current Time" msgid "condition_help_TimeCondition" msgstr "" "Matches if the current local time is in the range defined by " "starting hour and ending hour, both inclusive.
" "Local time, starting hour and ending hour are all calculated in " "24-hour format (from 0 to 23).
" "The calculation happens roughly at the moment when the request is sent." msgid "condition_WeekdayCondition" msgstr "Day of the Week" msgid "condition_help_WeekdayCondition" msgstr "" "Matches if the current day of week is selected in condition details. " "Day is calculated according to local timezone.
" "The request and its URL don't matter to this condition. " "The result is solely based on the day of the week when the request is sent." msgid "condition_alert_fullUrlLimitation" msgstr "" "Full URL matching is no longer possible for https:// " "URLs as of Chrome 52. " "" "Learn more..." msgid "condition_alert_fullUrlLimitationLink" msgstr "https://github.com/FelisCatus/SwitchyOmega/wiki/Chromium-Full-URL-Limitation" msgid "condition_group_default" msgstr " " msgid "condition_group_host" msgstr "Host" msgid "condition_group_url" msgstr "Url" msgid "condition_group_special" msgstr "Special" msgid "ruleListFormat_Switchy" msgstr "Switchy" msgid "ruleListFormat_AutoProxy" msgstr "AutoProxy" msgid "ruleList_usageUrl" msgstr "https://github.com/FelisCatus/SwitchyOmega/wiki/RuleListUsage" msgid "ruleList_error_resultNotEnabled" msgstr "Missing '@with result' directive!" msgid "ruleList_error_unknownProfile" msgstr "Unknown profile: $PROFILE$" msgid "ruleList_error_missingResultProfile" msgstr "Missing result profile name at Line $LNO$: $SOURCE$" msgid "ruleList_error_invalidRule" msgstr "Invalid rule at Line $LNO$: $SOURCE$" msgid "ruleList_error_noDefaultRule" msgstr "Missing default rule with catch-all '*' condition!" msgid "dialog_close" msgstr "Close" msgid "dialog_save" msgstr "Save changes" msgid "dialog_ok" msgstr "OK" msgid "dialog_cancel" msgstr "Cancel" msgid "inputClear_clear" msgstr "Clear" msgid "inputClear_restore" msgstr "Restore" msgid "options_title" msgstr "SwitchyOmega Options" msgid "options_experimental_badge" msgstr "α" msgid "options_navHeader_setting" msgstr "Settings" msgid "options_navHeader_profiles" msgstr "Profiles" msgid "options_navHeader_actions" msgstr "Actions" msgid "options_tab_ui" msgstr "Interface" msgid "options_tab_general" msgstr "General" msgid "options_tab_importExport" msgstr "Import/Export" msgid "options_newProfile" msgstr "New profile…" msgid "options_apply" msgstr "Apply changes" msgid "options_discard" msgstr "Discard changes" msgid "options_reset" msgstr "Reset options" msgid "options_group_miscOptions" msgstr "Misc Options" msgid "options_confirmDeletion" msgstr "Confirm on condition deletion." msgid "options_refreshOnProfileChange" msgstr "Refresh current tab on profile change." msgid "options_showInspectMenu" msgstr "Allow inspecting proxy used for page elements via context menu." msgid "options_addConditionsToBottom" msgstr "Put new conditions added using the popup to the bottom of the list." msgid "options_group_keyboardShortcut" msgstr "Keyboard Shortcut" msgid "options_menuShortcutHelp" msgstr "" "Pressing the shortcut will open the switch popup menu. (Defaults to Alt+Shift+" "O)." msgid "options_menuShortcutMore" msgstr "" "The items in the popup menu can also be accessed using the keyboard. Press ? (" "or /) in the menu to learn more." msgid "options_menuShortcutConfigure" msgstr "Configure shortcut" msgid "options_group_switchOptions" msgstr "Switch Options" msgid "options_startupProfile" msgstr "Startup Profile" msgid "options_startupProfile_none" msgstr "(Current profile)" msgid "options_showConditionTypesAdvanced" msgstr "Show advanced condition types" msgid "options_showConditionTypesAdvancedHelp" msgstr "" "Unlocks new types of advanced but complicated switch conditions. For most " "scenarios, the basic condition types should be enough, so this option is not " "recommended." msgid "options_quickSwitch" msgstr "Quick Switch" msgid "options_cycledProfiles" msgstr "Cycled Profiles" msgid "options_cycledProfilesHelp" msgstr "" "When you click on the icon (or use the shortcut above), the following " "profiles will be applied in their order." msgid "options_cycledProfilesTooFew" msgstr "" "You need to select at least 2 profiles to enable this function! You can drag " "them from the box below." msgid "options_notCycledProfiles" msgstr "Not Cycled Profiles" msgid "options_group_proxyChanges" msgstr "Proxy Changes" msgid "options_revertProxyChanges" msgstr "Revert proxy changes done by other apps." msgid "options_group_conflicts" msgstr "Conflicts" msgid "options_conflicts_introduction" msgstr "" "Sometimes, other apps will also try to control the proxy settings, resulting " "in conflicts. Note that ad blockers and other extensions may also use proxy " "settings under the hood. Such conflicts cannot be avoided due to how the " "browser works." msgid "options_conflicts_lowerPriority" msgstr "" "A red badge like this on the SwitchyOmega icon indicates that another app has " "higher priority so SwitchyOmega cannot control the settings. Please try to " "uninstall SwitchyOmega and reinstall, which should raise SwitchyOmega's " "priority. If you still see conflicts after reinstallation, please consider " "removing the other app causing the conflict." msgid "options_conflicts_higherPriority" msgstr "" "If SwitchyOmega has higher priority, you can give the control back to other " "apps or system settings by selecting $SYSTEMPROFILE$ in the popup menu." msgid "options_showExternalProfile" msgstr "Show popup menu item to import proxy settings from other apps." msgid "options_showExternalProfileHelp" msgstr "" "When $SYSTEMPROFILE$ is selected, you can import the effective proxy settings " "from other apps by selecting $EXTERNALPROFILE$ on the popup menu. " "The settings will be imported as a profile using the name you provide. " "Please note that the imported profile is a snapshot and will not reflect " "any changes from the source app thereafter." msgid "options_group_networkRequests" msgstr "Network Requests" msgid "options_monitorWebRequests" msgstr "Show count of failed web requests for resources in the current tab." msgid "options_monitorWebRequestsHelp" msgstr "A yellow badge will be displayed on the icon if some resources fail to load,
" "and you can set the profile for such resources conveniently via the popup menu." msgid "options_downloadOptions" msgstr "Download Options" msgid "options_downloadOptionsHelp" msgstr "Configure the update frequency of online rule lists and PAC scripts." msgid "options_downloadInterval" msgstr "Download Interval" msgid "options_downloadInterval_15" msgstr "15 Minutes" msgid "options_downloadInterval_60" msgstr "1 Hour" msgid "options_downloadInterval_180" msgstr "3 Hours" msgid "options_downloadInterval_360" msgstr "6 Hours" msgid "options_downloadInterval_720" msgstr "12 Hours" msgid "options_downloadInterval_1440" msgstr "Every day" msgid "options_downloadInterval_never" msgstr "Never" msgid "options_group_importExportProfile" msgstr "Profile" msgid "options_exportPacFile" msgstr "Export as PAC File" msgid "options_exportPacFileHelp" msgstr "Export the current profile as a PAC file, so you can use it in other browsers." msgid "options_exportProfileHelp" msgstr "To export a profile, use the top-right action bar on the profile page." msgid "options_exportLegacyRuleList" msgstr "" "Export rule lists using Proxy Switchy!/SwitchyPlus/SwitchySharp compatible " "format when possible." msgid "options_exportLegacyRuleListHelp" msgstr "" "Enable this option only if you publish rule lists for users of those projects.<" "br>Please consider advising your audience to upgrade to SwitchyOmega for the " "improvements." msgid "options_group_importExportSettings" msgstr "Settings" msgid "options_makeBackup" msgstr "Make backup" msgid "options_makeBackupHelp" msgstr "Make a full backup of your options (including profiles and all other options)." msgid "options_restoreLocal" msgstr "Restore from file" msgid "options_restoreLocalHelp" msgstr "Restore your SwitchyOmega options from a local file." msgid "options_restoreOnline" msgstr "Restore from online" msgid "options_restoreOnlinePlaceholder" msgstr "Options file URL (e.g. 'http://example.com/switchy.bak')" msgid "options_restoreOnlineSubmit" msgstr "Restore" msgid "options_group_syncing" msgstr "Syncing (Experimental)" msgid "options_syncEnable" msgstr "Enable Syncing" msgid "options_syncEnableForce" msgstr "Download from Syncing" msgid "options_syncDisable" msgstr "Disable syncing" msgid "options_syncReset" msgstr "Clear remote copy" msgid "options_syncPristineHelp" msgstr "" "You can now automatically synchronize your settings and profiles across all " "your desktop devices running Chrome browser." msgid "options_syncSyncAlert" msgstr "Your options are automatically synchronized with your other devices." msgid "options_syncSyncHelp" msgstr "" "Please note that you must sign in to Chrome on each of your devices (" "including this one) for the syncing to actually work.
You may check this " "section on other devices to ensure that it is working." msgid "options_syncConflictAlert" msgstr "You have uploaded a copy of your options on another device via syncing." msgid "options_syncConflictHelp" msgstr "" "You may download the remote copy to your device if you like.
However, " "doing so would overwrite your existing settings and profiles on this " "device." msgid "options_syncUnsupportedHelp" msgstr "" "Options syncing is not supported on your platform or browser. For now, only " "Chrome browser on desktop is supported." msgid "options_profileSyncDisabled" msgstr "Syncing is disabled for this profile." msgid "options_profileSyncDisabled_quotaPerItem" msgstr "Syncing is disabled for this profile for using too much storage space." msgid "options_profileTabPrefix" msgstr "Profile :: " msgid "options_renameProfile" msgstr "Rename" msgid "options_deleteProfile" msgstr "Delete" msgid "options_profileExportRuleList" msgstr "Publish rule list" msgid "options_profileExportRuleListHelp" msgstr "Export Switch Rules as text format for publishing." msgid "options_profileExportPac" msgstr "Export PAC" msgid "options_profileUnsupported" msgstr "Unsupported profile type $TYPE$!" msgid "options_profileUnsupportedHelp" msgstr "The options could be broken, or from a newer version of this program." msgid "options_profileEditSource" msgstr "Edit source code" msgid "options_profileEditSourceHelp" msgstr "Show help about the source code format" msgid "options_profileEditSourceHelpUrl" msgstr "" "https://github.com/FelisCatus/SwitchyOmega/wiki/SwitchyOmega-conditions-" "format#result-profile" msgid "options_group_proxyServers" msgstr "Proxy servers" msgid "options_proxy_scheme" msgstr "Scheme" msgid "options_proxy_protocol" msgstr "Protocol" msgid "options_proxy_server" msgstr "Server" msgid "options_proxy_port" msgstr "Port" msgid "options_proxy_auth" msgstr "Authentication" msgid "options_proxy_authNotSupported" msgstr "Your browser DOES NOT support $PROTOCOLDISP$ proxy authentication! " "Please do not report this issue to SwitchyOmega. Contact the support for " "your browser instead." msgid "options_proxy_authAllWarningPac" msgstr "" "Warning: The username/password may be sent to unexpected servers returned by " "the PAC script." msgid "options_proxy_authAllWarningPacUrl" msgstr "" "Please make sure that you trust the script provided via the URL above before " "entering sensitive credentials." msgid "options_proxy_authAllWarningPacScript" msgstr "" "Please make sure that you trust the script below before providing sensitive " "credentials." msgid "options_proxy_authReferencedWarning" msgstr "" "Additionally, using this profile in other profiles (e.g. Switch Profile) may " "cause the username/password to be sent to proxy servers configured in other " "profiles." msgid "options_scheme_default" msgstr "(default)" msgid "options_protocol_direct" msgstr "DIRECT" msgid "options_protocol_useDefault" msgstr "(use default)" msgid "options_proxy_single" msgstr "Use the proxy above for all protocols." msgid "options_proxy_expand" msgstr "Show Advanced" msgid "options_group_bypassList" msgstr "Bypass List" msgid "options_bypassListHelp" msgstr "Servers for which you do not want to use any proxy: (One server on each line.)" msgid "options_bypassListHelpLinkText" msgstr "(Wildcards and more available…)" msgid "options_group_pacUrl" msgstr "PAC URL" msgid "options_pacUrlHelp" msgstr "" "The PAC script will be updated from this URL. If it is left blank, the " "following script will be used directly instead." msgid "options_pacUrlFile" msgstr "" "PAC profiles with file: URLs can only be applied directly. They cannot be " "used as result profiles because local files cannot be accessed due to browser " "limitation." msgid "options_pacUrlFileDisabled" msgstr "" "Therefore, you cannot use local PAC file for this profile. You can create a " "new PAC profile for that if you really want that." msgid "options_group_pacScript" msgstr "PAC Script" msgid "options_pacScriptLastUpdate" msgstr "PAC script downloaded at $TIME$:" msgid "options_pacScriptObsolete" msgstr "" "PAC script is obsolete due to URL change. Press the download button above to " "update." msgid "options_group_virtualProfile" msgstr "Virtual Profile" msgid "options_virtualProfileTarget" msgstr "Target" msgid "options_virtualProfileTargetHelp" msgstr "" "When this profile is applied, it acts exactly the same as the profile " "selected below." msgid "options_group_virtualProfileReplace" msgstr "Migrate to Virtual Profile" msgid "options_virtualProfileReplace" msgstr "Replace target profile" msgid "options_virtualProfileReplaceHelp" msgstr "" "You can migrate existing options to use this virtual profile instead of $" "PROFILE$. Doing so will update all existing rules concerning $PROFILE$ and " "point them to this virtual profile, so that their result profile can be " "controlled here." msgid "options_group_ruleListConfig" msgstr "Rule List Config" msgid "options_ruleListFormat" msgstr "Rule List Format" msgid "options_group_ruleListResult" msgstr "Rule list result profiles" msgid "options_ruleListMatchProfile" msgstr "Match profile" msgid "options_ruleListDefaultProfile" msgstr "Default profile" msgid "options_group_ruleListUrl" msgstr "Rule List URL" msgid "options_ruleListUrlHelp" msgstr "" "The rule list will be updated from this URL. If it is left blank, the " "following text will be parsed instead." msgid "options_group_ruleListText" msgstr "Rule List Text" msgid "options_ruleListLastUpdate" msgstr "Rule list downloaded at $TIME$:" msgid "options_ruleListObsolete" msgstr "" "Rule list is obsolete due to URL change. Press the download button above to " "update." msgid "options_group_switchRules" msgstr "Switch rules" msgid "options_sort" msgstr "Sort" msgid "options_conditionType" msgstr "Condition Type" msgid "options_showConditionTypeHelp" msgstr "Show help" msgid "options_conditionDetails" msgstr "Condition Details" msgid "options_resultProfile" msgstr "Profile" msgid "options_conditionActions" msgstr "Actions" msgid "options_addCondition" msgstr "Add condition" msgid "options_cloneRule" msgstr "Clone" msgid "options_ruleNote" msgstr "Note" msgid "options_switchAttachedProfileInCondition" msgstr "Rule list rules" msgid "options_switchAttachedProfileInConditionDetails" msgstr "(Any request matching the rule list below)" msgid "options_switchAttachedProfileInConditionDisabled" msgstr "(Rule list rules are DISABLED)" msgid "options_switchDefaultProfile" msgstr "Default" msgid "options_hostLevelsBetween" msgstr "≤ host levels ≤" msgid "options_hourBetween" msgstr "≤ current hour ≤" msgid "options_weekDayShort_0" msgstr "Su" msgid "options_weekDayShort_1" msgstr "Mo" msgid "options_weekDayShort_2" msgstr "Tu" msgid "options_weekDayShort_3" msgstr "We" msgid "options_weekDayShort_4" msgstr "Th" msgid "options_weekDayShort_5" msgstr "Fr" msgid "options_weekDayShort_6" msgstr "Sa" msgid "options_group_conditionHelp" msgstr "About Condition Types" msgid "options_group_attachProfile" msgstr "Import online rule lists" msgid "options_attachProfile" msgstr "Add a rule list" msgid "options_attachProfileHelp" msgstr "" "You can reuse an online collection of conditions published by others by " "adding a rule list." msgid "options_modalHeader_welcome" msgstr "Welcome to SwitchyOmega" msgid "options_welcomeNormal" msgstr "You have successfully installed SwitchyOmega, the ultimate proxy switcher." msgid "options_welcomeNormalGuide" msgstr "" "Please tell SwitchyOmega about your proxies through the options page. Let's " "see how." msgid "options_welcomeUpgrade" msgstr "" "You have successfully upgraded to SwitchyOmega. Don't panic, your existing " "options are fully preserved." msgid "options_welcomeUpgradeGuide" msgstr "Now let's go through a quick guide of the new options page." msgid "options_guideNext" msgstr "Next" msgid "options_guideDone" msgstr "Done" msgid "options_guideSkip" msgstr "Skip guide" msgid "options_modalHeader_applyOptions" msgstr "Apply Options" msgid "options_optionsNotSaved" msgstr "" "Your modifications to the options have not been saved and will be lost if you " "proceed!" msgid "options_applyOptionsRequired" msgstr "Your changes to the options must be applied before you proceed." msgid "options_applyOptionsConfirm" msgstr "Do you want to save and apply the options?" msgid "options_modalHeader_renameProfile" msgstr "Rename Profile" msgid "options_renameProfileName" msgstr "New profile name" msgid "options_profileNameConflict" msgstr "A profile with this name already exists." msgid "options_profileNameReserved" msgstr "Profile names beginning with double-underscore are reserved." msgid "options_profileNameHidden" msgstr "" "Profiles with names starting with underscore will be hidden on the popup menu. " "However, they can still be used in places like switch profile results." msgid "options_modalHeader_replaceProfile" msgstr "Replace Profile" msgid "options_replaceProfile" msgstr "Replace Profile" msgid "options_replaceProfileConfirm" msgstr "Do you really want to replace $FromProfile$ with $ToProfile$?" msgid "options_replaceProfileHelp" msgstr "" "If you proceed, all rules pointing to $FromProfile$ will be updated to use $" "ToProfile$ instead. Other options, such as startup profile and Quick Switch " "will also be modified as appropriate. However, the two profile themselves " "will NOT be changed or deleted." msgid "options_replaceProfileSuccess" msgstr "Options updated." msgid "options_modalHeader_deleteProfile" msgstr "Delete Profile" msgid "options_deleteProfileConfirm" msgstr "Do you really want to delete the following profile?" msgid "options_modalHeader_cannotDeleteProfile" msgstr "Unable to Delete Profile" msgid "options_profileReferredBy" msgstr "" "This profile cannot be deleted because it is referred by the following " "profiles:" msgid "options_modifyReferringProfiles" msgstr "" "You must modify these profiles and make them stop referring to this profile " "before you can delete it." msgid "options_profileNameEmpty" msgstr "The name of the profile must not be empty." msgid "popup_title" msgstr "SwitchyOmega Popup" msgid "options_modalHeader_proxyAuth" msgstr "Proxy Authentication" msgid "options_proxyAuthUsername" msgstr "Username" msgid "options_proxyAuthPassword" msgstr "Password" msgid "options_proxyAuthShowPassword" msgstr "Show password" msgid "options_proxyAuthHidePassword" msgstr "Hide password" msgid "options_proxyAuthNone" msgstr "No Authentication" msgid "options_modalHeader_deleteRule" msgstr "Delete Rule" msgid "options_deleteRuleConfirm" msgstr "Do you really want to delete the following rule?" msgid "options_deleteRule" msgstr "Delete" msgid "options_modalHeader_resetRules" msgstr "Reset rules" msgid "options_resetRulesConfirm" msgstr "Are you sure to set the result profile of ALL rules to the following profile?" msgid "options_resetRules" msgstr "Reset rules" msgid "options_resetRules_help" msgstr "Set profile for all rules" msgid "options_modalHeader_deleteAttached" msgstr "Remove Rule List" msgid "options_deleteAttachedConfirm" msgstr "Do you really want to remove the rule list from the current profile?" msgid "options_ruleListLineCount" msgstr "$COUNT$ line(s) of rules" msgid "options_deleteAttached" msgstr "Remove rule list" msgid "options_modalHeader_newProfile" msgstr "New Profile" msgid "options_newProfileName" msgstr "Profile name" msgid "options_profileType" msgstr "Please select the type of the profile:" msgid "options_profileTypeFixedProfile" msgstr "Proxy Profile" msgid "options_profileDescFixedProfile" msgstr "Tunneling traffic through proxy servers." msgid "options_profileTypePacProfile" msgstr "PAC Profile" msgid "options_profileDescPacProfile" msgstr "Choosing proxies using an online/local PAC script." msgid "options_profileDescMorePacProfile" msgstr "" "You will only need this if you have a PAC script or a URL to it. Don't try to " "create one unless you have knowledge about PAC." msgid "options_profileTypeSwitchProfile" msgstr "Switch Profile" msgid "options_profileDescSwitchProfile" msgstr "" "Applying different profiles automatically on various conditions such as " "domains or patterns.\n" " You can also import rules published online for easier switching. (Replaces " "AutoSwitch mode + Rule List.)" msgid "options_profileTypeRuleListProfile" msgstr "Rule List Profile" msgid "options_profileDescRuleListProfile" msgstr "Reusing an online collection of conditions published by others." msgid "options_profileTypeVirtualProfile" msgstr "Virtual Profile" msgid "options_profileDescVirtualProfile" msgstr "" "A virtual profile can act as any of the other profiles on demand. It works " "well with SwitchProfile, allowing you to change the result of multiple " "conditions by one click." msgid "options_createProfile" msgstr "Create" msgid "options_modalHeader_resetOptions" msgstr "Reset Options" msgid "options_resetOptionsConfirm" msgstr "" "Do you really want to reset the options? All profiles and settings will be " "LOST!" msgid "options_formInvalid" msgstr "Please correct the errors in this page." msgid "options_profileNotFound" msgstr "Profile $PROFILE$ does not exist! The options may be corrupted." msgid "options_resetSuccess" msgstr "Options reset." msgid "options_saveSuccess" msgstr "Options saved." msgid "options_importSuccess" msgstr "Options imported." msgid "options_importFormatError" msgstr "Invalid backup file!" msgid "options_importDownloadError" msgstr "Error downloading backup file!" msgid "options_profileDownloadSuccess" msgstr "Successfully updated profile." msgid "options_profileDownloadError" msgstr "Error downloading profile data!" msgid "options_profileDownloadError_NetworkError" msgstr "A network error occurred when updating." msgid "options_profileDownloadError_HttpError" msgstr "An HTTP error ($STATUS$) occurred when updating." msgid "options_profileDownloadError_HttpNotFoundError" msgstr "The Profile URL was not found on the server. Please double-check." msgid "options_profileDownloadError_HttpServerError" msgstr "The remote server responded with error ($STATUS$) when updating." msgid "options_profileDownloadError_ContentTypeRejectedError" msgstr "The downloaded data is invalid! " "You may open the Profile URL in your browser to inspect it." msgid "options_downloadProfileNow" msgstr "Download Profile Now" msgid "options_guide_fixedProfileStep" msgstr "" "A Proxy Profile contains settings like server ip & port for proxy.<" "br>Profiles are the the basic configuration units in SwitchyOmega.
We have " "already created an example profile for you. Try opening it." msgid "options_guide_fixedServersStep" msgstr "" "You can fill in your proxy server and port here as you like.
SwitchyOmega <" "b>does not come with any proxy servers
.
Please consult your network " "provider or proxy software manual if you don't know what should be filled in " "here." msgid "options_guide_autoSwitchProfileStep" msgstr "" "You can tell SwitchyOmega to switch between proxies automatically through the " "mighty Switch Profile.
However, its features cannot be covered in " "this quick guide.
You can open this profile to unlock its power some time " "later." msgid "options_guide_addMoreProfilesStep" msgstr "" "Need more profiles? You can always add more Proxy, Switch and other " "profiles
for all your proxying needs.
Enjoy proxying!" msgid "options_guide_conditionStep" msgstr "" "SwitchyOmega can apply different profiles to requests based on conditions.
For example, the Host wildcard condition allows you to set the " "profile for all URLs in a domain." msgid "options_guide_conditionTypeStep" msgstr "" "You can use various condition types to match the host or full URL.
Click " "on the question mark to open the type reference." msgid "options_guide_conditionProfileStep" msgstr "" "SwitchyOmega applies the selected profile here to any request matching the " "condition.
The special \"[Direct]\" profile will cause the " "request to be sent without any proxy." msgid "options_guide_switchDefaultStep" msgstr "" "If no condition applies to some request, the \"Default\" profile will be used. <" "br>Conditions are always considered from top to bottom in order.
" "You can change their order by dragging the sort icon." msgid "options_guide_applySwitchProfileStep" msgstr "" "When you are done setting the switch profile, don't forget to switch to it " "in the popup menu.
The icon will show you the final result " "profile applied for the current tab.
Hovering on the icon will " "reveal a tooltip with details." msgid "popup_externalProfile" msgstr "(External Profile)" msgid "popup_externalProfileName" msgstr "profile name" msgid "popup_proxyNotControllable_app" msgstr "" "The proxy settings are controlled by other app(s) or extension(s). Please " "disable or uninstall the apps or extensions in conflict." msgid "popup_proxyNotControllable_policy" msgstr "" "The proxy settings are overruled by policies. Please contact your " "administrator." msgid "popup_proxyNotControllable_unknown" msgstr "" "The proxy settings cannot be controlled. Please check your system and browser " "settings." msgid "popup_proxyNotControllable_disabled" msgstr "" "The proxy settings are disabled by explicit request from other app(s) or " "extension(s)." msgid "popup_proxyNotControllable_upgrade" msgstr "Proxy settings are now controlled by a newer version of SwitchyOmega." msgid "popup_proxyNotControllableDetails" msgstr "You cannot switch profiles with SwitchyOmega unless you fix the problem above." msgid "popup_proxyNotControllableDetails_upgrade" msgstr "" "You can't enable two (or more) versions of SwitchyOmega at the same time. " "Please disable one of them." msgid "popup_proxyNotControllableManage" msgstr "Manage extensions" msgid "popup_addConditionTo" msgstr "Add condition to" msgid "popup_addCondition" msgstr "Add condition" msgid "popup_showOptions" msgstr "Options" msgid "popup_reportIssues" msgstr "Report issues" msgid "popup_errorLog" msgstr "Save error log" msgid "popup_requestErrorCount" msgstr "$COUNT$ failed resources" msgid "popup_requestErrorHeading" msgstr "Resources that failed to load" msgid "popup_requestErrorWarning" msgstr "A few resources failed to load due to issues with your network, proxy server or the webpage." msgid "popup_requestErrorWarningHelp" msgstr "SwitchyOmega is just the reporter of these issues, not the cause of them." msgid "popup_requestErrorAddCondition" msgstr "You can review the following domains and use proxy for them when appropriate." msgid "popup_requestErrorCannotAddCondition" msgstr "You can add switch conditions for them only when using a Switch Profile." msgid "popup_configureMonitorWebRequests" msgstr "Configure Network Monitor" msgid "options_resultProfileForSelectedDomains" msgstr "Use this profile for all selected domains" msgid "options_pac_profile_unsupported_moz" msgstr "PAC Profiles WILL NOT work in Mozilla Firefox due to technical limitations!" msgid "popup_issueTemplate" msgstr "" "\n" "\n" "\n" "\n" "SwitchyOmega $projectVersion$\n" "$userAgent$" msgid "browserAction_profileDetails_PacProfile" msgstr "(PAC script)" msgid "browserAction_profileDetails_SystemProfile" msgstr "(controlled by other extensions or environment)" msgid "browserAction_profileDetails_DirectProfile" msgstr "(not using any proxy)" msgid "browserAction_profileDetails_SwitchProfile" msgstr "(switching based on conditions)" msgid "browserAction_profileDetails_RuleListProfile" msgstr "(switching based on rule list)" msgid "browserAction_titleNormal" msgstr "SwitchyOmega:: $PROFILE$" msgid "browserAction_titleWithResult" msgstr "" "SwitchyOmega:: $1:PROFILE$\n" "$3:DETAILS$" msgid "browserAction_titleNewerOptions" msgstr "ERROR: A newer version of SwitchOmega is required to load the stored options." msgid "browserAction_titleOptionError" msgstr "ERROR: The stored options are corrupted. Click here to RESET OPTIONS." msgid "browserAction_titleDownloadFail" msgstr "Warning: Failed to download PAC scripts and/or rule lists." msgid "browserAction_titleExternalProxy" msgstr "Note: The proxy settings are currently controlled by other app(s)." msgid "browserAction_titleInspect" msgstr "[Inspect] $URL$" msgid "browserAction_defaultRuleDetails" msgstr "(default)" msgid "browserAction_directResult" msgstr "DIRECT" msgid "browserAction_attachedPrefix" msgstr "(RL) " msgid "browserAction_tempRulePrefix" msgstr "(TEMP) " msgid "contextMenu_inspectPage" msgstr "Inspect proxy used for this page" msgid "contextMenu_inspectFrame" msgstr "Inspect proxy used for this Frame" msgid "contextMenu_inspectLink" msgstr "Inspect proxy to be used if this Link is opened" msgid "contextMenu_inspectElement" msgstr "Inspect proxy used for this Element" msgid "contextMenu_enableQuickSwitch" msgstr "Enable Quick Switch" msgid "about_title" msgstr "About" msgid "about_app_description" msgstr "A proxy configuration tool" msgid "about_version" msgstr "Version $VERSION$" msgid "about_experimental_warning_moz" msgstr "Mozilla Firefox support is highly experimental! If you encounter issues, please report using the buttons below." msgid "about_disclaimer_networkService" msgstr "SwitchyOmega does not provide proxies, VPNs, or other network services." msgid "about_disclaimer_privacy" msgstr "SwitchyOmega does not track you or insert ads into webpages. Please see" " our privacy policy." msgid "about_help" msgstr "Other questions? Need help with using SwitchyOmega? Please see our " "FAQ." msgid "about_copyright" msgstr "Copyright 2012-2017 The SwitchyOmega Authors. All rights reserved." msgid "about_credits" msgstr "SwitchyOmega is made possible by the SwitchyOmega open source project and other open source software." msgid "about_license" msgstr "SwitchyOmega is free software licensed under GNU General Public License Version 3 or later." ================================================ FILE: omega-locales/es/LC_MESSAGES/omega-web.po ================================================ msgid "" msgstr "" "Project-Id-Version: SwitchyOmega 2.3.3\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2015-02-13 10:29+0000\n" "PO-Revision-Date: 2020-08-30 19:36+0000\n" "Last-Translator: Scoopity Whoop \n" "Language-Team: Spanish \n" "Language: es\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Generator: Weblate 4.2.1-dev\n" msgid "appNameShort" msgstr "SwitchyOmega" msgid "manifest_app_name" msgstr "SwitchyOmega Proxy" msgid "manifest_app_description" msgstr "" "Gestiona y utiliza diferentes servidores proxy de forma rápida y sencilla." msgid "manifest_icon_default_title" msgstr "Cargando…" msgid "upgrade_profile_auto" msgstr "Cambio automático" msgid "profile_direct" msgstr "[Directo]" msgid "profile_system" msgstr "[Proxy del sistema]" msgid "condition_HostWildcardCondition" msgstr "Patrón de servidor" msgid "condition_help_HostWildcardCondition" msgstr "" "Detecta servidores (nombres de dominio) según patrones.
El asterisco " "* equivale a cero o más caracteres.
La interrogación " "? equivale exactamente a un carácter.

Tenga en " "cuenta que reglas que comienzan con *. se tratan de forma " "especial únicamente al usar patrones de sevidor.
Ejemplo: *.example." "com detecta www.example.com Y example.com también.
Para " "detectar únicamente subdominios, utilice dos asteriscos " "**.example.com." msgid "condition_HostRegexCondition" msgstr "Expresión regular de servidor" msgid "condition_help_HostRegexCondition" msgstr "" "Igual que los patrones de servidor, pero detecta servidores (nombres de " "dominio) mediante expresiones " "regulares.
Las expresiones regulares pueden ser díficiles de crear (e " "interpretar).
Generalmente se recomienda usar patrones y utilizar " "expresiones regulares para condiciones que no se puedan detectar de ninguna " "otra forma." msgid "condition_HostLevelsCondition" msgstr "Niveles de servidor" msgid "condition_help_HostLevelsCondition" msgstr "" "Detecta la petición únicamente si tiene un determinado nivel de servidor.
" "El nivel de servidor se define como el número de componentes separados " "por punto en el nombre de dominio.
Ejemplo: " "www.example.com tiene 3 niveles, ,mientras que " "internal tiene sólo 1." msgid "condition_IpCondition" msgstr "Literales IP" msgid "condition_help_IpCondition" msgstr "" "Detecta peticiones únicamente por direcciones IP literales y en una " "determinada red especificada en notación CIDR.
Por " "ejemplo, la regla 127.0.0.1/16, detecta todas las direcciones " "IP de tipo 127.0.*.*.
La IP 127.0.0.1 cumple la " "regla, mientras que 127.1.0.0 no la cumple. Nombres como " "localhost nunca cumplirán la regla porque no son " "literales IP." msgid "condition_UrlWildcardCondition" msgstr "Patrones de URL" msgid "condition_help_UrlWildcardCondition" msgstr "" "Detecta patrones en la URL de la petición.
Consulte la sección de " "patrones de servidor para tener una referencia rápida sobre patrones.
" "Tenga presente que para los patrones URL no hay casos especiales (como el de " "subdominios en los patrones de servidor).
Así que " "*://*.example.com/* detecta http://www.example.com/ " "perono detecta http://example.com/." msgid "condition_UrlRegexCondition" msgstr "Expresión regular URL" msgid "condition_help_UrlRegexCondition" msgstr "" "Detecta URL con la potencia de las expresiones " "regulares.
De todas formas,las expresiones regulares son difíciles de " "crear (e interpretar).
Se recomienda utilizar patrones en la mayoría de " "las situaciones y usar sólo las expresiones regulares cuando no funcionen " "otros tipos de condiciones." msgid "condition_KeywordCondition" msgstr "Palabra clave" msgid "condition_help_KeywordCondition" msgstr "" "Detecta palabras clave que aparezcan como subcadenas en la URL de peticiones " "que usen el protocolo HTTP.
Funcionan igual que el patrón " "http://*texto*, donde texto es la palabra clave " ".
Es útil para burlar cortafuegos que bloquean algunas palabras clave en " "la URL, realizando esas peticiones a través de proxy." msgid "condition_FalseCondition" msgstr "(Deshabilitado)" msgid "condition_details_FalseCondition" msgstr "(Condición ignorada al procesar)" msgid "condition_help_FalseCondition" msgstr "" "Puede anular una condición cambiando su tipo a (Deshabilitada). " "Será como si esa condición no existiera.
Esto permite anular condiciones " "temporalmente.
Las condiciones deshabilitadas conservan toda la " "información (patrones) y se pueden habilitar de nuevo cambiando su tipo al " "que tuvieran antes." msgid "condition_TimeCondition" msgstr "Hora actual" msgid "condition_help_TimeCondition" msgstr "" "Detecta si la hora actual está en el intervalo definido por hora " "inicio y hora fin, incluyendo ambas.
La hora local, la de " "inicio y la de fin se calculan en formato de 24-horas (entre 0 y " "23).
El cálculo se realiza en el momento en que se envía la petición." msgid "condition_WeekdayCondition" msgstr "Día de la semana" msgid "condition_help_WeekdayCondition" msgstr "" "Detecta si el día de la semana actual es uno de los seleccionados en " "el detalle de la condición. El día se calcula según la zona horaria " "local.
La petición y su URL se ignoran. El resultado se basa únicamente " "en el día de la semana en que se envía la petición." msgid "condition_alert_fullUrlLimitation" msgstr "" "La detección sobre URL completas no es posible al usar direcciones " "https:// desde la versión 52 de Chrome. Más información..." msgid "condition_alert_fullUrlLimitationLink" msgstr "" "https://github.com/FelisCatus/SwitchyOmega/wiki/Chromium-Full-URL-Limitation" msgid "condition_group_default" msgstr " . " msgid "condition_group_host" msgstr "Servidor" msgid "condition_group_url" msgstr "Url" msgid "condition_group_special" msgstr "Especial" msgid "ruleListFormat_Switchy" msgstr "Switchy" msgid "ruleListFormat_AutoProxy" msgstr "Proxy Automático" msgid "ruleList_usageUrl" msgstr "https://github.com/FelisCatus/SwitchyOmega/wiki/RuleListUsage" msgid "ruleList_error_resultNotEnabled" msgstr "¡ Falta directiva '@with result' !" msgid "ruleList_error_unknownProfile" msgstr "Perfil desconocido: $PROFILE$" msgid "ruleList_error_missingResultProfile" msgstr "Falta nombre del perfil en la línea $LNO$: $SOURCE$" msgid "ruleList_error_invalidRule" msgstr "Regla no válida en la línea $LNO$: $SOURCE$" msgid "ruleList_error_noDefaultRule" msgstr "¡ Falta regla por defecto con condición universal '*' !" msgid "dialog_close" msgstr "Cerrar" msgid "dialog_save" msgstr "Guardar cambios" msgid "dialog_ok" msgstr "OK" msgid "dialog_cancel" msgstr "Cancelar" msgid "inputClear_clear" msgstr "Borrar" msgid "inputClear_restore" msgstr "Deshacer" msgid "options_title" msgstr "Opciones SwitchyOmega" msgid "options_experimental_badge" msgstr "α" msgid "options_navHeader_setting" msgstr "Ajustes" msgid "options_navHeader_profiles" msgstr "Perfiles" msgid "options_navHeader_actions" msgstr "Acciones" msgid "options_tab_ui" msgstr "Interfaz" msgid "options_tab_general" msgstr "General" msgid "options_tab_importExport" msgstr "Importar/Exportar" msgid "options_newProfile" msgstr "Nuevo perfil…" msgid "options_apply" msgstr "Aplicar cambios" msgid "options_discard" msgstr "Descartar cambios" msgid "options_reset" msgstr "Opciones por defecto" msgid "options_group_miscOptions" msgstr "Opciones adicionales" msgid "options_confirmDeletion" msgstr "Confirmar al borrar condición." msgid "options_refreshOnProfileChange" msgstr "Recargar pestaña actual al cambiar perfil." msgid "options_showInspectMenu" msgstr "" "Permitir inspeccionar el proxy utilizado por cada elemento de la página a " "través del menú contextual." msgid "options_addConditionsToBottom" msgstr "" "Agregue nuevas condiciones usando la ventana emergente al final de la lista." msgid "options_group_keyboardShortcut" msgstr "Atajo de teclado" msgid "options_menuShortcutHelp" msgstr "" "Al utilizar el atajo se abrirá el menú emergente. (Predeterminado Alt+May+O)." msgid "options_menuShortcutMore" msgstr "" "Los elementos del menú emergente también son accesibles usando el teclado. " "Pulse ? (o /) en el menú para más información." msgid "options_menuShortcutConfigure" msgstr "Configurar atajo" msgid "options_group_switchOptions" msgstr "Opciones del Conmutador" msgid "options_startupProfile" msgstr "Perfil inicial" msgid "options_startupProfile_none" msgstr "(Perfil actual)" msgid "options_showConditionTypesAdvanced" msgstr "Mostrar tipos de condición avanzados" msgid "options_showConditionTypesAdvancedHelp" msgstr "" "Habilita nuevos tipos de condiciones avanzadas pero más complicadas. En la " "mayoría de las situaciones los tipos básicos son más que suficientes, por lo " "que no se recomienda habilitar los avanzados." msgid "options_quickSwitch" msgstr "Conmutador Rápido" msgid "options_cycledProfiles" msgstr "Perfiles cíclicos" msgid "options_cycledProfilesHelp" msgstr "" "Cuando pulses el icono(o el atajo superior), los siguientes perfiles se " "aplicarán en el orden indicado." msgid "options_cycledProfilesTooFew" msgstr "" "¡Necesitas seleccionar al menos 2 perfiles para habilitar esta función! " "Puedes arrastrarlos desde el cuadro inferior." msgid "options_notCycledProfiles" msgstr "Perfiles no cíclicos" msgid "options_group_proxyChanges" msgstr "Cambios Proxy" msgid "options_revertProxyChanges" msgstr "Deshacer cambios de proxy realizados por otras aplicaciones." msgid "options_group_conflicts" msgstr "Conflictos" msgid "options_conflicts_introduction" msgstr "" "Algunas veces, otras aplicaciones también intentarán controlar la " "configuración del proxy, lo que generará conflictos. Tenga en cuenta que los " "bloqueadores de anuncios y otras extensiones también pueden usar " "configuraciones de proxy. Dichos conflictos no se pueden evitar debido a la " "forma en que funciona el navegador." msgid "options_conflicts_lowerPriority" msgstr "" "Una insignia roja como esta en el icono de SwitchyOmega indica que otra " "aplicación tiene mayor prioridad, por lo que SwitchyOmega no puede controlar " "la configuración. Intente desinstalar SwitchyOmega y reinstalar, lo que " "debería aumentar la prioridad de SwitchyOmega. Si sigue viendo conflictos " "después de la reinstalación, considere eliminar la otra aplicación que causa " "el conflicto." msgid "options_conflicts_higherPriority" msgstr "" "Si SwitchyOmega tiene una prioridad más alta, puede devolver el control a " "otras aplicaciones o configuraciones del sistema seleccionando " "$SYSTEMPROFILE$ en el menú emergente." msgid "options_showExternalProfile" msgstr "" "Mostrar el elemento del menú emergente para importar configuraciones proxy " "de otras aplicaciones." msgid "options_showExternalProfileHelp" msgstr "" "Cuando se selecciona $SYSTEMPROFILE$, puede importar la configuración " "efectiva del proxy de otras aplicaciones seleccionando $EXTERNALPROFILE$ en " "el menú emergente. La configuración se importará como un perfil con el " "nombre que proporcione. Tenga en cuenta que el perfil importado es una " "instantánea y no reflejará ningún cambio desde la aplicación de origen a " "partir de entonces." msgid "options_group_networkRequests" msgstr "Peticiones de red" msgid "options_monitorWebRequests" msgstr "Muestra el número de peticiones web con error en la pestaña actual." msgid "options_monitorWebRequestsHelp" msgstr "" "Aparecerá un marcador amarillo sobre el icono si no pudieron cargarse " "algunos recursos,
y podrá actualizar el perfil a utilizar para ellos " "desde el menú emergente." msgid "options_downloadOptions" msgstr "Opciones de descarga" msgid "options_downloadOptionsHelp" msgstr "" "Configurar la frecuencia de actualización en línea de reglas y scripts PAC." msgid "options_downloadInterval" msgstr "Intervalo de descarga" msgid "options_downloadInterval_15" msgstr "15 minutos" msgid "options_downloadInterval_60" msgstr "1 Hora" msgid "options_downloadInterval_180" msgstr "3 Horas" msgid "options_downloadInterval_360" msgstr "6 Horas" msgid "options_downloadInterval_720" msgstr "12 Horas" msgid "options_downloadInterval_1440" msgstr "a diario" msgid "options_downloadInterval_never" msgstr "Nunca" msgid "options_group_importExportProfile" msgstr "Perfil" msgid "options_exportPacFile" msgstr "Exportar como archivo PAC" msgid "options_exportPacFileHelp" msgstr "" "Exporta el perfil actual como un archivo PAC, para poder utilizarlo en otros " "navegadores." msgid "options_exportProfileHelp" msgstr "" "Para exportar un perfil, utilice la barra de acción de arriba a la derecha " "en la página del perfil." msgid "options_exportLegacyRuleList" msgstr "" "Exporta la lista de reglas utilizando, si es posible, un formato compatible " "con Proxy Switchy!/SwitchyPlus/SwitchySharp." msgid "options_exportLegacyRuleListHelp" msgstr "" "Habilite esta opción si publica listas de reglas para usuarios de esos " "proyectos.
Le agradeceríamos que recomendara a sus contactos actualizar " "a SwitchyOmega para disfrutar de las mejoras." msgid "options_group_importExportSettings" msgstr "Ajustes" msgid "options_makeBackup" msgstr "Crear copia de seguridad" msgid "options_makeBackupHelp" msgstr "" "Haga una copia de seguridad de sus opciones (incluye perfiles y el resto de " "opciones)." msgid "options_restoreLocal" msgstr "Restaurar desde archivo" msgid "options_restoreLocalHelp" msgstr "Restaura las opciones de SwitchyOmega desde un archivo local." msgid "options_restoreOnline" msgstr "Restaurar en línea" msgid "options_restoreOnlinePlaceholder" msgstr "URL del archivo de opciones (p.e. 'http://example.com/switchy.bak')" msgid "options_restoreOnlineSubmit" msgstr "Restaurar" msgid "options_group_syncing" msgstr "Sincronizando (Experimental)" msgid "options_syncEnable" msgstr "Habilitar sincronización" msgid "options_syncEnableForce" msgstr "Descargar desde la sincronización" msgid "options_syncDisable" msgstr "Deshabilitar sincronización" msgid "options_syncReset" msgstr "Borrar copia remota" msgid "options_syncPristineHelp" msgstr "" "Puede sincronizar automáticamente sus ajustes y perfiles en todos los " "dispositivos donde utilice el navegador Chrome." msgid "options_syncSyncAlert" msgstr "Sus opciones se sincronizan automáticamente en todos sus equipos." msgid "options_syncSyncHelp" msgstr "" "Tenga en cuenta que debe iniciar sesión en Chrome en cada uno de sus " "dispositivos (incluido este) para que la sincronización funcione realmente. " "
Puede verificar esta sección en otros dispositivos para asegurarse de " "que esté funcionando." msgid "options_syncConflictAlert" msgstr "" "Usted ha cargado una copia de sus opciones en otro dispositivo mediante la " "sincronización." msgid "options_syncConflictHelp" msgstr "" "Puede descargar la copia remota a su dispositivo si lo desea.
Sin " "embargo, al hacerlo, sobrescribirá sus configuraciones y perfiles " "existentes en este dispositivo." msgid "options_syncUnsupportedHelp" msgstr "" "Las opciones de sincronización no son soportadas por su plataforma o " "navegador. Por ahora, solo el navegador Chrome en el escritorio las soporta." msgid "options_profileSyncDisabled" msgstr "La sincronización esta inhabilitada para este perfil." msgid "options_profileSyncDisabled_quotaPerItem" msgstr "" "La sincronización esta inhabilitada para este perfil por usar mucho espacio " "de almacenamiento." msgid "options_profileTabPrefix" msgstr "Perfil :: " msgid "options_renameProfile" msgstr "Renombrar" msgid "options_deleteProfile" msgstr "Borrar" msgid "options_profileExportRuleList" msgstr "Publicar lista de reglas" msgid "options_profileExportRuleListHelp" msgstr "Exportar Reglas del Conmutador para publicar en formato texto." msgid "options_profileExportPac" msgstr "Exportar PAC" msgid "options_profileUnsupported" msgstr "¡Tipo de perfil no soportado $TYPE$!" msgid "options_profileUnsupportedHelp" msgstr "" "Las opciones pueden haber fallado, o de una versión mas reciente de este " "programa." msgid "options_profileEditSource" msgstr "Editar código fuente" msgid "options_profileEditSourceHelp" msgstr "Mostrar ayuda sobre el formato del código fuente" msgid "options_profileEditSourceHelpUrl" msgstr "" "https://github.com/FelisCatus/SwitchyOmega/wiki/SwitchyOmega-conditions-" "format#result-profile" msgid "options_group_proxyServers" msgstr "Servidores proxy" msgid "options_proxy_scheme" msgstr "Esquema" msgid "options_proxy_protocol" msgstr "Protocolo" msgid "options_proxy_server" msgstr "Servidor" msgid "options_proxy_port" msgstr "Puerto" msgid "options_proxy_auth" msgstr "Autenticación" msgid "options_proxy_authNotSupported" msgstr "" "¡Tu navegador NO soporta la autenticación proxy $PROTOCOLDISP$! Por favor no " "reportes esta incidencia a SwitchyOmega. Ponte en contacto con el soporte " "para tu navegador." msgid "options_proxy_authAllWarningPac" msgstr "" "Advertencia: El nombre usuario/contraseña pueden enviarse a servidores " "inesperados devueltos por el script PAC." msgid "options_proxy_authAllWarningPacUrl" msgstr "" "Asegúrese de confiar en el script proporcionado a través de la URL anterior " "antes de ingresar credenciales confidenciales." msgid "options_proxy_authAllWarningPacScript" msgstr "" "Asegúrese de confiar en el script de a continuación antes de proporcionar " "credenciales confidenciales." msgid "options_proxy_authReferencedWarning" msgstr "" "Adicionalmente, el uso de este perfil en otros perfiles (p. ej. Perfil " "Conmutador) puede hacer que el nombre de usuario/contraseña se envíe a los " "servidores proxy configurados en otros perfiles." msgid "options_scheme_default" msgstr "(por defecto)" msgid "options_protocol_direct" msgstr "DIRECTO" msgid "options_protocol_useDefault" msgstr "(usa por defecto)" msgid "options_proxy_single" msgstr "Use el proxy anterior para todos los protocolos." msgid "options_proxy_expand" msgstr "Mostrar avanzado" msgid "options_group_bypassList" msgstr "Lista de omisión" msgid "options_bypassListHelp" msgstr "" "Servidores para los cuales no desea usar ningún proxy: (Un servidor en cada " "línea)" msgid "options_bypassListHelpLinkText" msgstr "(Comodines y más disponible ...)" msgid "options_group_pacUrl" msgstr "URL PAC" msgid "options_pacUrlHelp" msgstr "" "El script PAC será actualizado desde esta URL. Si se deja en blanco, el " "siguiente script se usará directamente en su lugar." msgid "options_pacUrlFile" msgstr "" "Archivos con perfiles PAC: las URL solamente se pueden aplicar directamente. " "No se pueden usar como perfiles de resultados porque no se puede acceder a " "los archivos locales debido a una limitación del navegador." msgid "options_pacUrlFileDisabled" msgstr "" "Por lo tanto, no puedes usar un archivo PAC local para este perfil. Puedes " "crear un nuevo perfil PAC para eso si realmente quieres eso." msgid "options_group_pacScript" msgstr "Script PAC" msgid "options_pacScriptLastUpdate" msgstr "Script PAC descargado el $TIME$:" msgid "options_pacScriptObsolete" msgstr "" "Script PAC obsoleto debido a cambio de URL. Presiona el botón de descarga de " "arriba para actualizar." msgid "options_group_virtualProfile" msgstr "Perfil Virtual" msgid "options_virtualProfileTarget" msgstr "Objetivo" msgid "options_virtualProfileTargetHelp" msgstr "" "Cuando este perfil se aplique, actuará exactamente igual que el perfil " "seleccionado abajo." msgid "options_group_virtualProfileReplace" msgstr "Migrar a Perfil Virtual" msgid "options_virtualProfileReplace" msgstr "Reemplazar perfil objetivo" msgid "options_virtualProfileReplaceHelp" msgstr "" "Puedes migrar las opciones existentes para usar este perfil virtual en vez " "de $PROFILE$. Haciendo esto actualizarás todas las reglas existentes " "concernientes a $PROFILE$ y apuntarán a este perfil virtual, para que su " "perfil de resultados pueda ser controlado aquí." msgid "options_group_ruleListConfig" msgstr "Configuración de la Lista de Reglas" msgid "options_ruleListFormat" msgstr "Formato de la Lista de Reglas" msgid "options_group_ruleListResult" msgstr "Perfiles de resultados de la lista de reglas" msgid "options_ruleListMatchProfile" msgstr "Emparejar perfil" msgid "options_ruleListDefaultProfile" msgstr "Perfil por defecto" msgid "options_group_ruleListUrl" msgstr "URL de la lista de reglas" msgid "options_ruleListUrlHelp" msgstr "" "Esta lista de reglas será actualizada desde esta URL. Si se deja en blanco, " "el siguiente texto será interpretado en su lugar." msgid "options_group_ruleListText" msgstr "Texto de la Lista de Reglas" msgid "options_ruleListLastUpdate" msgstr "Lista de reglas descargada el $TIME$:" msgid "options_ruleListObsolete" msgstr "" "La lista de reglas está obsoleta debido a un cambio de URL. Presiona el " "botón descargar de arriba para actualizar." msgid "options_group_switchRules" msgstr "Reglas de conmutación" msgid "options_sort" msgstr "Ordenar" msgid "options_conditionType" msgstr "Tipo de Condición" msgid "options_showConditionTypeHelp" msgstr "Mostrar ayuda" msgid "options_conditionDetails" msgstr "Detalles de la Condición" msgid "options_resultProfile" msgstr "Perfil" msgid "options_conditionActions" msgstr "Acciones" msgid "options_addCondition" msgstr "Añadir condición" msgid "options_cloneRule" msgstr "Clonar" msgid "options_ruleNote" msgstr "Nota" msgid "options_switchAttachedProfileInCondition" msgstr "Reglas de la lista de reglas" msgid "options_switchAttachedProfileInConditionDetails" msgstr "" "(Cualquier solicitud que coincida con la lista de reglas a continuación)" msgid "options_switchAttachedProfileInConditionDisabled" msgstr "(Las reglas de la lista de reglas están DESHABILITADAS)" msgid "options_switchDefaultProfile" msgstr "Por defecto" msgid "options_hostLevelsBetween" msgstr "≤ niveles de host ≤" msgid "options_hourBetween" msgstr "≤ hora actual ≤" msgid "options_weekDayShort_0" msgstr "Lu" msgid "options_weekDayShort_1" msgstr "Ma" msgid "options_weekDayShort_2" msgstr "Mi" msgid "options_weekDayShort_3" msgstr "Ju" msgid "options_weekDayShort_4" msgstr "Vi" msgid "options_weekDayShort_5" msgstr "Sa" msgid "options_weekDayShort_6" msgstr "Do" msgid "options_group_conditionHelp" msgstr "Acerca de Tipos de Condición" msgid "options_group_attachProfile" msgstr "Importar lista de reglas en línea" msgid "options_attachProfile" msgstr "Añadir una lista de reglas" msgid "options_attachProfileHelp" msgstr "" "Puedes reusar una colección de condiciones en línea publicada por otros al " "añadirla a tu lista de reglas." msgid "options_modalHeader_welcome" msgstr "Bienvenido/a a SwitchyOmega" msgid "options_welcomeNormal" msgstr "Has instalado exitosamente SwitchyOmega, el proxy switcher definitivo." msgid "options_welcomeNormalGuide" msgstr "" "Indica a SwitchyOmega acerca de tus proxies a través de la pagina de " "opciones. Vamos a ver cómo." msgid "options_welcomeUpgrade" msgstr "" "Has actualizado exitosamente a SwitchyOmega. No te asustes, tus opciones " "existentes han sido completamente preservadas." msgid "options_welcomeUpgradeGuide" msgstr "Ahora veamos una guía rápida de la nueva página de opciones." msgid "options_guideNext" msgstr "Siguiente" msgid "options_guideDone" msgstr "Hecho" msgid "options_guideSkip" msgstr "Omitir guía" msgid "options_modalHeader_applyOptions" msgstr "Aplicar Opciones" msgid "options_optionsNotSaved" msgstr "" "¡Tus modificaciones de las opciones no han sido guardadas y se perderán si " "continúas!" msgid "options_applyOptionsRequired" msgstr "Tus cambios de las opciones deben aplicarse antes de proceder." msgid "options_applyOptionsConfirm" msgstr "¿Quieres guardar y aplicar las opciones?" msgid "options_modalHeader_renameProfile" msgstr "Renombrar Perfil" msgid "options_renameProfileName" msgstr "Nuevo nombre de perfil" msgid "options_profileNameConflict" msgstr "Ya existe un perfil con este nombre." msgid "options_profileNameReserved" msgstr "" "Los nombres de perfil que empiezan con doble guión bajo están reservados." msgid "options_profileNameHidden" msgstr "" "Los perfiles con nombres que empiecen por guión bajo se ocultarán en el menú " "emergente. Sin embargo, pueden seguirse utilizando en sitios como los " "resultados del perfil conmutador." msgid "options_modalHeader_replaceProfile" msgstr "Reemplazar Perfil" msgid "options_replaceProfile" msgstr "Reemplazar perfil" msgid "options_replaceProfileConfirm" msgstr "¿De verdad deseas reemplazar $FromProfile$ con $ToProfile$?" msgid "options_replaceProfileHelp" msgstr "" "Si continúas, todas las reglas apuntando a $FromProfile$ se actualizarán " "para usar $ToProfile$ en su lugar. Otras opciones, como el perfil de inicio " "y el Conmutador Rápido también se modificarán según corresponda. Sin " "embargo, los dos perfiles en sí NO serán modificados o eliminados." msgid "options_replaceProfileSuccess" msgstr "Opciones actualizadas." msgid "options_modalHeader_deleteProfile" msgstr "Eliminar Perfil" msgid "options_deleteProfileConfirm" msgstr "¿De verdad quieres borrar el siguiente perfil?" msgid "options_modalHeader_cannotDeleteProfile" msgstr "Incapaz de Borrar el Perfil" msgid "options_profileReferredBy" msgstr "" "Este perfil no puede ser borrado porque está referenciado por los siguientes " "perfiles:" msgid "options_modifyReferringProfiles" msgstr "" "Debes modificar estos perfiles y hacer que dejen de referenciar este perfil " "antes de que puedas borrarlo." msgid "options_profileNameEmpty" msgstr "El nombre del perfil no debe estar vacío." msgid "popup_title" msgstr "Ventana emergente de SwitchyOmega" msgid "options_modalHeader_proxyAuth" msgstr "Autenticación Proxy" msgid "options_proxyAuthUsername" msgstr "Nombre de usuario" msgid "options_proxyAuthPassword" msgstr "Contraseña" msgid "options_proxyAuthShowPassword" msgstr "Mostrar contraseña" msgid "options_proxyAuthHidePassword" msgstr "Ocultar contraseña" msgid "options_proxyAuthNone" msgstr "Sin Autenticación" msgid "options_modalHeader_deleteRule" msgstr "Eliminar Regla" msgid "options_deleteRuleConfirm" msgstr "¿De verdad quieres borrar la siguiente regla?" msgid "options_deleteRule" msgstr "Borrar" msgid "options_modalHeader_resetRules" msgstr "Reestablecer reglas" msgid "options_resetRulesConfirm" msgstr "" "¿Estás seguro/a de establecer el perfil resultante de TODAS las reglas en el " "siguiente perfil?" msgid "options_resetRules" msgstr "Reestablecer reglas" msgid "options_resetRules_help" msgstr "Establecer perfil para todas las reglas" msgid "options_modalHeader_deleteAttached" msgstr "Eliminar Lista de Reglas" msgid "options_deleteAttachedConfirm" msgstr "" "¿Estás seguro/a de querer eliminar la lista de reglas del perfil actual?" msgid "options_ruleListLineCount" msgstr "$COUNT$ linea(s) de reglas" msgid "options_deleteAttached" msgstr "Eliminar lista de reglas" msgid "options_modalHeader_newProfile" msgstr "Nuevo Perfil" msgid "options_newProfileName" msgstr "Nombre del perfil" msgid "options_profileType" msgstr "Por favor selecciona el tipo de perfil:" msgid "options_profileTypeFixedProfile" msgstr "Perfil de Proxy" msgid "options_profileDescFixedProfile" msgstr "Tunelización del tráfico a través de servidores proxy." msgid "options_profileTypePacProfile" msgstr "Perfil PAC" msgid "options_profileDescPacProfile" msgstr "Elegir proxies usando un script PAC en línea/local." msgid "options_profileDescMorePacProfile" msgstr "" "Solo necesitarás esto si tienes un script PAC o una URL hacia uno. No " "intentes crear uno a menos que tengas conocimiento sobre PAC." msgid "options_profileTypeSwitchProfile" msgstr "Perfil Conmutador" msgid "options_profileDescSwitchProfile" msgstr "" "Aplicando distintos perfiles automáticamente en diversas condiciones tales " "como dominios o patrones.\n" " También puedes importar reglas publicadas en línea para un cambio más " "fácil. (Reemplaza el modo AutoSwitch + Lista de Reglas.)" msgid "options_profileTypeRuleListProfile" msgstr "Perfil de Lista de Reglas" msgid "options_profileDescRuleListProfile" msgstr "Reusando una colección en línea de condiciones publicadas por otros." msgid "options_profileTypeVirtualProfile" msgstr "Perfil Virtual" msgid "options_profileDescVirtualProfile" msgstr "" "Un perfil virtual puede actuar como cualquier otro perfil bajo demanda. " "Funciona bien con SwitchProfile, permitiondo cambiar el resultado de " "múltiples condiciones con un solo click." msgid "options_createProfile" msgstr "Crear" msgid "options_modalHeader_resetOptions" msgstr "Reestablecer Opciones" msgid "options_resetOptionsConfirm" msgstr "" "¿Realmente quieres reestablecer las opciones? ¡Todos los perfiles y " "configuración se PERDERÁN!" msgid "options_formInvalid" msgstr "Por favor corrige los errores de esta página." msgid "options_profileNotFound" msgstr "¡El perfil $PROFILE$ no existe! Las opciones pueden estar corruptas." msgid "options_resetSuccess" msgstr "Opciones reestablecidas." msgid "options_saveSuccess" msgstr "Opciones guardadas." msgid "options_importSuccess" msgstr "Opciones importadas." msgid "options_importFormatError" msgstr "¡Archivo de copia de seguridad no válido!" msgid "options_importDownloadError" msgstr "¡Error descargando el archivo de copia de seguridad!" msgid "options_profileDownloadSuccess" msgstr "Perfil actualizado existosamente." msgid "options_profileDownloadError" msgstr "¡Error descargando los datos del perfil!" msgid "options_profileDownloadError_NetworkError" msgstr "Un error de red ha ocurrido al actualizar." msgid "options_profileDownloadError_HttpError" msgstr "Un error HTTP ($STATUS$) ha ocurrido al actualizar." msgid "options_profileDownloadError_HttpNotFoundError" msgstr "" "La URL del Perfil no ha sido encontrada en el servidor. Por favor vuelve a " "comprobarla." msgid "options_profileDownloadError_HttpServerError" msgstr "El servidor remoto ha respondido con error ($STATUS$) al actualizar." msgid "options_profileDownloadError_ContentTypeRejectedError" msgstr "" "¡Los datos descargados son inválidos! Puedes abrir la URL del Perfil en tu " "navegador para inspeccionarla." msgid "options_downloadProfileNow" msgstr "Descargar el Perfil Ahora" msgid "options_guide_fixedProfileStep" msgstr "" "Un Perfil Proxy contiene ajustes como la ip y puerto del servidor " "para proxy.
Los perfiles son las unidades basicas de configuración en " "SwitchyOmega.
Hemos creado un perfil de ejemplo para ti. Intenta abrirlo." msgid "options_guide_fixedServersStep" msgstr "" "Puedes completar tu servidor proxy y puerto como desees.
SwitchyOmega " "no viene con ningún servidor proxy.
Por favor consulta con tu " "proveedor de red o con el manual de software de tu proxy si no sabes lo que " "se debe llenar aquí." msgid "options_guide_autoSwitchProfileStep" msgstr "" "Puedes decirle a SwitchyOmega que cambie entre proxies automáticamente a " "través del poderoso Perfil Conmutador.
Sin embargo, sus " "características no pueden ser cubiertas con esta breve guía.
Puedes abrir " "este perfil para desbloquear su poder más tarde." msgid "options_guide_addMoreProfilesStep" msgstr "" "¿Necesitas más perfiles? Siempre puedes añadir más perfiles de tipo " "Proxy, Conmutador y otros
para todas tus necesidades de configuración " "con proxies.
¡Disfruta configurando tus proxies!" msgid "options_guide_conditionStep" msgstr "" "SwitchyOmega puede aplicar distintos perfiles para peticiones basadas en " "condiciones.
Por ejemplo, la condición Comodín host " "permite establecer el perfil para todas las URL en un domino." msgid "options_guide_conditionTypeStep" msgstr "" "Puedes usar varios tipos de condición para coincidir con el host o la URL " "completa.
Haz clic en el símbolo de interrogación para abrir la " "referencia de tipo." msgid "options_guide_conditionProfileStep" msgstr "" "SwitchyOmega aplica el perfil aquí seleccionado a cualquier petición que " "coincida con la condición.
El perfil especial \"[Por defecto]\"" " hará que la petición se envíe sin ningún proxy." msgid "options_guide_switchDefaultStep" msgstr "" "Si ninguna condición se aplica a alguna solicitud, el perfil \"Por defecto\" " "será usado.
Las condiciones siempre serán consideradas desde arriba " "hacia abajo en orden.
Puedes cambiar el order arrastrando el icono " "ordenar." msgid "options_guide_applySwitchProfileStep" msgstr "" "Cuando termines de configurar el perfil conmutador, no te olvides de " "cambiar a el en el menú emergente.
El icono mostrará el perfil " "resultante final aplicado a la pestaña actual.
Pasando el " "cursor sobre el icono revelará información detallada." msgid "popup_externalProfile" msgstr "(Perfil Externo)" msgid "popup_externalProfileName" msgstr "nombre del perfil" msgid "popup_proxyNotControllable_app" msgstr "" "La configuración del proxy está controlada por otra(s) aplicación(es) o " "extensión(es). Por favor deshabilita o desinstala las aplicaciones o " "extensiones en conflicto." msgid "popup_proxyNotControllable_policy" msgstr "" "La configuración del proxy está anulada por las políticas. Por favor, " "póngase en contacto con su administrador." msgid "popup_proxyNotControllable_unknown" msgstr "" "La configuración del proxy no puede ser controlada. Por favor, compruebe su " "sistema y la configuración del navegador." msgid "popup_proxyNotControllable_disabled" msgstr "" "La configuración del proxy está deshabilitada por solicitud explícita de " "otra(s) aplicación(es) o extensión(es)." msgid "popup_proxyNotControllable_upgrade" msgstr "" "Las configuraciones de proxy ahora están controladas por una versión más " "reciente de SwitchyOmega." msgid "popup_proxyNotControllableDetails" msgstr "" "No puedes cambiar los perfiles con SwitchyOmega a menos que soluciones el " "problema anterior." msgid "popup_proxyNotControllableDetails_upgrade" msgstr "" "No puede habilitar dos (o más) versiones de SwitchyOmega al mismo tiempo. " "Por favor deshabilita una de ellas." msgid "popup_proxyNotControllableManage" msgstr "Administrar extensiones" msgid "popup_addConditionTo" msgstr "Añadir condición a" msgid "popup_addCondition" msgstr "Añadir condición" msgid "popup_showOptions" msgstr "Opciones" msgid "popup_reportIssues" msgstr "Reportar problemas" msgid "popup_errorLog" msgstr "Guardar registro de errores" msgid "popup_requestErrorCount" msgstr "$COUNT$ recursos fallidos" msgid "popup_requestErrorHeading" msgstr "Recursos que no se pudieron cargar" msgid "popup_requestErrorWarning" msgstr "" "Algunos recursos no se pudieron cargar debido a problemas con tu red, " "servidor proxy o la página web." msgid "popup_requestErrorWarningHelp" msgstr "" "SwitchyOmega es solo el informador de estos problemas, no la causa de ellos." msgid "popup_requestErrorAddCondition" msgstr "" "Puede revisar los siguientes dominios y usar un proxy cuando sea apropiado." msgid "popup_requestErrorCannotAddCondition" msgstr "" "Puedes agregar condiciones de conmutación solo cuando se usa un Perfil " "Conmutador." msgid "popup_configureMonitorWebRequests" msgstr "Configurar el Monitor de Red" msgid "options_resultProfileForSelectedDomains" msgstr "Usar este perfil para todos los dominios seleccionados" msgid "options_pac_profile_unsupported_moz" msgstr "" "¡Los Perfiles PAC NO funcionan en Mozilla Firefox debido a limitaciones " "técnicas!" msgid "popup_issueTemplate" msgstr "" "\n" "\n" "\n" "\n" "SwitchyOmega $projectVersion$\n" "$userAgent$" msgid "browserAction_profileDetails_PacProfile" msgstr "(Script PAC)" msgid "browserAction_profileDetails_SystemProfile" msgstr "(controllado por otras extensiones o entorno)" msgid "browserAction_profileDetails_DirectProfile" msgstr "(sin usar ningún proxy)" msgid "browserAction_profileDetails_SwitchProfile" msgstr "(cambio basado en condiciones)" msgid "browserAction_profileDetails_RuleListProfile" msgstr "(cambio basado en la lista de reglas)" msgid "browserAction_titleNormal" msgstr "SwitchyOmega:: $PROFILE$" msgid "browserAction_titleWithResult" msgstr "" "SwitchyOmega:: $1:PROFILE$\n" "$3:DETAILS$" msgid "browserAction_titleNewerOptions" msgstr "" "ERROR: Una nueva versión de SwitchOmega es necesaria para cargar las " "opciones guardadas." msgid "browserAction_titleOptionError" msgstr "" "ERROR: Las opciones guardadas están corrompidas. Haz clic aquí para " "REINICIAR LAS OPCIONES." msgid "browserAction_titleDownloadFail" msgstr "" "Advertencia: Error al descargar los scripts PAC y/o las listas de reglas." msgid "browserAction_titleExternalProxy" msgstr "" "Nota: La configuración del proxy está actualmente controlada por otra(s) " "aplicación(es)." msgid "browserAction_titleInspect" msgstr "[Inspeccionar] $URL$" msgid "browserAction_defaultRuleDetails" msgstr "(por defecto)" msgid "browserAction_directResult" msgstr "DIRECTO" msgid "browserAction_attachedPrefix" msgstr "(RL) " msgid "browserAction_tempRulePrefix" msgstr "(TEMP) " msgid "contextMenu_inspectPage" msgstr "Inspeccionar proxy usado en esta página" msgid "contextMenu_inspectFrame" msgstr "Inspeccionar proxy utilizado para este Frame" msgid "contextMenu_inspectLink" msgstr "Inspeccionar proxy utilizado si este Enlace es abierto" msgid "contextMenu_inspectElement" msgstr "Inspeccionar proxy utilizado para este Elemento" msgid "contextMenu_enableQuickSwitch" msgstr "Habilitar Conmutador Rápido" msgid "about_title" msgstr "Acerca de" msgid "about_app_description" msgstr "Una herramienta de configuración de proxy" msgid "about_version" msgstr "Versión $VERSION$" msgid "about_experimental_warning_moz" msgstr "" "¡El soporte de Mozilla Firefox es altamente experimental! Si tienes " "problemas, informa utilizando los botones a continuación." msgid "about_disclaimer_networkService" msgstr "SwitchyOmega no proporciona proxies, VPN u otros servicios de red." msgid "about_disclaimer_privacy" msgstr "" "SwitchyOmega no te rastrea ni inserta anuncios en páginas web. Por favor ve " "nuestra " "política de privacidad." msgid "about_help" msgstr "" "¿Otras preguntas? ¿Necesitas ayuda con el uso de SwitchyOmega? Por favor ve " "nuestro FAQ." msgid "about_copyright" msgstr "" "Copyright 2012-2017 Los autores de SwitchyOmega. Todos los derechos " "reservados." msgid "about_credits" msgstr "" "SwitchyOmega es posible gracias al proyecto de código abierto SwitchyOmega y otro " "software de código abierto." msgid "about_license" msgstr "" "SwitchyOmega es " "software libre licenciado bajo GNU General Public License Versión 3 o posterior." ================================================ FILE: omega-locales/es_AR/LC_MESSAGES/omega-web.po ================================================ msgid "" msgstr "" "Project-Id-Version: SwitchyOmega 2.3.3\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2015-02-13 10:29+0000\n" "PO-Revision-Date: 2018-11-14 05:08+0000\n" "Last-Translator: Rodrigo Bernardi \n" "Language-Team: Spanish (Argentina) \n" "Language: es_AR\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Generator: Weblate 3.3-dev\n" msgid "appNameShort" msgstr "SwitchyOmega" msgid "manifest_app_name" msgstr "Proxy SwitchyOmega" msgid "manifest_app_description" msgstr "Administra e intercambia entre múltiples proxys rápida y fácilmente." msgid "manifest_icon_default_title" msgstr "Cargando…" msgid "upgrade_profile_auto" msgstr "Intercambio automático" msgid "profile_direct" msgstr "[Directo]" msgid "profile_system" msgstr "[Proxy del sistema]" msgid "condition_HostWildcardCondition" msgstr "Host comodín" msgid "condition_help_HostWildcardCondition" msgstr "" "Coincide con hosts (nombres de dominio) por comodines.
El asterisco " "* es comodín para cero o más caracteres.
El signo de " "interrogación ? lo es para exactamente un carácter.

" "Ten en cuenta que las reglas que comienzan con *. son " "especialmente tratadas solo en las condiciones de comodines de " "Host.
Ejemplo: *.example.com coincidirá www.ejemplo.com Y " "ejemplo.com por igual.
Para coincidir subdominios solamente, " "usa dos asteriscos como **.ejemplo.com." msgid "condition_HostRegexCondition" msgstr "Host regex" msgid "condition_help_HostRegexCondition" msgstr "" "Como la condición de comodín de Host, pero coincide hosts (nombres de " "dominio) por " "expresión regular.
Las expresiones regulares pueden ser difíciles de " "construir (y leer).
Es recomendado usar comodines para la mayoría de los " "casos y solo usar expresiones regulares para las condiciones que no se " "pueden expresar por ningún otro tipo de condición." msgid "condition_HostLevelsCondition" msgstr "Niveles de Host" msgid "condition_help_HostLevelsCondition" msgstr "" "Encuentra una coincidencia si y sólo si el nivel del host está dentro del " "rango.
El nivel de host se define como el número de porciones " "separadas por puntos en el nombre de dominio del host.
Ejemplo: " "www.ejemplo.com tiene un nivel 3 de host, mientras que " "interno es un host de nivel 1." msgid "condition_IpCondition" msgstr "IP Literals" msgid "condition_help_IpCondition" msgstr "" "Matches the request if and only if the host is a literal IP address and" " in the subnet as specified by " "CIDR notation.
For example, given the rule 127.0.0.1/16, " "it matches all IP addresses like 127.0.*.*.
" "So 127.0.0.1 matches while 127.1.0.0 does not. " "Host names like localhost will never match because they are " "not IP literals." msgid "condition_UrlWildcardCondition" msgstr "Comodín de URL" msgid "condition_help_UrlWildcardCondition" msgstr "" "Matches URLs of the request by wildcard.
See the Host wildcard section " "above for a quick wildcard reference.
Note that URL wildcards are not " "specially treated (no subdomain magic as in Host wildcard).
So *://" "*.example.com/* matches http://www.example.com/ but does not " "match http://example.com/." msgid "condition_UrlRegexCondition" msgstr "Expresión regular de URL" msgid "condition_help_UrlRegexCondition" msgstr "" "Matches URL by extremely powerful regular expression.
However, regular " "expressions can be hard to construct (and read).
It is recommended to use " "wildcards for most cases and only use regex for conditions that cannot be " "achieved by any other condition type." msgid "condition_KeywordCondition" msgstr "Palabra clave" msgid "condition_help_KeywordCondition" msgstr "" "A keyword condition matches if the URL protocol is HTTP, and the pattern is " "an exact sub-string of the URL.
It behaves like the URL wildcard pattern " "http://*pattern*, where pattern is the keyword " "pattern.
Keyword conditions are useful if you want to bypass a firewall " "blocking some keywords in the URL, by requesting such URLs through a proxy." msgid "condition_FalseCondition" msgstr "(Deshabilitado)" msgid "condition_details_FalseCondition" msgstr "(Condición ignorada cuando se haya coincidencia)" msgid "condition_help_FalseCondition" msgstr "" "You can disable a condition by setting its type to (Disabled). " "A Disabled condition act as if it does not exist.
This feature can be " "used to disable conditions temporarily.
Disabled conditions still hold " "the previous information (like patterns) and can be re-enabled by setting " "the condition type back to the previous type." msgid "condition_TimeCondition" msgstr "Tiempo Actual" msgid "condition_help_TimeCondition" msgstr "" "Matches if the current local time is in the range defined by " "starting hour and ending hour, both inclusive.
" "Local time, starting hour and ending hour are all calculated in " "24-hour format (from 0 to 23).
" "The calculation happens roughly at the moment when the request is sent." msgid "condition_WeekdayCondition" msgstr "Day of the Week" msgid "condition_help_WeekdayCondition" msgstr "" "Matches if the current day of week is selected in condition details. " "Day is calculated according to local timezone.
" "The request and its URL don't matter to this condition. " "The result is solely based on the day of the week when the request is sent." msgid "condition_alert_fullUrlLimitation" msgstr "" "Full URL matching is no longer possible for https:// " "URLs as of Chrome 52. " "" "Learn more..." msgid "condition_alert_fullUrlLimitationLink" msgstr "https://github.com/FelisCatus/SwitchyOmega/wiki/Chromium-Full-URL-Limitation" msgid "condition_group_default" msgstr " " msgid "condition_group_host" msgstr "Host" msgid "condition_group_url" msgstr "Url" msgid "condition_group_special" msgstr "Especial" msgid "ruleListFormat_Switchy" msgstr "Switchy" msgid "ruleListFormat_AutoProxy" msgstr "Proxy Automático" msgid "ruleList_usageUrl" msgstr "https://github.com/FelisCatus/SwitchyOmega/wiki/RuleListUsage" msgid "ruleList_error_resultNotEnabled" msgstr "¡Falta la directiva '@with result'!" msgid "ruleList_error_unknownProfile" msgstr "Perfil desconocido: $PROFILE$" msgid "ruleList_error_missingResultProfile" msgstr "Missing result profile name at Line $LNO$: $SOURCE$" msgid "ruleList_error_invalidRule" msgstr "Invalid rule at Line $LNO$: $SOURCE$" msgid "ruleList_error_noDefaultRule" msgstr "Missing default rule with catch-all '*' condition!" msgid "dialog_close" msgstr "Cerrar" msgid "dialog_save" msgstr "Guardar cambios" msgid "dialog_ok" msgstr "OK" msgid "dialog_cancel" msgstr "Cancelar" msgid "inputClear_clear" msgstr "Borrar" msgid "inputClear_restore" msgstr "Restaurar" msgid "options_title" msgstr "Opciones SwitchyOmega" msgid "options_experimental_badge" msgstr "α" msgid "options_navHeader_setting" msgstr "Configuraciones" msgid "options_navHeader_profiles" msgstr "Perfiles" msgid "options_navHeader_actions" msgstr "Acciones" msgid "options_tab_ui" msgstr "Interface" msgid "options_tab_general" msgstr "General" msgid "options_tab_importExport" msgstr "Importar/Exportar" msgid "options_newProfile" msgstr "Nuevo perfil…" msgid "options_apply" msgstr "Aplicar cambios" msgid "options_discard" msgstr "Descartar cambios" msgid "options_reset" msgstr "Reiniciar las opciones" msgid "options_group_miscOptions" msgstr "Opciones misceláneas" msgid "options_confirmDeletion" msgstr "Confirm on condition deletion." msgid "options_refreshOnProfileChange" msgstr "Refresh current tab on profile change." msgid "options_showInspectMenu" msgstr "Allow inspecting proxy used for page elements via context menu." msgid "options_addConditionsToBottom" msgstr "Put new conditions added using the popup to the bottom of the list." msgid "options_group_keyboardShortcut" msgstr "Keyboard Shortcut" msgid "options_menuShortcutHelp" msgstr "" "Pressing the shortcut will open the switch popup menu. (Defaults to Alt+Shift" "+O)." msgid "options_menuShortcutMore" msgstr "" "The items in the popup menu can also be accessed using the keyboard. Press ? " "(or /) in the menu to learn more." msgid "options_menuShortcutConfigure" msgstr "Configure shortcut" msgid "options_group_switchOptions" msgstr "Switch Options" msgid "options_startupProfile" msgstr "Startup Profile" msgid "options_startupProfile_none" msgstr "(Current profile)" msgid "options_showConditionTypesAdvanced" msgstr "Show advanced condition types" msgid "options_showConditionTypesAdvancedHelp" msgstr "" "Desbloquea nuevos tipos complicados pero avanzados de condiciones 'switch'. " "Para la mayoría de los casos, los tipos básicos de condición deberían ser " "suficientes; así que no se recomienda usar esta opción." msgid "options_quickSwitch" msgstr "Quick Switch" msgid "options_cycledProfiles" msgstr "Cycled Profiles" msgid "options_cycledProfilesHelp" msgstr "" "When you click on the icon (or use the shortcut above), the following " "profiles will be applied in their order." msgid "options_cycledProfilesTooFew" msgstr "" "You need to select at least 2 profiles to enable this function! You can drag " "them from the box below." msgid "options_notCycledProfiles" msgstr "Not Cycled Profiles" msgid "options_group_proxyChanges" msgstr "Proxy Changes" msgid "options_revertProxyChanges" msgstr "Revert proxy changes done by other apps." msgid "options_group_conflicts" msgstr "Conflicts" msgid "options_conflicts_introduction" msgstr "" "Sometimes, other apps will also try to control the proxy settings, resulting " "in conflicts. Note that ad blockers and other extensions may also use proxy " "settings under the hood. Such conflicts cannot be avoided due to how the " "browser works." msgid "options_conflicts_lowerPriority" msgstr "" "A red badge like this on the SwitchyOmega icon indicates that another app has " "higher priority so SwitchyOmega cannot control the settings. Please try to " "uninstall SwitchyOmega and reinstall, which should raise SwitchyOmega's " "priority. If you still see conflicts after reinstallation, please consider " "removing the other app causing the conflict." msgid "options_conflicts_higherPriority" msgstr "" "If SwitchyOmega has higher priority, you can give the control back to other " "apps or system settings by selecting $SYSTEMPROFILE$ in the popup menu." msgid "options_showExternalProfile" msgstr "Show popup menu item to import proxy settings from other apps." msgid "options_showExternalProfileHelp" msgstr "" "When $SYSTEMPROFILE$ is selected, you can import the effective proxy settings " "from other apps by selecting $EXTERNALPROFILE$ on the popup menu. " "The settings will be imported as a profile using the name you provide. " "Please note that the imported profile is a snapshot and will not reflect " "any changes from the source app thereafter." msgid "options_group_networkRequests" msgstr "Network Requests" msgid "options_monitorWebRequests" msgstr "Show count of failed web requests for resources in the current tab." msgid "options_monitorWebRequestsHelp" msgstr "" "A yellow badge will be displayed on the icon if some resources fail to load," "
and you can set the profile for such resources conveniently via the " "popup menu." msgid "options_downloadOptions" msgstr "Download Options" msgid "options_downloadOptionsHelp" msgstr "Configure the update frequency of online rule lists and PAC scripts." msgid "options_downloadInterval" msgstr "Download Interval" msgid "options_downloadInterval_15" msgstr "15 Minutes" msgid "options_downloadInterval_60" msgstr "1 Hour" msgid "options_downloadInterval_180" msgstr "3 Hours" msgid "options_downloadInterval_360" msgstr "6 Hours" msgid "options_downloadInterval_720" msgstr "12 Hours" msgid "options_downloadInterval_1440" msgstr "Every day" msgid "options_downloadInterval_never" msgstr "Never" msgid "options_group_importExportProfile" msgstr "Profile" msgid "options_exportPacFile" msgstr "Export as PAC File" msgid "options_exportPacFileHelp" msgstr "" "Export the current profile as a PAC file, so you can use it in other " "browsers." msgid "options_exportProfileHelp" msgstr "To export a profile, use the top-right action bar on the profile page." msgid "options_exportLegacyRuleList" msgstr "" "Export rule lists using Proxy Switchy!/SwitchyPlus/SwitchySharp compatible " "format when possible." msgid "options_exportLegacyRuleListHelp" msgstr "" "Enable this option only if you publish rule lists for users of those " "projects.
Please consider advising your audience to upgrade to " "SwitchyOmega for the improvements." msgid "options_group_importExportSettings" msgstr "Settings" msgid "options_makeBackup" msgstr "Make backup" msgid "options_makeBackupHelp" msgstr "" "Make a full backup of your options (including profiles and all other " "options)." msgid "options_restoreLocal" msgstr "Restore from file" msgid "options_restoreLocalHelp" msgstr "Restore your SwitchyOmega options from a local file." msgid "options_restoreOnline" msgstr "Restore from online" msgid "options_restoreOnlinePlaceholder" msgstr "Options file URL (e.g. 'http://example.com/switchy.bak')" msgid "options_restoreOnlineSubmit" msgstr "Restore" msgid "options_group_syncing" msgstr "Syncing (Experimental)" msgid "options_syncEnable" msgstr "Enable Syncing" msgid "options_syncEnableForce" msgstr "Download from Syncing" msgid "options_syncDisable" msgstr "Disable syncing" msgid "options_syncReset" msgstr "Clear remote copy" msgid "options_syncPristineHelp" msgstr "" "You can now automatically synchronize your settings and profiles across all " "your desktop devices running Chrome browser." msgid "options_syncSyncAlert" msgstr "Your options are automatically synchronized with your other devices." msgid "options_syncSyncHelp" msgstr "" "Please note that you must sign in to Chrome on each of your devices " "(including this one) for the syncing to actually work.
You may check " "this section on other devices to ensure that it is working." msgid "options_syncConflictAlert" msgstr "" "You have uploaded a copy of your options on another device via syncing." msgid "options_syncConflictHelp" msgstr "" "You may download the remote copy to your device if you like.
However, " "doing so would overwrite your existing settings and profiles on this " "device." msgid "options_syncUnsupportedHelp" msgstr "" "Options syncing is not supported on your platform or browser. For now, only " "Chrome browser on desktop is supported." msgid "options_profileSyncDisabled" msgstr "Syncing is disabled for this profile." msgid "options_profileSyncDisabled_quotaPerItem" msgstr "Syncing is disabled for this profile for using too much storage space." msgid "options_profileTabPrefix" msgstr "Profile :: " msgid "options_renameProfile" msgstr "Rename" msgid "options_deleteProfile" msgstr "Delete" msgid "options_profileExportRuleList" msgstr "Publish rule list" msgid "options_profileExportRuleListHelp" msgstr "Export Switch Rules as text format for publishing." msgid "options_profileExportPac" msgstr "Export PAC" msgid "options_profileUnsupported" msgstr "Unsupported profile type $TYPE$!" msgid "options_profileUnsupportedHelp" msgstr "The options could be broken, or from a newer version of this program." msgid "options_profileEditSource" msgstr "Edit source code" msgid "options_profileEditSourceHelp" msgstr "Show help about the source code format" msgid "options_profileEditSourceHelpUrl" msgstr "" "https://github.com/FelisCatus/SwitchyOmega/wiki/SwitchyOmega-conditions-" "format#result-profile" msgid "options_group_proxyServers" msgstr "Proxy servers" msgid "options_proxy_scheme" msgstr "Scheme" msgid "options_proxy_protocol" msgstr "Protocol" msgid "options_proxy_server" msgstr "Server" msgid "options_proxy_port" msgstr "Port" msgid "options_proxy_auth" msgstr "Authentication" msgid "options_proxy_authNotSupported" msgstr "Your browser DOES NOT support $PROTOCOLDISP$ proxy authentication! " "Please do not report this issue to SwitchyOmega. Contact the support for " "your browser instead." msgid "options_proxy_authAllWarningPac" msgstr "" "Warning: The username/password may be sent to unexpected servers returned by " "the PAC script." msgid "options_proxy_authAllWarningPacUrl" msgstr "" "Please make sure that you trust the script provided via the URL above before " "entering sensitive credentials." msgid "options_proxy_authAllWarningPacScript" msgstr "" "Please make sure that you trust the script below before providing sensitive " "credentials." msgid "options_proxy_authReferencedWarning" msgstr "" "Additionally, using this profile in other profiles (e.g. Switch Profile) may " "cause the username/password to be sent to proxy servers configured in other " "profiles." msgid "options_scheme_default" msgstr "(default)" msgid "options_protocol_direct" msgstr "DIRECT" msgid "options_protocol_useDefault" msgstr "(use default)" msgid "options_proxy_single" msgstr "Use the proxy above for all protocols." msgid "options_proxy_expand" msgstr "Show Advanced" msgid "options_group_bypassList" msgstr "Bypass List" msgid "options_bypassListHelp" msgstr "" "Servers for which you do not want to use any proxy: (One server on each " "line.)" msgid "options_bypassListHelpLinkText" msgstr "(Wildcards and more available…)" msgid "options_group_pacUrl" msgstr "PAC URL" msgid "options_pacUrlHelp" msgstr "" "The PAC script will be updated from this URL. If it is left blank, the " "following script will be used directly instead." msgid "options_pacUrlFile" msgstr "" "PAC profiles with file: URLs can only be applied directly. They cannot be " "used as result profiles because local files cannot be accessed due to " "browser limitation." msgid "options_pacUrlFileDisabled" msgstr "" "Therefore, you cannot use local PAC file for this profile. You can create a " "new PAC profile for that if you really want that." msgid "options_group_pacScript" msgstr "PAC Script" msgid "options_pacScriptLastUpdate" msgstr "PAC script downloaded at $TIME$:" msgid "options_pacScriptObsolete" msgstr "" "PAC script is obsolete due to URL change. Press the download button above to " "update." msgid "options_group_virtualProfile" msgstr "Virtual Profile" msgid "options_virtualProfileTarget" msgstr "Target" msgid "options_virtualProfileTargetHelp" msgstr "" "When this profile is applied, it acts exactly the same as the profile " "selected below." msgid "options_group_virtualProfileReplace" msgstr "Migrate to Virtual Profile" msgid "options_virtualProfileReplace" msgstr "Replace target profile" msgid "options_virtualProfileReplaceHelp" msgstr "" "You can migrate existing options to use this virtual profile instead of " "$PROFILE$. Doing so will update all existing rules concerning $PROFILE$ and " "point them to this virtual profile, so that their result profile can be " "controlled here." msgid "options_group_ruleListConfig" msgstr "Rule List Config" msgid "options_ruleListFormat" msgstr "Rule List Format" msgid "options_group_ruleListResult" msgstr "Rule list result profiles" msgid "options_ruleListMatchProfile" msgstr "Match profile" msgid "options_ruleListDefaultProfile" msgstr "Default profile" msgid "options_group_ruleListUrl" msgstr "Rule List URL" msgid "options_ruleListUrlHelp" msgstr "" "The rule list will be updated from this URL. If it is left blank, the " "following text will be parsed instead." msgid "options_group_ruleListText" msgstr "Rule List Text" msgid "options_ruleListLastUpdate" msgstr "Rule list downloaded at $TIME$:" msgid "options_ruleListObsolete" msgstr "" "Rule list is obsolete due to URL change. Press the download button above to " "update." msgid "options_group_switchRules" msgstr "Switch rules" msgid "options_sort" msgstr "Sort" msgid "options_conditionType" msgstr "Condition Type" msgid "options_showConditionTypeHelp" msgstr "Show help" msgid "options_conditionDetails" msgstr "Condition Details" msgid "options_resultProfile" msgstr "Profile" msgid "options_conditionActions" msgstr "Actions" msgid "options_addCondition" msgstr "Add condition" msgid "options_cloneRule" msgstr "Clone" msgid "options_ruleNote" msgstr "Note" msgid "options_switchAttachedProfileInCondition" msgstr "Rule list rules" msgid "options_switchAttachedProfileInConditionDetails" msgstr "(Any request matching the rule list below)" msgid "options_switchAttachedProfileInConditionDisabled" msgstr "(Rule list rules are DISABLED)" msgid "options_switchDefaultProfile" msgstr "Default" msgid "options_hostLevelsBetween" msgstr "≤ host levels ≤" msgid "options_hourBetween" msgstr "≤ current hour ≤" msgid "options_weekDayShort_0" msgstr "Su" msgid "options_weekDayShort_1" msgstr "Mo" msgid "options_weekDayShort_2" msgstr "Tu" msgid "options_weekDayShort_3" msgstr "We" msgid "options_weekDayShort_4" msgstr "Th" msgid "options_weekDayShort_5" msgstr "Fr" msgid "options_weekDayShort_6" msgstr "Sa" msgid "options_group_conditionHelp" msgstr "About Condition Types" msgid "options_group_attachProfile" msgstr "Import online rule lists" msgid "options_attachProfile" msgstr "Add a rule list" msgid "options_attachProfileHelp" msgstr "" "You can reuse an online collection of conditions published by others by " "adding a rule list." msgid "options_modalHeader_welcome" msgstr "Welcome to SwitchyOmega" msgid "options_welcomeNormal" msgstr "" "You have successfully installed SwitchyOmega, the ultimate proxy switcher." msgid "options_welcomeNormalGuide" msgstr "" "Please tell SwitchyOmega about your proxies through the options page. Let's " "see how." msgid "options_welcomeUpgrade" msgstr "" "You have successfully upgraded to SwitchyOmega. Don't panic, your existing " "options are fully preserved." msgid "options_welcomeUpgradeGuide" msgstr "Now let's go through a quick guide of the new options page." msgid "options_guideNext" msgstr "Next" msgid "options_guideDone" msgstr "Done" msgid "options_guideSkip" msgstr "Skip guide" msgid "options_modalHeader_applyOptions" msgstr "Apply Options" msgid "options_optionsNotSaved" msgstr "" "Your modifications to the options have not been saved and will be lost if " "you proceed!" msgid "options_applyOptionsRequired" msgstr "Your changes to the options must be applied before you proceed." msgid "options_applyOptionsConfirm" msgstr "Do you want to save and apply the options?" msgid "options_modalHeader_renameProfile" msgstr "Rename Profile" msgid "options_renameProfileName" msgstr "New profile name" msgid "options_profileNameConflict" msgstr "A profile with this name already exists." msgid "options_profileNameReserved" msgstr "Profile names beginning with double-underscore are reserved." msgid "options_profileNameHidden" msgstr "" "Profiles with names starting with underscore will be hidden on the popup " "menu. However, they can still be used in places like switch profile results." msgid "options_modalHeader_replaceProfile" msgstr "Replace Profile" msgid "options_replaceProfile" msgstr "Replace Profile" msgid "options_replaceProfileConfirm" msgstr "Do you really want to replace $FromProfile$ with $ToProfile$?" msgid "options_replaceProfileHelp" msgstr "" "If you proceed, all rules pointing to $FromProfile$ will be updated to use " "$ToProfile$ instead. Other options, such as startup profile and Quick Switch " "will also be modified as appropriate. However, the two profile themselves " "will NOT be changed or deleted." msgid "options_replaceProfileSuccess" msgstr "Options updated." msgid "options_modalHeader_deleteProfile" msgstr "Delete Profile" msgid "options_deleteProfileConfirm" msgstr "Do you really want to delete the following profile?" msgid "options_modalHeader_cannotDeleteProfile" msgstr "Unable to Delete Profile" msgid "options_profileReferredBy" msgstr "" "This profile cannot be deleted because it is referred by the following " "profiles:" msgid "options_modifyReferringProfiles" msgstr "" "You must modify these profiles and make them stop referring to this profile " "before you can delete it." msgid "options_profileNameEmpty" msgstr "The name of the profile must not be empty." msgid "popup_title" msgstr "SwitchyOmega Popup" msgid "options_modalHeader_proxyAuth" msgstr "Proxy Authentication" msgid "options_proxyAuthUsername" msgstr "Username" msgid "options_proxyAuthPassword" msgstr "Password" msgid "options_proxyAuthShowPassword" msgstr "Show password" msgid "options_proxyAuthHidePassword" msgstr "Hide password" msgid "options_proxyAuthNone" msgstr "No Authentication" msgid "options_modalHeader_deleteRule" msgstr "Delete Rule" msgid "options_deleteRuleConfirm" msgstr "Do you really want to delete the following rule?" msgid "options_deleteRule" msgstr "Delete" msgid "options_modalHeader_resetRules" msgstr "Reset rules" msgid "options_resetRulesConfirm" msgstr "" "Are you sure to set the result profile of ALL rules to the following profile?" msgid "options_resetRules" msgstr "Reset rules" msgid "options_resetRules_help" msgstr "Set profile for all rules" msgid "options_modalHeader_deleteAttached" msgstr "Remove Rule List" msgid "options_deleteAttachedConfirm" msgstr "Do you really want to remove the rule list from the current profile?" msgid "options_ruleListLineCount" msgstr "$COUNT$ line(s) of rules" msgid "options_deleteAttached" msgstr "Remove rule list" msgid "options_modalHeader_newProfile" msgstr "New Profile" msgid "options_newProfileName" msgstr "Profile name" msgid "options_profileType" msgstr "Please select the type of the profile:" msgid "options_profileTypeFixedProfile" msgstr "Proxy Profile" msgid "options_profileDescFixedProfile" msgstr "Tunneling traffic through proxy servers." msgid "options_profileTypePacProfile" msgstr "PAC Profile" msgid "options_profileDescPacProfile" msgstr "Choosing proxies using an online/local PAC script." msgid "options_profileDescMorePacProfile" msgstr "" "You will only need this if you have a PAC script or a URL to it. Don't try " "to create one unless you have knowledge about PAC." msgid "options_profileTypeSwitchProfile" msgstr "Switch Profile" msgid "options_profileDescSwitchProfile" msgstr "" "Applying different profiles automatically on various conditions such as " "domains or patterns.\n" " You can also import rules published online for easier switching. (Replaces " "AutoSwitch mode + Rule List.)" msgid "options_profileTypeRuleListProfile" msgstr "Rule List Profile" msgid "options_profileDescRuleListProfile" msgstr "Reusing an online collection of conditions published by others." msgid "options_profileTypeVirtualProfile" msgstr "Virtual Profile" msgid "options_profileDescVirtualProfile" msgstr "" "A virtual profile can act as any of the other profiles on demand. It works " "well with SwitchProfile, allowing you to change the result of multiple " "conditions by one click." msgid "options_createProfile" msgstr "Create" msgid "options_modalHeader_resetOptions" msgstr "Reset Options" msgid "options_resetOptionsConfirm" msgstr "" "Do you really want to reset the options? All profiles and settings will be " "LOST!" msgid "options_formInvalid" msgstr "Please correct the errors in this page." msgid "options_profileNotFound" msgstr "Profile $PROFILE$ does not exist! The options may be corrupted." msgid "options_resetSuccess" msgstr "Options reset." msgid "options_saveSuccess" msgstr "Options saved." msgid "options_importSuccess" msgstr "Options imported." msgid "options_importFormatError" msgstr "Invalid backup file!" msgid "options_importDownloadError" msgstr "Error downloading backup file!" msgid "options_profileDownloadSuccess" msgstr "Successfully updated profile." msgid "options_profileDownloadError" msgstr "Error downloading profile data!" msgid "options_profileDownloadError_NetworkError" msgstr "A network error occurred when updating." msgid "options_profileDownloadError_HttpError" msgstr "An HTTP error ($STATUS$) occurred when updating." msgid "options_profileDownloadError_HttpNotFoundError" msgstr "The Profile URL was not found on the server. Please double-check." msgid "options_profileDownloadError_HttpServerError" msgstr "The remote server responded with error ($STATUS$) when updating." msgid "options_profileDownloadError_ContentTypeRejectedError" msgstr "The downloaded data is invalid! " "You may open the Profile URL in your browser to inspect it." msgid "options_downloadProfileNow" msgstr "Download Profile Now" msgid "options_guide_fixedProfileStep" msgstr "" "A Proxy Profile contains settings like server ip & port for proxy." "
Profiles are the the basic configuration units in SwitchyOmega.
We " "have already created an example profile for you. Try opening it." msgid "options_guide_fixedServersStep" msgstr "" "You can fill in your proxy server and port here as you like.
SwitchyOmega " "does not come with any proxy servers.
Please consult your network " "provider or proxy software manual if you don't know what should be filled in " "here." msgid "options_guide_autoSwitchProfileStep" msgstr "" "You can tell SwitchyOmega to switch between proxies automatically through " "the mighty Switch Profile.
However, its features cannot be covered " "in this quick guide.
You can open this profile to unlock its power some " "time later." msgid "options_guide_addMoreProfilesStep" msgstr "" "Need more profiles? You can always add more Proxy, Switch and other " "profiles
for all your proxying needs.
Enjoy proxying!" msgid "options_guide_conditionStep" msgstr "" "SwitchyOmega can apply different profiles to requests based on " "conditions.
For example, the Host wildcard condition " "allows you to set the profile for all URLs in a domain." msgid "options_guide_conditionTypeStep" msgstr "" "You can use various condition types to match the host or full URL.
" "Click on the question mark to open the type reference." msgid "options_guide_conditionProfileStep" msgstr "" "SwitchyOmega applies the selected profile here to any request matching " "the condition.
The special \"[Direct]\" profile will cause " "the request to be sent without any proxy." msgid "options_guide_switchDefaultStep" msgstr "" "If no condition applies to some request, the \"Default\" profile will be " "used.
Conditions are always considered from top to bottom in " "order.
You can change their order by dragging the sort icon." msgid "options_guide_applySwitchProfileStep" msgstr "" "When you are done setting the switch profile, don't forget to switch to " "it in the popup menu.
The icon will show you the final result profile applied for the current tab.
Hovering on the icon " "will reveal a tooltip with details." msgid "popup_externalProfile" msgstr "(External Profile)" msgid "popup_externalProfileName" msgstr "profile name" msgid "popup_proxyNotControllable_app" msgstr "" "The proxy settings are controlled by other app(s) or extension(s). Please " "disable or uninstall the apps or extensions in conflict." msgid "popup_proxyNotControllable_policy" msgstr "" "The proxy settings are overruled by policies. Please contact your " "administrator." msgid "popup_proxyNotControllable_unknown" msgstr "" "The proxy settings cannot be controlled. Please check your system and " "browser settings." msgid "popup_proxyNotControllable_disabled" msgstr "" "The proxy settings are disabled by explicit request from other app(s) or " "extension(s)." msgid "popup_proxyNotControllable_upgrade" msgstr "Proxy settings are now controlled by a newer version of SwitchyOmega." msgid "popup_proxyNotControllableDetails" msgstr "" "You cannot switch profiles with SwitchyOmega unless you fix the problem " "above." msgid "popup_proxyNotControllableDetails_upgrade" msgstr "" "You can't enable two (or more) versions of SwitchyOmega at the same time. " "Please disable one of them." msgid "popup_proxyNotControllableManage" msgstr "Manage extensions" msgid "popup_addConditionTo" msgstr "Add condition to" msgid "popup_addCondition" msgstr "Add condition" msgid "popup_showOptions" msgstr "Options" msgid "popup_reportIssues" msgstr "Report issues" msgid "popup_errorLog" msgstr "Save error log" msgid "popup_requestErrorCount" msgstr "$COUNT$ failed resources" msgid "popup_requestErrorHeading" msgstr "Resources that failed to load" msgid "popup_requestErrorWarning" msgstr "" "A few resources failed to load due to issues with your network, proxy server " "or the webpage." msgid "popup_requestErrorWarningHelp" msgstr "" "SwitchyOmega is just the reporter of these issues, not the cause of them." msgid "popup_requestErrorAddCondition" msgstr "" "You can review the following domains and use proxy for them when appropriate." msgid "popup_requestErrorCannotAddCondition" msgstr "" "You can add switch conditions for them only when using a Switch Profile." msgid "popup_configureMonitorWebRequests" msgstr "Configure Network Monitor" msgid "options_resultProfileForSelectedDomains" msgstr "Use this profile for all selected domains" msgid "options_pac_profile_unsupported_moz" msgstr "PAC Profiles WILL NOT work in Mozilla Firefox due to technical limitations!" msgid "popup_issueTemplate" msgstr "" "\n" "\n" "\n" "\n" "SwitchyOmega $projectVersion$\n" "$userAgent$" msgid "browserAction_profileDetails_PacProfile" msgstr "(PAC script)" msgid "browserAction_profileDetails_SystemProfile" msgstr "(controlled by other extensions or environment)" msgid "browserAction_profileDetails_DirectProfile" msgstr "(not using any proxy)" msgid "browserAction_profileDetails_SwitchProfile" msgstr "(switching based on conditions)" msgid "browserAction_profileDetails_RuleListProfile" msgstr "(switching based on rule list)" msgid "browserAction_titleNormal" msgstr "SwitchyOmega:: $PROFILE$" msgid "browserAction_titleWithResult" msgstr "" "SwitchyOmega:: $1:PROFILE$\n" "$3:DETAILS$" msgid "browserAction_titleNewerOptions" msgstr "" "ERROR: A newer version of SwitchOmega is required to load the stored options." msgid "browserAction_titleOptionError" msgstr "ERROR: The stored options are corrupted. Click here to RESET OPTIONS." msgid "browserAction_titleDownloadFail" msgstr "Warning: Failed to download PAC scripts and/or rule lists." msgid "browserAction_titleExternalProxy" msgstr "Note: The proxy settings are currently controlled by other app(s)." msgid "browserAction_titleInspect" msgstr "[Inspect] $URL$" msgid "browserAction_defaultRuleDetails" msgstr "(default)" msgid "browserAction_directResult" msgstr "DIRECT" msgid "browserAction_attachedPrefix" msgstr "(RL) " msgid "browserAction_tempRulePrefix" msgstr "(TEMP) " msgid "contextMenu_inspectPage" msgstr "Inspect proxy used for this page" msgid "contextMenu_inspectFrame" msgstr "Inspect proxy used for this Frame" msgid "contextMenu_inspectLink" msgstr "Inspect proxy to be used if this Link is opened" msgid "contextMenu_inspectElement" msgstr "Inspeccionar proxy utilizado para este Elemento." msgid "contextMenu_enableQuickSwitch" msgstr "Enable Quick Switch" msgid "about_title" msgstr "About" msgid "about_app_description" msgstr "A proxy configuration tool" msgid "about_version" msgstr "Version $VERSION$" msgid "about_experimental_warning_moz" msgstr "Mozilla Firefox support is highly experimental! If you encounter issues, please report using the buttons below." msgid "about_disclaimer_networkService" msgstr "SwitchyOmega does not provide proxies, VPNs, or other network services." msgid "about_disclaimer_privacy" msgstr "SwitchyOmega does not track you or insert ads into webpages. Please see" " our privacy policy." msgid "about_help" msgstr "Other questions? Need help with using SwitchyOmega? Please see our " "FAQ." msgid "about_copyright" msgstr "Copyright 2012-2017 The SwitchyOmega Authors. All rights reserved." msgid "about_credits" msgstr "SwitchyOmega is made possible by the SwitchyOmega open source project and other open source software." msgid "about_license" msgstr "SwitchyOmega is free software licensed under GNU General Public License Version 3 or later." ================================================ FILE: omega-locales/fa/LC_MESSAGES/omega-web.po ================================================ msgid "" msgstr "" "Project-Id-Version: SwitchyOmega 2.3.3\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2015-02-13 10:29+0000\n" "PO-Revision-Date: 2024-07-28 18:09+0000\n" "Last-Translator: Parsa Nobahari \n" "Language-Team: Persian \n" "Language: fa\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n > 1;\n" "X-Generator: Weblate 5.7-dev\n" msgid "appNameShort" msgstr "سوییچی‌اومگا" msgid "manifest_app_name" msgstr "سوییچی‌اومگای پیشکار" msgid "manifest_app_description" msgstr "مدیریت و تعویض سریع و آسان بین چندین پیشکار." msgid "manifest_icon_default_title" msgstr "بار کردن…" msgid "upgrade_profile_auto" msgstr "تعویض خودکار" msgid "profile_direct" msgstr "[مستقیم]" msgid "profile_system" msgstr "[پیشکار سامانه]" msgid "condition_HostWildcardCondition" msgstr "وایلدکارد میزبان" msgid "condition_help_HostWildcardCondition" msgstr "" "انتخاب و تطبیق میزبان ها ( نام دامین ) به کمک فرا نویسه .
ستاره " "* صفر کارکتر یا بیشتر را تطابق می‌دهد .
علامت سوال " "? فقط یک کارکتر را انتخاب و تطابق می‌دهد ..

توجه " "داشته باشید که قوانینی که با *شروع می‌شوند به صورت ویژه تنها در " "شروط فرانویسه ایه میزبان کاربرد دارند .
به طور مثال: *.example." "com این ادرس ها را تشخیص می‌دهد. www.example.com و example.com .
کافیست
، از دو ستاره استفاده " "نمایید . **.example.com." msgid "condition_HostRegexCondition" msgstr "عبارت باقاعدهٔ میزبان" msgid "condition_help_HostRegexCondition" msgstr "" "همانند شرط فرانویسه ی میزبان،اما با کمک عبارت منظم.
میزبان " "ها ( اسامی دامنه ها ) را انتخاب و تطابق میدهد . نوشتن یا حتی خواندن عبارات " "منظم میتواند سخت باشد.
پیشنهاد میشود که از فرانویسه استفاده کنید و فقط " "در مواقعی که به هیچ روشی نمیشود عبارتی رو یافت از عبارات منظم استفاده کنید ." msgid "condition_HostLevelsCondition" msgstr "سطح‌های میزبان" msgid "condition_help_HostLevelsCondition" msgstr "" "تنها درصورتی درخواست را انطباق می‌دهد که سطح میزبان در محدوده‌ی داده شده " "باشد .
به تعداد بخش های جدا شده توسط نقطه ( دات ) سطح میزبان ، " "هاست ( دامنه ) داده شده می‌گویند .
به طور مثال www.example.com دارای سطح میزابن سه می‌باشد ، در حالی که داخل سطح میزبان " "یک را دارد." msgid "condition_IpCondition" msgstr "مجموعه IP Literals" msgid "condition_help_IpCondition" msgstr "" "تنها و تنها در صورتی درخواست را قبول می‌کند اگر دقیقا ای پی آدرس ذکر " "شده باشد و در زیر مجموعه مشخص شده در CIDR notation باشد.
\n" "برای مثال، در صورت وجود قانون 127.0.0.1/16، تمامی آدرس های آی " "پی مثل127.0.*.*را می‌پذیرد.
بنابراین 127.0.0.1 " "پذیرفته می‌شود در حالی که127.1.0.0 پذیرفته نمی‌شود.\n" "میزبان هایی مانند localhost هیچوقت پذیرفته نمی‌شوند بخاطر اینکه " "آی پیدقیق نمی‌باشند." msgid "condition_UrlWildcardCondition" msgstr "وایلدکارد نشانی" msgid "condition_help_UrlWildcardCondition" msgstr "" "ادرس های درخواست داده شده را به کمک فرانویسه بررسی و مطابقت می‌دهد .
" "برای اشنایی با فرانویسه به بخش فرانویسه ی میزبان مراجعه کنید .
توجه " "داشته باشید که فرانویسه‌ی آدرس به صورت ویژه‌ای برخورد نمی‌شوند ( تشخیص " "جادویی زیردامنه همانند هاست وجود ندارد )
بنابراین دستور *://*." "example.com/* ادرس http://www.example.com/ را تشخیص می‌دهد اما این " "ادرس http://example.com راتشخیص نمی‌دهد .." msgid "condition_UrlRegexCondition" msgstr "عبارت باقاعدهٔ نشانی" msgid "condition_help_UrlRegexCondition" msgstr "" "ادرس ها را ابزار قدرتمند عبارت منظم تشخیص و انتطباق می‌دهد .
پیشنهاد می‌شود که از " "فرانویسه استفاده کنید و فقط در مواقعی که به هیچ روشی نمی‌شود عبارتی رو یافت " "از عبارات منظم استفاده کنید ." msgid "condition_KeywordCondition" msgstr "کلیدواژه" msgid "condition_help_KeywordCondition" msgstr "" "شرط کلمات کلیدی درصورتی انتخاب انجام می‌دهد که پروتکل مورد استفاده HTTP باشد " "، و الگو (pattern) یک خرده-رشته ی ادرس باشد .
همانند الگوی فرانویسه ی " "ادرس کار می‌کند که در اینجا http://*pattern* قسمت " "pattern الگوی کلمه ی کلیدی می‌باشد .
شرط کلمات کلیدی زمانی مفید " "هستند که قصد دارید از یک فایروالی که کلمات خاصی را که در ادرس بلاک می‌کند " "بگذرید . اینگونه می‌توانید اینگونه آدرس های خاص را پیدا کرده و با پروکسی از " "آن ها عبور کرده." msgid "condition_FalseCondition" msgstr "(از کار افتاده)" msgid "condition_details_FalseCondition" msgstr "(شرط هنگام تطبیق نادیده گرفته شد)" msgid "condition_help_FalseCondition" msgstr "" "شما می‌توانید یک شرط را با قرار دادن نوع آن به (غیرفعال) " "غیرفعال کنید . یک شرط غیرفعال طوری عمل میکند که انگار وجود ندارد .
از " "این قابلیت برای غیرفعال کردن موقت شرط استفاده نمایید .
شروط غیرفعال " "تمامی تنظیمات خود را حفظ می‌کنند و در صورت نیاز می‌توانید با برگردان نوع آن " "به حالت قبلی آن را فعال کنید ." msgid "condition_TimeCondition" msgstr "زمان کنونی" msgid "condition_help_TimeCondition" msgstr "" "اگر زمان محلی فعلی در محدوده تعریف شده توسط ساعت شروع و ساعت " "پایان باشد ، هر دو با هم مطابقت دارند.
زمان محلی ، ساعت شروع و " "ساعت پایان همه در محاسبه می شوند قالب 24 ساعته (از 0 تا 23 " ").
محاسبه تقریباً در لحظه ارسال درخواست انجام می شود." msgid "condition_WeekdayCondition" msgstr "روز هفته" msgid "condition_help_WeekdayCondition" msgstr "" "در صورت انتخاب روز جاری هفته با جزئیات شرایط مطابقت دارد. روز " "براساس منطقه زمانی محلی محاسبه می شود.
درخواست و آدرس اینترنتی آن برای " "این شرایط مهم نیست. نتیجه صرفاً براساس روز هفته ارسال درخواست است." msgid "condition_alert_fullUrlLimitation" msgstr "" "مچ کامل دیگر برای این آدرس از کروم 52 به ممکن نیست. https:// . <" "a href='https://github.com/FelisCatus/SwitchyOmega/wiki/Chromium-Full-URL-" "Limitation'>اصلاعات بیشتر..." msgid "condition_alert_fullUrlLimitationLink" msgstr "https://github.com/FelisCatus/SwitchyOmega/wiki/Chromium-Full-URL-Limitation" msgid "condition_group_default" msgstr " " msgid "condition_group_host" msgstr "میزبان" msgid "condition_group_url" msgstr "نشانی" msgid "condition_group_special" msgstr "ویژه" msgid "ruleListFormat_Switchy" msgstr "سوییچی" msgid "ruleListFormat_AutoProxy" msgstr "پیشکار خودکار" msgid "ruleList_usageUrl" msgstr "https://github.com/FelisCatus/SwitchyOmega/wiki/RuleListUsage" msgid "ruleList_error_resultNotEnabled" msgstr "دستور '@with result' غایب است!" msgid "ruleList_error_unknownProfile" msgstr "پروفایل ناشناس : $PROFILE$" msgid "ruleList_error_missingResultProfile" msgstr "نام نتیجه ی پروفایل در خط $LNO$: $SOURCE$ غایب است" msgid "ruleList_error_invalidRule" msgstr "قانون نامعتبر در خط $LNO$: $SOURCE$" msgid "ruleList_error_noDefaultRule" msgstr "قانون پیش فرض با شرط انتخاب همه '*' غایب است !" msgid "dialog_close" msgstr "بستن" msgid "dialog_save" msgstr "ذخیرهٔ تغییرات" msgid "dialog_ok" msgstr "قبول" msgid "dialog_cancel" msgstr "لغو" msgid "inputClear_clear" msgstr "پاک‌سازی" msgid "inputClear_restore" msgstr "بازگردانی" msgid "options_title" msgstr "گزینه‌های سوییچی‌اومگا" msgid "options_experimental_badge" msgstr "α" msgid "options_navHeader_setting" msgstr "تنظیمات" msgid "options_navHeader_profiles" msgstr "نمایه‌ها" msgid "options_navHeader_actions" msgstr "کنش‌ها" msgid "options_tab_ui" msgstr "رابط" msgid "options_tab_general" msgstr "عمومی" msgid "options_tab_importExport" msgstr "درون یا برون‌ریزی" msgid "options_newProfile" msgstr "نمایهٔ جدید…" msgid "options_apply" msgstr "اعمال تغییرات" msgid "options_discard" msgstr "دور ریختن تغییرات" msgid "options_reset" msgstr "بازنشانی گزینه‌ها" msgid "options_group_miscOptions" msgstr "گزینه‌های متفرّقه" msgid "options_confirmDeletion" msgstr "تصدیق در زمان حذف شروط." msgid "options_refreshOnProfileChange" msgstr "رفرش کردن تب کنونی در هنگام تغییر پروفایل." msgid "options_showInspectMenu" msgstr "" "مجوز برای بررسی پروکسی مورد استفاده برای یک المان صفحه در منوی زمنیه (" "context menu)." msgid "options_addConditionsToBottom" msgstr "شرایط جدید اضافه شد از طریق پنجره ی pop-up را در انتهای لیست قرار بده." msgid "options_group_keyboardShortcut" msgstr "میان‌برهای صفحه‌کلید" msgid "options_menuShortcutHelp" msgstr "کلید میانبر برای باز کردن منوی popup .( پیش فرض Alt+Shift+O )." msgid "options_menuShortcutMore" msgstr "" "با استفاده از دکمه های کیبرد میتوانید به موارد داخل منوی بالاپر (popup) " "دسترسی داشته باشید . با فشاردادن ؟ ( یا /) میتوانید بیشتر یاد بگیرید ." msgid "options_menuShortcutConfigure" msgstr "پیکربندی میان‌بر" msgid "options_group_switchOptions" msgstr "گزینه‌های تعویض" msgid "options_startupProfile" msgstr "نمایهٔ آغازین" msgid "options_startupProfile_none" msgstr "(نمایهٔ کنونی)" msgid "options_showConditionTypesAdvanced" msgstr "نمایش حالت های پیشرفته ی شروط" msgid "options_showConditionTypesAdvancedHelp" msgstr "" "نوع‌های جدید پیشرفته اما پیچیده‌تر از شرط‌ها را فعال کنید .برای بیشتر حالات " "نوع‌های عادی کافی میباشد ، این گزینه پیشنهاد نمی‌شود." msgid "options_quickSwitch" msgstr "تعویض سریع" msgid "options_cycledProfiles" msgstr "نمایه‌های چرخشی" msgid "options_cycledProfilesHelp" msgstr "" "وقتی بر روی آیکون کلید می‌کنید ( یا از میانبرهای بالا ) استفاده می‌کنید، " "پروفایل های زیر به ترتیب اجرا می‌شوند ." msgid "options_cycledProfilesTooFew" msgstr "" "شما باید حداقل دو پروفایل را انتخاب کنید برای فعال کردن این وظیفه ! میتوانید " "از جعبه ی زیر آن را به اینجا بکشید ." msgid "options_notCycledProfiles" msgstr "پروفایل های غیرچرخشی" msgid "options_group_proxyChanges" msgstr "تغییرات پیشکار" msgid "options_revertProxyChanges" msgstr "بازگرداندن تغییرات پروکسی انجام شده توسط دیگر برنامه ها." msgid "options_group_conflicts" msgstr "تداخل‌ها" msgid "options_conflicts_introduction" msgstr "" "بعضی اوقات، بقیه برنامه‌ها هم سعی میکنند که تنظیمات پراکسی را کنترل کنند، که " "نتیجه آن تضادها در تنظیمات پراکسی است. به این نکته توجه فرمایید که Ad-" "blocker ها و دیگر افزونه ها ممکن است از تنظیمات پراکسی در سطح زیرین‌شان " "استفاده کنند. این تضادها غیرقابل اجتناب‌اند چرا که این نحوه کارکرد مرورگر " "است." msgid "options_conflicts_lowerPriority" msgstr "" "وقتی یک نمایانگر قرمز مثل این روی نماد SwitchyOmega نمایان می‌شود این را " "نشان میدهد که برنامه دیگری کنترل بیشتری دارد پس SwitchyOmega نمیتواند " "تنظیمات را کنترل کند. لطفا SwitchyOmega را دوباره نصب کنید. کاری که بایستی " "باعث شود کنترل SwitchyOmega بر تنظیمات بیشتر شود. اگر باز هم تضادهایی در " "تنظیمات دیدید، لطفا اقدام به حذف برنامه‌ای که این تضاد را باعث میشود کنید." msgid "options_conflicts_higherPriority" msgstr "" "اگر SwitchyOmega دارای اولویت بیشتری است ، می توانید با انتخاب " "$SYSTEMPROFILE$ در منوی باز شده ، کنترل را به سایر برنامه ها یا تنظیمات " "سیستم بازگردانید." msgid "options_showExternalProfile" msgstr "" "آیتم های منوی pop-up را برای ایمپورت تنظیمات پروکسی از دیگر برنامه ها نمایش " "بده." msgid "options_showExternalProfileHelp" msgstr "" "وقتی $ SYSTEMPROFILE $ انتخاب شد ، می توانید با انتخاب $ EXTERNALPROFILE $ " "در منوی باز شده ، تنظیمات پروکسی موثر را از سایر برنامه ها وارد کنید. با " "استفاده از نامی که ارائه می کنید ، تنظیمات به عنوان نمایه وارد می شوند. لطفاً" " توجه داشته باشید که نمایه وارد شده یک عکس فوری است و پس از آن هیچ تغییری از " "برنامه منبع را نشان نمی دهد." msgid "options_group_networkRequests" msgstr "درخواست‌های شبکه" msgid "options_monitorWebRequests" msgstr "نمایش میزان درخواست های ناموفق منابع وب در تب کنونی." msgid "options_monitorWebRequestsHelp" msgstr "" "یک نشان زرد بر روی آیکون قرارخواهد گرفت اگر در لود شدن منبعی مشکل پیش بیاید " ",
و شما میتوانید به راحتی پروفایل این گونه منابع را در منوی بالاپر(popup)" " تنظیم کنید ." msgid "options_downloadOptions" msgstr "گزینه‌های بارگیری" msgid "options_downloadOptionsHelp" msgstr "تناوب بروزرسانی لیست قوانین آنلاین و اسکریپت های PAC را تنظیم کنید ." msgid "options_downloadInterval" msgstr "دورهٔ بارگیری" msgid "options_downloadInterval_15" msgstr "۱۵ دقیقه" msgid "options_downloadInterval_60" msgstr "۱ ساعت" msgid "options_downloadInterval_180" msgstr "۳ ساعت" msgid "options_downloadInterval_360" msgstr "۶ ساعت" msgid "options_downloadInterval_720" msgstr "۱۲ ساعت" msgid "options_downloadInterval_1440" msgstr "هر روز" msgid "options_downloadInterval_never" msgstr "هرگز" msgid "options_group_importExportProfile" msgstr "نمایه" msgid "options_exportPacFile" msgstr "خروجی به صورت فایل PAC" msgid "options_exportPacFileHelp" msgstr "" "خروجی گرفتن پروفایل کنونی به صورت فایل PAC ، برای استفاده در دیگر مرورگرها ." msgid "options_exportProfileHelp" msgstr "" "برای خروجی گرفتن از یک پروفایل ، از عملگر سمت راست بالای صفحه ی پروفایل ها " "استفاده نمایید ." msgid "options_exportLegacyRuleList" msgstr "" "در صورت امکان با استفاده از قالب سازگار Proxy Switchy!/SwitchyPlus/" "SwitchySharp فهرست قوانین را صادر کنید." msgid "options_exportLegacyRuleListHelp" msgstr "" "این گزینه را تنها درصورتی که میخواهید لیست قوانین را برای کاربران اون پروژه " "ها انتشار دهید فعال کنید .
لطفا به کاربران خود پیشنهاد بروزرسانی به " "SwitchyOmega را برای بهره بری بهتر پیشنهاد دهید ." msgid "options_group_importExportSettings" msgstr "تنظیمات" msgid "options_makeBackup" msgstr "پشتیبان‌گیری" msgid "options_makeBackupHelp" msgstr "گرفتن پشتیبان کامل از تنظیمات ( شامل پروفایل ها و تمامی تنظیمات )." msgid "options_restoreLocal" msgstr "برگرداندن از فایل" msgid "options_restoreLocalHelp" msgstr "گزینه های SwitchyOmega خود را از یک فایل محلی بازیابی کنید." msgid "options_restoreOnline" msgstr "بازگرداندن از فایل آنلاین" msgid "options_restoreOnlinePlaceholder" msgstr "تنظیمات آدرس فایل ( به طور مثال 'http://example.com/switchy.bak' )" msgid "options_restoreOnlineSubmit" msgstr "بازگردانی" msgid "options_group_syncing" msgstr "همگام‌سازی (آزمایشی)" msgid "options_syncEnable" msgstr "به کار انداختن همگام‌سازی" msgid "options_syncEnableForce" msgstr "دانلود از همگام سازی" msgid "options_syncDisable" msgstr "از کار انداختن همگام‌سازی" msgid "options_syncReset" msgstr "پاک کردن کپی ریموت" msgid "options_syncPristineHelp" msgstr "" "شما اکنون میتوانید به صورت خودکار تمامی تنظیمات و پروفایل های خود را بین " "تمامی دستگاه های خانگی که از مرورگر کروم استفاده میکنند همگام سازی کنید ." msgid "options_syncSyncAlert" msgstr "تنظیمات شما به صورت خودکار بین دیگر دستگاه های خود همگام سازی میشوند ." msgid "options_syncSyncHelp" msgstr "" "لطفا توجه داشته باشید که برای کارکردن همگام سازی باید در مرورگرهای کروم خود " "وارد شده باشید (همین دستگاه راهم شامل میشود ).
میتوانید این قسمت را در " "دیگر دستگاه ها بررسی کنید تا مطمئن شوید که کار میکند ." msgid "options_syncConflictAlert" msgstr "" "شما یک کپی از تنظیمات خود را در یک دستگاه دیگر با استفاده از همگام سازی " "فراهم ساختید ." msgid "options_syncConflictHelp" msgstr "" "شما میتوانید کپی موجود در دیگر دستگاه خود را در اینجا دانلود کنید .
هرچند " "این عمل باعث میشود تنظیمات این دستگاه پاک و تنظیمات آن یکی پروفایل مورد " "استفاده قرار گیرد ." msgid "options_syncUnsupportedHelp" msgstr "" "همگام سازی گزینه ها در پلت فرم یا مرورگر شما پشتیبانی نمی شود. در حال حاضر ، " "فقط مرورگر Chrome روی دسکتاپ پشتیبانی می شود." msgid "options_profileSyncDisabled" msgstr "همگام سازی برای این پروفایل غیرفعال میباشد ." msgid "options_profileSyncDisabled_quotaPerItem" msgstr "" "همگام سازی برای این پروفایل به دلیل استفاده ی زیاد از فضای حافظه غیرفعال شده " "است ." msgid "options_profileTabPrefix" msgstr "نمایه :: " msgid "options_renameProfile" msgstr "تغییر نام" msgid "options_deleteProfile" msgstr "حذف" msgid "options_profileExportRuleList" msgstr "انتشار لیست قوانین" msgid "options_profileExportRuleListHelp" msgstr "قوانین تغییر را به صورت تکست برای انتشار خروجی بگیر ." msgid "options_profileExportPac" msgstr "برون‌ریزی PAC" msgid "options_profileUnsupported" msgstr "نوع $TYPE$! برای پروفایل پشتیبانی نمیشود!" msgid "options_profileUnsupportedHelp" msgstr "این گزینه ممکن است خراب شده باشد ، یا از یک ورژن جدیدی از برنامه باشد ." msgid "options_profileEditSource" msgstr "ویرایش سورس کد" msgid "options_profileEditSourceHelp" msgstr "نمایش کمک درباره ی فرمت سورس کد" msgid "options_profileEditSourceHelpUrl" msgstr "" "https://github.com/FelisCatus/SwitchyOmega/wiki/SwitchyOmega-conditions-" "format#result-profile" msgid "options_group_proxyServers" msgstr "کارسازهای پیشکار" msgid "options_proxy_scheme" msgstr "طرحواره" msgid "options_proxy_protocol" msgstr "شیوه‌نامه" msgid "options_proxy_server" msgstr "کارساز" msgid "options_proxy_port" msgstr "درگاه" msgid "options_proxy_auth" msgstr "هویت‌سنجی" msgid "options_proxy_authNotSupported" msgstr "" "مرورگر شما از احراز هویت پروکسی $ PROTOCOLDISP $ پشتیبانی نمی کند! لطفاً این " "موضوع را به SwitchyOmega گزارش نکنید. در عوض با پشتیبانی مرورگر خود تماس " "بگیرید." msgid "options_proxy_authAllWarningPac" msgstr "" "اخطار : نام کاربری / رمز عبور ممکن است برای سرور های غیرمنتظره توسط اسکریپت " "PAC بازگشتی فرستاده شود ." msgid "options_proxy_authAllWarningPacUrl" msgstr "" "قبل از ارسال هرگونه اطلاعات حساس ، لطفا از اعتبار اسکریپ فراهم شده در ادرس " "بالا اطمینان حاصل فرمایید ." msgid "options_proxy_authAllWarningPacScript" msgstr "" "قبل از ارسال هرگونه اطلاعات حساس ،لطفا از اعتبار اسکریپ فراهم شده در پایین " "اطمینان حاصل فرمایید ." msgid "options_proxy_authReferencedWarning" msgstr "" "در ضمن ، استفاده از این پروفایل در دیگر پروفایل ها ( به طور مثال : پروفایل " "متغیر ) ممکن است باعث ارسال نام کاربری / رمز به سرور های تعیین شده در دیگر " "پروفایل ها شود." msgid "options_scheme_default" msgstr "(پیش‌گزیده)" msgid "options_protocol_direct" msgstr "مستقیم" msgid "options_protocol_useDefault" msgstr "(استفاده از پیش‌گزیده)" msgid "options_proxy_single" msgstr "استفاده از پروکسی بالا برای همه ی پروتکل ها." msgid "options_proxy_expand" msgstr "نمایش پیش‌رفته" msgid "options_group_bypassList" msgstr "لیست سیاه" msgid "options_bypassListHelp" msgstr "" "سرورهایی که نمیخواهید برای آن ها از پروکسی استفاده کنید : ( هرکدام در یک خط " ". )" msgid "options_bypassListHelpLinkText" msgstr "( فرانویسه و بیشتر فراهم است .... )" msgid "options_group_pacUrl" msgstr "نشانی PAC" msgid "options_pacUrlHelp" msgstr "" "اسکریپ PAC از این آدرس بروزرسانی میشود . درصورت خالی بودن ، اسکریپت زیر به " "صورت مستقیم استفاده میشود ." msgid "options_pacUrlFile" msgstr "" "پروفایل های PAC به همراه فایل : آدرس ها تنها میتوانند مستقیما اعمال شوند . " "به دلیل محدودیت مرورگر فایل های محلی دسترسی قابل دسترسی نمیباشند که سبب " "میشود که نتوان از آن ها به عنوان نتایج پروفایل استفاده کرد." msgid "options_pacUrlFileDisabled" msgstr "" "از اینرو ، شما نمیتوانید از فایل های PAC محلی استفاده نمایید . شما میتوانید " "یک پروفایل PAC جدید بسازید اگر واقعا نیاز هست ." msgid "options_group_pacScript" msgstr "کدنوشتهٔ PAC" msgid "options_pacScriptLastUpdate" msgstr "دانلود اسکریپت PAC در تاریخ $TIME$:" msgid "options_pacScriptObsolete" msgstr "" "اسکریپ PAC به دلیل تغییر آدرس منسوخ میباشد . دکمه ی دانلود بالا را برای بروز " "رسانی فشاردهید ." msgid "options_group_virtualProfile" msgstr "نمایهٔ مجازی" msgid "options_virtualProfileTarget" msgstr "هدف" msgid "options_virtualProfileTargetHelp" msgstr "" "در هنگام اعمال این پروفایل ، دقیقا همانند پروفایل انتخاب شده ی پایینی عمل " "میکند ." msgid "options_group_virtualProfileReplace" msgstr "مهاجرت به پروفایل مجازی" msgid "options_virtualProfileReplace" msgstr "پروفایل هدف را جایگزین کنید" msgid "options_virtualProfileReplaceHelp" msgstr "" "می توانید گزینه های موجود را برای استفاده از این نمایهٔ مجازی به جای " "$PROFILE$ مهاجرت دهید. انجام این کار همهٔ قوانین موجود در مورد $PROFILE$ را " "نیز به‌روز خواهد کرد و آن‌ها را به این نمایهٔ مجازی منتقل می‌کند تا نمایهٔ " "نتیجه‌شان بتواند این‌جا واپایش شود." msgid "options_group_ruleListConfig" msgstr "تنظیمات لیست قوانین" msgid "options_ruleListFormat" msgstr "فرمت لیست قوانین" msgid "options_group_ruleListResult" msgstr "نتایج پروفایل های لیست قوانین" msgid "options_ruleListMatchProfile" msgstr "انطباق پروفایل" msgid "options_ruleListDefaultProfile" msgstr "پروفایل پیش فرض" msgid "options_group_ruleListUrl" msgstr "آدرس لیست قوانین" msgid "options_ruleListUrlHelp" msgstr "" "لیست قوانین از این آدرس به روز رسانی میشود ، در صورت خالی بودن ، متن بعدی " "پردازش میشود." msgid "options_group_ruleListText" msgstr "متن لیست قوانین" msgid "options_ruleListLastUpdate" msgstr "سیاههٔ قوانین بارگیری شده در $TIME$:" msgid "options_ruleListObsolete" msgstr "" "لیست قوانین به دلیل تغییر آدرس منسوخ میباشد . دکمه ی دانلود بالا را برای " "بروز رسانی فشاردهید ." msgid "options_group_switchRules" msgstr "قوانین سوییچ" msgid "options_sort" msgstr "چینش" msgid "options_conditionType" msgstr "نوع شرط" msgid "options_showConditionTypeHelp" msgstr "نمایش کمک" msgid "options_conditionDetails" msgstr "جزییات شرط" msgid "options_resultProfile" msgstr "نمایه" msgid "options_conditionActions" msgstr "کنش‌ها" msgid "options_addCondition" msgstr "افزودن شرط" msgid "options_cloneRule" msgstr "شبیه‌سازی" msgid "options_ruleNote" msgstr "یادداشت" msgid "options_switchAttachedProfileInCondition" msgstr "قوانین لیست قوانین" msgid "options_switchAttachedProfileInConditionDetails" msgstr "( هرگونه درخواست منطبق بر لیست پایین )" msgid "options_switchAttachedProfileInConditionDisabled" msgstr "( قوانین لیست قوانین غیرفعالند )" msgid "options_switchDefaultProfile" msgstr "پیش‌گزیده" msgid "options_hostLevelsBetween" msgstr "≤ سطوح میزبان ≤" msgid "options_hourBetween" msgstr "≤ ساعت کنونی ≤" msgid "options_weekDayShort_0" msgstr "ی" msgid "options_weekDayShort_1" msgstr "د" msgid "options_weekDayShort_2" msgstr "س" msgid "options_weekDayShort_3" msgstr "چ" msgid "options_weekDayShort_4" msgstr "پ" msgid "options_weekDayShort_5" msgstr "آ" msgid "options_weekDayShort_6" msgstr "ش" msgid "options_group_conditionHelp" msgstr "درباره ی انوع شروط" msgid "options_group_attachProfile" msgstr "واردکردن لیست های قوانین آنلاین" msgid "options_attachProfile" msgstr "افزوردن لیست قوانین" msgid "options_attachProfileHelp" msgstr "" "شما میتوانید با افزودن لیست قوانین از مجموعه های آنلاین شروطی که توسط دیگران " "منتشر شده استفاده نمایید ." msgid "options_modalHeader_welcome" msgstr "به SwitchyOmega خوش آمدید" msgid "options_welcomeNormal" msgstr "" "شما با موفقیت SwitchyOmega را نصب نموده اید ، برترین تغییر دهنده ی پروکسی." msgid "options_welcomeNormalGuide" msgstr "" "لطفا به SwitchyOmega از طریق صفجه ی تنظیمات ، پروکسی های خود را معرفی کنید ." msgid "options_welcomeUpgrade" msgstr "" "شما با موفقیت به SwitchyOmega ارتقا پیدا کرده اید ، نگران نباشید ، تمامی " "تنظیمات شما به طور کامل حفظ شده اند ." msgid "options_welcomeUpgradeGuide" msgstr "خب بریم سراغ آموزش کوچیکی از صفحه ی تنظیمات جدید." msgid "options_guideNext" msgstr "بعدی" msgid "options_guideDone" msgstr "انجام شد" msgid "options_guideSkip" msgstr "بیخیال آموزش" msgid "options_modalHeader_applyOptions" msgstr "ثبت تنظیمات" msgid "options_optionsNotSaved" msgstr "" "تغییرات شما بر روی تنظیمات ذخیره نشده است و درصورت ادامه از بین خواهند رفت !" msgid "options_applyOptionsRequired" msgstr "قبل از ادامه دادن تنظمات خود را ثبت کنید." msgid "options_applyOptionsConfirm" msgstr "آیا میخواهید تنظیمات خود را ذخیره و اعمال کنید ؟" msgid "options_modalHeader_renameProfile" msgstr "تغییرنام پروفایل" msgid "options_renameProfileName" msgstr "اسم جدید پروفایل" msgid "options_profileNameConflict" msgstr "یک پروفایل با این نام وجود دارد." msgid "options_profileNameReserved" msgstr "نام های پروفایل که با دو\"_\"(خط زیر) شروع میشوند رزرو میباشند." msgid "options_profileNameHidden" msgstr "" "پروفایل هایی که نامشان با دو زیر خط \"_\" شروع میشوند در منوی بالاپر مخفی " "میباشند . هرجند ، در مکان هایی مانند نتایج پروفایل متغیر ، قابل استفاده اند." msgid "options_modalHeader_replaceProfile" msgstr "جایگزینی پروفایل" msgid "options_replaceProfile" msgstr "جایگزینی پروفایل" msgid "options_replaceProfileConfirm" msgstr "آیا قصد جایگزینی $FromProfile$ را با $ToProfile$ دارید ؟" msgid "options_replaceProfileHelp" msgstr "" "در صورت ادامه ، تمامی قوانین مربوط به $FromProfile$ بروز رسانی میشوند تا عضو " "$ToProfile$ شوند . دیگر تنظیمات ، همانند پروفایل آغازین و تغییر سریع به صورت " "مناسب تغییر میکنند . هرچند ، این دو پروفایل تغییر یا حذف نمیشوند ." msgid "options_replaceProfileSuccess" msgstr "تنظیمات بروزرسانی شد." msgid "options_modalHeader_deleteProfile" msgstr "حذف پروفایل" msgid "options_deleteProfileConfirm" msgstr "آیا از حذف نمودن پروفایل های زیرمطمئن هستید ؟" msgid "options_modalHeader_cannotDeleteProfile" msgstr "عدم موفقیت در حذف پروفایل" msgid "options_profileReferredBy" msgstr "این پروفایل قابل حذف نمیباشد چونکه توسط این پروفایل ها صدا میشود :" msgid "options_modifyReferringProfiles" msgstr "" "قبل از حذف شما باید این پروفایل ها را تغییر دهید و از صدا زدن این پروفایل " "جلوگیری کنید ." msgid "options_profileNameEmpty" msgstr "اسم پروفایل نمیتواند خالی باشد." msgid "popup_title" msgstr "بالاپر SwitchyOmega" msgid "options_modalHeader_proxyAuth" msgstr "تصدیق پروکسی" msgid "options_proxyAuthUsername" msgstr "نام کاربری" msgid "options_proxyAuthPassword" msgstr "گذرواژه" msgid "options_proxyAuthShowPassword" msgstr "نمایش رمز عبور" msgid "options_proxyAuthHidePassword" msgstr "مخفی کردن رمز عبور" msgid "options_proxyAuthNone" msgstr "بدون تصدیق" msgid "options_modalHeader_deleteRule" msgstr "حذف قانون" msgid "options_deleteRuleConfirm" msgstr "واقعا قصد حذف نمودن قانون را دارید ؟" msgid "options_deleteRule" msgstr "حذف" msgid "options_modalHeader_resetRules" msgstr "بازنشانی قوانین" msgid "options_resetRulesConfirm" msgstr "" "آیا از تغییر دادن نتایج پروفایل تمامی قوانین به پروفایل زیر مطمئن هستید ؟" msgid "options_resetRules" msgstr "بازنشانی قوانین" msgid "options_resetRules_help" msgstr "تنظیم پورفایل برای تمام کاربران" msgid "options_modalHeader_deleteAttached" msgstr "حذف لیست قوانین" msgid "options_deleteAttachedConfirm" msgstr "آیا از حذف نمودن لیست قوانین از پروفایل فعلی مطمئن هستید ؟" msgid "options_ruleListLineCount" msgstr "قوانین : $COUNT$ خط" msgid "options_deleteAttached" msgstr "حذف لیست قوانین" msgid "options_modalHeader_newProfile" msgstr "پروفایل جدید" msgid "options_newProfileName" msgstr "اسم پروفایل" msgid "options_profileType" msgstr "لطفا نوع پروفایل را انتخاب نمایید :" msgid "options_profileTypeFixedProfile" msgstr "پروفایل پروکسی" msgid "options_profileDescFixedProfile" msgstr "تونل ترافیک از طریق پروکسی سرور ها." msgid "options_profileTypePacProfile" msgstr "پرفایل PAC" msgid "options_profileDescPacProfile" msgstr "انتخاب پروکسی ها از طریق اسکریپ PAC آنلاین/محلی ." msgid "options_profileDescMorePacProfile" msgstr "" "شما در صورتی که یک اسکریپت PAC یا آدرس مرجوعه به آن را دارید نیازمند این " "میشوید .درصورت عدم آشنایی با PAC تلاش برای ساخت یک نمونه نکنید ." msgid "options_profileTypeSwitchProfile" msgstr "پروفایل متغیر" msgid "options_profileDescSwitchProfile" msgstr "" "اعمال پروفایل های مختلف به صورت خودکار بر روی شروط گوناگون از جمله دامنه یا " "الگو ها .\n" " شما میتوانید از قوانین منتظر شده ی آنلاین برای جا به جایی راحتر بین پروفایل " "نیز استفاده کنید ( جایگزین مود AutoSwitch + لیست قوانین .)" msgid "options_profileTypeRuleListProfile" msgstr "پروفایل لیست پروفایل" msgid "options_profileDescRuleListProfile" msgstr "استفاده ی مجدد از مجموعه ی قوانین آنلاین منتشر شده توسط دیگران ." msgid "options_profileTypeVirtualProfile" msgstr "پروفایل مجازی" msgid "options_profileDescVirtualProfile" msgstr "" "یک پروفایل مجازی همانند هرگونه پروفایل دیگر در حین تقاضا عمل میکند . با " "SwitchProfile خوب عمل میکند ، که این امکان را به شما میدهد که نتایج چندین " "شرط را با یک کلیک تغییر دهید." msgid "options_createProfile" msgstr "ایجاد" msgid "options_modalHeader_resetOptions" msgstr "ریست کردن تنظیمات" msgid "options_resetOptionsConfirm" msgstr "" "آیا از ریست کردن تنظیمات اطمینان دارید ؟ تمامی پروفایل ها و تنظیمات از بین " "خواهند رفت !" msgid "options_formInvalid" msgstr "لطفا خطاهای موجود در صفحه را تصحیح کنید." msgid "options_profileNotFound" msgstr "پروفایل $PROFILE$ وجود ندارد ! تنظیمات ممکن است خراب شده باشند ." msgid "options_resetSuccess" msgstr "تنظیمات ریست شد ." msgid "options_saveSuccess" msgstr "تنظیمات ذخیره شد ." msgid "options_importSuccess" msgstr "تنظیمات با موفقیت فراگیری شدند ." msgid "options_importFormatError" msgstr "فایل پشتیبان غیرمعتبر !" msgid "options_importDownloadError" msgstr "خطا در حین دانلود فایل پشتیبان !" msgid "options_profileDownloadSuccess" msgstr "پروفایل با موفقیت بروزسانی شد ." msgid "options_profileDownloadError" msgstr "خطا در حین دانلود داده ی پروفایل !" msgid "options_profileDownloadError_NetworkError" msgstr "هنگام به‌روز رسانی خطای در شبکه اینترنت رخ داد." msgid "options_profileDownloadError_HttpError" msgstr "هنگام به روز رسانی خطای HTTP ($ STATUS $) رخ داد." msgid "options_profileDownloadError_HttpNotFoundError" msgstr "آدرس پروفایل بر روی سرور یافت نشد. لطفا دوباره بررسی کنید." msgid "options_profileDownloadError_HttpServerError" msgstr "سرور ریموت با خطای ($STATUS$) در هنگام بروز رسانی پاسخ داد." msgid "options_profileDownloadError_ContentTypeRejectedError" msgstr "" "دیتای دانلود شده نامعتبر است! میتوانید آدرس پروفایل را برای بررسی در مرورگر " "باز کنید." msgid "options_downloadProfileNow" msgstr "هم اکنون پروفایل را دانلود کنید" msgid "options_guide_fixedProfileStep" msgstr "" "نمایهٔ پیشکار شامل تنظیماتی چون درگاه و آی‌پی کارساز پیشکار " "است.
نمایه‌ها واحدهای پیکربندی پایهٔ سوییچی اومگا هستند.
از پیش نمایهٔ " "نمونه‌ای برایتان ایجاد کرده‌ایم. گشودنش را بیازمایید." msgid "options_guide_fixedServersStep" msgstr "" "می توانید سرور و پورت پروکسی خود را در اینجا به دلخواه پر کنید.
" "SwitchyOmega با هیچ سرور پروکسی ارائه نمی شود .
بدانید چه چیزی " "باید در اینجا پر شود." msgid "options_guide_autoSwitchProfileStep" msgstr "" "می توانید به SwitchyOmega بگویید که از طریق تغییر پروفایل به طور " "خودکار بین پراکسی جابجا شود.
با این حال ، در این راهنمای سریع نمی توان " "ویژگی های آن را پوشش داد.
می توانید این نمایه را باز کنید تا قفل قدرت " "آن کمی باز شود. زمان بعد" msgid "options_guide_addMoreProfilesStep" msgstr "" "به پروفایل بیشتری نیازمندید ؟ شما همیشه میتوانید پروکسی ، سوییچ و یا " "پروفایل های دیگری
را برای نیاز های پروکسی خود اضافه نمایید .
" "از پروکسی زدن لذت ببرید !" msgid "options_guide_conditionStep" msgstr "" "SwitchyOmega میتوانید پروفایل های متفاوتی را بر اساس شروط تقاضا کند " ".
برای مثال ، شرط فرانویسه ی میزبان به شما این قابلیت را میدهد که " "پروفایلی برای تمامی آدرس های یک دامنه تعیین کنید ." msgid "options_guide_conditionTypeStep" msgstr "" "برای مطابقت با نشانی وب میزبان یا کامل می توانید از انواع شرایط مختلف " "استفاده کنید.
روی علامت سوال کلیک کنید تا مرجع نوع باز شود." msgid "options_guide_conditionProfileStep" msgstr "" "SwitchyOmega نمایه انتخاب شده را در اینجا برای هر درخواستی که با شرایط " "مطابقت دارد اعمال می کند.
نمایه \"[مستقیم]\" باعث می شود " "درخواست بدون هیچ پراکسی ارسال شود." msgid "options_guide_switchDefaultStep" msgstr "" "اگر هیچ گونه شرطی منطبق بر درخواست نباشد ، پروفایل \"پیش فرض\" استفاده خواهد " "شد .
شروط همیشه از بالا به پایین در نظر گرفته میشوند .
شما " "میتوان نظم آن را با گرفتن آیکون نظم (sort) عوض کنید ." msgid "options_guide_applySwitchProfileStep" msgstr "" "وقتی انجام تنظیمات پروفایل متغییر(سوییچ) به پایان رسید ، فراموش نکنید که " "در منونی بالاپر(popup) آن را فعال کنید.
آیکون به شما نتیجه ی " "نهایی پروفایل اعمال شده در تب جاری را نشان میدهد
شناور " "ماندن بر روی آیکون توضیحات اجمالی به شما نشان خواهد داد ." msgid "popup_externalProfile" msgstr "(پروفایل خارجی)" msgid "popup_externalProfileName" msgstr "نام پروفایل" msgid "popup_proxyNotControllable_app" msgstr "" "تنظیمات پروکسی توسط دیگر برنامه (ها) یا افزونه (ها) میدیریت میشوند . لطفا یا " "آن ها را غیرفعال کرده یا برنامه یا افزونه ی مشکل ساز را حذف نمایید ." msgid "popup_proxyNotControllable_policy" msgstr "" "تنظیمات پروکسی توسط policy ها سیستم کنترل میشوند . لطفا با آدمین تماس بگیرید " "." msgid "popup_proxyNotControllable_unknown" msgstr "" "تنظیمات پروکسی قابل کنترل نیست . لطفا تنظیمات سیستم یا مرورگر را بررسی کنید." msgid "popup_proxyNotControllable_disabled" msgstr "" "تنظیمات پروکسی بخاطر درخواست مستقیم دیگر برنامه (ها) یا افزونه (ها) غیرفعال " "شده است ." msgid "popup_proxyNotControllable_upgrade" msgstr "تنظیمات پروکسی توسط ورژن جدیدی از SwitchyOmega کنترل میشود ." msgid "popup_proxyNotControllableDetails" msgstr "" "شما نمیتوانید پروفایل ها را توسط SwitchyOmega عوض نمایید ، مگر اینکه مشکلات " "بالا را حل نمایید ." msgid "popup_proxyNotControllableDetails_upgrade" msgstr "" "شما نمیتوانید از دو (یا چند) ورژن SwitchyOmega به طور همزمان استفاده کنید . " "لطفا یکی از آن ها را غیرفعال کنید ." msgid "popup_proxyNotControllableManage" msgstr "میدیریت افزونه" msgid "popup_addConditionTo" msgstr "افزودن شرط به" msgid "popup_addCondition" msgstr "افزودن شرط" msgid "popup_showOptions" msgstr "گزینه‌ها" msgid "popup_reportIssues" msgstr "گزارش مشکلات" msgid "popup_errorLog" msgstr "ذخیره لاگ خطا" msgid "popup_requestErrorCount" msgstr "$COUNT$ خطای منبع" msgid "popup_requestErrorHeading" msgstr "عدم موفقیت در بارگزاری منابع" msgid "popup_requestErrorWarning" msgstr "" "بارگزاری تعدا کمی از منابع بخاطر مشکلات شبکه ، سرور پروکسی یا صفحه ی وب به " "مشکل برخورد ." msgid "popup_requestErrorWarningHelp" msgstr "" "SwitchyOmega تنها گزارش دهنده این خطاها میباشد ، نه ایجاد کننده ی آن ها ." msgid "popup_requestErrorAddCondition" msgstr "" "شما میتوانید دامین های زیر را بررسی کنید و در صورت نیاز از پروکسی برای آن ها " "استفاده نمایید ." msgid "popup_requestErrorCannotAddCondition" msgstr "" "شما در صورتی میتوانید شرط متغییر ( سوییچ) برای آن ها تعیین کنید که از " "پروفایل متغییر استفاده کرده باشید ." msgid "popup_configureMonitorWebRequests" msgstr "تنظیم مانیتور شبکه" msgid "options_resultProfileForSelectedDomains" msgstr "از این پروفایل برای تمامی دامنه های منتخب استفاده کن" msgid "options_pac_profile_unsupported_moz" msgstr "" "نمایه(پروفایل) های PAC در به دلیل محدودیت های تکنیکی در موزیلا فایرفاکس کار " "نخواهند کرد!" msgid "popup_issueTemplate" msgstr "" "\n" "\n" "\n" "\n" "SwitchyOmega $projectVersion$↵\n" "$userAgent$" msgid "browserAction_profileDetails_PacProfile" msgstr "( اسکریپت PAC )" msgid "browserAction_profileDetails_SystemProfile" msgstr "( کنترل شده توسط دیگر افزونه ها یا محیط )" msgid "browserAction_profileDetails_DirectProfile" msgstr "(عدم استفاده از هرگونه پروکسی)" msgid "browserAction_profileDetails_SwitchProfile" msgstr "(جابه جایی بر اساس شروط)" msgid "browserAction_profileDetails_RuleListProfile" msgstr "(جابه جایی بر اساس لیست قوانین)" msgid "browserAction_titleNormal" msgstr "SwitchyOmega :: $PROFILE$" msgid "browserAction_titleWithResult" msgstr "" "SwitchyOmega :: $1:PROFILE$\n" " $3:DETAILS$" msgid "browserAction_titleNewerOptions" msgstr "" "خطا: برای بارگیری گزینه های ذخیره شده ، نسخه جدیدتر SwitchyOmega مورد نیاز " "است." msgid "browserAction_titleOptionError" msgstr "" "خطا : تنظیمات دخیره شده خراب شده اند .برای ریست کردن تنظیمات کلیک کنید ." msgid "browserAction_titleDownloadFail" msgstr "اخطار: شکست در دانلود اسکریپت PAC و/یا لیست های قوانین ." msgid "browserAction_titleExternalProxy" msgstr "نکته : تنظیمات پروکسی هم اکنون توسط دیگر برنامه (ها) مدیریت میشود ." msgid "browserAction_titleInspect" msgstr "[بررسی] $URL$" msgid "browserAction_defaultRuleDetails" msgstr "(پیش‌گزیده)" msgid "browserAction_directResult" msgstr "مستقیم" msgid "browserAction_attachedPrefix" msgstr "(RL) " msgid "browserAction_tempRulePrefix" msgstr "(موقت) " msgid "contextMenu_inspectPage" msgstr "بررسی پروکسی مورد استفاده برای این صفحه" msgid "contextMenu_inspectFrame" msgstr "بررسی پروکسی مورد استفاده برای این فریم" msgid "contextMenu_inspectLink" msgstr "بررسی پروکسی مورد استفاده اگر لینک باز شود" msgid "contextMenu_inspectElement" msgstr "بررسی پروکسی مورد استفاده برای این المان" msgid "contextMenu_enableQuickSwitch" msgstr "فعال سازی تغییر سرعتی" msgid "about_title" msgstr "درباره" msgid "about_app_description" msgstr "ابزار پیکربندی پراکسی" msgid "about_version" msgstr "نسخه $VERSION$" msgid "about_experimental_warning_moz" msgstr "" "پشتیبانی از فایرفاکس کاملا آزمایشی میباشد! در صورت مواجه با خطا، لطفا از " "طریق دکمه ی زیر ما را در جریان بگذارید." msgid "about_disclaimer_networkService" msgstr "SwitchyOmega پروکسی، وی پی ان یا دیگر خدمات شبکه ای فراهم نمیکند." msgid "about_disclaimer_privacy" msgstr "" "SwitchyOmega شما را ردیابی نمی کند یا تبلیغاتی را در صفحات وب درج نمی کند. " "لطفاً خط مشی رازداری ما را ببینید." msgid "about_help" msgstr "" "بازم سوال دارید؟ نیاز به کمک دارید؟ لطفا به صفحه FAQ مراجعه بفرمایید." msgid "about_copyright" msgstr "" "کپی رایت 2012-2017 " "نویسندگان The SwitchyOmega . کلیه حقوق محفوظ است، ترجمه شده به فارسی " "توسط گودرز جعفری." msgid "about_credits" msgstr "" "SwitchyOmega به کمک پروژه ی متن باز SwitchyOmega و دیگر پروژه های متن بازمیسر " "شده است." msgid "about_license" msgstr "" "SwitchyOmega یک نرم " "افزار آزاد ، تحت لیسانس" "GNU نسخه ی 3 به بعد میباشد." ================================================ FILE: omega-locales/fr/LC_MESSAGES/omega-web.po ================================================ msgid "" msgstr "" "Project-Id-Version: SwitchyOmega 2.3.3\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2015-02-13 10:29+0000\n" "PO-Revision-Date: 2022-02-02 14:52+0000\n" "Last-Translator: My \n" "Language-Team: French \n" "Language: fr\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n > 1;\n" "X-Generator: Weblate 4.11-dev\n" msgid "appNameShort" msgstr "SwitchyOmega" msgid "manifest_app_name" msgstr "Proxy SwitchyOmega" msgid "manifest_app_description" msgstr "" "Gérez et alternez entre plusieurs serveurs proxy rapidement et facilement." msgid "manifest_icon_default_title" msgstr "Chargement…" msgid "upgrade_profile_auto" msgstr "Automatique" msgid "profile_direct" msgstr "[Direct]" msgid "profile_system" msgstr "[Proxy du système]" msgid "condition_HostWildcardCondition" msgstr "Hôtes (wildcard)" msgid "condition_help_HostWildcardCondition" msgstr "" "Correspondance des hôtes (noms de domaines) par joker.
L’astérisque " "* correspond à zéro ou plusieurs caractères.
Le point " "d'interrogation ? correspond à exactement un " "caractère.

Les règles de correspondance qui commencent par " "*. ont un fonctionnement différent, uniquement avec les règles " "d'hôtes génériques.
Exemple : *.example.com correspond à " "www.example.com ET aussi à example.com.
Pour ne faire correspondre " "que les sous-domaines, utilisez deux astérisques : " "**.example.com." msgid "condition_HostRegexCondition" msgstr "Hôte (RegExp)" msgid "condition_help_HostRegexCondition" msgstr "" "À la différence des règles d'hôtes génériques, une " "expression rationnelle est utilisée pour faire correspondre les hôtes (" "noms de domaines).
Les expressions rationnelles peuvent être compliquées " "à écrire (et à relire).
Il est conseillé d'utilisé les jokers dans le cas " "général, et de n'utiliser les expressions rationnelles que dans le cas où " "les autres types de correspondance ne peuvent être utilisés." msgid "condition_HostLevelsCondition" msgstr "Niveaux d'hôte" msgid "condition_help_HostLevelsCondition" msgstr "" "Correspond à la demande si et seulement si le niveau de l'hôte est dans la " "plage donnée.
Le niveau d'hôte est défini comme le nombre de segments " "séparés par un point de l'hôte (nom de domaine).
Par exemple : " "www.example.com correspond à un niveau d'hôte de 3, alors que " "internal correspond à un niveau 1." msgid "condition_IpCondition" msgstr "IP Literals" msgid "condition_help_IpCondition" msgstr "" "Correspond à la demande si et seulement si l'hôte est une adresse IP " "littérale et est dans le sous-réseau, comme spécifié par lanotation CIDR.
Par exemple, étant donné la règles " "127.0.0.1/16, cela correspond à toute adresse IP comme 127" ".0.*.*.
Donc 127.0.0.1 correspond alors que ce n'est " "pa sle cas pour 127.1.0.0. Les noms d'hôte comme " "localhost ne correspondront jamais parce qu'ils ne sont pas des IP littérales." msgid "condition_UrlWildcardCondition" msgstr "URL wildcard" msgid "condition_help_UrlWildcardCondition" msgstr "" "Matches URLs of the request by wildcard.
See the Host wildcard section " "above for a quick wildcard reference.
Note that URL wildcards are not " "specially treated (no subdomain magic as in Host wildcard).
So *://" "*.example.com/* matches http://www.example.com/ but does not " "match http://example.com/." msgid "condition_UrlRegexCondition" msgstr "URL regex" msgid "condition_help_UrlRegexCondition" msgstr "" "Matches URL by extremely powerful regular expression.
However, regular " "expressions can be hard to construct (and read).
It is recommended to use " "wildcards for most cases and only use regex for conditions that cannot be " "achieved by any other condition type." msgid "condition_KeywordCondition" msgstr "Mot-clé" msgid "condition_help_KeywordCondition" msgstr "" "A keyword condition matches if the URL protocol is HTTP, and the pattern is " "an exact sub-string of the URL.
It behaves like the URL wildcard pattern " "http://*pattern*, where pattern is the keyword " "pattern.
Keyword conditions are useful if you want to bypass a firewall " "blocking some keywords in the URL, by requesting such URLs through a proxy." msgid "condition_FalseCondition" msgstr "(Désactivé)" msgid "condition_details_FalseCondition" msgstr "(Condition ignored when matching)" msgid "condition_help_FalseCondition" msgstr "" "You can disable a condition by setting its type to (Disabled). " "A Disabled condition act as if it does not exist.
This feature can be " "used to disable conditions temporarily.
Disabled conditions still hold " "the previous information (like patterns) and can be re-enabled by setting " "the condition type back to the previous type." msgid "condition_TimeCondition" msgstr "Heure actuelle" msgid "condition_help_TimeCondition" msgstr "" "Matches if the current local time is in the range defined by " "starting hour and ending hour, both inclusive.
" "Local time, starting hour and ending hour are all calculated in " "24-hour format (from 0 to 23).
" "The calculation happens roughly at the moment when the request is sent." msgid "condition_WeekdayCondition" msgstr "Jour de la semaine" msgid "condition_help_WeekdayCondition" msgstr "" "Matches if the current day of week is selected in condition details. " "Day is calculated according to local timezone.
" "The request and its URL don't matter to this condition. " "The result is solely based on the day of the week when the request is sent." msgid "condition_alert_fullUrlLimitation" msgstr "" "Full URL matching is no longer possible for https:// " "URLs as of Chrome 52. " "" "Learn more..." msgid "condition_alert_fullUrlLimitationLink" msgstr "https://github.com/FelisCatus/SwitchyOmega/wiki/Chromium-Full-URL-Limitation" msgid "condition_group_default" msgstr " " msgid "condition_group_host" msgstr "Host" msgid "condition_group_url" msgstr "Url" msgid "condition_group_special" msgstr "Spécial" msgid "ruleListFormat_Switchy" msgstr "Switchy" msgid "ruleListFormat_AutoProxy" msgstr "AutoProxy" msgid "ruleList_usageUrl" msgstr "https://github.com/FelisCatus/SwitchyOmega/wiki/RuleListUsage" msgid "ruleList_error_resultNotEnabled" msgstr "Missing '@with result' directive!" msgid "ruleList_error_unknownProfile" msgstr "Unknown profile: $PROFILE$" msgid "ruleList_error_missingResultProfile" msgstr "Missing result profile name at Line $LNO$: $SOURCE$" msgid "ruleList_error_invalidRule" msgstr "Invalid rule at Line $LNO$: $SOURCE$" msgid "ruleList_error_noDefaultRule" msgstr "Missing default rule with catch-all '*' condition!" msgid "dialog_close" msgstr "Close" msgid "dialog_save" msgstr "Save changes" msgid "dialog_ok" msgstr "OK" msgid "dialog_cancel" msgstr "Cancel" msgid "inputClear_clear" msgstr "Clear" msgid "inputClear_restore" msgstr "Restore" msgid "options_title" msgstr "SwitchyOmega Options" msgid "options_experimental_badge" msgstr "α" msgid "options_navHeader_setting" msgstr "Settings" msgid "options_navHeader_profiles" msgstr "Profiles" msgid "options_navHeader_actions" msgstr "Actions" msgid "options_tab_ui" msgstr "Interface" msgid "options_tab_general" msgstr "General" msgid "options_tab_importExport" msgstr "Import/Export" msgid "options_newProfile" msgstr "New profile…" msgid "options_apply" msgstr "Apply changes" msgid "options_discard" msgstr "Discard changes" msgid "options_reset" msgstr "Reset options" msgid "options_group_miscOptions" msgstr "Misc Options" msgid "options_confirmDeletion" msgstr "Confirm on condition deletion." msgid "options_refreshOnProfileChange" msgstr "Refresh current tab on profile change." msgid "options_showInspectMenu" msgstr "Allow inspecting proxy used for page elements via context menu." msgid "options_addConditionsToBottom" msgstr "Put new conditions added using the popup to the bottom of the list." msgid "options_group_keyboardShortcut" msgstr "Keyboard Shortcut" msgid "options_menuShortcutHelp" msgstr "" "Pressing the shortcut will open the switch popup menu. (Defaults to Alt+Shift" "+O)." msgid "options_menuShortcutMore" msgstr "" "The items in the popup menu can also be accessed using the keyboard. Press ? " "(or /) in the menu to learn more." msgid "options_menuShortcutConfigure" msgstr "Configure shortcut" msgid "options_group_switchOptions" msgstr "Switch Options" msgid "options_startupProfile" msgstr "Startup Profile" msgid "options_startupProfile_none" msgstr "(Current profile)" msgid "options_showConditionTypesAdvanced" msgstr "Show advanced condition types" msgid "options_showConditionTypesAdvancedHelp" msgstr "" "Permet l'usage de nouvaux types de conditions complexes. Pour la plupart des " "scénarios, les conditions de base devraient être suffisantes. Cette option " "n'est donc pas recommandée." msgid "options_quickSwitch" msgstr "Quick Switch" msgid "options_cycledProfiles" msgstr "Cycled Profiles" msgid "options_cycledProfilesHelp" msgstr "" "When you click on the icon (or use the shortcut above), the following " "profiles will be applied in their order." msgid "options_cycledProfilesTooFew" msgstr "" "You need to select at least 2 profiles to enable this function! You can drag " "them from the box below." msgid "options_notCycledProfiles" msgstr "Not Cycled Profiles" msgid "options_group_proxyChanges" msgstr "Proxy Changes" msgid "options_revertProxyChanges" msgstr "Revert proxy changes done by other apps." msgid "options_group_conflicts" msgstr "Conflicts" msgid "options_conflicts_introduction" msgstr "" "Sometimes, other apps will also try to control the proxy settings, resulting " "in conflicts. Note that ad blockers and other extensions may also use proxy " "settings under the hood. Such conflicts cannot be avoided due to how the " "browser works." msgid "options_conflicts_lowerPriority" msgstr "" "A red badge like this on the SwitchyOmega icon indicates that another app has " "higher priority so SwitchyOmega cannot control the settings. Please try to " "uninstall SwitchyOmega and reinstall, which should raise SwitchyOmega's " "priority. If you still see conflicts after reinstallation, please consider " "removing the other app causing the conflict." msgid "options_conflicts_higherPriority" msgstr "" "If SwitchyOmega has higher priority, you can give the control back to other " "apps or system settings by selecting $SYSTEMPROFILE$ in the popup menu." msgid "options_showExternalProfile" msgstr "Show popup menu item to import proxy settings from other apps." msgid "options_showExternalProfileHelp" msgstr "" "When $SYSTEMPROFILE$ is selected, you can import the effective proxy settings " "from other apps by selecting $EXTERNALPROFILE$ on the popup menu. " "The settings will be imported as a profile using the name you provide. " "Please note that the imported profile is a snapshot and will not reflect " "any changes from the source app thereafter." msgid "options_group_networkRequests" msgstr "Network Requests" msgid "options_monitorWebRequests" msgstr "Show count of failed web requests for resources in the current tab." msgid "options_monitorWebRequestsHelp" msgstr "" "A yellow badge will be displayed on the icon if some resources fail to load," "
and you can set the profile for such resources conveniently via the " "popup menu." msgid "options_downloadOptions" msgstr "Download Options" msgid "options_downloadOptionsHelp" msgstr "Configure the update frequency of online rule lists and PAC scripts." msgid "options_downloadInterval" msgstr "Download Interval" msgid "options_downloadInterval_15" msgstr "15 Minutes" msgid "options_downloadInterval_60" msgstr "1 Hour" msgid "options_downloadInterval_180" msgstr "3 Hours" msgid "options_downloadInterval_360" msgstr "6 Hours" msgid "options_downloadInterval_720" msgstr "12 Hours" msgid "options_downloadInterval_1440" msgstr "Every day" msgid "options_downloadInterval_never" msgstr "Never" msgid "options_group_importExportProfile" msgstr "Profile" msgid "options_exportPacFile" msgstr "Export as PAC File" msgid "options_exportPacFileHelp" msgstr "" "Export the current profile as a PAC file, so you can use it in other " "browsers." msgid "options_exportProfileHelp" msgstr "To export a profile, use the top-right action bar on the profile page." msgid "options_exportLegacyRuleList" msgstr "" "Export rule lists using Proxy Switchy!/SwitchyPlus/SwitchySharp compatible " "format when possible." msgid "options_exportLegacyRuleListHelp" msgstr "" "Enable this option only if you publish rule lists for users of those " "projects.
Please consider advising your audience to upgrade to " "SwitchyOmega for the improvements." msgid "options_group_importExportSettings" msgstr "Settings" msgid "options_makeBackup" msgstr "Make backup" msgid "options_makeBackupHelp" msgstr "" "Make a full backup of your options (including profiles and all other " "options)." msgid "options_restoreLocal" msgstr "Restore from file" msgid "options_restoreLocalHelp" msgstr "Restore your SwitchyOmega options from a local file." msgid "options_restoreOnline" msgstr "Restore from online" msgid "options_restoreOnlinePlaceholder" msgstr "Options file URL (e.g. 'http://example.com/switchy.bak')" msgid "options_restoreOnlineSubmit" msgstr "Restore" msgid "options_group_syncing" msgstr "Syncing (Experimental)" msgid "options_syncEnable" msgstr "Enable Syncing" msgid "options_syncEnableForce" msgstr "Download from Syncing" msgid "options_syncDisable" msgstr "Disable syncing" msgid "options_syncReset" msgstr "Clear remote copy" msgid "options_syncPristineHelp" msgstr "" "You can now automatically synchronize your settings and profiles across all " "your desktop devices running Chrome browser." msgid "options_syncSyncAlert" msgstr "Your options are automatically synchronized with your other devices." msgid "options_syncSyncHelp" msgstr "" "Please note that you must sign in to Chrome on each of your devices " "(including this one) for the syncing to actually work.
You may check " "this section on other devices to ensure that it is working." msgid "options_syncConflictAlert" msgstr "" "You have uploaded a copy of your options on another device via syncing." msgid "options_syncConflictHelp" msgstr "" "You may download the remote copy to your device if you like.
However, " "doing so would overwrite your existing settings and profiles on this " "device." msgid "options_syncUnsupportedHelp" msgstr "" "Options syncing is not supported on your platform or browser. For now, only " "Chrome browser on desktop is supported." msgid "options_profileSyncDisabled" msgstr "Syncing is disabled for this profile." msgid "options_profileSyncDisabled_quotaPerItem" msgstr "Syncing is disabled for this profile for using too much storage space." msgid "options_profileTabPrefix" msgstr "Profile :: " msgid "options_renameProfile" msgstr "Rename" msgid "options_deleteProfile" msgstr "Delete" msgid "options_profileExportRuleList" msgstr "Publish rule list" msgid "options_profileExportRuleListHelp" msgstr "Export Switch Rules as text format for publishing." msgid "options_profileExportPac" msgstr "Export PAC" msgid "options_profileUnsupported" msgstr "Unsupported profile type $TYPE$!" msgid "options_profileUnsupportedHelp" msgstr "The options could be broken, or from a newer version of this program." msgid "options_profileEditSource" msgstr "Edit source code" msgid "options_profileEditSourceHelp" msgstr "Show help about the source code format" msgid "options_profileEditSourceHelpUrl" msgstr "" "https://github.com/FelisCatus/SwitchyOmega/wiki/SwitchyOmega-conditions-" "format#result-profile" msgid "options_group_proxyServers" msgstr "Proxy servers" msgid "options_proxy_scheme" msgstr "Scheme" msgid "options_proxy_protocol" msgstr "Protocol" msgid "options_proxy_server" msgstr "Server" msgid "options_proxy_port" msgstr "Port" msgid "options_proxy_auth" msgstr "Authentication" msgid "options_proxy_authNotSupported" msgstr "Your browser DOES NOT support $PROTOCOLDISP$ proxy authentication! " "Please do not report this issue to SwitchyOmega. Contact the support for " "your browser instead." msgid "options_proxy_authAllWarningPac" msgstr "" "Warning: The username/password may be sent to unexpected servers returned by " "the PAC script." msgid "options_proxy_authAllWarningPacUrl" msgstr "" "Please make sure that you trust the script provided via the URL above before " "entering sensitive credentials." msgid "options_proxy_authAllWarningPacScript" msgstr "" "Please make sure that you trust the script below before providing sensitive " "credentials." msgid "options_proxy_authReferencedWarning" msgstr "" "Additionally, using this profile in other profiles (e.g. Switch Profile) may " "cause the username/password to be sent to proxy servers configured in other " "profiles." msgid "options_scheme_default" msgstr "(default)" msgid "options_protocol_direct" msgstr "DIRECT" msgid "options_protocol_useDefault" msgstr "(use default)" msgid "options_proxy_single" msgstr "Use the proxy above for all protocols." msgid "options_proxy_expand" msgstr "Show Advanced" msgid "options_group_bypassList" msgstr "Bypass List" msgid "options_bypassListHelp" msgstr "" "Servers for which you do not want to use any proxy: (One server on each " "line.)" msgid "options_bypassListHelpLinkText" msgstr "(Wildcards and more available…)" msgid "options_group_pacUrl" msgstr "PAC URL" msgid "options_pacUrlHelp" msgstr "" "The PAC script will be updated from this URL. If it is left blank, the " "following script will be used directly instead." msgid "options_pacUrlFile" msgstr "" "PAC profiles with file: URLs can only be applied directly. They cannot be " "used as result profiles because local files cannot be accessed due to " "browser limitation." msgid "options_pacUrlFileDisabled" msgstr "" "Therefore, you cannot use local PAC file for this profile. You can create a " "new PAC profile for that if you really want that." msgid "options_group_pacScript" msgstr "PAC Script" msgid "options_pacScriptLastUpdate" msgstr "PAC script downloaded at $TIME$:" msgid "options_pacScriptObsolete" msgstr "" "PAC script is obsolete due to URL change. Press the download button above to " "update." msgid "options_group_virtualProfile" msgstr "Virtual Profile" msgid "options_virtualProfileTarget" msgstr "Target" msgid "options_virtualProfileTargetHelp" msgstr "" "When this profile is applied, it acts exactly the same as the profile " "selected below." msgid "options_group_virtualProfileReplace" msgstr "Migrate to Virtual Profile" msgid "options_virtualProfileReplace" msgstr "Replace target profile" msgid "options_virtualProfileReplaceHelp" msgstr "" "You can migrate existing options to use this virtual profile instead of " "$PROFILE$. Doing so will update all existing rules concerning $PROFILE$ and " "point them to this virtual profile, so that their result profile can be " "controlled here." msgid "options_group_ruleListConfig" msgstr "Rule List Config" msgid "options_ruleListFormat" msgstr "Rule List Format" msgid "options_group_ruleListResult" msgstr "Rule list result profiles" msgid "options_ruleListMatchProfile" msgstr "Match profile" msgid "options_ruleListDefaultProfile" msgstr "Default profile" msgid "options_group_ruleListUrl" msgstr "Rule List URL" msgid "options_ruleListUrlHelp" msgstr "" "The rule list will be updated from this URL. If it is left blank, the " "following text will be parsed instead." msgid "options_group_ruleListText" msgstr "Rule List Text" msgid "options_ruleListLastUpdate" msgstr "Rule list downloaded at $TIME$:" msgid "options_ruleListObsolete" msgstr "" "Rule list is obsolete due to URL change. Press the download button above to " "update." msgid "options_group_switchRules" msgstr "Switch rules" msgid "options_sort" msgstr "Sort" msgid "options_conditionType" msgstr "Condition Type" msgid "options_showConditionTypeHelp" msgstr "Show help" msgid "options_conditionDetails" msgstr "Condition Details" msgid "options_resultProfile" msgstr "Profile" msgid "options_conditionActions" msgstr "Actions" msgid "options_addCondition" msgstr "Add condition" msgid "options_cloneRule" msgstr "Clone" msgid "options_ruleNote" msgstr "Note" msgid "options_switchAttachedProfileInCondition" msgstr "Rule list rules" msgid "options_switchAttachedProfileInConditionDetails" msgstr "(Any request matching the rule list below)" msgid "options_switchAttachedProfileInConditionDisabled" msgstr "(Rule list rules are DISABLED)" msgid "options_switchDefaultProfile" msgstr "Default" msgid "options_hostLevelsBetween" msgstr "≤ host levels ≤" msgid "options_hourBetween" msgstr "≤ current hour ≤" msgid "options_weekDayShort_0" msgstr "Su" msgid "options_weekDayShort_1" msgstr "Mo" msgid "options_weekDayShort_2" msgstr "Tu" msgid "options_weekDayShort_3" msgstr "We" msgid "options_weekDayShort_4" msgstr "Th" msgid "options_weekDayShort_5" msgstr "Fr" msgid "options_weekDayShort_6" msgstr "Sa" msgid "options_group_conditionHelp" msgstr "About Condition Types" msgid "options_group_attachProfile" msgstr "Import online rule lists" msgid "options_attachProfile" msgstr "Add a rule list" msgid "options_attachProfileHelp" msgstr "" "You can reuse an online collection of conditions published by others by " "adding a rule list." msgid "options_modalHeader_welcome" msgstr "Welcome to SwitchyOmega" msgid "options_welcomeNormal" msgstr "" "You have successfully installed SwitchyOmega, the ultimate proxy switcher." msgid "options_welcomeNormalGuide" msgstr "" "Please tell SwitchyOmega about your proxies through the options page. Let's " "see how." msgid "options_welcomeUpgrade" msgstr "" "You have successfully upgraded to SwitchyOmega. Don't panic, your existing " "options are fully preserved." msgid "options_welcomeUpgradeGuide" msgstr "Now let's go through a quick guide of the new options page." msgid "options_guideNext" msgstr "Next" msgid "options_guideDone" msgstr "Done" msgid "options_guideSkip" msgstr "Skip guide" msgid "options_modalHeader_applyOptions" msgstr "Apply Options" msgid "options_optionsNotSaved" msgstr "" "Your modifications to the options have not been saved and will be lost if " "you proceed!" msgid "options_applyOptionsRequired" msgstr "Your changes to the options must be applied before you proceed." msgid "options_applyOptionsConfirm" msgstr "Do you want to save and apply the options?" msgid "options_modalHeader_renameProfile" msgstr "Rename Profile" msgid "options_renameProfileName" msgstr "New profile name" msgid "options_profileNameConflict" msgstr "A profile with this name already exists." msgid "options_profileNameReserved" msgstr "Profile names beginning with double-underscore are reserved." msgid "options_profileNameHidden" msgstr "" "Profiles with names starting with underscore will be hidden on the popup " "menu. However, they can still be used in places like switch profile results." msgid "options_modalHeader_replaceProfile" msgstr "Replace Profile" msgid "options_replaceProfile" msgstr "Replace Profile" msgid "options_replaceProfileConfirm" msgstr "Do you really want to replace $FromProfile$ with $ToProfile$?" msgid "options_replaceProfileHelp" msgstr "" "If you proceed, all rules pointing to $FromProfile$ will be updated to use " "$ToProfile$ instead. Other options, such as startup profile and Quick Switch " "will also be modified as appropriate. However, the two profile themselves " "will NOT be changed or deleted." msgid "options_replaceProfileSuccess" msgstr "Options updated." msgid "options_modalHeader_deleteProfile" msgstr "Delete Profile" msgid "options_deleteProfileConfirm" msgstr "Do you really want to delete the following profile?" msgid "options_modalHeader_cannotDeleteProfile" msgstr "Unable to Delete Profile" msgid "options_profileReferredBy" msgstr "" "This profile cannot be deleted because it is referred by the following " "profiles:" msgid "options_modifyReferringProfiles" msgstr "" "You must modify these profiles and make them stop referring to this profile " "before you can delete it." msgid "options_profileNameEmpty" msgstr "The name of the profile must not be empty." msgid "popup_title" msgstr "SwitchyOmega Popup" msgid "options_modalHeader_proxyAuth" msgstr "Proxy Authentication" msgid "options_proxyAuthUsername" msgstr "Username" msgid "options_proxyAuthPassword" msgstr "Password" msgid "options_proxyAuthShowPassword" msgstr "Show password" msgid "options_proxyAuthHidePassword" msgstr "Hide password" msgid "options_proxyAuthNone" msgstr "No Authentication" msgid "options_modalHeader_deleteRule" msgstr "Delete Rule" msgid "options_deleteRuleConfirm" msgstr "Do you really want to delete the following rule?" msgid "options_deleteRule" msgstr "Delete" msgid "options_modalHeader_resetRules" msgstr "Reset rules" msgid "options_resetRulesConfirm" msgstr "" "Are you sure to set the result profile of ALL rules to the following profile?" msgid "options_resetRules" msgstr "Reset rules" msgid "options_resetRules_help" msgstr "Set profile for all rules" msgid "options_modalHeader_deleteAttached" msgstr "Remove Rule List" msgid "options_deleteAttachedConfirm" msgstr "Do you really want to remove the rule list from the current profile?" msgid "options_ruleListLineCount" msgstr "$COUNT$ line(s) of rules" msgid "options_deleteAttached" msgstr "Remove rule list" msgid "options_modalHeader_newProfile" msgstr "New Profile" msgid "options_newProfileName" msgstr "Profile name" msgid "options_profileType" msgstr "Please select the type of the profile:" msgid "options_profileTypeFixedProfile" msgstr "Proxy Profile" msgid "options_profileDescFixedProfile" msgstr "Tunneling traffic through proxy servers." msgid "options_profileTypePacProfile" msgstr "PAC Profile" msgid "options_profileDescPacProfile" msgstr "Choosing proxies using an online/local PAC script." msgid "options_profileDescMorePacProfile" msgstr "" "You will only need this if you have a PAC script or a URL to it. Don't try " "to create one unless you have knowledge about PAC." msgid "options_profileTypeSwitchProfile" msgstr "Switch Profile" msgid "options_profileDescSwitchProfile" msgstr "" "Applying different profiles automatically on various conditions such as " "domains or patterns.\n" " You can also import rules published online for easier switching. (Replaces " "AutoSwitch mode + Rule List.)" msgid "options_profileTypeRuleListProfile" msgstr "Rule List Profile" msgid "options_profileDescRuleListProfile" msgstr "Reusing an online collection of conditions published by others." msgid "options_profileTypeVirtualProfile" msgstr "Virtual Profile" msgid "options_profileDescVirtualProfile" msgstr "" "A virtual profile can act as any of the other profiles on demand. It works " "well with SwitchProfile, allowing you to change the result of multiple " "conditions by one click." msgid "options_createProfile" msgstr "Create" msgid "options_modalHeader_resetOptions" msgstr "Reset Options" msgid "options_resetOptionsConfirm" msgstr "" "Do you really want to reset the options? All profiles and settings will be " "LOST!" msgid "options_formInvalid" msgstr "Please correct the errors in this page." msgid "options_profileNotFound" msgstr "Profile $PROFILE$ does not exist! The options may be corrupted." msgid "options_resetSuccess" msgstr "Options reset." msgid "options_saveSuccess" msgstr "Options saved." msgid "options_importSuccess" msgstr "Options imported." msgid "options_importFormatError" msgstr "Invalid backup file!" msgid "options_importDownloadError" msgstr "Error downloading backup file!" msgid "options_profileDownloadSuccess" msgstr "Successfully updated profile." msgid "options_profileDownloadError" msgstr "Error downloading profile data!" msgid "options_profileDownloadError_NetworkError" msgstr "A network error occurred when updating." msgid "options_profileDownloadError_HttpError" msgstr "An HTTP error ($STATUS$) occurred when updating." msgid "options_profileDownloadError_HttpNotFoundError" msgstr "The Profile URL was not found on the server. Please double-check." msgid "options_profileDownloadError_HttpServerError" msgstr "The remote server responded with error ($STATUS$) when updating." msgid "options_profileDownloadError_ContentTypeRejectedError" msgstr "The downloaded data is invalid! " "You may open the Profile URL in your browser to inspect it." msgid "options_downloadProfileNow" msgstr "Download Profile Now" msgid "options_guide_fixedProfileStep" msgstr "" "A Proxy Profile contains settings like server ip & port for proxy." "
Profiles are the the basic configuration units in SwitchyOmega.
We " "have already created an example profile for you. Try opening it." msgid "options_guide_fixedServersStep" msgstr "" "You can fill in your proxy server and port here as you like.
SwitchyOmega " "does not come with any proxy servers.
Please consult your network " "provider or proxy software manual if you don't know what should be filled in " "here." msgid "options_guide_autoSwitchProfileStep" msgstr "" "You can tell SwitchyOmega to switch between proxies automatically through " "the mighty Switch Profile.
However, its features cannot be covered " "in this quick guide.
You can open this profile to unlock its power some " "time later." msgid "options_guide_addMoreProfilesStep" msgstr "" "Need more profiles? You can always add more Proxy, Switch and other " "profiles
for all your proxying needs.
Enjoy proxying!" msgid "options_guide_conditionStep" msgstr "" "SwitchyOmega can apply different profiles to requests based on " "conditions.
For example, the Host wildcard condition " "allows you to set the profile for all URLs in a domain." msgid "options_guide_conditionTypeStep" msgstr "" "You can use various condition types to match the host or full URL.
" "Click on the question mark to open the type reference." msgid "options_guide_conditionProfileStep" msgstr "" "SwitchyOmega applies the selected profile here to any request matching " "the condition.
The special \"[Direct]\" profile will cause " "the request to be sent without any proxy." msgid "options_guide_switchDefaultStep" msgstr "" "If no condition applies to some request, the \"Default\" profile will be " "used.
Conditions are always considered from top to bottom in " "order.
You can change their order by dragging the sort icon." msgid "options_guide_applySwitchProfileStep" msgstr "" "When you are done setting the switch profile, don't forget to switch to " "it in the popup menu.
The icon will show you the final result profile applied for the current tab.
Hovering on the icon " "will reveal a tooltip with details." msgid "popup_externalProfile" msgstr "(External Profile)" msgid "popup_externalProfileName" msgstr "profile name" msgid "popup_proxyNotControllable_app" msgstr "" "The proxy settings are controlled by other app(s) or extension(s). Please " "disable or uninstall the apps or extensions in conflict." msgid "popup_proxyNotControllable_policy" msgstr "" "The proxy settings are overruled by policies. Please contact your " "administrator." msgid "popup_proxyNotControllable_unknown" msgstr "" "The proxy settings cannot be controlled. Please check your system and " "browser settings." msgid "popup_proxyNotControllable_disabled" msgstr "" "The proxy settings are disabled by explicit request from other app(s) or " "extension(s)." msgid "popup_proxyNotControllable_upgrade" msgstr "Proxy settings are now controlled by a newer version of SwitchyOmega." msgid "popup_proxyNotControllableDetails" msgstr "" "You cannot switch profiles with SwitchyOmega unless you fix the problem " "above." msgid "popup_proxyNotControllableDetails_upgrade" msgstr "" "You can't enable two (or more) versions of SwitchyOmega at the same time. " "Please disable one of them." msgid "popup_proxyNotControllableManage" msgstr "Manage extensions" msgid "popup_addConditionTo" msgstr "Add condition to" msgid "popup_addCondition" msgstr "Add condition" msgid "popup_showOptions" msgstr "Options" msgid "popup_reportIssues" msgstr "Report issues" msgid "popup_errorLog" msgstr "Save error log" msgid "popup_requestErrorCount" msgstr "$COUNT$ failed resources" msgid "popup_requestErrorHeading" msgstr "Resources that failed to load" msgid "popup_requestErrorWarning" msgstr "" "A few resources failed to load due to issues with your network, proxy server " "or the webpage." msgid "popup_requestErrorWarningHelp" msgstr "" "SwitchyOmega is just the reporter of these issues, not the cause of them." msgid "popup_requestErrorAddCondition" msgstr "" "You can review the following domains and use proxy for them when appropriate." msgid "popup_requestErrorCannotAddCondition" msgstr "" "You can add switch conditions for them only when using a Switch Profile." msgid "popup_configureMonitorWebRequests" msgstr "Configure Network Monitor" msgid "options_resultProfileForSelectedDomains" msgstr "Use this profile for all selected domains" msgid "options_pac_profile_unsupported_moz" msgstr "PAC Profiles WILL NOT work in Mozilla Firefox due to technical limitations!" msgid "popup_issueTemplate" msgstr "" "\n" "\n" "\n" "\n" "SwitchyOmega $projectVersion$\n" "$userAgent$" msgid "browserAction_profileDetails_PacProfile" msgstr "(PAC script)" msgid "browserAction_profileDetails_SystemProfile" msgstr "(controlled by other extensions or environment)" msgid "browserAction_profileDetails_DirectProfile" msgstr "(not using any proxy)" msgid "browserAction_profileDetails_SwitchProfile" msgstr "(switching based on conditions)" msgid "browserAction_profileDetails_RuleListProfile" msgstr "(switching based on rule list)" msgid "browserAction_titleNormal" msgstr "SwitchyOmega:: $PROFILE$" msgid "browserAction_titleWithResult" msgstr "" "SwitchyOmega:: $1:PROFILE$\n" "$3:DETAILS$" msgid "browserAction_titleNewerOptions" msgstr "" "ERROR: A newer version of SwitchOmega is required to load the stored options." msgid "browserAction_titleOptionError" msgstr "ERROR: The stored options are corrupted. Click here to RESET OPTIONS." msgid "browserAction_titleDownloadFail" msgstr "Warning: Failed to download PAC scripts and/or rule lists." msgid "browserAction_titleExternalProxy" msgstr "Note: The proxy settings are currently controlled by other app(s)." msgid "browserAction_titleInspect" msgstr "[Inspect] $URL$" msgid "browserAction_defaultRuleDetails" msgstr "(default)" msgid "browserAction_directResult" msgstr "DIRECT" msgid "browserAction_attachedPrefix" msgstr "(RL) " msgid "browserAction_tempRulePrefix" msgstr "(TEMP) " msgid "contextMenu_inspectPage" msgstr "Inspect proxy used for this page" msgid "contextMenu_inspectFrame" msgstr "Inspect proxy used for this Frame" msgid "contextMenu_inspectLink" msgstr "Inspect proxy to be used if this Link is opened" msgid "contextMenu_inspectElement" msgstr "Inspect proxy used for this Element" msgid "contextMenu_enableQuickSwitch" msgstr "Enable Quick Switch" msgid "about_title" msgstr "À propos" msgid "about_app_description" msgstr "Un outil de configuration de mandataire" msgid "about_version" msgstr "Version $VERSION$" msgid "about_experimental_warning_moz" msgstr "Mozilla Firefox support is highly experimental! If you encounter issues, please report using the buttons below." msgid "about_disclaimer_networkService" msgstr "SwitchyOmega does not provide proxies, VPNs, or other network services." msgid "about_disclaimer_privacy" msgstr "SwitchyOmega does not track you or insert ads into webpages. Please see" " our privacy policy." msgid "about_help" msgstr "Other questions? Need help with using SwitchyOmega? Please see our " "FAQ." msgid "about_copyright" msgstr "Copyright 2012-2017 The SwitchyOmega Authors. All rights reserved." msgid "about_credits" msgstr "SwitchyOmega is made possible by the SwitchyOmega open source project and other open source software." msgid "about_license" msgstr "SwitchyOmega is free software licensed under GNU General Public License Version 3 or later." ================================================ FILE: omega-locales/he_IL/LC_MESSAGES/omega-web.po ================================================ msgid "" msgstr "" "Project-Id-Version: SwitchyOmega 2.3.3\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2015-02-13 10:29+0000\n" "PO-Revision-Date: 2018-06-13 01:52+0000\n" "Last-Translator: Automatically generated\n" "Language-Team: none\n" "Language: he_IL\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=4; plural=(n == 1) ? 0 : ((n == 2) ? 1 : ((n > 10 && " "n % 10 == 0) ? 2 : 3));\n" "X-Generator: Weblate 3.0.1\n" msgid "appNameShort" msgstr "" msgid "manifest_app_name" msgstr "" msgid "manifest_app_description" msgstr "" msgid "manifest_icon_default_title" msgstr "" msgid "upgrade_profile_auto" msgstr "" msgid "profile_direct" msgstr "" msgid "profile_system" msgstr "" msgid "condition_HostWildcardCondition" msgstr "" msgid "condition_help_HostWildcardCondition" msgstr "" msgid "condition_HostRegexCondition" msgstr "" msgid "condition_help_HostRegexCondition" msgstr "" msgid "condition_HostLevelsCondition" msgstr "" msgid "condition_help_HostLevelsCondition" msgstr "" msgid "condition_IpCondition" msgstr "" msgid "condition_help_IpCondition" msgstr "" msgid "condition_UrlWildcardCondition" msgstr "" msgid "condition_help_UrlWildcardCondition" msgstr "" msgid "condition_UrlRegexCondition" msgstr "" msgid "condition_help_UrlRegexCondition" msgstr "" msgid "condition_KeywordCondition" msgstr "" msgid "condition_help_KeywordCondition" msgstr "" msgid "condition_FalseCondition" msgstr "" msgid "condition_details_FalseCondition" msgstr "" msgid "condition_help_FalseCondition" msgstr "" msgid "condition_TimeCondition" msgstr "" msgid "condition_help_TimeCondition" msgstr "" msgid "condition_WeekdayCondition" msgstr "" msgid "condition_help_WeekdayCondition" msgstr "" msgid "condition_alert_fullUrlLimitation" msgstr "" msgid "condition_alert_fullUrlLimitationLink" msgstr "" msgid "condition_group_default" msgstr "" msgid "condition_group_host" msgstr "" msgid "condition_group_url" msgstr "" msgid "condition_group_special" msgstr "" msgid "ruleListFormat_Switchy" msgstr "" msgid "ruleListFormat_AutoProxy" msgstr "" msgid "ruleList_usageUrl" msgstr "" msgid "ruleList_error_resultNotEnabled" msgstr "" msgid "ruleList_error_unknownProfile" msgstr "" msgid "ruleList_error_missingResultProfile" msgstr "" msgid "ruleList_error_invalidRule" msgstr "" msgid "ruleList_error_noDefaultRule" msgstr "" msgid "dialog_close" msgstr "" msgid "dialog_save" msgstr "" msgid "dialog_ok" msgstr "" msgid "dialog_cancel" msgstr "" msgid "inputClear_clear" msgstr "" msgid "inputClear_restore" msgstr "" msgid "options_title" msgstr "" msgid "options_experimental_badge" msgstr "" msgid "options_navHeader_setting" msgstr "" msgid "options_navHeader_profiles" msgstr "" msgid "options_navHeader_actions" msgstr "" msgid "options_tab_ui" msgstr "" msgid "options_tab_general" msgstr "" msgid "options_tab_importExport" msgstr "" msgid "options_newProfile" msgstr "" msgid "options_apply" msgstr "" msgid "options_discard" msgstr "" msgid "options_reset" msgstr "" msgid "options_group_miscOptions" msgstr "" msgid "options_confirmDeletion" msgstr "" msgid "options_refreshOnProfileChange" msgstr "" msgid "options_showInspectMenu" msgstr "" msgid "options_addConditionsToBottom" msgstr "" msgid "options_group_keyboardShortcut" msgstr "" msgid "options_menuShortcutHelp" msgstr "" msgid "options_menuShortcutMore" msgstr "" msgid "options_menuShortcutConfigure" msgstr "" msgid "options_group_switchOptions" msgstr "" msgid "options_startupProfile" msgstr "" msgid "options_startupProfile_none" msgstr "" msgid "options_showConditionTypesAdvanced" msgstr "" msgid "options_showConditionTypesAdvancedHelp" msgstr "" msgid "options_quickSwitch" msgstr "" msgid "options_cycledProfiles" msgstr "" msgid "options_cycledProfilesHelp" msgstr "" msgid "options_cycledProfilesTooFew" msgstr "" msgid "options_notCycledProfiles" msgstr "" msgid "options_group_proxyChanges" msgstr "" msgid "options_revertProxyChanges" msgstr "" msgid "options_group_conflicts" msgstr "" msgid "options_conflicts_introduction" msgstr "" msgid "options_conflicts_lowerPriority" msgstr "" msgid "options_conflicts_higherPriority" msgstr "" msgid "options_showExternalProfile" msgstr "" msgid "options_showExternalProfileHelp" msgstr "" msgid "options_group_networkRequests" msgstr "" msgid "options_monitorWebRequests" msgstr "" msgid "options_monitorWebRequestsHelp" msgstr "" msgid "options_downloadOptions" msgstr "" msgid "options_downloadOptionsHelp" msgstr "" msgid "options_downloadInterval" msgstr "" msgid "options_downloadInterval_15" msgstr "" msgid "options_downloadInterval_60" msgstr "" msgid "options_downloadInterval_180" msgstr "" msgid "options_downloadInterval_360" msgstr "" msgid "options_downloadInterval_720" msgstr "" msgid "options_downloadInterval_1440" msgstr "" msgid "options_downloadInterval_never" msgstr "" msgid "options_group_importExportProfile" msgstr "" msgid "options_exportPacFile" msgstr "" msgid "options_exportPacFileHelp" msgstr "" msgid "options_exportProfileHelp" msgstr "" msgid "options_exportLegacyRuleList" msgstr "" msgid "options_exportLegacyRuleListHelp" msgstr "" msgid "options_group_importExportSettings" msgstr "" msgid "options_makeBackup" msgstr "" msgid "options_makeBackupHelp" msgstr "" msgid "options_restoreLocal" msgstr "" msgid "options_restoreLocalHelp" msgstr "" msgid "options_restoreOnline" msgstr "" msgid "options_restoreOnlinePlaceholder" msgstr "" msgid "options_restoreOnlineSubmit" msgstr "" msgid "options_group_syncing" msgstr "" msgid "options_syncEnable" msgstr "" msgid "options_syncEnableForce" msgstr "" msgid "options_syncDisable" msgstr "" msgid "options_syncReset" msgstr "" msgid "options_syncPristineHelp" msgstr "" msgid "options_syncSyncAlert" msgstr "" msgid "options_syncSyncHelp" msgstr "" msgid "options_syncConflictAlert" msgstr "" msgid "options_syncConflictHelp" msgstr "" msgid "options_syncUnsupportedHelp" msgstr "" msgid "options_profileSyncDisabled" msgstr "" msgid "options_profileSyncDisabled_quotaPerItem" msgstr "" msgid "options_profileTabPrefix" msgstr "" msgid "options_renameProfile" msgstr "" msgid "options_deleteProfile" msgstr "" msgid "options_profileExportRuleList" msgstr "" msgid "options_profileExportRuleListHelp" msgstr "" msgid "options_profileExportPac" msgstr "" msgid "options_profileUnsupported" msgstr "" msgid "options_profileUnsupportedHelp" msgstr "" msgid "options_profileEditSource" msgstr "" msgid "options_profileEditSourceHelp" msgstr "" msgid "options_profileEditSourceHelpUrl" msgstr "" msgid "options_group_proxyServers" msgstr "" msgid "options_proxy_scheme" msgstr "" msgid "options_proxy_protocol" msgstr "" msgid "options_proxy_server" msgstr "" msgid "options_proxy_port" msgstr "" msgid "options_proxy_auth" msgstr "" msgid "options_proxy_authNotSupported" msgstr "" msgid "options_proxy_authAllWarningPac" msgstr "" msgid "options_proxy_authAllWarningPacUrl" msgstr "" msgid "options_proxy_authAllWarningPacScript" msgstr "" msgid "options_proxy_authReferencedWarning" msgstr "" msgid "options_scheme_default" msgstr "" msgid "options_protocol_direct" msgstr "" msgid "options_protocol_useDefault" msgstr "" msgid "options_proxy_single" msgstr "" msgid "options_proxy_expand" msgstr "" msgid "options_group_bypassList" msgstr "" msgid "options_bypassListHelp" msgstr "" msgid "options_bypassListHelpLinkText" msgstr "" msgid "options_group_pacUrl" msgstr "" msgid "options_pacUrlHelp" msgstr "" msgid "options_pacUrlFile" msgstr "" msgid "options_pacUrlFileDisabled" msgstr "" msgid "options_group_pacScript" msgstr "" msgid "options_pacScriptLastUpdate" msgstr "" msgid "options_pacScriptObsolete" msgstr "" msgid "options_group_virtualProfile" msgstr "" msgid "options_virtualProfileTarget" msgstr "" msgid "options_virtualProfileTargetHelp" msgstr "" msgid "options_group_virtualProfileReplace" msgstr "" msgid "options_virtualProfileReplace" msgstr "" msgid "options_virtualProfileReplaceHelp" msgstr "" msgid "options_group_ruleListConfig" msgstr "" msgid "options_ruleListFormat" msgstr "" msgid "options_group_ruleListResult" msgstr "" msgid "options_ruleListMatchProfile" msgstr "" msgid "options_ruleListDefaultProfile" msgstr "" msgid "options_group_ruleListUrl" msgstr "" msgid "options_ruleListUrlHelp" msgstr "" msgid "options_group_ruleListText" msgstr "" msgid "options_ruleListLastUpdate" msgstr "" msgid "options_ruleListObsolete" msgstr "" msgid "options_group_switchRules" msgstr "" msgid "options_sort" msgstr "" msgid "options_conditionType" msgstr "" msgid "options_showConditionTypeHelp" msgstr "" msgid "options_conditionDetails" msgstr "" msgid "options_resultProfile" msgstr "" msgid "options_conditionActions" msgstr "" msgid "options_addCondition" msgstr "" msgid "options_cloneRule" msgstr "" msgid "options_ruleNote" msgstr "" msgid "options_switchAttachedProfileInCondition" msgstr "" msgid "options_switchAttachedProfileInConditionDetails" msgstr "" msgid "options_switchAttachedProfileInConditionDisabled" msgstr "" msgid "options_switchDefaultProfile" msgstr "" msgid "options_hostLevelsBetween" msgstr "" msgid "options_hourBetween" msgstr "" msgid "options_weekDayShort_0" msgstr "" msgid "options_weekDayShort_1" msgstr "" msgid "options_weekDayShort_2" msgstr "" msgid "options_weekDayShort_3" msgstr "" msgid "options_weekDayShort_4" msgstr "" msgid "options_weekDayShort_5" msgstr "" msgid "options_weekDayShort_6" msgstr "" msgid "options_group_conditionHelp" msgstr "" msgid "options_group_attachProfile" msgstr "" msgid "options_attachProfile" msgstr "" msgid "options_attachProfileHelp" msgstr "" msgid "options_modalHeader_welcome" msgstr "" msgid "options_welcomeNormal" msgstr "" msgid "options_welcomeNormalGuide" msgstr "" msgid "options_welcomeUpgrade" msgstr "" msgid "options_welcomeUpgradeGuide" msgstr "" msgid "options_guideNext" msgstr "" msgid "options_guideDone" msgstr "" msgid "options_guideSkip" msgstr "" msgid "options_modalHeader_applyOptions" msgstr "" msgid "options_optionsNotSaved" msgstr "" msgid "options_applyOptionsRequired" msgstr "" msgid "options_applyOptionsConfirm" msgstr "" msgid "options_modalHeader_renameProfile" msgstr "" msgid "options_renameProfileName" msgstr "" msgid "options_profileNameConflict" msgstr "" msgid "options_profileNameReserved" msgstr "" msgid "options_profileNameHidden" msgstr "" msgid "options_modalHeader_replaceProfile" msgstr "" msgid "options_replaceProfile" msgstr "" msgid "options_replaceProfileConfirm" msgstr "" msgid "options_replaceProfileHelp" msgstr "" msgid "options_replaceProfileSuccess" msgstr "" msgid "options_modalHeader_deleteProfile" msgstr "" msgid "options_deleteProfileConfirm" msgstr "" msgid "options_modalHeader_cannotDeleteProfile" msgstr "" msgid "options_profileReferredBy" msgstr "" msgid "options_modifyReferringProfiles" msgstr "" msgid "options_profileNameEmpty" msgstr "" msgid "popup_title" msgstr "" msgid "options_modalHeader_proxyAuth" msgstr "" msgid "options_proxyAuthUsername" msgstr "" msgid "options_proxyAuthPassword" msgstr "" msgid "options_proxyAuthShowPassword" msgstr "" msgid "options_proxyAuthHidePassword" msgstr "" msgid "options_proxyAuthNone" msgstr "" msgid "options_modalHeader_deleteRule" msgstr "" msgid "options_deleteRuleConfirm" msgstr "" msgid "options_deleteRule" msgstr "" msgid "options_modalHeader_resetRules" msgstr "" msgid "options_resetRulesConfirm" msgstr "" msgid "options_resetRules" msgstr "" msgid "options_resetRules_help" msgstr "" msgid "options_modalHeader_deleteAttached" msgstr "" msgid "options_deleteAttachedConfirm" msgstr "" msgid "options_ruleListLineCount" msgstr "" msgid "options_deleteAttached" msgstr "" msgid "options_modalHeader_newProfile" msgstr "" msgid "options_newProfileName" msgstr "" msgid "options_profileType" msgstr "" msgid "options_profileTypeFixedProfile" msgstr "" msgid "options_profileDescFixedProfile" msgstr "" msgid "options_profileTypePacProfile" msgstr "" msgid "options_profileDescPacProfile" msgstr "" msgid "options_profileDescMorePacProfile" msgstr "" msgid "options_profileTypeSwitchProfile" msgstr "" msgid "options_profileDescSwitchProfile" msgstr "" msgid "options_profileTypeRuleListProfile" msgstr "" msgid "options_profileDescRuleListProfile" msgstr "" msgid "options_profileTypeVirtualProfile" msgstr "" msgid "options_profileDescVirtualProfile" msgstr "" msgid "options_createProfile" msgstr "" msgid "options_modalHeader_resetOptions" msgstr "" msgid "options_resetOptionsConfirm" msgstr "" msgid "options_formInvalid" msgstr "" msgid "options_profileNotFound" msgstr "" msgid "options_resetSuccess" msgstr "" msgid "options_saveSuccess" msgstr "" msgid "options_importSuccess" msgstr "" msgid "options_importFormatError" msgstr "" msgid "options_importDownloadError" msgstr "" msgid "options_profileDownloadSuccess" msgstr "" msgid "options_profileDownloadError" msgstr "" msgid "options_profileDownloadError_NetworkError" msgstr "" msgid "options_profileDownloadError_HttpError" msgstr "" msgid "options_profileDownloadError_HttpNotFoundError" msgstr "" msgid "options_profileDownloadError_HttpServerError" msgstr "" msgid "options_profileDownloadError_ContentTypeRejectedError" msgstr "" msgid "options_downloadProfileNow" msgstr "" msgid "options_guide_fixedProfileStep" msgstr "" msgid "options_guide_fixedServersStep" msgstr "" msgid "options_guide_autoSwitchProfileStep" msgstr "" msgid "options_guide_addMoreProfilesStep" msgstr "" msgid "options_guide_conditionStep" msgstr "" msgid "options_guide_conditionTypeStep" msgstr "" msgid "options_guide_conditionProfileStep" msgstr "" msgid "options_guide_switchDefaultStep" msgstr "" msgid "options_guide_applySwitchProfileStep" msgstr "" msgid "popup_externalProfile" msgstr "" msgid "popup_externalProfileName" msgstr "" msgid "popup_proxyNotControllable_app" msgstr "" msgid "popup_proxyNotControllable_policy" msgstr "" msgid "popup_proxyNotControllable_unknown" msgstr "" msgid "popup_proxyNotControllable_disabled" msgstr "" msgid "popup_proxyNotControllable_upgrade" msgstr "" msgid "popup_proxyNotControllableDetails" msgstr "" msgid "popup_proxyNotControllableDetails_upgrade" msgstr "" msgid "popup_proxyNotControllableManage" msgstr "" msgid "popup_addConditionTo" msgstr "" msgid "popup_addCondition" msgstr "" msgid "popup_showOptions" msgstr "" msgid "popup_reportIssues" msgstr "" msgid "popup_errorLog" msgstr "" msgid "popup_requestErrorCount" msgstr "" msgid "popup_requestErrorHeading" msgstr "" msgid "popup_requestErrorWarning" msgstr "" msgid "popup_requestErrorWarningHelp" msgstr "" msgid "popup_requestErrorAddCondition" msgstr "" msgid "popup_requestErrorCannotAddCondition" msgstr "" msgid "popup_configureMonitorWebRequests" msgstr "" msgid "options_resultProfileForSelectedDomains" msgstr "" msgid "options_pac_profile_unsupported_moz" msgstr "" msgid "popup_issueTemplate" msgstr "" msgid "browserAction_profileDetails_PacProfile" msgstr "" msgid "browserAction_profileDetails_SystemProfile" msgstr "" msgid "browserAction_profileDetails_DirectProfile" msgstr "" msgid "browserAction_profileDetails_SwitchProfile" msgstr "" msgid "browserAction_profileDetails_RuleListProfile" msgstr "" msgid "browserAction_titleNormal" msgstr "" msgid "browserAction_titleWithResult" msgstr "" msgid "browserAction_titleNewerOptions" msgstr "" msgid "browserAction_titleOptionError" msgstr "" msgid "browserAction_titleDownloadFail" msgstr "" msgid "browserAction_titleExternalProxy" msgstr "" msgid "browserAction_titleInspect" msgstr "" msgid "browserAction_defaultRuleDetails" msgstr "" msgid "browserAction_directResult" msgstr "" msgid "browserAction_attachedPrefix" msgstr "" msgid "browserAction_tempRulePrefix" msgstr "" msgid "contextMenu_inspectPage" msgstr "" msgid "contextMenu_inspectFrame" msgstr "" msgid "contextMenu_inspectLink" msgstr "" msgid "contextMenu_inspectElement" msgstr "" msgid "contextMenu_enableQuickSwitch" msgstr "" msgid "about_title" msgstr "" msgid "about_app_description" msgstr "" msgid "about_version" msgstr "" msgid "about_experimental_warning_moz" msgstr "" msgid "about_disclaimer_networkService" msgstr "" msgid "about_disclaimer_privacy" msgstr "" msgid "about_help" msgstr "" msgid "about_copyright" msgstr "" msgid "about_credits" msgstr "" msgid "about_license" msgstr "" ================================================ FILE: omega-locales/id/LC_MESSAGES/omega-web.po ================================================ msgid "" msgstr "" "Project-Id-Version: SwitchyOmega 2.3.3\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2015-02-13 10:29+0000\n" "PO-Revision-Date: 2024-12-27 12:00+0000\n" "Last-Translator: Doctorredits_here \n" "Language-Team: Indonesian \n" "Language: id\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" "X-Generator: Weblate 5.10-dev\n" msgid "appNameShort" msgstr "SwitchyOmega" msgid "manifest_app_name" msgstr "Proxsi SwitchyOmega" msgid "manifest_app_description" msgstr "Kelola dan beralih di antara beberapa proxy dengan cepat & mudah." msgid "manifest_icon_default_title" msgstr "Memuat…" msgid "upgrade_profile_auto" msgstr "Saklar Otomatis" msgid "profile_direct" msgstr "[Langsung]" msgid "profile_system" msgstr "[System Proxsi]" msgid "condition_HostWildcardCondition" msgstr "Tuan rumah wildcard" msgid "condition_help_HostWildcardCondition" msgstr "" "Mencocokkan host (nama domain) dengan karakter pengganti.
Tanda " "bintang * cocok dengan nol karakter atau lebih.
Tanda " "tanya ? cocok dengan tepat satu karakter.

Perlu " "diketahui bahwa aturan yang dimulai dengan *. diperlakukan " "secara khusus hanya dalam kondisi karakter pengganti Host.
Contoh: *" ".example.com akan cocok dengan www.example.com DAN example.com " "juga.
Untuk mencocokkan subdomain saja, gunakan dua tanda " "bintang seperti **.example.com." msgid "condition_HostRegexCondition" msgstr "Tuan rumah regex" msgid "condition_help_HostRegexCondition" msgstr "" "Seperti kondisi wildcard Host, tetapi cocok dengan host (nama domain) dengan " "ekspresi " "reguler.
Ekspresi reguler sulit dibuat (dan dibaca).
Disarankan " "untuk menggunakan wildcard untuk sebagian besar kasus dan hanya menggunakan " "regex untuk kondisi yang tidak dapat dicapai oleh jenis kondisi lainnya." msgid "condition_HostLevelsCondition" msgstr "Tingkat tuan rumah" msgid "condition_help_HostLevelsCondition" msgstr "" "Mencocokkan permintaan jika dan hanya jika level host berada dalam rentang " "yang diberikan.
Level host didefinisikan sebagai jumlah segmen yang " "dipisahkan titik dari host (nama domain).
Contoh: " "www.example.com memiliki level host 3, sedangkan " "internal memiliki level host 1." msgid "condition_IpCondition" msgstr "Literal IP" msgid "condition_help_IpCondition" msgstr "" "Mencocokkan permintaan jika dan hanya jika host adalah alamat IP " "literal dan dalam subnet sebagaimana ditetapkan oleh
notasi CIDR.
Misalnya, dengan aturan " "127.0.0.116, maka ia akan mencocokkan semua alamat IP seperti " "127.0.*.*.
Jadi 127.0.0.1 cocok sedangkan " "127.1.0.0 tidak. Nama host seperti localhost tidak " "akan pernah cocok karena keduanya bukan IP literal." msgid "condition_UrlWildcardCondition" msgstr "URL wildcard" msgid "condition_help_UrlWildcardCondition" msgstr "" "Mencocokkan URL permintaan dengan karakter pengganti.
Lihat bagian " "karakter pengganti Host di atas untuk referensi karakter pengganti " "cepat.
Perhatikan bahwa karakter pengganti URL tidak diperlakukan secara " "khusus (tidak ada keajaiban subdomain seperti pada karakter pengganti Host)" ".
Jadi *:*.example.com* cocok dengan http:www.example.com " "tetapi tidak cocok dengan http:example.com." msgid "condition_UrlRegexCondition" msgstr "URL regex" msgid "condition_help_UrlRegexCondition" msgstr "" msgid "condition_KeywordCondition" msgstr "" msgid "condition_help_KeywordCondition" msgstr "" msgid "condition_FalseCondition" msgstr "" msgid "condition_details_FalseCondition" msgstr "" msgid "condition_help_FalseCondition" msgstr "" msgid "condition_TimeCondition" msgstr "" msgid "condition_help_TimeCondition" msgstr "" msgid "condition_WeekdayCondition" msgstr "" msgid "condition_help_WeekdayCondition" msgstr "" msgid "condition_alert_fullUrlLimitation" msgstr "" msgid "condition_alert_fullUrlLimitationLink" msgstr "" msgid "condition_group_default" msgstr "" msgid "condition_group_host" msgstr "" msgid "condition_group_url" msgstr "" msgid "condition_group_special" msgstr "" msgid "ruleListFormat_Switchy" msgstr "" msgid "ruleListFormat_AutoProxy" msgstr "" msgid "ruleList_usageUrl" msgstr "" msgid "ruleList_error_resultNotEnabled" msgstr "" msgid "ruleList_error_unknownProfile" msgstr "" msgid "ruleList_error_missingResultProfile" msgstr "" msgid "ruleList_error_invalidRule" msgstr "" msgid "ruleList_error_noDefaultRule" msgstr "" msgid "dialog_close" msgstr "" msgid "dialog_save" msgstr "" msgid "dialog_ok" msgstr "" msgid "dialog_cancel" msgstr "" msgid "inputClear_clear" msgstr "" msgid "inputClear_restore" msgstr "" msgid "options_title" msgstr "" msgid "options_experimental_badge" msgstr "" msgid "options_navHeader_setting" msgstr "" msgid "options_navHeader_profiles" msgstr "" msgid "options_navHeader_actions" msgstr "" msgid "options_tab_ui" msgstr "" msgid "options_tab_general" msgstr "" msgid "options_tab_importExport" msgstr "" msgid "options_newProfile" msgstr "" msgid "options_apply" msgstr "" msgid "options_discard" msgstr "" msgid "options_reset" msgstr "" msgid "options_group_miscOptions" msgstr "" msgid "options_confirmDeletion" msgstr "" msgid "options_refreshOnProfileChange" msgstr "" msgid "options_showInspectMenu" msgstr "" msgid "options_addConditionsToBottom" msgstr "" msgid "options_group_keyboardShortcut" msgstr "" msgid "options_menuShortcutHelp" msgstr "" msgid "options_menuShortcutMore" msgstr "" msgid "options_menuShortcutConfigure" msgstr "" msgid "options_group_switchOptions" msgstr "" msgid "options_startupProfile" msgstr "" msgid "options_startupProfile_none" msgstr "" msgid "options_showConditionTypesAdvanced" msgstr "" msgid "options_showConditionTypesAdvancedHelp" msgstr "" msgid "options_quickSwitch" msgstr "" msgid "options_cycledProfiles" msgstr "" msgid "options_cycledProfilesHelp" msgstr "" msgid "options_cycledProfilesTooFew" msgstr "" msgid "options_notCycledProfiles" msgstr "" msgid "options_group_proxyChanges" msgstr "" msgid "options_revertProxyChanges" msgstr "" msgid "options_group_conflicts" msgstr "" msgid "options_conflicts_introduction" msgstr "" msgid "options_conflicts_lowerPriority" msgstr "" msgid "options_conflicts_higherPriority" msgstr "" msgid "options_showExternalProfile" msgstr "" msgid "options_showExternalProfileHelp" msgstr "" msgid "options_group_networkRequests" msgstr "" msgid "options_monitorWebRequests" msgstr "" msgid "options_monitorWebRequestsHelp" msgstr "" msgid "options_downloadOptions" msgstr "" msgid "options_downloadOptionsHelp" msgstr "" msgid "options_downloadInterval" msgstr "" msgid "options_downloadInterval_15" msgstr "" msgid "options_downloadInterval_60" msgstr "" msgid "options_downloadInterval_180" msgstr "" msgid "options_downloadInterval_360" msgstr "" msgid "options_downloadInterval_720" msgstr "" msgid "options_downloadInterval_1440" msgstr "" msgid "options_downloadInterval_never" msgstr "" msgid "options_group_importExportProfile" msgstr "" msgid "options_exportPacFile" msgstr "" msgid "options_exportPacFileHelp" msgstr "" msgid "options_exportProfileHelp" msgstr "" msgid "options_exportLegacyRuleList" msgstr "" msgid "options_exportLegacyRuleListHelp" msgstr "" msgid "options_group_importExportSettings" msgstr "" msgid "options_makeBackup" msgstr "" msgid "options_makeBackupHelp" msgstr "" msgid "options_restoreLocal" msgstr "" msgid "options_restoreLocalHelp" msgstr "" msgid "options_restoreOnline" msgstr "" msgid "options_restoreOnlinePlaceholder" msgstr "" msgid "options_restoreOnlineSubmit" msgstr "" msgid "options_group_syncing" msgstr "" msgid "options_syncEnable" msgstr "" msgid "options_syncEnableForce" msgstr "" msgid "options_syncDisable" msgstr "" msgid "options_syncReset" msgstr "" msgid "options_syncPristineHelp" msgstr "" msgid "options_syncSyncAlert" msgstr "" msgid "options_syncSyncHelp" msgstr "" msgid "options_syncConflictAlert" msgstr "" msgid "options_syncConflictHelp" msgstr "" msgid "options_syncUnsupportedHelp" msgstr "" msgid "options_profileSyncDisabled" msgstr "" msgid "options_profileSyncDisabled_quotaPerItem" msgstr "" msgid "options_profileTabPrefix" msgstr "" msgid "options_renameProfile" msgstr "" msgid "options_deleteProfile" msgstr "" msgid "options_profileExportRuleList" msgstr "" msgid "options_profileExportRuleListHelp" msgstr "" msgid "options_profileExportPac" msgstr "" msgid "options_profileUnsupported" msgstr "" msgid "options_profileUnsupportedHelp" msgstr "" msgid "options_profileEditSource" msgstr "" msgid "options_profileEditSourceHelp" msgstr "" msgid "options_profileEditSourceHelpUrl" msgstr "" msgid "options_group_proxyServers" msgstr "" msgid "options_proxy_scheme" msgstr "" msgid "options_proxy_protocol" msgstr "" msgid "options_proxy_server" msgstr "" msgid "options_proxy_port" msgstr "" msgid "options_proxy_auth" msgstr "" msgid "options_proxy_authNotSupported" msgstr "" msgid "options_proxy_authAllWarningPac" msgstr "" msgid "options_proxy_authAllWarningPacUrl" msgstr "" msgid "options_proxy_authAllWarningPacScript" msgstr "" msgid "options_proxy_authReferencedWarning" msgstr "" msgid "options_scheme_default" msgstr "" msgid "options_protocol_direct" msgstr "" msgid "options_protocol_useDefault" msgstr "" msgid "options_proxy_single" msgstr "" msgid "options_proxy_expand" msgstr "" msgid "options_group_bypassList" msgstr "" msgid "options_bypassListHelp" msgstr "" msgid "options_bypassListHelpLinkText" msgstr "" msgid "options_group_pacUrl" msgstr "" msgid "options_pacUrlHelp" msgstr "" msgid "options_pacUrlFile" msgstr "" msgid "options_pacUrlFileDisabled" msgstr "" msgid "options_group_pacScript" msgstr "" msgid "options_pacScriptLastUpdate" msgstr "" msgid "options_pacScriptObsolete" msgstr "" msgid "options_group_virtualProfile" msgstr "" msgid "options_virtualProfileTarget" msgstr "" msgid "options_virtualProfileTargetHelp" msgstr "" msgid "options_group_virtualProfileReplace" msgstr "" msgid "options_virtualProfileReplace" msgstr "" msgid "options_virtualProfileReplaceHelp" msgstr "" msgid "options_group_ruleListConfig" msgstr "" msgid "options_ruleListFormat" msgstr "" msgid "options_group_ruleListResult" msgstr "" msgid "options_ruleListMatchProfile" msgstr "" msgid "options_ruleListDefaultProfile" msgstr "" msgid "options_group_ruleListUrl" msgstr "" msgid "options_ruleListUrlHelp" msgstr "" msgid "options_group_ruleListText" msgstr "" msgid "options_ruleListLastUpdate" msgstr "" msgid "options_ruleListObsolete" msgstr "" msgid "options_group_switchRules" msgstr "" msgid "options_sort" msgstr "" msgid "options_conditionType" msgstr "" msgid "options_showConditionTypeHelp" msgstr "" msgid "options_conditionDetails" msgstr "" msgid "options_resultProfile" msgstr "" msgid "options_conditionActions" msgstr "" msgid "options_addCondition" msgstr "" msgid "options_cloneRule" msgstr "" msgid "options_ruleNote" msgstr "" msgid "options_switchAttachedProfileInCondition" msgstr "" msgid "options_switchAttachedProfileInConditionDetails" msgstr "" msgid "options_switchAttachedProfileInConditionDisabled" msgstr "" msgid "options_switchDefaultProfile" msgstr "" msgid "options_hostLevelsBetween" msgstr "" msgid "options_hourBetween" msgstr "" msgid "options_weekDayShort_0" msgstr "" msgid "options_weekDayShort_1" msgstr "" msgid "options_weekDayShort_2" msgstr "" msgid "options_weekDayShort_3" msgstr "" msgid "options_weekDayShort_4" msgstr "" msgid "options_weekDayShort_5" msgstr "" msgid "options_weekDayShort_6" msgstr "" msgid "options_group_conditionHelp" msgstr "" msgid "options_group_attachProfile" msgstr "" msgid "options_attachProfile" msgstr "" msgid "options_attachProfileHelp" msgstr "" msgid "options_modalHeader_welcome" msgstr "" msgid "options_welcomeNormal" msgstr "" msgid "options_welcomeNormalGuide" msgstr "" msgid "options_welcomeUpgrade" msgstr "" msgid "options_welcomeUpgradeGuide" msgstr "" msgid "options_guideNext" msgstr "" msgid "options_guideDone" msgstr "" msgid "options_guideSkip" msgstr "" msgid "options_modalHeader_applyOptions" msgstr "" msgid "options_optionsNotSaved" msgstr "" msgid "options_applyOptionsRequired" msgstr "" msgid "options_applyOptionsConfirm" msgstr "" msgid "options_modalHeader_renameProfile" msgstr "" msgid "options_renameProfileName" msgstr "" msgid "options_profileNameConflict" msgstr "" msgid "options_profileNameReserved" msgstr "" msgid "options_profileNameHidden" msgstr "" msgid "options_modalHeader_replaceProfile" msgstr "" msgid "options_replaceProfile" msgstr "" msgid "options_replaceProfileConfirm" msgstr "" msgid "options_replaceProfileHelp" msgstr "" msgid "options_replaceProfileSuccess" msgstr "" msgid "options_modalHeader_deleteProfile" msgstr "" msgid "options_deleteProfileConfirm" msgstr "" msgid "options_modalHeader_cannotDeleteProfile" msgstr "" msgid "options_profileReferredBy" msgstr "" msgid "options_modifyReferringProfiles" msgstr "" msgid "options_profileNameEmpty" msgstr "" msgid "popup_title" msgstr "" msgid "options_modalHeader_proxyAuth" msgstr "" msgid "options_proxyAuthUsername" msgstr "" msgid "options_proxyAuthPassword" msgstr "" msgid "options_proxyAuthShowPassword" msgstr "" msgid "options_proxyAuthHidePassword" msgstr "" msgid "options_proxyAuthNone" msgstr "" msgid "options_modalHeader_deleteRule" msgstr "" msgid "options_deleteRuleConfirm" msgstr "" msgid "options_deleteRule" msgstr "" msgid "options_modalHeader_resetRules" msgstr "" msgid "options_resetRulesConfirm" msgstr "" msgid "options_resetRules" msgstr "" msgid "options_resetRules_help" msgstr "" msgid "options_modalHeader_deleteAttached" msgstr "" msgid "options_deleteAttachedConfirm" msgstr "" msgid "options_ruleListLineCount" msgstr "" msgid "options_deleteAttached" msgstr "" msgid "options_modalHeader_newProfile" msgstr "" msgid "options_newProfileName" msgstr "" msgid "options_profileType" msgstr "" msgid "options_profileTypeFixedProfile" msgstr "" msgid "options_profileDescFixedProfile" msgstr "" msgid "options_profileTypePacProfile" msgstr "" msgid "options_profileDescPacProfile" msgstr "" msgid "options_profileDescMorePacProfile" msgstr "" msgid "options_profileTypeSwitchProfile" msgstr "" msgid "options_profileDescSwitchProfile" msgstr "" msgid "options_profileTypeRuleListProfile" msgstr "" msgid "options_profileDescRuleListProfile" msgstr "" msgid "options_profileTypeVirtualProfile" msgstr "" msgid "options_profileDescVirtualProfile" msgstr "" msgid "options_createProfile" msgstr "" msgid "options_modalHeader_resetOptions" msgstr "" msgid "options_resetOptionsConfirm" msgstr "" msgid "options_formInvalid" msgstr "" msgid "options_profileNotFound" msgstr "" msgid "options_resetSuccess" msgstr "" msgid "options_saveSuccess" msgstr "" msgid "options_importSuccess" msgstr "" msgid "options_importFormatError" msgstr "" msgid "options_importDownloadError" msgstr "" msgid "options_profileDownloadSuccess" msgstr "" msgid "options_profileDownloadError" msgstr "" msgid "options_profileDownloadError_NetworkError" msgstr "" msgid "options_profileDownloadError_HttpError" msgstr "" msgid "options_profileDownloadError_HttpNotFoundError" msgstr "" msgid "options_profileDownloadError_HttpServerError" msgstr "" msgid "options_profileDownloadError_ContentTypeRejectedError" msgstr "" msgid "options_downloadProfileNow" msgstr "" msgid "options_guide_fixedProfileStep" msgstr "" msgid "options_guide_fixedServersStep" msgstr "" msgid "options_guide_autoSwitchProfileStep" msgstr "" msgid "options_guide_addMoreProfilesStep" msgstr "" msgid "options_guide_conditionStep" msgstr "" msgid "options_guide_conditionTypeStep" msgstr "" msgid "options_guide_conditionProfileStep" msgstr "" msgid "options_guide_switchDefaultStep" msgstr "" msgid "options_guide_applySwitchProfileStep" msgstr "" msgid "popup_externalProfile" msgstr "" msgid "popup_externalProfileName" msgstr "" msgid "popup_proxyNotControllable_app" msgstr "" msgid "popup_proxyNotControllable_policy" msgstr "" msgid "popup_proxyNotControllable_unknown" msgstr "" msgid "popup_proxyNotControllable_disabled" msgstr "" msgid "popup_proxyNotControllable_upgrade" msgstr "" msgid "popup_proxyNotControllableDetails" msgstr "" msgid "popup_proxyNotControllableDetails_upgrade" msgstr "" msgid "popup_proxyNotControllableManage" msgstr "" msgid "popup_addConditionTo" msgstr "" msgid "popup_addCondition" msgstr "" msgid "popup_showOptions" msgstr "" msgid "popup_reportIssues" msgstr "" msgid "popup_errorLog" msgstr "" msgid "popup_requestErrorCount" msgstr "" msgid "popup_requestErrorHeading" msgstr "" msgid "popup_requestErrorWarning" msgstr "" msgid "popup_requestErrorWarningHelp" msgstr "" msgid "popup_requestErrorAddCondition" msgstr "" msgid "popup_requestErrorCannotAddCondition" msgstr "" msgid "popup_configureMonitorWebRequests" msgstr "" msgid "options_resultProfileForSelectedDomains" msgstr "" msgid "options_pac_profile_unsupported_moz" msgstr "" msgid "popup_issueTemplate" msgstr "" msgid "browserAction_profileDetails_PacProfile" msgstr "" msgid "browserAction_profileDetails_SystemProfile" msgstr "" msgid "browserAction_profileDetails_DirectProfile" msgstr "" msgid "browserAction_profileDetails_SwitchProfile" msgstr "" msgid "browserAction_profileDetails_RuleListProfile" msgstr "" msgid "browserAction_titleNormal" msgstr "" msgid "browserAction_titleWithResult" msgstr "" msgid "browserAction_titleNewerOptions" msgstr "" msgid "browserAction_titleOptionError" msgstr "" msgid "browserAction_titleDownloadFail" msgstr "" msgid "browserAction_titleExternalProxy" msgstr "" msgid "browserAction_titleInspect" msgstr "" msgid "browserAction_defaultRuleDetails" msgstr "" msgid "browserAction_directResult" msgstr "" msgid "browserAction_attachedPrefix" msgstr "" msgid "browserAction_tempRulePrefix" msgstr "" msgid "contextMenu_inspectPage" msgstr "" msgid "contextMenu_inspectFrame" msgstr "" msgid "contextMenu_inspectLink" msgstr "" msgid "contextMenu_inspectElement" msgstr "" msgid "contextMenu_enableQuickSwitch" msgstr "" msgid "about_title" msgstr "" msgid "about_app_description" msgstr "" msgid "about_version" msgstr "" msgid "about_experimental_warning_moz" msgstr "" msgid "about_disclaimer_networkService" msgstr "" msgid "about_disclaimer_privacy" msgstr "" msgid "about_help" msgstr "" msgid "about_copyright" msgstr "" msgid "about_credits" msgstr "" msgid "about_license" msgstr "" ================================================ FILE: omega-locales/is/LC_MESSAGES/omega-web.po ================================================ msgid "" msgstr "" "Project-Id-Version: SwitchyOmega 2.3.3\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2015-02-13 10:29+0000\n" "PO-Revision-Date: 2016-04-03 03:49+0000\n" "Last-Translator: Simon Leonhardt \n" "Language-Team: Icelandic " "\n" "Language: is\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Generator: Weblate 2.6-dev\n" msgid "appNameShort" msgstr "SwitchyOmega" msgid "manifest_app_name" msgstr "Proxy SwitchyOmega" msgid "manifest_app_description" msgstr "Stjórnaðu eða skiptu á milli margra proxy hratt og auðveldlega." msgid "manifest_icon_default_title" msgstr "Hleður…" msgid "upgrade_profile_auto" msgstr "Sjálfskipting" msgid "profile_direct" msgstr "[Beint]" msgid "profile_system" msgstr "[System Proxy]" msgid "condition_HostWildcardCondition" msgstr "" msgid "condition_help_HostWildcardCondition" msgstr "" msgid "condition_HostRegexCondition" msgstr "" msgid "condition_help_HostRegexCondition" msgstr "" msgid "condition_HostLevelsCondition" msgstr "" msgid "condition_help_HostLevelsCondition" msgstr "" msgid "condition_IpCondition" msgstr "IP Literals" msgid "condition_help_IpCondition" msgstr "" "Matches the request if and only if the host is a literal IP address and" " in the subnet as specified by
" "CIDR notation.
For example, given the rule 127.0.0.1/16, " "it matches all IP addresses like 127.0.*.*.
" "So 127.0.0.1 matches while 127.1.0.0 does not. " "Host names like localhost will never match because they are " "not IP literals." msgid "condition_UrlWildcardCondition" msgstr "" msgid "condition_help_UrlWildcardCondition" msgstr "" msgid "condition_UrlRegexCondition" msgstr "" msgid "condition_help_UrlRegexCondition" msgstr "" msgid "condition_KeywordCondition" msgstr "" msgid "condition_help_KeywordCondition" msgstr "" msgid "condition_FalseCondition" msgstr "(Slökkt)" msgid "condition_details_FalseCondition" msgstr "" msgid "condition_help_FalseCondition" msgstr "" msgid "condition_TimeCondition" msgstr "" msgid "condition_help_TimeCondition" msgstr "" msgid "condition_WeekdayCondition" msgstr "Vikudagur" msgid "condition_help_WeekdayCondition" msgstr "" msgid "condition_alert_fullUrlLimitation" msgstr "" "Full URL matching is no longer possible for https:// " "URLs as of Chrome 52. " "" "Learn more..." msgid "condition_alert_fullUrlLimitationLink" msgstr "https://github.com/FelisCatus/SwitchyOmega/wiki/Chromium-Full-URL-Limitation" msgid "condition_group_default" msgstr "" msgid "condition_group_host" msgstr "" msgid "condition_group_url" msgstr "" msgid "condition_group_special" msgstr "" msgid "ruleListFormat_Switchy" msgstr "Switchy" msgid "ruleListFormat_AutoProxy" msgstr "AutoProxy" msgid "ruleList_usageUrl" msgstr "https://github.com/FelisCatus/SwitchyOmega/wiki/RuleListUsage" msgid "ruleList_error_resultNotEnabled" msgstr "" msgid "ruleList_error_unknownProfile" msgstr "" msgid "ruleList_error_missingResultProfile" msgstr "" msgid "ruleList_error_invalidRule" msgstr "" msgid "ruleList_error_noDefaultRule" msgstr "" msgid "dialog_close" msgstr "" msgid "dialog_save" msgstr "" msgid "dialog_ok" msgstr "" msgid "dialog_cancel" msgstr "" msgid "inputClear_clear" msgstr "" msgid "inputClear_restore" msgstr "" msgid "options_title" msgstr "" msgid "options_experimental_badge" msgstr "α" msgid "options_navHeader_setting" msgstr "" msgid "options_navHeader_profiles" msgstr "" msgid "options_navHeader_actions" msgstr "" msgid "options_tab_ui" msgstr "" msgid "options_tab_general" msgstr "" msgid "options_tab_importExport" msgstr "" msgid "options_newProfile" msgstr "" msgid "options_apply" msgstr "" msgid "options_discard" msgstr "" msgid "options_reset" msgstr "" msgid "options_group_miscOptions" msgstr "" msgid "options_confirmDeletion" msgstr "" msgid "options_refreshOnProfileChange" msgstr "" msgid "options_showInspectMenu" msgstr "" msgid "options_addConditionsToBottom" msgstr "Put new conditions added using the popup to the bottom of the list." msgid "options_group_keyboardShortcut" msgstr "" msgid "options_menuShortcutHelp" msgstr "" msgid "options_menuShortcutMore" msgstr "" msgid "options_menuShortcutConfigure" msgstr "" msgid "options_group_switchOptions" msgstr "" msgid "options_startupProfile" msgstr "" msgid "options_startupProfile_none" msgstr "" msgid "options_showConditionTypesAdvanced" msgstr "" msgid "options_showConditionTypesAdvancedHelp" msgstr "" msgid "options_quickSwitch" msgstr "" msgid "options_cycledProfiles" msgstr "" msgid "options_cycledProfilesHelp" msgstr "" msgid "options_cycledProfilesTooFew" msgstr "" msgid "options_notCycledProfiles" msgstr "" msgid "options_group_proxyChanges" msgstr "" msgid "options_revertProxyChanges" msgstr "" msgid "options_group_conflicts" msgstr "Conflicts" msgid "options_conflicts_introduction" msgstr "" "Sometimes, other apps will also try to control the proxy settings, resulting " "in conflicts. Note that ad blockers and other extensions may also use proxy " "settings under the hood. Such conflicts cannot be avoided due to how the " "browser works." msgid "options_conflicts_lowerPriority" msgstr "" "A red badge like this on the SwitchyOmega icon indicates that another app has " "higher priority so SwitchyOmega cannot control the settings. Please try to " "uninstall SwitchyOmega and reinstall, which should raise SwitchyOmega's " "priority. If you still see conflicts after reinstallation, please consider " "removing the other app causing the conflict." msgid "options_conflicts_higherPriority" msgstr "" "If SwitchyOmega has higher priority, you can give the control back to other " "apps or system settings by selecting $SYSTEMPROFILE$ in the popup menu." msgid "options_showExternalProfile" msgstr "Show popup menu item to import proxy settings from other apps." msgid "options_showExternalProfileHelp" msgstr "" "When $SYSTEMPROFILE$ is selected, you can import the effective proxy settings " "from other apps by selecting $EXTERNALPROFILE$ on the popup menu. " "The settings will be imported as a profile using the name you provide. " "Please note that the imported profile is a snapshot and will not reflect " "any changes from the source app thereafter." msgid "options_group_networkRequests" msgstr "" msgid "options_monitorWebRequests" msgstr "" msgid "options_monitorWebRequestsHelp" msgstr "" msgid "options_downloadOptions" msgstr "" msgid "options_downloadOptionsHelp" msgstr "" msgid "options_downloadInterval" msgstr "" msgid "options_downloadInterval_15" msgstr "" msgid "options_downloadInterval_60" msgstr "" msgid "options_downloadInterval_180" msgstr "" msgid "options_downloadInterval_360" msgstr "" msgid "options_downloadInterval_720" msgstr "" msgid "options_downloadInterval_1440" msgstr "" msgid "options_downloadInterval_never" msgstr "" msgid "options_group_importExportProfile" msgstr "" msgid "options_exportPacFile" msgstr "" msgid "options_exportPacFileHelp" msgstr "" msgid "options_exportProfileHelp" msgstr "" msgid "options_exportLegacyRuleList" msgstr "" msgid "options_exportLegacyRuleListHelp" msgstr "" msgid "options_group_importExportSettings" msgstr "" msgid "options_makeBackup" msgstr "" msgid "options_makeBackupHelp" msgstr "" msgid "options_restoreLocal" msgstr "" msgid "options_restoreLocalHelp" msgstr "" msgid "options_restoreOnline" msgstr "" msgid "options_restoreOnlinePlaceholder" msgstr "" msgid "options_restoreOnlineSubmit" msgstr "" msgid "options_group_syncing" msgstr "" msgid "options_syncEnable" msgstr "" msgid "options_syncEnableForce" msgstr "" msgid "options_syncDisable" msgstr "" msgid "options_syncReset" msgstr "" msgid "options_syncPristineHelp" msgstr "" msgid "options_syncSyncAlert" msgstr "" msgid "options_syncSyncHelp" msgstr "" msgid "options_syncConflictAlert" msgstr "" msgid "options_syncConflictHelp" msgstr "" msgid "options_syncUnsupportedHelp" msgstr "" msgid "options_profileSyncDisabled" msgstr "" msgid "options_profileSyncDisabled_quotaPerItem" msgstr "" msgid "options_profileTabPrefix" msgstr "" msgid "options_renameProfile" msgstr "" msgid "options_deleteProfile" msgstr "" msgid "options_profileExportRuleList" msgstr "" msgid "options_profileExportRuleListHelp" msgstr "" msgid "options_profileExportPac" msgstr "" msgid "options_profileUnsupported" msgstr "" msgid "options_profileUnsupportedHelp" msgstr "" msgid "options_profileEditSource" msgstr "" msgid "options_profileEditSourceHelp" msgstr "" msgid "options_profileEditSourceHelpUrl" msgstr "" msgid "options_group_proxyServers" msgstr "" msgid "options_proxy_scheme" msgstr "" msgid "options_proxy_protocol" msgstr "" msgid "options_proxy_server" msgstr "" msgid "options_proxy_port" msgstr "" msgid "options_proxy_auth" msgstr "" msgid "options_proxy_authNotSupported" msgstr "Your browser DOES NOT support $PROTOCOLDISP$ proxy authentication! " "Please do not report this issue to SwitchyOmega. Contact the support for " "your browser instead." msgid "options_proxy_authAllWarningPac" msgstr "" msgid "options_proxy_authAllWarningPacUrl" msgstr "" msgid "options_proxy_authAllWarningPacScript" msgstr "" msgid "options_proxy_authReferencedWarning" msgstr "" msgid "options_scheme_default" msgstr "" msgid "options_protocol_direct" msgstr "" msgid "options_protocol_useDefault" msgstr "" msgid "options_proxy_single" msgstr "" msgid "options_proxy_expand" msgstr "" msgid "options_group_bypassList" msgstr "" msgid "options_bypassListHelp" msgstr "" msgid "options_bypassListHelpLinkText" msgstr "" msgid "options_group_pacUrl" msgstr "" msgid "options_pacUrlHelp" msgstr "" msgid "options_pacUrlFile" msgstr "" msgid "options_pacUrlFileDisabled" msgstr "" msgid "options_group_pacScript" msgstr "" msgid "options_pacScriptLastUpdate" msgstr "" msgid "options_pacScriptObsolete" msgstr "" msgid "options_group_virtualProfile" msgstr "" msgid "options_virtualProfileTarget" msgstr "" msgid "options_virtualProfileTargetHelp" msgstr "" msgid "options_group_virtualProfileReplace" msgstr "" msgid "options_virtualProfileReplace" msgstr "" msgid "options_virtualProfileReplaceHelp" msgstr "" msgid "options_group_ruleListConfig" msgstr "" msgid "options_ruleListFormat" msgstr "" msgid "options_group_ruleListResult" msgstr "" msgid "options_ruleListMatchProfile" msgstr "" msgid "options_ruleListDefaultProfile" msgstr "" msgid "options_group_ruleListUrl" msgstr "" msgid "options_ruleListUrlHelp" msgstr "" msgid "options_group_ruleListText" msgstr "" msgid "options_ruleListLastUpdate" msgstr "" msgid "options_ruleListObsolete" msgstr "" msgid "options_group_switchRules" msgstr "" msgid "options_sort" msgstr "" msgid "options_conditionType" msgstr "" msgid "options_showConditionTypeHelp" msgstr "" msgid "options_conditionDetails" msgstr "" msgid "options_resultProfile" msgstr "" msgid "options_conditionActions" msgstr "" msgid "options_addCondition" msgstr "" msgid "options_cloneRule" msgstr "" msgid "options_ruleNote" msgstr "Note" msgid "options_switchAttachedProfileInCondition" msgstr "" msgid "options_switchAttachedProfileInConditionDetails" msgstr "" msgid "options_switchAttachedProfileInConditionDisabled" msgstr "" msgid "options_switchDefaultProfile" msgstr "" msgid "options_hostLevelsBetween" msgstr "" msgid "options_hourBetween" msgstr "" msgid "options_weekDayShort_0" msgstr "" msgid "options_weekDayShort_1" msgstr "" msgid "options_weekDayShort_2" msgstr "" msgid "options_weekDayShort_3" msgstr "" msgid "options_weekDayShort_4" msgstr "" msgid "options_weekDayShort_5" msgstr "" msgid "options_weekDayShort_6" msgstr "" msgid "options_group_conditionHelp" msgstr "" msgid "options_group_attachProfile" msgstr "" msgid "options_attachProfile" msgstr "" msgid "options_attachProfileHelp" msgstr "" msgid "options_modalHeader_welcome" msgstr "" msgid "options_welcomeNormal" msgstr "" msgid "options_welcomeNormalGuide" msgstr "" msgid "options_welcomeUpgrade" msgstr "" msgid "options_welcomeUpgradeGuide" msgstr "" msgid "options_guideNext" msgstr "" msgid "options_guideDone" msgstr "" msgid "options_guideSkip" msgstr "" msgid "options_modalHeader_applyOptions" msgstr "" msgid "options_optionsNotSaved" msgstr "" msgid "options_applyOptionsRequired" msgstr "" msgid "options_applyOptionsConfirm" msgstr "" msgid "options_modalHeader_renameProfile" msgstr "" msgid "options_renameProfileName" msgstr "" msgid "options_profileNameConflict" msgstr "" msgid "options_profileNameReserved" msgstr "" msgid "options_profileNameHidden" msgstr "" msgid "options_modalHeader_replaceProfile" msgstr "" msgid "options_replaceProfile" msgstr "" msgid "options_replaceProfileConfirm" msgstr "" msgid "options_replaceProfileHelp" msgstr "" msgid "options_replaceProfileSuccess" msgstr "" msgid "options_modalHeader_deleteProfile" msgstr "" msgid "options_deleteProfileConfirm" msgstr "" msgid "options_modalHeader_cannotDeleteProfile" msgstr "" msgid "options_profileReferredBy" msgstr "" msgid "options_modifyReferringProfiles" msgstr "" msgid "options_profileNameEmpty" msgstr "" msgid "popup_title" msgstr "" msgid "options_modalHeader_proxyAuth" msgstr "" msgid "options_proxyAuthUsername" msgstr "" msgid "options_proxyAuthPassword" msgstr "" msgid "options_proxyAuthShowPassword" msgstr "Show password" msgid "options_proxyAuthHidePassword" msgstr "Hide password" msgid "options_proxyAuthNone" msgstr "" msgid "options_modalHeader_deleteRule" msgstr "" msgid "options_deleteRuleConfirm" msgstr "" msgid "options_deleteRule" msgstr "" msgid "options_modalHeader_resetRules" msgstr "" msgid "options_resetRulesConfirm" msgstr "" msgid "options_resetRules" msgstr "" msgid "options_resetRules_help" msgstr "" msgid "options_modalHeader_deleteAttached" msgstr "" msgid "options_deleteAttachedConfirm" msgstr "" msgid "options_ruleListLineCount" msgstr "" msgid "options_deleteAttached" msgstr "" msgid "options_modalHeader_newProfile" msgstr "" msgid "options_newProfileName" msgstr "" msgid "options_profileType" msgstr "" msgid "options_profileTypeFixedProfile" msgstr "" msgid "options_profileDescFixedProfile" msgstr "" msgid "options_profileTypePacProfile" msgstr "" msgid "options_profileDescPacProfile" msgstr "" msgid "options_profileDescMorePacProfile" msgstr "" msgid "options_profileTypeSwitchProfile" msgstr "" msgid "options_profileDescSwitchProfile" msgstr "" msgid "options_profileTypeRuleListProfile" msgstr "" msgid "options_profileDescRuleListProfile" msgstr "" msgid "options_profileTypeVirtualProfile" msgstr "" msgid "options_profileDescVirtualProfile" msgstr "" msgid "options_createProfile" msgstr "" msgid "options_modalHeader_resetOptions" msgstr "" msgid "options_resetOptionsConfirm" msgstr "" msgid "options_formInvalid" msgstr "" msgid "options_profileNotFound" msgstr "" msgid "options_resetSuccess" msgstr "" msgid "options_saveSuccess" msgstr "" msgid "options_importSuccess" msgstr "" msgid "options_importFormatError" msgstr "" msgid "options_importDownloadError" msgstr "" msgid "options_profileDownloadSuccess" msgstr "" msgid "options_profileDownloadError" msgstr "" msgid "options_profileDownloadError_NetworkError" msgstr "A network error occurred when updating." msgid "options_profileDownloadError_HttpError" msgstr "An HTTP error ($STATUS$) occurred when updating." msgid "options_profileDownloadError_HttpNotFoundError" msgstr "The Profile URL was not found on the server. Please double-check." msgid "options_profileDownloadError_HttpServerError" msgstr "The remote server responded with error ($STATUS$) when updating." msgid "options_profileDownloadError_ContentTypeRejectedError" msgstr "The downloaded data is invalid! " "You may open the Profile URL in your browser to inspect it." msgid "options_downloadProfileNow" msgstr "" msgid "options_guide_fixedProfileStep" msgstr "" msgid "options_guide_fixedServersStep" msgstr "" msgid "options_guide_autoSwitchProfileStep" msgstr "" msgid "options_guide_addMoreProfilesStep" msgstr "" msgid "options_guide_conditionStep" msgstr "" msgid "options_guide_conditionTypeStep" msgstr "" msgid "options_guide_conditionProfileStep" msgstr "" msgid "options_guide_switchDefaultStep" msgstr "" msgid "options_guide_applySwitchProfileStep" msgstr "" msgid "popup_externalProfile" msgstr "" msgid "popup_externalProfileName" msgstr "" msgid "popup_proxyNotControllable_app" msgstr "" msgid "popup_proxyNotControllable_policy" msgstr "" msgid "popup_proxyNotControllable_unknown" msgstr "" msgid "popup_proxyNotControllable_disabled" msgstr "" msgid "popup_proxyNotControllable_upgrade" msgstr "" msgid "popup_proxyNotControllableDetails" msgstr "" msgid "popup_proxyNotControllableDetails_upgrade" msgstr "" msgid "popup_proxyNotControllableManage" msgstr "" msgid "popup_addConditionTo" msgstr "" msgid "popup_addCondition" msgstr "" msgid "popup_showOptions" msgstr "" msgid "popup_reportIssues" msgstr "" msgid "popup_errorLog" msgstr "" msgid "popup_requestErrorCount" msgstr "" msgid "popup_requestErrorHeading" msgstr "" msgid "popup_requestErrorWarning" msgstr "" msgid "popup_requestErrorWarningHelp" msgstr "" msgid "popup_requestErrorAddCondition" msgstr "" msgid "popup_requestErrorCannotAddCondition" msgstr "" msgid "popup_configureMonitorWebRequests" msgstr "" msgid "options_resultProfileForSelectedDomains" msgstr "" msgid "options_pac_profile_unsupported_moz" msgstr "PAC Profiles WILL NOT work in Mozilla Firefox due to technical limitations!" msgid "popup_issueTemplate" msgstr "" msgid "browserAction_profileDetails_PacProfile" msgstr "" msgid "browserAction_profileDetails_SystemProfile" msgstr "" msgid "browserAction_profileDetails_DirectProfile" msgstr "" msgid "browserAction_profileDetails_SwitchProfile" msgstr "" msgid "browserAction_profileDetails_RuleListProfile" msgstr "" msgid "browserAction_titleNormal" msgstr "" msgid "browserAction_titleWithResult" msgstr "" msgid "browserAction_titleNewerOptions" msgstr "" msgid "browserAction_titleOptionError" msgstr "" msgid "browserAction_titleDownloadFail" msgstr "" msgid "browserAction_titleExternalProxy" msgstr "" msgid "browserAction_titleInspect" msgstr "" msgid "browserAction_defaultRuleDetails" msgstr "" msgid "browserAction_directResult" msgstr "" msgid "browserAction_attachedPrefix" msgstr "" msgid "browserAction_tempRulePrefix" msgstr "" msgid "contextMenu_inspectPage" msgstr "" msgid "contextMenu_inspectFrame" msgstr "" msgid "contextMenu_inspectLink" msgstr "" msgid "contextMenu_inspectElement" msgstr "" msgid "contextMenu_enableQuickSwitch" msgstr "" msgid "about_title" msgstr "About" msgid "about_app_description" msgstr "A proxy configuration tool" msgid "about_version" msgstr "Version $VERSION$" msgid "about_experimental_warning_moz" msgstr "Mozilla Firefox support is highly experimental! If you encounter issues, please report using the buttons below." msgid "about_disclaimer_networkService" msgstr "SwitchyOmega does not provide proxies, VPNs, or other network services." msgid "about_disclaimer_privacy" msgstr "SwitchyOmega does not track you or insert ads into webpages. Please see" " our privacy policy." msgid "about_help" msgstr "Other questions? Need help with using SwitchyOmega? Please see our " "FAQ." msgid "about_copyright" msgstr "Copyright 2012-2017 The SwitchyOmega Authors. All rights reserved." msgid "about_credits" msgstr "SwitchyOmega is made possible by the SwitchyOmega open source project and other open source software." msgid "about_license" msgstr "SwitchyOmega is free software licensed under GNU General Public License Version 3 or later." ================================================ FILE: omega-locales/it/LC_MESSAGES/omega-web.po ================================================ msgid "" msgstr "" "Project-Id-Version: SwitchyOmega 2.3.3\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2015-02-13 10:29+0000\n" "PO-Revision-Date: 2019-05-10 11:34+0000\n" "Last-Translator: Riccardo Feletto \n" "Language-Team: Italian \n" "Language: it\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Generator: Weblate 3.7-dev\n" msgid "appNameShort" msgstr "SwitchyOmega" msgid "manifest_app_name" msgstr "Proxy SwitchyOmega" msgid "manifest_app_description" msgstr "Organizza e scegli fra proxy multipli in maniera facile e veloce." msgid "manifest_icon_default_title" msgstr "Caricamento…" msgid "upgrade_profile_auto" msgstr "Auto Switch" msgid "profile_direct" msgstr "[Diretto]" msgid "profile_system" msgstr "[Proxy di Sistema]" msgid "condition_HostWildcardCondition" msgstr "Host wildcard" msgid "condition_help_HostWildcardCondition" msgstr "" msgid "condition_HostRegexCondition" msgstr "Host regex" msgid "condition_help_HostRegexCondition" msgstr "" msgid "condition_HostLevelsCondition" msgstr "" msgid "condition_help_HostLevelsCondition" msgstr "" msgid "condition_IpCondition" msgstr "" msgid "condition_help_IpCondition" msgstr "" msgid "condition_UrlWildcardCondition" msgstr "URL wildcard" msgid "condition_help_UrlWildcardCondition" msgstr "" msgid "condition_UrlRegexCondition" msgstr "URL regex" msgid "condition_help_UrlRegexCondition" msgstr "" msgid "condition_KeywordCondition" msgstr "Parole chiave" msgid "condition_help_KeywordCondition" msgstr "" msgid "condition_FalseCondition" msgstr "(Disabilitato)" msgid "condition_details_FalseCondition" msgstr "(Condizioni ignorate quando riscontrate)" msgid "condition_help_FalseCondition" msgstr "" msgid "condition_TimeCondition" msgstr "Tempo attuale" msgid "condition_help_TimeCondition" msgstr "" msgid "condition_WeekdayCondition" msgstr "Giorno della settimana" msgid "condition_help_WeekdayCondition" msgstr "" msgid "condition_alert_fullUrlLimitation" msgstr "" msgid "condition_alert_fullUrlLimitationLink" msgstr "" "https://github.com/FelisCatus/SwitchyOmega/wiki/Chromium-Full-URL-Limitation" msgid "condition_group_default" msgstr "" msgid "condition_group_host" msgstr "Host" msgid "condition_group_url" msgstr "Url" msgid "condition_group_special" msgstr "Speciale" msgid "ruleListFormat_Switchy" msgstr "Switchy" msgid "ruleListFormat_AutoProxy" msgstr "AutoProxy" msgid "ruleList_usageUrl" msgstr "https://github.com/FelisCatus/SwitchyOmega/wiki/RuleListUsage" msgid "ruleList_error_resultNotEnabled" msgstr "" msgid "ruleList_error_unknownProfile" msgstr "Profilo sconosciuto: $PROFILE$" msgid "ruleList_error_missingResultProfile" msgstr "" msgid "ruleList_error_invalidRule" msgstr "Regola non valida alla linea $LNO$: $SOURCE$" msgid "ruleList_error_noDefaultRule" msgstr "" msgid "dialog_close" msgstr "Chiusa" msgid "dialog_save" msgstr "Salva le modifiche" msgid "dialog_ok" msgstr "OK" msgid "dialog_cancel" msgstr "Cancella" msgid "inputClear_clear" msgstr "Pulisci" msgid "inputClear_restore" msgstr "Ripristina" msgid "options_title" msgstr "Opzioni di SwitchyOmega" msgid "options_experimental_badge" msgstr "α" msgid "options_navHeader_setting" msgstr "Impostazioni" msgid "options_navHeader_profiles" msgstr "Profili" msgid "options_navHeader_actions" msgstr "Azioni" msgid "options_tab_ui" msgstr "Interfaccia" msgid "options_tab_general" msgstr "Generale" msgid "options_tab_importExport" msgstr "Importa/Esporta" msgid "options_newProfile" msgstr "Nuovo profilo…" msgid "options_apply" msgstr "Applica i cambiamenti" msgid "options_discard" msgstr "Scarta i cambiamenti" msgid "options_reset" msgstr "Ripristina le opzioni" msgid "options_group_miscOptions" msgstr "" msgid "options_confirmDeletion" msgstr "" msgid "options_refreshOnProfileChange" msgstr "" msgid "options_showInspectMenu" msgstr "" msgid "options_addConditionsToBottom" msgstr "" msgid "options_group_keyboardShortcut" msgstr "" msgid "options_menuShortcutHelp" msgstr "" msgid "options_menuShortcutMore" msgstr "" msgid "options_menuShortcutConfigure" msgstr "" msgid "options_group_switchOptions" msgstr "" msgid "options_startupProfile" msgstr "" msgid "options_startupProfile_none" msgstr "" msgid "options_showConditionTypesAdvanced" msgstr "" msgid "options_showConditionTypesAdvancedHelp" msgstr "" msgid "options_quickSwitch" msgstr "" msgid "options_cycledProfiles" msgstr "" msgid "options_cycledProfilesHelp" msgstr "" msgid "options_cycledProfilesTooFew" msgstr "" msgid "options_notCycledProfiles" msgstr "" msgid "options_group_proxyChanges" msgstr "" msgid "options_revertProxyChanges" msgstr "" msgid "options_group_conflicts" msgstr "" msgid "options_conflicts_introduction" msgstr "" msgid "options_conflicts_lowerPriority" msgstr "" msgid "options_conflicts_higherPriority" msgstr "" msgid "options_showExternalProfile" msgstr "" msgid "options_showExternalProfileHelp" msgstr "" msgid "options_group_networkRequests" msgstr "" msgid "options_monitorWebRequests" msgstr "" msgid "options_monitorWebRequestsHelp" msgstr "" msgid "options_downloadOptions" msgstr "" msgid "options_downloadOptionsHelp" msgstr "" msgid "options_downloadInterval" msgstr "" msgid "options_downloadInterval_15" msgstr "" msgid "options_downloadInterval_60" msgstr "" msgid "options_downloadInterval_180" msgstr "" msgid "options_downloadInterval_360" msgstr "" msgid "options_downloadInterval_720" msgstr "" msgid "options_downloadInterval_1440" msgstr "" msgid "options_downloadInterval_never" msgstr "" msgid "options_group_importExportProfile" msgstr "" msgid "options_exportPacFile" msgstr "" msgid "options_exportPacFileHelp" msgstr "" msgid "options_exportProfileHelp" msgstr "" msgid "options_exportLegacyRuleList" msgstr "" msgid "options_exportLegacyRuleListHelp" msgstr "" msgid "options_group_importExportSettings" msgstr "" msgid "options_makeBackup" msgstr "" msgid "options_makeBackupHelp" msgstr "" msgid "options_restoreLocal" msgstr "" msgid "options_restoreLocalHelp" msgstr "" msgid "options_restoreOnline" msgstr "" msgid "options_restoreOnlinePlaceholder" msgstr "" msgid "options_restoreOnlineSubmit" msgstr "" msgid "options_group_syncing" msgstr "" msgid "options_syncEnable" msgstr "" msgid "options_syncEnableForce" msgstr "" msgid "options_syncDisable" msgstr "" msgid "options_syncReset" msgstr "" msgid "options_syncPristineHelp" msgstr "" msgid "options_syncSyncAlert" msgstr "" msgid "options_syncSyncHelp" msgstr "" msgid "options_syncConflictAlert" msgstr "" msgid "options_syncConflictHelp" msgstr "" msgid "options_syncUnsupportedHelp" msgstr "" msgid "options_profileSyncDisabled" msgstr "" msgid "options_profileSyncDisabled_quotaPerItem" msgstr "" msgid "options_profileTabPrefix" msgstr "" msgid "options_renameProfile" msgstr "" msgid "options_deleteProfile" msgstr "" msgid "options_profileExportRuleList" msgstr "" msgid "options_profileExportRuleListHelp" msgstr "" msgid "options_profileExportPac" msgstr "" msgid "options_profileUnsupported" msgstr "" msgid "options_profileUnsupportedHelp" msgstr "" msgid "options_profileEditSource" msgstr "" msgid "options_profileEditSourceHelp" msgstr "" msgid "options_profileEditSourceHelpUrl" msgstr "" msgid "options_group_proxyServers" msgstr "" msgid "options_proxy_scheme" msgstr "" msgid "options_proxy_protocol" msgstr "" msgid "options_proxy_server" msgstr "" msgid "options_proxy_port" msgstr "" msgid "options_proxy_auth" msgstr "" msgid "options_proxy_authNotSupported" msgstr "" msgid "options_proxy_authAllWarningPac" msgstr "" msgid "options_proxy_authAllWarningPacUrl" msgstr "" msgid "options_proxy_authAllWarningPacScript" msgstr "" msgid "options_proxy_authReferencedWarning" msgstr "" msgid "options_scheme_default" msgstr "" msgid "options_protocol_direct" msgstr "" msgid "options_protocol_useDefault" msgstr "" msgid "options_proxy_single" msgstr "" msgid "options_proxy_expand" msgstr "" msgid "options_group_bypassList" msgstr "" msgid "options_bypassListHelp" msgstr "" msgid "options_bypassListHelpLinkText" msgstr "" msgid "options_group_pacUrl" msgstr "" msgid "options_pacUrlHelp" msgstr "" msgid "options_pacUrlFile" msgstr "" msgid "options_pacUrlFileDisabled" msgstr "" msgid "options_group_pacScript" msgstr "" msgid "options_pacScriptLastUpdate" msgstr "" msgid "options_pacScriptObsolete" msgstr "" msgid "options_group_virtualProfile" msgstr "" msgid "options_virtualProfileTarget" msgstr "" msgid "options_virtualProfileTargetHelp" msgstr "" msgid "options_group_virtualProfileReplace" msgstr "" msgid "options_virtualProfileReplace" msgstr "" msgid "options_virtualProfileReplaceHelp" msgstr "" msgid "options_group_ruleListConfig" msgstr "" msgid "options_ruleListFormat" msgstr "" msgid "options_group_ruleListResult" msgstr "" msgid "options_ruleListMatchProfile" msgstr "" msgid "options_ruleListDefaultProfile" msgstr "" msgid "options_group_ruleListUrl" msgstr "" msgid "options_ruleListUrlHelp" msgstr "" msgid "options_group_ruleListText" msgstr "" msgid "options_ruleListLastUpdate" msgstr "" msgid "options_ruleListObsolete" msgstr "" msgid "options_group_switchRules" msgstr "" msgid "options_sort" msgstr "" msgid "options_conditionType" msgstr "" msgid "options_showConditionTypeHelp" msgstr "" msgid "options_conditionDetails" msgstr "" msgid "options_resultProfile" msgstr "" msgid "options_conditionActions" msgstr "" msgid "options_addCondition" msgstr "" msgid "options_cloneRule" msgstr "" msgid "options_ruleNote" msgstr "" msgid "options_switchAttachedProfileInCondition" msgstr "" msgid "options_switchAttachedProfileInConditionDetails" msgstr "" msgid "options_switchAttachedProfileInConditionDisabled" msgstr "" msgid "options_switchDefaultProfile" msgstr "" msgid "options_hostLevelsBetween" msgstr "" msgid "options_hourBetween" msgstr "" msgid "options_weekDayShort_0" msgstr "" msgid "options_weekDayShort_1" msgstr "" msgid "options_weekDayShort_2" msgstr "" msgid "options_weekDayShort_3" msgstr "" msgid "options_weekDayShort_4" msgstr "" msgid "options_weekDayShort_5" msgstr "" msgid "options_weekDayShort_6" msgstr "" msgid "options_group_conditionHelp" msgstr "" msgid "options_group_attachProfile" msgstr "" msgid "options_attachProfile" msgstr "" msgid "options_attachProfileHelp" msgstr "" msgid "options_modalHeader_welcome" msgstr "" msgid "options_welcomeNormal" msgstr "" msgid "options_welcomeNormalGuide" msgstr "" msgid "options_welcomeUpgrade" msgstr "" msgid "options_welcomeUpgradeGuide" msgstr "" msgid "options_guideNext" msgstr "" msgid "options_guideDone" msgstr "" msgid "options_guideSkip" msgstr "" msgid "options_modalHeader_applyOptions" msgstr "" msgid "options_optionsNotSaved" msgstr "" msgid "options_applyOptionsRequired" msgstr "" msgid "options_applyOptionsConfirm" msgstr "" msgid "options_modalHeader_renameProfile" msgstr "" msgid "options_renameProfileName" msgstr "" msgid "options_profileNameConflict" msgstr "" msgid "options_profileNameReserved" msgstr "" msgid "options_profileNameHidden" msgstr "" msgid "options_modalHeader_replaceProfile" msgstr "" msgid "options_replaceProfile" msgstr "" msgid "options_replaceProfileConfirm" msgstr "" msgid "options_replaceProfileHelp" msgstr "" msgid "options_replaceProfileSuccess" msgstr "" msgid "options_modalHeader_deleteProfile" msgstr "" msgid "options_deleteProfileConfirm" msgstr "" msgid "options_modalHeader_cannotDeleteProfile" msgstr "" msgid "options_profileReferredBy" msgstr "" msgid "options_modifyReferringProfiles" msgstr "" msgid "options_profileNameEmpty" msgstr "" msgid "popup_title" msgstr "" msgid "options_modalHeader_proxyAuth" msgstr "" msgid "options_proxyAuthUsername" msgstr "" msgid "options_proxyAuthPassword" msgstr "" msgid "options_proxyAuthShowPassword" msgstr "" msgid "options_proxyAuthHidePassword" msgstr "" msgid "options_proxyAuthNone" msgstr "" msgid "options_modalHeader_deleteRule" msgstr "" msgid "options_deleteRuleConfirm" msgstr "" msgid "options_deleteRule" msgstr "" msgid "options_modalHeader_resetRules" msgstr "" msgid "options_resetRulesConfirm" msgstr "" msgid "options_resetRules" msgstr "" msgid "options_resetRules_help" msgstr "" msgid "options_modalHeader_deleteAttached" msgstr "" msgid "options_deleteAttachedConfirm" msgstr "" msgid "options_ruleListLineCount" msgstr "" msgid "options_deleteAttached" msgstr "" msgid "options_modalHeader_newProfile" msgstr "" msgid "options_newProfileName" msgstr "" msgid "options_profileType" msgstr "" msgid "options_profileTypeFixedProfile" msgstr "" msgid "options_profileDescFixedProfile" msgstr "" msgid "options_profileTypePacProfile" msgstr "" msgid "options_profileDescPacProfile" msgstr "" msgid "options_profileDescMorePacProfile" msgstr "" msgid "options_profileTypeSwitchProfile" msgstr "" msgid "options_profileDescSwitchProfile" msgstr "" msgid "options_profileTypeRuleListProfile" msgstr "" msgid "options_profileDescRuleListProfile" msgstr "" msgid "options_profileTypeVirtualProfile" msgstr "" msgid "options_profileDescVirtualProfile" msgstr "" msgid "options_createProfile" msgstr "" msgid "options_modalHeader_resetOptions" msgstr "" msgid "options_resetOptionsConfirm" msgstr "" msgid "options_formInvalid" msgstr "" msgid "options_profileNotFound" msgstr "" msgid "options_resetSuccess" msgstr "" msgid "options_saveSuccess" msgstr "" msgid "options_importSuccess" msgstr "" msgid "options_importFormatError" msgstr "" msgid "options_importDownloadError" msgstr "" msgid "options_profileDownloadSuccess" msgstr "" msgid "options_profileDownloadError" msgstr "" msgid "options_profileDownloadError_NetworkError" msgstr "" msgid "options_profileDownloadError_HttpError" msgstr "" msgid "options_profileDownloadError_HttpNotFoundError" msgstr "" msgid "options_profileDownloadError_HttpServerError" msgstr "" msgid "options_profileDownloadError_ContentTypeRejectedError" msgstr "" msgid "options_downloadProfileNow" msgstr "" msgid "options_guide_fixedProfileStep" msgstr "" msgid "options_guide_fixedServersStep" msgstr "" msgid "options_guide_autoSwitchProfileStep" msgstr "" msgid "options_guide_addMoreProfilesStep" msgstr "" msgid "options_guide_conditionStep" msgstr "" msgid "options_guide_conditionTypeStep" msgstr "" msgid "options_guide_conditionProfileStep" msgstr "" msgid "options_guide_switchDefaultStep" msgstr "" msgid "options_guide_applySwitchProfileStep" msgstr "" msgid "popup_externalProfile" msgstr "" msgid "popup_externalProfileName" msgstr "" msgid "popup_proxyNotControllable_app" msgstr "" msgid "popup_proxyNotControllable_policy" msgstr "" msgid "popup_proxyNotControllable_unknown" msgstr "" msgid "popup_proxyNotControllable_disabled" msgstr "" msgid "popup_proxyNotControllable_upgrade" msgstr "" msgid "popup_proxyNotControllableDetails" msgstr "" msgid "popup_proxyNotControllableDetails_upgrade" msgstr "" msgid "popup_proxyNotControllableManage" msgstr "" msgid "popup_addConditionTo" msgstr "" msgid "popup_addCondition" msgstr "" msgid "popup_showOptions" msgstr "" msgid "popup_reportIssues" msgstr "" msgid "popup_errorLog" msgstr "" msgid "popup_requestErrorCount" msgstr "" msgid "popup_requestErrorHeading" msgstr "" msgid "popup_requestErrorWarning" msgstr "" msgid "popup_requestErrorWarningHelp" msgstr "" msgid "popup_requestErrorAddCondition" msgstr "" msgid "popup_requestErrorCannotAddCondition" msgstr "" msgid "popup_configureMonitorWebRequests" msgstr "" msgid "options_resultProfileForSelectedDomains" msgstr "" msgid "options_pac_profile_unsupported_moz" msgstr "" msgid "popup_issueTemplate" msgstr "" msgid "browserAction_profileDetails_PacProfile" msgstr "" msgid "browserAction_profileDetails_SystemProfile" msgstr "" msgid "browserAction_profileDetails_DirectProfile" msgstr "" msgid "browserAction_profileDetails_SwitchProfile" msgstr "" msgid "browserAction_profileDetails_RuleListProfile" msgstr "" msgid "browserAction_titleNormal" msgstr "" msgid "browserAction_titleWithResult" msgstr "" msgid "browserAction_titleNewerOptions" msgstr "" msgid "browserAction_titleOptionError" msgstr "" msgid "browserAction_titleDownloadFail" msgstr "" msgid "browserAction_titleExternalProxy" msgstr "" msgid "browserAction_titleInspect" msgstr "" msgid "browserAction_defaultRuleDetails" msgstr "" msgid "browserAction_directResult" msgstr "" msgid "browserAction_attachedPrefix" msgstr "" msgid "browserAction_tempRulePrefix" msgstr "" msgid "contextMenu_inspectPage" msgstr "" msgid "contextMenu_inspectFrame" msgstr "" msgid "contextMenu_inspectLink" msgstr "" msgid "contextMenu_inspectElement" msgstr "" msgid "contextMenu_enableQuickSwitch" msgstr "" msgid "about_title" msgstr "" msgid "about_app_description" msgstr "" msgid "about_version" msgstr "" msgid "about_experimental_warning_moz" msgstr "" msgid "about_disclaimer_networkService" msgstr "" msgid "about_disclaimer_privacy" msgstr "" msgid "about_help" msgstr "" msgid "about_copyright" msgstr "" msgid "about_credits" msgstr "" msgid "about_license" msgstr "" ================================================ FILE: omega-locales/ja/LC_MESSAGES/omega-web.po ================================================ msgid "" msgstr "" "Project-Id-Version: SwitchyOmega 2.3.3\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2015-02-13 10:29+0000\n" "PO-Revision-Date: 2022-02-18 08:54+0000\n" "Last-Translator: Plat \n" "Language-Team: Japanese \n" "Language: ja\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" "X-Generator: Weblate 4.11-dev\n" msgid "appNameShort" msgstr "SwitchyOmega" msgid "manifest_app_name" msgstr "Proxy SwitchyOmega" msgid "manifest_app_description" msgstr "素早く簡単に複数のプロキシを管理・切替できます。" msgid "manifest_icon_default_title" msgstr "読み込んでいます…" msgid "upgrade_profile_auto" msgstr "自動切替" msgid "profile_direct" msgstr "[直接接続]" msgid "profile_system" msgstr "[システムのプロキシ]" msgid "condition_HostWildcardCondition" msgstr "ホスト名とワイルドカード" msgid "condition_help_HostWildcardCondition" msgstr "" "ワイルドカードを使ってホスト名(ドメイン名)にマッチします。
アスタリスク*は0個以上の文字にマッチします。" "
疑問符?は1文字のみにマッチします。特にホストをワイルドカードの条件を使って指定するときに限っては、
*.から始まるルールは特別に扱います。

例えば、*.example.comはw" "ww.example.comに限らずexample.comにも同様にマッチします。
サブドメインのみにマッチさせたいとき" "は、**.example.comといった具合に、アスタリスクを2つ使用してください。" msgid "condition_HostRegexCondition" msgstr "ホスト名の正規表現" msgid "condition_help_HostRegexCondition" msgstr "" "ホスト名のワイルドカード条件と似ていますが、ホスト名(ドメイン名)に正規表現</a>を利用してマッチします。
正規表現は作成や解読が難しくなりことがあります。
大抵の" "場合ではワイルドカードを使い、どうしても他の方法では記述できない場合にのみ正規表現を使った方がよいでしょう。" msgid "condition_HostLevelsCondition" msgstr "ホストレベル" msgid "condition_help_HostLevelsCondition" msgstr "" "ホストレベルが指定された範囲内にある場合にのみ、リクエストに一致します。
ホストレベルは、ホスト(ドメイン名)のドットで区切られたセグメントの" "数として定義されます。
例:www.example." "comのホストレベルは3ですが、internalのホストレベルは1です。" msgid "condition_IpCondition" msgstr "IPリテラル" msgid "condition_help_IpCondition" msgstr "" "Matches the request if and only if the host is a literal IP address and" " in the subnet as specified by
" "CIDR notation.
For example, given the rule 127.0.0.1/16, " "it matches all IP addresses like 127.0.*.*.
" "So 127.0.0.1 matches while 127.1.0.0 does not. " "Host names like localhost will never match because they are " "not IP literals." msgid "condition_UrlWildcardCondition" msgstr "URLワイルドカード" msgid "condition_help_UrlWildcardCondition" msgstr "" "Matches URLs of the request by wildcard.
See the Host wildcard section " "above for a quick wildcard reference.
Note that URL wildcards are not " "specially treated (no subdomain magic as in Host wildcard).
So *://" "*.example.com/* matches http://www.example.com/ but does not " "match http://example.com/." msgid "condition_UrlRegexCondition" msgstr "URL正規表現" msgid "condition_help_UrlRegexCondition" msgstr "" "Matches URL by extremely powerful regular expression.
However, regular " "expressions can be hard to construct (and read).
It is recommended to use " "wildcards for most cases and only use regex for conditions that cannot be " "achieved by any other condition type." msgid "condition_KeywordCondition" msgstr "キーワード" msgid "condition_help_KeywordCondition" msgstr "" "A keyword condition matches if the URL protocol is HTTP, and the pattern is " "an exact sub-string of the URL.
It behaves like the URL wildcard pattern " "http://*pattern*, where pattern is the keyword " "pattern.
Keyword conditions are useful if you want to bypass a firewall " "blocking some keywords in the URL, by requesting such URLs through a proxy." msgid "condition_FalseCondition" msgstr "(無効)" msgid "condition_details_FalseCondition" msgstr "(マッチ時に無視される条件)" msgid "condition_help_FalseCondition" msgstr "" "You can disable a condition by setting its type to (Disabled). " "A Disabled condition act as if it does not exist.
This feature can be " "used to disable conditions temporarily.
Disabled conditions still hold " "the previous information (like patterns) and can be re-enabled by setting " "the condition type back to the previous type." msgid "condition_TimeCondition" msgstr "現在の時刻" msgid "condition_help_TimeCondition" msgstr "" "Matches if the current local time is in the range defined by " "starting hour and ending hour, both inclusive.
" "Local time, starting hour and ending hour are all calculated in " "24-hour format (from 0 to 23).
" "The calculation happens roughly at the moment when the request is sent." msgid "condition_WeekdayCondition" msgstr "曜日" msgid "condition_help_WeekdayCondition" msgstr "" "Matches if the current day of week is selected in condition details. " "Day is calculated according to local timezone.
" "The request and its URL don't matter to this condition. " "The result is solely based on the day of the week when the request is sent." msgid "condition_alert_fullUrlLimitation" msgstr "" "URL全体のマッチは https:// を使用したURLにおいてはChrome 52からできなくなりました。 詳細はこちら" msgid "condition_alert_fullUrlLimitationLink" msgstr "https://github.com/FelisCatus/SwitchyOmega/wiki/Chromium-Full-URL-Limitation" msgid "condition_group_default" msgstr " " msgid "condition_group_host" msgstr "ホスト" msgid "condition_group_url" msgstr "URL" msgid "condition_group_special" msgstr "特別" msgid "ruleListFormat_Switchy" msgstr "Switchy" msgid "ruleListFormat_AutoProxy" msgstr "自動プロキシ" msgid "ruleList_usageUrl" msgstr "https://github.com/FelisCatus/SwitchyOmega/wiki/RuleListUsage" msgid "ruleList_error_resultNotEnabled" msgstr "'@with result'の部分がありません!" msgid "ruleList_error_unknownProfile" msgstr "不明なプロファイル: $PROFILE$" msgid "ruleList_error_missingResultProfile" msgstr "Missing result profile name at Line $LNO$: $SOURCE$" msgid "ruleList_error_invalidRule" msgstr "$SOURCE$の$LNO$:のルールは無効です" msgid "ruleList_error_noDefaultRule" msgstr "Missing default rule with catch-all '*' condition!" msgid "dialog_close" msgstr "閉じる" msgid "dialog_save" msgstr "変更を保存する" msgid "dialog_ok" msgstr "OK" msgid "dialog_cancel" msgstr "キャンセル" msgid "inputClear_clear" msgstr "クリア" msgid "inputClear_restore" msgstr "復元" msgid "options_title" msgstr "SwitchyOmega オプション" msgid "options_experimental_badge" msgstr "α" msgid "options_navHeader_setting" msgstr "設定" msgid "options_navHeader_profiles" msgstr "プロファイル" msgid "options_navHeader_actions" msgstr "Actions" msgid "options_tab_ui" msgstr "インターフェイス" msgid "options_tab_general" msgstr "総合" msgid "options_tab_importExport" msgstr "インポート/エクスポート" msgid "options_newProfile" msgstr "新しくプロファイルを作る…" msgid "options_apply" msgstr "変更を適用" msgid "options_discard" msgstr "変更を破棄" msgid "options_reset" msgstr "設定をリセットする" msgid "options_group_miscOptions" msgstr "その他の設定" msgid "options_confirmDeletion" msgstr "条件を削除する際に確認する。" msgid "options_refreshOnProfileChange" msgstr "プロファイルの変更にともなって現在のタブを更新する。" msgid "options_showInspectMenu" msgstr "Allow inspecting proxy used for page elements via context menu." msgid "options_addConditionsToBottom" msgstr "Put new conditions added using the popup to the bottom of the list." msgid "options_group_keyboardShortcut" msgstr "キーボードショートカット" msgid "options_menuShortcutHelp" msgstr "ショートカットを押すと切替ポップアップメニューが開きます。(デフォルトではAlt+Shift+O)" msgid "options_menuShortcutMore" msgstr "ポップアップメニューの項目は、キーボードを使ってもアクセスすることができます。キーボードの「?」(または「/」) を押して詳細を表示します。" msgid "options_menuShortcutConfigure" msgstr "ショートカットの設定" msgid "options_group_switchOptions" msgstr "切替オプション" msgid "options_startupProfile" msgstr "起動時プロファイル" msgid "options_startupProfile_none" msgstr "(現在のプロファイル)" msgid "options_showConditionTypesAdvanced" msgstr "高度な条件の種類を表示する" msgid "options_showConditionTypesAdvancedHelp" msgstr "" "新しいタイプの高度で複雑なスイッチ条件のロックを解除します。ほとんどのシナリオでは、基本的な条件タイプで十分であるため、このオプションはお勧めしません。" msgid "options_quickSwitch" msgstr "クイック切替" msgid "options_cycledProfiles" msgstr "Cycled Profiles" msgid "options_cycledProfilesHelp" msgstr "" "When you click on the icon (or use the shortcut above), the following " "profiles will be applied in their order." msgid "options_cycledProfilesTooFew" msgstr "この機能を有効にするには最低でも二つのプロファイルを選択する必要があります。下のボックスからアイテムをドラッグすることができます。" msgid "options_notCycledProfiles" msgstr "Not Cycled Profiles" msgid "options_group_proxyChanges" msgstr "Proxy Changes" msgid "options_revertProxyChanges" msgstr "Revert proxy changes done by other apps." msgid "options_group_conflicts" msgstr "競合" msgid "options_conflicts_introduction" msgstr "" "他のアプリもプロキシ設定を制御しようとするため、競合が発生することがあります。広告ブロッカーやその他の拡張機能も、プロキシ設定を水面下で使用している可能性" "があることに気をつけてください。このような競合は、ブラウザの仕組み上、避けることができません。" msgid "options_conflicts_lowerPriority" msgstr "" "SwitchyOmegaのアイコンにこのような赤いバッジが表示されるのは、他のアプリの方が優先度が高く、SwitchyOmegaが設定をコントロールできな" "いことを示しています。SwitchyOmegaを一度アンインストールして再インストールすると、SwitchyOmegaの優先順位が上がるはずなので、試して" "みてください。再インストール後も競合が発生する場合は、競合の原因となっている他のアプリを削除することを検討してください。" msgid "options_conflicts_higherPriority" msgstr "" "If SwitchyOmega has higher priority, you can give the control back to other " "apps or system settings by selecting $SYSTEMPROFILE$ in the popup menu." msgid "options_showExternalProfile" msgstr "Show popup menu item to import proxy settings from other apps." msgid "options_showExternalProfileHelp" msgstr "" "When $SYSTEMPROFILE$ is selected, you can import the effective proxy settings " "from other apps by selecting $EXTERNALPROFILE$ on the popup menu. " "The settings will be imported as a profile using the name you provide. " "Please note that the imported profile is a snapshot and will not reflect " "any changes from the source app thereafter." msgid "options_group_networkRequests" msgstr "Network Requests" msgid "options_monitorWebRequests" msgstr "Show count of failed web requests for resources in the current tab." msgid "options_monitorWebRequestsHelp" msgstr "" "A yellow badge will be displayed on the icon if some resources fail to load," "
and you can set the profile for such resources conveniently via the " "popup menu." msgid "options_downloadOptions" msgstr "Download Options" msgid "options_downloadOptionsHelp" msgstr "Configure the update frequency of online rule lists and PAC scripts." msgid "options_downloadInterval" msgstr "更新間隔" msgid "options_downloadInterval_15" msgstr "15 Minutes" msgid "options_downloadInterval_60" msgstr "1時間" msgid "options_downloadInterval_180" msgstr "3時間" msgid "options_downloadInterval_360" msgstr "6時間" msgid "options_downloadInterval_720" msgstr "12時間" msgid "options_downloadInterval_1440" msgstr "每日" msgid "options_downloadInterval_never" msgstr "Never" msgid "options_group_importExportProfile" msgstr "Profile" msgid "options_exportPacFile" msgstr "Export as PAC File" msgid "options_exportPacFileHelp" msgstr "" "Export the current profile as a PAC file, so you can use it in other " "browsers." msgid "options_exportProfileHelp" msgstr "To export a profile, use the top-right action bar on the profile page." msgid "options_exportLegacyRuleList" msgstr "" "Export rule lists using Proxy Switchy!/SwitchyPlus/SwitchySharp compatible " "format when possible." msgid "options_exportLegacyRuleListHelp" msgstr "" "Enable this option only if you publish rule lists for users of those " "projects.
Please consider advising your audience to upgrade to " "SwitchyOmega for the improvements." msgid "options_group_importExportSettings" msgstr "設定" msgid "options_makeBackup" msgstr "Make backup" msgid "options_makeBackupHelp" msgstr "" "Make a full backup of your options (including profiles and all other " "options)." msgid "options_restoreLocal" msgstr "Restore from file" msgid "options_restoreLocalHelp" msgstr "Restore your SwitchyOmega options from a local file." msgid "options_restoreOnline" msgstr "Restore from online" msgid "options_restoreOnlinePlaceholder" msgstr "Options file URL (e.g. 'http://example.com/switchy.bak')" msgid "options_restoreOnlineSubmit" msgstr "Restore" msgid "options_group_syncing" msgstr "Syncing (Experimental)" msgid "options_syncEnable" msgstr "Enable Syncing" msgid "options_syncEnableForce" msgstr "Download from Syncing" msgid "options_syncDisable" msgstr "Disable syncing" msgid "options_syncReset" msgstr "Clear remote copy" msgid "options_syncPristineHelp" msgstr "" "You can now automatically synchronize your settings and profiles across all " "your desktop devices running Chrome browser." msgid "options_syncSyncAlert" msgstr "Your options are automatically synchronized with your other devices." msgid "options_syncSyncHelp" msgstr "" "Please note that you must sign in to Chrome on each of your devices " "(including this one) for the syncing to actually work.
You may check " "this section on other devices to ensure that it is working." msgid "options_syncConflictAlert" msgstr "" "You have uploaded a copy of your options on another device via syncing." msgid "options_syncConflictHelp" msgstr "" "You may download the remote copy to your device if you like.
However, " "doing so would overwrite your existing settings and profiles on this " "device." msgid "options_syncUnsupportedHelp" msgstr "" "Options syncing is not supported on your platform or browser. For now, only " "Chrome browser on desktop is supported." msgid "options_profileSyncDisabled" msgstr "Syncing is disabled for this profile." msgid "options_profileSyncDisabled_quotaPerItem" msgstr "Syncing is disabled for this profile for using too much storage space." msgid "options_profileTabPrefix" msgstr "Profile :: " msgid "options_renameProfile" msgstr "Rename" msgid "options_deleteProfile" msgstr "Delete" msgid "options_profileExportRuleList" msgstr "Publish rule list" msgid "options_profileExportRuleListHelp" msgstr "Export Switch Rules as text format for publishing." msgid "options_profileExportPac" msgstr "Export PAC" msgid "options_profileUnsupported" msgstr "Unsupported profile type $TYPE$!" msgid "options_profileUnsupportedHelp" msgstr "The options could be broken, or from a newer version of this program." msgid "options_profileEditSource" msgstr "Edit source code" msgid "options_profileEditSourceHelp" msgstr "Show help about the source code format" msgid "options_profileEditSourceHelpUrl" msgstr "" "https://github.com/FelisCatus/SwitchyOmega/wiki/SwitchyOmega-conditions-" "format#result-profile" msgid "options_group_proxyServers" msgstr "Proxy servers" msgid "options_proxy_scheme" msgstr "Scheme" msgid "options_proxy_protocol" msgstr "Protocol" msgid "options_proxy_server" msgstr "Server" msgid "options_proxy_port" msgstr "Port" msgid "options_proxy_auth" msgstr "Authentication" msgid "options_proxy_authNotSupported" msgstr "Your browser DOES NOT support $PROTOCOLDISP$ proxy authentication! " "Please do not report this issue to SwitchyOmega. Contact the support for " "your browser instead." msgid "options_proxy_authAllWarningPac" msgstr "" "Warning: The username/password may be sent to unexpected servers returned by " "the PAC script." msgid "options_proxy_authAllWarningPacUrl" msgstr "" "Please make sure that you trust the script provided via the URL above before " "entering sensitive credentials." msgid "options_proxy_authAllWarningPacScript" msgstr "" "Please make sure that you trust the script below before providing sensitive " "credentials." msgid "options_proxy_authReferencedWarning" msgstr "" "Additionally, using this profile in other profiles (e.g. Switch Profile) may " "cause the username/password to be sent to proxy servers configured in other " "profiles." msgid "options_scheme_default" msgstr "(default)" msgid "options_protocol_direct" msgstr "DIRECT" msgid "options_protocol_useDefault" msgstr "(use default)" msgid "options_proxy_single" msgstr "Use the proxy above for all protocols." msgid "options_proxy_expand" msgstr "Show Advanced" msgid "options_group_bypassList" msgstr "Bypass List" msgid "options_bypassListHelp" msgstr "" "Servers for which you do not want to use any proxy: (One server on each " "line.)" msgid "options_bypassListHelpLinkText" msgstr "(Wildcards and more available…)" msgid "options_group_pacUrl" msgstr "PAC URL" msgid "options_pacUrlHelp" msgstr "" "The PAC script will be updated from this URL. If it is left blank, the " "following script will be used directly instead." msgid "options_pacUrlFile" msgstr "" "PAC profiles with file: URLs can only be applied directly. They cannot be " "used as result profiles because local files cannot be accessed due to " "browser limitation." msgid "options_pacUrlFileDisabled" msgstr "" "Therefore, you cannot use local PAC file for this profile. You can create a " "new PAC profile for that if you really want that." msgid "options_group_pacScript" msgstr "PAC Script" msgid "options_pacScriptLastUpdate" msgstr "PAC script downloaded at $TIME$:" msgid "options_pacScriptObsolete" msgstr "" "PAC script is obsolete due to URL change. Press the download button above to " "update." msgid "options_group_virtualProfile" msgstr "Virtual Profile" msgid "options_virtualProfileTarget" msgstr "Target" msgid "options_virtualProfileTargetHelp" msgstr "" "When this profile is applied, it acts exactly the same as the profile " "selected below." msgid "options_group_virtualProfileReplace" msgstr "Migrate to Virtual Profile" msgid "options_virtualProfileReplace" msgstr "Replace target profile" msgid "options_virtualProfileReplaceHelp" msgstr "" "You can migrate existing options to use this virtual profile instead of " "$PROFILE$. Doing so will update all existing rules concerning $PROFILE$ and " "point them to this virtual profile, so that their result profile can be " "controlled here." msgid "options_group_ruleListConfig" msgstr "Rule List Config" msgid "options_ruleListFormat" msgstr "Rule List Format" msgid "options_group_ruleListResult" msgstr "Rule list result profiles" msgid "options_ruleListMatchProfile" msgstr "Match profile" msgid "options_ruleListDefaultProfile" msgstr "Default profile" msgid "options_group_ruleListUrl" msgstr "Rule List URL" msgid "options_ruleListUrlHelp" msgstr "" "The rule list will be updated from this URL. If it is left blank, the " "following text will be parsed instead." msgid "options_group_ruleListText" msgstr "Rule List Text" msgid "options_ruleListLastUpdate" msgstr "Rule list downloaded at $TIME$:" msgid "options_ruleListObsolete" msgstr "" "Rule list is obsolete due to URL change. Press the download button above to " "update." msgid "options_group_switchRules" msgstr "Switch rules" msgid "options_sort" msgstr "Sort" msgid "options_conditionType" msgstr "Condition Type" msgid "options_showConditionTypeHelp" msgstr "Show help" msgid "options_conditionDetails" msgstr "Condition Details" msgid "options_resultProfile" msgstr "Profile" msgid "options_conditionActions" msgstr "Actions" msgid "options_addCondition" msgstr "Add condition" msgid "options_cloneRule" msgstr "Clone" msgid "options_ruleNote" msgstr "Note" msgid "options_switchAttachedProfileInCondition" msgstr "Rule list rules" msgid "options_switchAttachedProfileInConditionDetails" msgstr "(Any request matching the rule list below)" msgid "options_switchAttachedProfileInConditionDisabled" msgstr "(Rule list rules are DISABLED)" msgid "options_switchDefaultProfile" msgstr "Default" msgid "options_hostLevelsBetween" msgstr "≤ host levels ≤" msgid "options_hourBetween" msgstr "≤ current hour ≤" msgid "options_weekDayShort_0" msgstr "Su" msgid "options_weekDayShort_1" msgstr "Mo" msgid "options_weekDayShort_2" msgstr "Tu" msgid "options_weekDayShort_3" msgstr "We" msgid "options_weekDayShort_4" msgstr "Th" msgid "options_weekDayShort_5" msgstr "Fr" msgid "options_weekDayShort_6" msgstr "Sa" msgid "options_group_conditionHelp" msgstr "About Condition Types" msgid "options_group_attachProfile" msgstr "Import online rule lists" msgid "options_attachProfile" msgstr "Add a rule list" msgid "options_attachProfileHelp" msgstr "" "You can reuse an online collection of conditions published by others by " "adding a rule list." msgid "options_modalHeader_welcome" msgstr "Welcome to SwitchyOmega" msgid "options_welcomeNormal" msgstr "" "You have successfully installed SwitchyOmega, the ultimate proxy switcher." msgid "options_welcomeNormalGuide" msgstr "" "Please tell SwitchyOmega about your proxies through the options page. Let's " "see how." msgid "options_welcomeUpgrade" msgstr "" "You have successfully upgraded to SwitchyOmega. Don't panic, your existing " "options are fully preserved." msgid "options_welcomeUpgradeGuide" msgstr "Now let's go through a quick guide of the new options page." msgid "options_guideNext" msgstr "Next" msgid "options_guideDone" msgstr "Done" msgid "options_guideSkip" msgstr "チュートリアルをスキップ" msgid "options_modalHeader_applyOptions" msgstr "変更を適応" msgid "options_optionsNotSaved" msgstr "変更点は保存されていないため、このまま続行すると変更は失われます。" msgid "options_applyOptionsRequired" msgstr "Your changes to the options must be applied before you proceed." msgid "options_applyOptionsConfirm" msgstr "Do you want to save and apply the options?" msgid "options_modalHeader_renameProfile" msgstr "Rename Profile" msgid "options_renameProfileName" msgstr "New profile name" msgid "options_profileNameConflict" msgstr "A profile with this name already exists." msgid "options_profileNameReserved" msgstr "Profile names beginning with double-underscore are reserved." msgid "options_profileNameHidden" msgstr "" "Profiles with names starting with underscore will be hidden on the popup " "menu. However, they can still be used in places like switch profile results." msgid "options_modalHeader_replaceProfile" msgstr "Replace Profile" msgid "options_replaceProfile" msgstr "Replace Profile" msgid "options_replaceProfileConfirm" msgstr "Do you really want to replace $FromProfile$ with $ToProfile$?" msgid "options_replaceProfileHelp" msgstr "" "If you proceed, all rules pointing to $FromProfile$ will be updated to use " "$ToProfile$ instead. Other options, such as startup profile and Quick Switch " "will also be modified as appropriate. However, the two profile themselves " "will NOT be changed or deleted." msgid "options_replaceProfileSuccess" msgstr "Options updated." msgid "options_modalHeader_deleteProfile" msgstr "Delete Profile" msgid "options_deleteProfileConfirm" msgstr "Do you really want to delete the following profile?" msgid "options_modalHeader_cannotDeleteProfile" msgstr "Unable to Delete Profile" msgid "options_profileReferredBy" msgstr "" "This profile cannot be deleted because it is referred by the following " "profiles:" msgid "options_modifyReferringProfiles" msgstr "" "You must modify these profiles and make them stop referring to this profile " "before you can delete it." msgid "options_profileNameEmpty" msgstr "The name of the profile must not be empty." msgid "popup_title" msgstr "SwitchyOmega Popup" msgid "options_modalHeader_proxyAuth" msgstr "Proxy Authentication" msgid "options_proxyAuthUsername" msgstr "Username" msgid "options_proxyAuthPassword" msgstr "Password" msgid "options_proxyAuthShowPassword" msgstr "Show password" msgid "options_proxyAuthHidePassword" msgstr "Hide password" msgid "options_proxyAuthNone" msgstr "No Authentication" msgid "options_modalHeader_deleteRule" msgstr "Delete Rule" msgid "options_deleteRuleConfirm" msgstr "Do you really want to delete the following rule?" msgid "options_deleteRule" msgstr "Delete" msgid "options_modalHeader_resetRules" msgstr "Reset rules" msgid "options_resetRulesConfirm" msgstr "" "Are you sure to set the result profile of ALL rules to the following profile?" msgid "options_resetRules" msgstr "Reset rules" msgid "options_resetRules_help" msgstr "Set profile for all rules" msgid "options_modalHeader_deleteAttached" msgstr "Remove Rule List" msgid "options_deleteAttachedConfirm" msgstr "Do you really want to remove the rule list from the current profile?" msgid "options_ruleListLineCount" msgstr "$COUNT$ line(s) of rules" msgid "options_deleteAttached" msgstr "Remove rule list" msgid "options_modalHeader_newProfile" msgstr "New Profile" msgid "options_newProfileName" msgstr "Profile name" msgid "options_profileType" msgstr "Please select the type of the profile:" msgid "options_profileTypeFixedProfile" msgstr "Proxy Profile" msgid "options_profileDescFixedProfile" msgstr "Tunneling traffic through proxy servers." msgid "options_profileTypePacProfile" msgstr "PAC Profile" msgid "options_profileDescPacProfile" msgstr "Choosing proxies using an online/local PAC script." msgid "options_profileDescMorePacProfile" msgstr "" "You will only need this if you have a PAC script or a URL to it. Don't try " "to create one unless you have knowledge about PAC." msgid "options_profileTypeSwitchProfile" msgstr "Switch Profile" msgid "options_profileDescSwitchProfile" msgstr "" "Applying different profiles automatically on various conditions such as " "domains or patterns.\n" " You can also import rules published online for easier switching. (Replaces " "AutoSwitch mode + Rule List.)" msgid "options_profileTypeRuleListProfile" msgstr "Rule List Profile" msgid "options_profileDescRuleListProfile" msgstr "Reusing an online collection of conditions published by others." msgid "options_profileTypeVirtualProfile" msgstr "Virtual Profile" msgid "options_profileDescVirtualProfile" msgstr "" "A virtual profile can act as any of the other profiles on demand. It works " "well with SwitchProfile, allowing you to change the result of multiple " "conditions by one click." msgid "options_createProfile" msgstr "Create" msgid "options_modalHeader_resetOptions" msgstr "Reset Options" msgid "options_resetOptionsConfirm" msgstr "" "Do you really want to reset the options? All profiles and settings will be " "LOST!" msgid "options_formInvalid" msgstr "Please correct the errors in this page." msgid "options_profileNotFound" msgstr "Profile $PROFILE$ does not exist! The options may be corrupted." msgid "options_resetSuccess" msgstr "Options reset." msgid "options_saveSuccess" msgstr "Options saved." msgid "options_importSuccess" msgstr "Options imported." msgid "options_importFormatError" msgstr "Invalid backup file!" msgid "options_importDownloadError" msgstr "Error downloading backup file!" msgid "options_profileDownloadSuccess" msgstr "Successfully updated profile." msgid "options_profileDownloadError" msgstr "Error downloading profile data!" msgid "options_profileDownloadError_NetworkError" msgstr "A network error occurred when updating." msgid "options_profileDownloadError_HttpError" msgstr "An HTTP error ($STATUS$) occurred when updating." msgid "options_profileDownloadError_HttpNotFoundError" msgstr "The Profile URL was not found on the server. Please double-check." msgid "options_profileDownloadError_HttpServerError" msgstr "The remote server responded with error ($STATUS$) when updating." msgid "options_profileDownloadError_ContentTypeRejectedError" msgstr "The downloaded data is invalid! " "You may open the Profile URL in your browser to inspect it." msgid "options_downloadProfileNow" msgstr "Download Profile Now" msgid "options_guide_fixedProfileStep" msgstr "" "A Proxy Profile contains settings like server ip & port for proxy." "
Profiles are the the basic configuration units in SwitchyOmega.
We " "have already created an example profile for you. Try opening it." msgid "options_guide_fixedServersStep" msgstr "" "You can fill in your proxy server and port here as you like.
SwitchyOmega " "does not come with any proxy servers.
Please consult your network " "provider or proxy software manual if you don't know what should be filled in " "here." msgid "options_guide_autoSwitchProfileStep" msgstr "" "You can tell SwitchyOmega to switch between proxies automatically through " "the mighty Switch Profile.
However, its features cannot be covered " "in this quick guide.
You can open this profile to unlock its power some " "time later." msgid "options_guide_addMoreProfilesStep" msgstr "" "Need more profiles? You can always add more Proxy, Switch and other " "profiles
for all your proxying needs.
Enjoy proxying!" msgid "options_guide_conditionStep" msgstr "" "SwitchyOmega can apply different profiles to requests based on " "conditions.
For example, the Host wildcard condition " "allows you to set the profile for all URLs in a domain." msgid "options_guide_conditionTypeStep" msgstr "" "You can use various condition types to match the host or full URL.
" "Click on the question mark to open the type reference." msgid "options_guide_conditionProfileStep" msgstr "" "SwitchyOmega applies the selected profile here to any request matching " "the condition.
The special \"[Direct]\" profile will cause " "the request to be sent without any proxy." msgid "options_guide_switchDefaultStep" msgstr "" "If no condition applies to some request, the \"Default\" profile will be " "used.
Conditions are always considered from top to bottom in " "order.
You can change their order by dragging the sort icon." msgid "options_guide_applySwitchProfileStep" msgstr "" "When you are done setting the switch profile, don't forget to switch to " "it in the popup menu.
The icon will show you the final result profile applied for the current tab.
Hovering on the icon " "will reveal a tooltip with details." msgid "popup_externalProfile" msgstr "(External Profile)" msgid "popup_externalProfileName" msgstr "profile name" msgid "popup_proxyNotControllable_app" msgstr "" "The proxy settings are controlled by other app(s) or extension(s). Please " "disable or uninstall the apps or extensions in conflict." msgid "popup_proxyNotControllable_policy" msgstr "" "The proxy settings are overruled by policies. Please contact your " "administrator." msgid "popup_proxyNotControllable_unknown" msgstr "" "The proxy settings cannot be controlled. Please check your system and " "browser settings." msgid "popup_proxyNotControllable_disabled" msgstr "" "The proxy settings are disabled by explicit request from other app(s) or " "extension(s)." msgid "popup_proxyNotControllable_upgrade" msgstr "Proxy settings are now controlled by a newer version of SwitchyOmega." msgid "popup_proxyNotControllableDetails" msgstr "" "You cannot switch profiles with SwitchyOmega unless you fix the problem " "above." msgid "popup_proxyNotControllableDetails_upgrade" msgstr "" "You can't enable two (or more) versions of SwitchyOmega at the same time. " "Please disable one of them." msgid "popup_proxyNotControllableManage" msgstr "Manage extensions" msgid "popup_addConditionTo" msgstr "Add condition to" msgid "popup_addCondition" msgstr "Add condition" msgid "popup_showOptions" msgstr "Options" msgid "popup_reportIssues" msgstr "Report issues" msgid "popup_errorLog" msgstr "Save error log" msgid "popup_requestErrorCount" msgstr "$COUNT$ failed resources" msgid "popup_requestErrorHeading" msgstr "Resources that failed to load" msgid "popup_requestErrorWarning" msgstr "A few resources failed to load due to issues with your network, proxy server or the webpage." msgid "popup_requestErrorWarningHelp" msgstr "SwitchyOmega is just the reporter of these issues, not the cause of them." msgid "popup_requestErrorAddCondition" msgstr "You can review the following domains and use proxy for them when appropriate." msgid "popup_requestErrorCannotAddCondition" msgstr "You can add switch conditions for them only when using a Switch Profile." msgid "popup_configureMonitorWebRequests" msgstr "Configure Network Monitor" msgid "options_resultProfileForSelectedDomains" msgstr "Use this profile for all selected domains" msgid "options_pac_profile_unsupported_moz" msgstr "PAC Profiles WILL NOT work in Mozilla Firefox due to technical limitations!" msgid "popup_issueTemplate" msgstr "" "\n" "\n" "\n" "\n" "SwitchyOmega $projectVersion$\n" "$userAgent$" msgid "browserAction_profileDetails_PacProfile" msgstr "(PAC script)" msgid "browserAction_profileDetails_SystemProfile" msgstr "(controlled by other extensions or environment)" msgid "browserAction_profileDetails_DirectProfile" msgstr "(not using any proxy)" msgid "browserAction_profileDetails_SwitchProfile" msgstr "(switching based on conditions)" msgid "browserAction_profileDetails_RuleListProfile" msgstr "(switching based on rule list)" msgid "browserAction_titleNormal" msgstr "SwitchyOmega:: $PROFILE$" msgid "browserAction_titleWithResult" msgstr "" "SwitchyOmega:: $1:PROFILE$\n" "$3:DETAILS$" msgid "browserAction_titleNewerOptions" msgstr "" "ERROR: A newer version of SwitchOmega is required to load the stored options." msgid "browserAction_titleOptionError" msgstr "ERROR: The stored options are corrupted. Click here to RESET OPTIONS." msgid "browserAction_titleDownloadFail" msgstr "Warning: Failed to download PAC scripts and/or rule lists." msgid "browserAction_titleExternalProxy" msgstr "Note: The proxy settings are currently controlled by other app(s)." msgid "browserAction_titleInspect" msgstr "[Inspect] $URL$" msgid "browserAction_defaultRuleDetails" msgstr "(default)" msgid "browserAction_directResult" msgstr "DIRECT" msgid "browserAction_attachedPrefix" msgstr "(RL) " msgid "browserAction_tempRulePrefix" msgstr "(TEMP) " msgid "contextMenu_inspectPage" msgstr "Inspect proxy used for this page" msgid "contextMenu_inspectFrame" msgstr "Inspect proxy used for this Frame" msgid "contextMenu_inspectLink" msgstr "Inspect proxy to be used if this Link is opened" msgid "contextMenu_inspectElement" msgstr "Inspect proxy used for this Element" msgid "contextMenu_enableQuickSwitch" msgstr "Enable Quick Switch" msgid "about_title" msgstr "About" msgid "about_app_description" msgstr "A proxy configuration tool" msgid "about_version" msgstr "Version $VERSION$" msgid "about_experimental_warning_moz" msgstr "Mozilla Firefox support is highly experimental! If you encounter issues, please report using the buttons below." msgid "about_disclaimer_networkService" msgstr "SwitchyOmega does not provide proxies, VPNs, or other network services." msgid "about_disclaimer_privacy" msgstr "SwitchyOmega does not track you or insert ads into webpages. Please see" " our privacy policy." msgid "about_help" msgstr "Other questions? Need help with using SwitchyOmega? Please see our " "FAQ." msgid "about_copyright" msgstr "Copyright 2012-2017 The SwitchyOmega Authors. All rights reserved." msgid "about_credits" msgstr "SwitchyOmega is made possible by the SwitchyOmega open source project and other open source software." msgid "about_license" msgstr "SwitchyOmega is free software licensed under GNU General Public License Version 3 or later." ================================================ FILE: omega-locales/lzh/LC_MESSAGES/omega-web.po ================================================ msgid "" msgstr "" "Project-Id-Version: SwitchyOmega 2.3.3\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2015-02-13 10:29+0000\n" "PO-Revision-Date: 2024-07-15 07:09+0000\n" "Last-Translator: Makerlife \n" "Language-Team: Chinese (Literary) \n" "Language: lzh\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Generator: Weblate 5.7-dev\n" msgid "appNameShort" msgstr "SwitchyOmega" msgid "manifest_app_name" msgstr "Proxy SwitchyOmega" msgid "manifest_app_description" msgstr "迅速易事地管理並切換多個代理。" msgid "manifest_icon_default_title" msgstr "載入中…" msgid "upgrade_profile_auto" msgstr "自動更迭" msgid "profile_direct" msgstr "[直指]" msgid "profile_system" msgstr "[系統代理]" msgid "condition_HostWildcardCondition" msgstr "主機萬象" msgid "condition_help_HostWildcardCondition" msgstr "" "依域名(主機名)匹配請求。
星號 * " "匹配零個或者多個字符。
問號 ? 匹配任意一字符。" "

請注意以 *. " "起首之規則有特別處理,能同時匹配子域名與自身。
例如: *.example.com 能匹配 www.example.com ,且亦能匹配 example." "com。
僅需匹配子域名,請以兩個星號起首,如 **." "example.com。" msgid "condition_HostRegexCondition" msgstr "域名綴形法" msgid "condition_help_HostRegexCondition" msgstr "" "如主機萬象之規,但以綴形法匹配主機(域名)。
綴形法可能難於構建(及閱讀)。
建議" "於大多數情況下使用萬象,僅於其他條件無法實現時使用綴形法。" msgid "condition_HostLevelsCondition" msgstr "域名層數" msgid "condition_help_HostLevelsCondition" msgstr "" "若且惟若主機層次在所給範圍內,則匹配該請求.
主機層次被定義為主機(域名)之" "以點分隔的片段數.
例如:www.example.com " "的主機層次為3,而 internal 的層次為1." msgid "condition_IpCondition" msgstr "" msgid "condition_help_IpCondition" msgstr "" msgid "condition_UrlWildcardCondition" msgstr "" msgid "condition_help_UrlWildcardCondition" msgstr "" "依通配符規則以匹配網址。
關於通配符之表達式,詳見上文域名通配符一節之述。<" "br>須知網址通配符無特殊處理,不會特殊處理子域名等。
://.example." "com/* 可匹配 http://www.example.com/ 然 不匹配 http://example." "com/." msgid "condition_UrlRegexCondition" msgstr "網址之正則式" msgid "condition_help_UrlRegexCondition" msgstr "" "以功能強大之regular expression正則式匹配網址。
然正" "則表達式難書而可讀性差。
因此,故建議大多數情況下用通配符,僅於他法不可行" "時用正則式。" msgid "condition_KeywordCondition" msgstr "關鍵字" msgid "condition_help_KeywordCondition" msgstr "" msgid "condition_FalseCondition" msgstr "(禁用)" msgid "condition_details_FalseCondition" msgstr "" msgid "condition_help_FalseCondition" msgstr "" "設規則類型為(禁用)可暫禁某條件。禁用之條件匹配時視為無。
條件" "禁用後,先前數據(如通配符或正則)仍存,故需時可將條件類型改回先前,以重新啟" "用。" msgid "condition_TimeCondition" msgstr "當前時辰" msgid "condition_help_TimeCondition" msgstr "" "若當前本地時辰在某範圍內,則匹配。此範圍由始時終時確定,包含" "始時與終時。
本地時辰、始時與終時皆依24小時制計(自0至23)。" "
此條件約在請求發出瞬時,乃算是否匹配。" msgid "condition_WeekdayCondition" msgstr "" msgid "condition_help_WeekdayCondition" msgstr "" msgid "condition_alert_fullUrlLimitation" msgstr "" msgid "condition_alert_fullUrlLimitationLink" msgstr "" msgid "condition_group_default" msgstr "" msgid "condition_group_host" msgstr "" msgid "condition_group_url" msgstr "" msgid "condition_group_special" msgstr "" msgid "ruleListFormat_Switchy" msgstr "" msgid "ruleListFormat_AutoProxy" msgstr "" msgid "ruleList_usageUrl" msgstr "" msgid "ruleList_error_resultNotEnabled" msgstr "" msgid "ruleList_error_unknownProfile" msgstr "" msgid "ruleList_error_missingResultProfile" msgstr "" msgid "ruleList_error_invalidRule" msgstr "" msgid "ruleList_error_noDefaultRule" msgstr "" msgid "dialog_close" msgstr "" msgid "dialog_save" msgstr "" msgid "dialog_ok" msgstr "" msgid "dialog_cancel" msgstr "" msgid "inputClear_clear" msgstr "" msgid "inputClear_restore" msgstr "" msgid "options_title" msgstr "" msgid "options_experimental_badge" msgstr "" msgid "options_navHeader_setting" msgstr "" msgid "options_navHeader_profiles" msgstr "" msgid "options_navHeader_actions" msgstr "" msgid "options_tab_ui" msgstr "" msgid "options_tab_general" msgstr "" msgid "options_tab_importExport" msgstr "" msgid "options_newProfile" msgstr "" msgid "options_apply" msgstr "" msgid "options_discard" msgstr "" msgid "options_reset" msgstr "" msgid "options_group_miscOptions" msgstr "" msgid "options_confirmDeletion" msgstr "" msgid "options_refreshOnProfileChange" msgstr "" msgid "options_showInspectMenu" msgstr "" msgid "options_addConditionsToBottom" msgstr "" msgid "options_group_keyboardShortcut" msgstr "" msgid "options_menuShortcutHelp" msgstr "" msgid "options_menuShortcutMore" msgstr "" msgid "options_menuShortcutConfigure" msgstr "" msgid "options_group_switchOptions" msgstr "" msgid "options_startupProfile" msgstr "" msgid "options_startupProfile_none" msgstr "" msgid "options_showConditionTypesAdvanced" msgstr "" msgid "options_showConditionTypesAdvancedHelp" msgstr "" msgid "options_quickSwitch" msgstr "" msgid "options_cycledProfiles" msgstr "" msgid "options_cycledProfilesHelp" msgstr "" msgid "options_cycledProfilesTooFew" msgstr "" msgid "options_notCycledProfiles" msgstr "" msgid "options_group_proxyChanges" msgstr "" msgid "options_revertProxyChanges" msgstr "" msgid "options_group_conflicts" msgstr "" msgid "options_conflicts_introduction" msgstr "" msgid "options_conflicts_lowerPriority" msgstr "" msgid "options_conflicts_higherPriority" msgstr "" msgid "options_showExternalProfile" msgstr "" msgid "options_showExternalProfileHelp" msgstr "" msgid "options_group_networkRequests" msgstr "" msgid "options_monitorWebRequests" msgstr "" msgid "options_monitorWebRequestsHelp" msgstr "" msgid "options_downloadOptions" msgstr "" msgid "options_downloadOptionsHelp" msgstr "" msgid "options_downloadInterval" msgstr "" msgid "options_downloadInterval_15" msgstr "" msgid "options_downloadInterval_60" msgstr "" msgid "options_downloadInterval_180" msgstr "" msgid "options_downloadInterval_360" msgstr "" msgid "options_downloadInterval_720" msgstr "" msgid "options_downloadInterval_1440" msgstr "" msgid "options_downloadInterval_never" msgstr "" msgid "options_group_importExportProfile" msgstr "" msgid "options_exportPacFile" msgstr "" msgid "options_exportPacFileHelp" msgstr "" msgid "options_exportProfileHelp" msgstr "" msgid "options_exportLegacyRuleList" msgstr "" msgid "options_exportLegacyRuleListHelp" msgstr "" msgid "options_group_importExportSettings" msgstr "" msgid "options_makeBackup" msgstr "" msgid "options_makeBackupHelp" msgstr "" msgid "options_restoreLocal" msgstr "" msgid "options_restoreLocalHelp" msgstr "" msgid "options_restoreOnline" msgstr "" msgid "options_restoreOnlinePlaceholder" msgstr "" msgid "options_restoreOnlineSubmit" msgstr "" msgid "options_group_syncing" msgstr "" msgid "options_syncEnable" msgstr "" msgid "options_syncEnableForce" msgstr "" msgid "options_syncDisable" msgstr "" msgid "options_syncReset" msgstr "" msgid "options_syncPristineHelp" msgstr "" msgid "options_syncSyncAlert" msgstr "" msgid "options_syncSyncHelp" msgstr "" msgid "options_syncConflictAlert" msgstr "" msgid "options_syncConflictHelp" msgstr "" msgid "options_syncUnsupportedHelp" msgstr "" msgid "options_profileSyncDisabled" msgstr "" msgid "options_profileSyncDisabled_quotaPerItem" msgstr "" msgid "options_profileTabPrefix" msgstr "" msgid "options_renameProfile" msgstr "" msgid "options_deleteProfile" msgstr "" msgid "options_profileExportRuleList" msgstr "" msgid "options_profileExportRuleListHelp" msgstr "" msgid "options_profileExportPac" msgstr "" msgid "options_profileUnsupported" msgstr "" msgid "options_profileUnsupportedHelp" msgstr "" msgid "options_profileEditSource" msgstr "" msgid "options_profileEditSourceHelp" msgstr "" msgid "options_profileEditSourceHelpUrl" msgstr "" msgid "options_group_proxyServers" msgstr "" msgid "options_proxy_scheme" msgstr "" msgid "options_proxy_protocol" msgstr "" msgid "options_proxy_server" msgstr "" msgid "options_proxy_port" msgstr "" msgid "options_proxy_auth" msgstr "" msgid "options_proxy_authNotSupported" msgstr "" msgid "options_proxy_authAllWarningPac" msgstr "" msgid "options_proxy_authAllWarningPacUrl" msgstr "" msgid "options_proxy_authAllWarningPacScript" msgstr "" msgid "options_proxy_authReferencedWarning" msgstr "" msgid "options_scheme_default" msgstr "" msgid "options_protocol_direct" msgstr "" msgid "options_protocol_useDefault" msgstr "" msgid "options_proxy_single" msgstr "" msgid "options_proxy_expand" msgstr "" msgid "options_group_bypassList" msgstr "" msgid "options_bypassListHelp" msgstr "" msgid "options_bypassListHelpLinkText" msgstr "" msgid "options_group_pacUrl" msgstr "" msgid "options_pacUrlHelp" msgstr "" msgid "options_pacUrlFile" msgstr "" msgid "options_pacUrlFileDisabled" msgstr "" msgid "options_group_pacScript" msgstr "" msgid "options_pacScriptLastUpdate" msgstr "" msgid "options_pacScriptObsolete" msgstr "" msgid "options_group_virtualProfile" msgstr "" msgid "options_virtualProfileTarget" msgstr "" msgid "options_virtualProfileTargetHelp" msgstr "" msgid "options_group_virtualProfileReplace" msgstr "" msgid "options_virtualProfileReplace" msgstr "" msgid "options_virtualProfileReplaceHelp" msgstr "" msgid "options_group_ruleListConfig" msgstr "" msgid "options_ruleListFormat" msgstr "" msgid "options_group_ruleListResult" msgstr "" msgid "options_ruleListMatchProfile" msgstr "" msgid "options_ruleListDefaultProfile" msgstr "" msgid "options_group_ruleListUrl" msgstr "" msgid "options_ruleListUrlHelp" msgstr "" msgid "options_group_ruleListText" msgstr "" msgid "options_ruleListLastUpdate" msgstr "" msgid "options_ruleListObsolete" msgstr "" msgid "options_group_switchRules" msgstr "" msgid "options_sort" msgstr "" msgid "options_conditionType" msgstr "" msgid "options_showConditionTypeHelp" msgstr "" msgid "options_conditionDetails" msgstr "" msgid "options_resultProfile" msgstr "" msgid "options_conditionActions" msgstr "" msgid "options_addCondition" msgstr "" msgid "options_cloneRule" msgstr "" msgid "options_ruleNote" msgstr "" msgid "options_switchAttachedProfileInCondition" msgstr "" msgid "options_switchAttachedProfileInConditionDetails" msgstr "" msgid "options_switchAttachedProfileInConditionDisabled" msgstr "" msgid "options_switchDefaultProfile" msgstr "" msgid "options_hostLevelsBetween" msgstr "" msgid "options_hourBetween" msgstr "" msgid "options_weekDayShort_0" msgstr "" msgid "options_weekDayShort_1" msgstr "" msgid "options_weekDayShort_2" msgstr "" msgid "options_weekDayShort_3" msgstr "" msgid "options_weekDayShort_4" msgstr "" msgid "options_weekDayShort_5" msgstr "" msgid "options_weekDayShort_6" msgstr "" msgid "options_group_conditionHelp" msgstr "" msgid "options_group_attachProfile" msgstr "" msgid "options_attachProfile" msgstr "" msgid "options_attachProfileHelp" msgstr "" msgid "options_modalHeader_welcome" msgstr "" msgid "options_welcomeNormal" msgstr "" msgid "options_welcomeNormalGuide" msgstr "" msgid "options_welcomeUpgrade" msgstr "" msgid "options_welcomeUpgradeGuide" msgstr "" msgid "options_guideNext" msgstr "" msgid "options_guideDone" msgstr "" msgid "options_guideSkip" msgstr "" msgid "options_modalHeader_applyOptions" msgstr "" msgid "options_optionsNotSaved" msgstr "" msgid "options_applyOptionsRequired" msgstr "" msgid "options_applyOptionsConfirm" msgstr "" msgid "options_modalHeader_renameProfile" msgstr "" msgid "options_renameProfileName" msgstr "" msgid "options_profileNameConflict" msgstr "" msgid "options_profileNameReserved" msgstr "" msgid "options_profileNameHidden" msgstr "" msgid "options_modalHeader_replaceProfile" msgstr "" msgid "options_replaceProfile" msgstr "" msgid "options_replaceProfileConfirm" msgstr "" msgid "options_replaceProfileHelp" msgstr "" msgid "options_replaceProfileSuccess" msgstr "" msgid "options_modalHeader_deleteProfile" msgstr "" msgid "options_deleteProfileConfirm" msgstr "" msgid "options_modalHeader_cannotDeleteProfile" msgstr "" msgid "options_profileReferredBy" msgstr "" msgid "options_modifyReferringProfiles" msgstr "" msgid "options_profileNameEmpty" msgstr "" msgid "popup_title" msgstr "" msgid "options_modalHeader_proxyAuth" msgstr "" msgid "options_proxyAuthUsername" msgstr "" msgid "options_proxyAuthPassword" msgstr "" msgid "options_proxyAuthShowPassword" msgstr "" msgid "options_proxyAuthHidePassword" msgstr "" msgid "options_proxyAuthNone" msgstr "" msgid "options_modalHeader_deleteRule" msgstr "" msgid "options_deleteRuleConfirm" msgstr "" msgid "options_deleteRule" msgstr "" msgid "options_modalHeader_resetRules" msgstr "" msgid "options_resetRulesConfirm" msgstr "" msgid "options_resetRules" msgstr "" msgid "options_resetRules_help" msgstr "" msgid "options_modalHeader_deleteAttached" msgstr "" msgid "options_deleteAttachedConfirm" msgstr "" msgid "options_ruleListLineCount" msgstr "" msgid "options_deleteAttached" msgstr "" msgid "options_modalHeader_newProfile" msgstr "" msgid "options_newProfileName" msgstr "" msgid "options_profileType" msgstr "" msgid "options_profileTypeFixedProfile" msgstr "" msgid "options_profileDescFixedProfile" msgstr "" msgid "options_profileTypePacProfile" msgstr "" msgid "options_profileDescPacProfile" msgstr "" msgid "options_profileDescMorePacProfile" msgstr "" msgid "options_profileTypeSwitchProfile" msgstr "" msgid "options_profileDescSwitchProfile" msgstr "" msgid "options_profileTypeRuleListProfile" msgstr "" msgid "options_profileDescRuleListProfile" msgstr "" msgid "options_profileTypeVirtualProfile" msgstr "" msgid "options_profileDescVirtualProfile" msgstr "" msgid "options_createProfile" msgstr "" msgid "options_modalHeader_resetOptions" msgstr "" msgid "options_resetOptionsConfirm" msgstr "" msgid "options_formInvalid" msgstr "" msgid "options_profileNotFound" msgstr "" msgid "options_resetSuccess" msgstr "" msgid "options_saveSuccess" msgstr "" msgid "options_importSuccess" msgstr "" msgid "options_importFormatError" msgstr "" msgid "options_importDownloadError" msgstr "" msgid "options_profileDownloadSuccess" msgstr "" msgid "options_profileDownloadError" msgstr "" msgid "options_profileDownloadError_NetworkError" msgstr "" msgid "options_profileDownloadError_HttpError" msgstr "" msgid "options_profileDownloadError_HttpNotFoundError" msgstr "" msgid "options_profileDownloadError_HttpServerError" msgstr "" msgid "options_profileDownloadError_ContentTypeRejectedError" msgstr "" msgid "options_downloadProfileNow" msgstr "" msgid "options_guide_fixedProfileStep" msgstr "" msgid "options_guide_fixedServersStep" msgstr "" msgid "options_guide_autoSwitchProfileStep" msgstr "" msgid "options_guide_addMoreProfilesStep" msgstr "" msgid "options_guide_conditionStep" msgstr "" msgid "options_guide_conditionTypeStep" msgstr "" msgid "options_guide_conditionProfileStep" msgstr "" msgid "options_guide_switchDefaultStep" msgstr "" msgid "options_guide_applySwitchProfileStep" msgstr "" msgid "popup_externalProfile" msgstr "" msgid "popup_externalProfileName" msgstr "" msgid "popup_proxyNotControllable_app" msgstr "" msgid "popup_proxyNotControllable_policy" msgstr "" msgid "popup_proxyNotControllable_unknown" msgstr "" msgid "popup_proxyNotControllable_disabled" msgstr "" msgid "popup_proxyNotControllable_upgrade" msgstr "" msgid "popup_proxyNotControllableDetails" msgstr "" msgid "popup_proxyNotControllableDetails_upgrade" msgstr "" msgid "popup_proxyNotControllableManage" msgstr "" msgid "popup_addConditionTo" msgstr "" msgid "popup_addCondition" msgstr "" msgid "popup_showOptions" msgstr "" msgid "popup_reportIssues" msgstr "" msgid "popup_errorLog" msgstr "" msgid "popup_requestErrorCount" msgstr "" msgid "popup_requestErrorHeading" msgstr "" msgid "popup_requestErrorWarning" msgstr "" msgid "popup_requestErrorWarningHelp" msgstr "" msgid "popup_requestErrorAddCondition" msgstr "" msgid "popup_requestErrorCannotAddCondition" msgstr "" msgid "popup_configureMonitorWebRequests" msgstr "" msgid "options_resultProfileForSelectedDomains" msgstr "" msgid "options_pac_profile_unsupported_moz" msgstr "" msgid "popup_issueTemplate" msgstr "" msgid "browserAction_profileDetails_PacProfile" msgstr "" msgid "browserAction_profileDetails_SystemProfile" msgstr "" msgid "browserAction_profileDetails_DirectProfile" msgstr "" msgid "browserAction_profileDetails_SwitchProfile" msgstr "" msgid "browserAction_profileDetails_RuleListProfile" msgstr "" msgid "browserAction_titleNormal" msgstr "" msgid "browserAction_titleWithResult" msgstr "" msgid "browserAction_titleNewerOptions" msgstr "" msgid "browserAction_titleOptionError" msgstr "" msgid "browserAction_titleDownloadFail" msgstr "" msgid "browserAction_titleExternalProxy" msgstr "" msgid "browserAction_titleInspect" msgstr "" msgid "browserAction_defaultRuleDetails" msgstr "" msgid "browserAction_directResult" msgstr "" msgid "browserAction_attachedPrefix" msgstr "" msgid "browserAction_tempRulePrefix" msgstr "" msgid "contextMenu_inspectPage" msgstr "" msgid "contextMenu_inspectFrame" msgstr "" msgid "contextMenu_inspectLink" msgstr "" msgid "contextMenu_inspectElement" msgstr "" msgid "contextMenu_enableQuickSwitch" msgstr "" msgid "about_title" msgstr "" msgid "about_app_description" msgstr "" msgid "about_version" msgstr "" msgid "about_experimental_warning_moz" msgstr "" msgid "about_disclaimer_networkService" msgstr "" msgid "about_disclaimer_privacy" msgstr "" msgid "about_help" msgstr "" msgid "about_copyright" msgstr "" msgid "about_credits" msgstr "" msgid "about_license" msgstr "" ================================================ FILE: omega-locales/nb_NO/LC_MESSAGES/omega-web.po ================================================ msgid "" msgstr "" "Project-Id-Version: SwitchyOmega 2.3.3\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2015-02-13 10:29+0000\n" "PO-Revision-Date: 2019-05-14 08:49+0000\n" "Last-Translator: Allan Nordhøy \n" "Language-Team: Norwegian Bokmål \n" "Language: nb_NO\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Generator: Weblate 3.7-dev\n" msgid "appNameShort" msgstr "SwitchyOmega" #, fuzzy msgid "manifest_app_name" msgstr "Mellomtjeneren SwitchyOmega" msgid "manifest_app_description" msgstr "Behandle og bytt mellom flerfoldige mellomtjenere raskt og enkelt." msgid "manifest_icon_default_title" msgstr "Laster inn…" msgid "upgrade_profile_auto" msgstr "Automatisk bytte" msgid "profile_direct" msgstr "[Direkte]" msgid "profile_system" msgstr "[Systemmellomtjener]" msgid "condition_HostWildcardCondition" msgstr "Vertsjokertegn" msgid "condition_help_HostWildcardCondition" msgstr "" msgid "condition_HostRegexCondition" msgstr "Regulært uttrykk for vert" msgid "condition_help_HostRegexCondition" msgstr "" msgid "condition_HostLevelsCondition" msgstr "Vertsnivåer" msgid "condition_help_HostLevelsCondition" msgstr "" msgid "condition_IpCondition" msgstr "IP Literals" msgid "condition_help_IpCondition" msgstr "" "Matches the request if and only if the host is a literal IP address and" " in the subnet as specified by " "CIDR notation.
For example, given the rule 127.0.0.1/16, " "it matches all IP addresses like 127.0.*.*.
" "So 127.0.0.1 matches while 127.1.0.0 does not. " "Host names like localhost will never match because they are " "not IP literals." msgid "condition_UrlWildcardCondition" msgstr "Nettadressejokertegn" msgid "condition_help_UrlWildcardCondition" msgstr "" msgid "condition_UrlRegexCondition" msgstr "Regulært uttrykk for URL" #, fuzzy msgid "condition_help_UrlRegexCondition" msgstr "" "Samsvarer med URL-er i kraft av ekstremt mektige regulære " "uttrykk.
Dog kan regulære uttrykk være vanskelige å lage (og " "lese).
Det er anbefalt å bruke wildcards i de fleste fall og bare bruke " "regulære uttrykk for tilstander som ikke kan oppnås av noen annen " "tilstandstype." msgid "condition_KeywordCondition" msgstr "Nøkkelord" msgid "condition_help_KeywordCondition" msgstr "" msgid "condition_FalseCondition" msgstr "(Avskrudd)" msgid "condition_details_FalseCondition" msgstr "(Tilstand sett bort fra ved jamførelse)" msgid "condition_help_FalseCondition" msgstr "" msgid "condition_TimeCondition" msgstr "Gjeldende tid" msgid "condition_help_TimeCondition" msgstr "" msgid "condition_WeekdayCondition" msgstr "Ukedag" msgid "condition_help_WeekdayCondition" msgstr "" msgid "condition_alert_fullUrlLimitation" msgstr "" "Full URL matching is no longer possible for https:// " "URLs as of Chrome 52. " "" "Learn more..." msgid "condition_alert_fullUrlLimitationLink" msgstr "https://github.com/FelisCatus/SwitchyOmega/wiki/Chromium-Full-URL-Limitation" msgid "condition_group_default" msgstr " " msgid "condition_group_host" msgstr "Vert" msgid "condition_group_url" msgstr "URL" msgid "condition_group_special" msgstr "Spesiell" msgid "ruleListFormat_Switchy" msgstr "Byttende" msgid "ruleListFormat_AutoProxy" msgstr "AutoProxy" msgid "ruleList_usageUrl" msgstr "https://github.com/FelisCatus/SwitchyOmega/wiki/RuleListUsage" msgid "ruleList_error_resultNotEnabled" msgstr "" msgid "ruleList_error_unknownProfile" msgstr "Ukjent profil: $PROFILE$" msgid "ruleList_error_missingResultProfile" msgstr "" msgid "ruleList_error_invalidRule" msgstr "" msgid "ruleList_error_noDefaultRule" msgstr "" msgid "dialog_close" msgstr "Lukk" msgid "dialog_save" msgstr "Lagre endringer" msgid "dialog_ok" msgstr "OK" msgid "dialog_cancel" msgstr "Avbryt" msgid "inputClear_clear" msgstr "Tøm" msgid "inputClear_restore" msgstr "Gjenopprett" msgid "options_title" msgstr "SwitchyOmega-valg" msgid "options_experimental_badge" msgstr "α" msgid "options_navHeader_setting" msgstr "Innstillinger" msgid "options_navHeader_profiles" msgstr "Profiler" msgid "options_navHeader_actions" msgstr "Handlinger" msgid "options_tab_ui" msgstr "Grensesnitt" msgid "options_tab_general" msgstr "" msgid "options_tab_importExport" msgstr "Importer/Exporter" msgid "options_newProfile" msgstr "Ny profil…" msgid "options_apply" msgstr "Legg til endringer" msgid "options_discard" msgstr "Forkast endringer" msgid "options_reset" msgstr "Tilbakestill valg" msgid "options_group_miscOptions" msgstr "Ymse valg" msgid "options_confirmDeletion" msgstr "" msgid "options_refreshOnProfileChange" msgstr "Gjenoppfrisk gjeldende fane ved profilendring." msgid "options_showInspectMenu" msgstr "" msgid "options_addConditionsToBottom" msgstr "Put new conditions added using the popup to the bottom of the list." msgid "options_group_keyboardShortcut" msgstr "Tastatursnarvei" msgid "options_menuShortcutHelp" msgstr "" msgid "options_menuShortcutMore" msgstr "" msgid "options_menuShortcutConfigure" msgstr "Sett opp snarvei" msgid "options_group_switchOptions" msgstr "Bytt valg" msgid "options_startupProfile" msgstr "Oppstartsprofil" msgid "options_startupProfile_none" msgstr "(Gjeldende profil)" msgid "options_showConditionTypesAdvanced" msgstr "" msgid "options_showConditionTypesAdvancedHelp" msgstr "" msgid "options_quickSwitch" msgstr "" msgid "options_cycledProfiles" msgstr "" msgid "options_cycledProfilesHelp" msgstr "" msgid "options_cycledProfilesTooFew" msgstr "" msgid "options_notCycledProfiles" msgstr "" msgid "options_group_proxyChanges" msgstr "Mellomtjenerendringer" msgid "options_revertProxyChanges" msgstr "Tilbakestill mellomtjenerinnstillinger gjort av andre programmer." msgid "options_group_conflicts" msgstr "Conflicts" msgid "options_conflicts_introduction" msgstr "" "Sometimes, other apps will also try to control the proxy settings, resulting " "in conflicts. Note that ad blockers and other extensions may also use proxy " "settings under the hood. Such conflicts cannot be avoided due to how the " "browser works." msgid "options_conflicts_lowerPriority" msgstr "" "A red badge like this on the SwitchyOmega icon indicates that another app has " "higher priority so SwitchyOmega cannot control the settings. Please try to " "uninstall SwitchyOmega and reinstall, which should raise SwitchyOmega's " "priority. If you still see conflicts after reinstallation, please consider " "removing the other app causing the conflict." msgid "options_conflicts_higherPriority" msgstr "" "If SwitchyOmega has higher priority, you can give the control back to other " "apps or system settings by selecting $SYSTEMPROFILE$ in the popup menu." msgid "options_showExternalProfile" msgstr "Show popup menu item to import proxy settings from other apps." msgid "options_showExternalProfileHelp" msgstr "" "When $SYSTEMPROFILE$ is selected, you can import the effective proxy settings " "from other apps by selecting $EXTERNALPROFILE$ on the popup menu. " "The settings will be imported as a profile using the name you provide. " "Please note that the imported profile is a snapshot and will not reflect " "any changes from the source app thereafter." msgid "options_group_networkRequests" msgstr "Nettverksforespørsler" msgid "options_monitorWebRequests" msgstr "Vis antall feilede nettforespørsler for ressurser i gjeldende fane." msgid "options_monitorWebRequestsHelp" msgstr "" msgid "options_downloadOptions" msgstr "Nedlastingsvalg" msgid "options_downloadOptionsHelp" msgstr "Sett oppdateringsfrekvensen for nettbaserte regellister og PAC-skript." msgid "options_downloadInterval" msgstr "Nedlastingsintervall" msgid "options_downloadInterval_15" msgstr "15 minutter" msgid "options_downloadInterval_60" msgstr "en time" msgid "options_downloadInterval_180" msgstr "tre timer" msgid "options_downloadInterval_360" msgstr "seks timer" msgid "options_downloadInterval_720" msgstr "12 timer" msgid "options_downloadInterval_1440" msgstr "Hver dag" msgid "options_downloadInterval_never" msgstr "Aldri" msgid "options_group_importExportProfile" msgstr "Profil" msgid "options_exportPacFile" msgstr "Eksporter som PAC-fil" msgid "options_exportPacFileHelp" msgstr "" "Eksporter gjeldende profil som PAC-fil, slik at du kan bruke den i andre " "nettlesere." #, fuzzy msgid "options_exportProfileHelp" msgstr "" "For å eksportere en profil, bruk handlingsfeltet øverst til høyre på " "profilsiden." msgid "options_exportLegacyRuleList" msgstr "" msgid "options_exportLegacyRuleListHelp" msgstr "" msgid "options_group_importExportSettings" msgstr "Innstillinger" msgid "options_makeBackup" msgstr "Ta sikkerhetskopi" msgid "options_makeBackupHelp" msgstr "" "Ta full sikkerhetskopi av dine valg (inkludert profiler og alle andre valg)." msgid "options_restoreLocal" msgstr "Gjenopprett fra fil" msgid "options_restoreLocalHelp" msgstr "Gjennopprett dine SwitchyOmega-valg fra ei lokal fil." msgid "options_restoreOnline" msgstr "Gjenopprett fra nett" msgid "options_restoreOnlinePlaceholder" msgstr "URL til valg-fil (f.eks. 'http://eksempel.no/switchy.bak')" msgid "options_restoreOnlineSubmit" msgstr "Gjenopprett" msgid "options_group_syncing" msgstr "Synkroniserer (eksperimentelt)" msgid "options_syncEnable" msgstr "Skru på synkronisering" msgid "options_syncEnableForce" msgstr "" msgid "options_syncDisable" msgstr "Skru av synkronisering" msgid "options_syncReset" msgstr "" msgid "options_syncPristineHelp" msgstr "" msgid "options_syncSyncAlert" msgstr "" msgid "options_syncSyncHelp" msgstr "" msgid "options_syncConflictAlert" msgstr "" msgid "options_syncConflictHelp" msgstr "" msgid "options_syncUnsupportedHelp" msgstr "" msgid "options_profileSyncDisabled" msgstr "" msgid "options_profileSyncDisabled_quotaPerItem" msgstr "" msgid "options_profileTabPrefix" msgstr "" msgid "options_renameProfile" msgstr "Gi nytt navn" msgid "options_deleteProfile" msgstr "Slett" msgid "options_profileExportRuleList" msgstr "Offentliggjør regelliste" msgid "options_profileExportRuleListHelp" msgstr "" msgid "options_profileExportPac" msgstr "Eksporter PAC" msgid "options_profileUnsupported" msgstr "Ustøttet profiltype $TYPE$!" msgid "options_profileUnsupportedHelp" msgstr "Valg kan være skadelidende, eller fra en nyere versjon av programmet." msgid "options_profileEditSource" msgstr "Rediger kildekode" msgid "options_profileEditSourceHelp" msgstr "Vis hjelp om kildekodeformatet" msgid "options_profileEditSourceHelpUrl" msgstr "" "https://github.com/FelisCatus/SwitchyOmega/wiki/SwitchyOmega-conditions-" "format#result-profile" msgid "options_group_proxyServers" msgstr "Tjenere for mellomtjening" msgid "options_proxy_scheme" msgstr "" msgid "options_proxy_protocol" msgstr "Protokoll" msgid "options_proxy_server" msgstr "Tjener" msgid "options_proxy_port" msgstr "Port" msgid "options_proxy_auth" msgstr "Identitetsbekreftelse" msgid "options_proxy_authNotSupported" msgstr "Your browser DOES NOT support $PROTOCOLDISP$ proxy authentication! " "Please do not report this issue to SwitchyOmega. Contact the support for " "your browser instead." #, fuzzy msgid "options_proxy_authAllWarningPac" msgstr "" "Advarsel: Brukernavn/passord kan bli sendt til uventede tjenere fra PAC-" "skriptet." msgid "options_proxy_authAllWarningPacUrl" msgstr "" msgid "options_proxy_authAllWarningPacScript" msgstr "" msgid "options_proxy_authReferencedWarning" msgstr "" msgid "options_scheme_default" msgstr "(forvalg)" #, fuzzy msgid "options_protocol_direct" msgstr "DIREKTE" msgid "options_protocol_useDefault" msgstr "(bruk forvalg)" msgid "options_proxy_single" msgstr "Bruk mellomtjeneren ovenfor for alle protokoller." msgid "options_proxy_expand" msgstr "Vis avanserte valg" msgid "options_group_bypassList" msgstr "" msgid "options_bypassListHelp" msgstr "" msgid "options_bypassListHelpLinkText" msgstr "" msgid "options_group_pacUrl" msgstr "" msgid "options_pacUrlHelp" msgstr "" msgid "options_pacUrlFile" msgstr "" msgid "options_pacUrlFileDisabled" msgstr "" msgid "options_group_pacScript" msgstr "" msgid "options_pacScriptLastUpdate" msgstr "" msgid "options_pacScriptObsolete" msgstr "" msgid "options_group_virtualProfile" msgstr "" msgid "options_virtualProfileTarget" msgstr "Mål" msgid "options_virtualProfileTargetHelp" msgstr "" msgid "options_group_virtualProfileReplace" msgstr "" msgid "options_virtualProfileReplace" msgstr "" msgid "options_virtualProfileReplaceHelp" msgstr "" msgid "options_group_ruleListConfig" msgstr "" msgid "options_ruleListFormat" msgstr "" msgid "options_group_ruleListResult" msgstr "" msgid "options_ruleListMatchProfile" msgstr "" msgid "options_ruleListDefaultProfile" msgstr "" msgid "options_group_ruleListUrl" msgstr "" msgid "options_ruleListUrlHelp" msgstr "" msgid "options_group_ruleListText" msgstr "" msgid "options_ruleListLastUpdate" msgstr "" msgid "options_ruleListObsolete" msgstr "" msgid "options_group_switchRules" msgstr "" msgid "options_sort" msgstr "" msgid "options_conditionType" msgstr "" msgid "options_showConditionTypeHelp" msgstr "" msgid "options_conditionDetails" msgstr "" msgid "options_resultProfile" msgstr "" msgid "options_conditionActions" msgstr "Handlinger" msgid "options_addCondition" msgstr "" msgid "options_cloneRule" msgstr "" msgid "options_ruleNote" msgstr "Note" msgid "options_switchAttachedProfileInCondition" msgstr "" msgid "options_switchAttachedProfileInConditionDetails" msgstr "" msgid "options_switchAttachedProfileInConditionDisabled" msgstr "" msgid "options_switchDefaultProfile" msgstr "" msgid "options_hostLevelsBetween" msgstr "" msgid "options_hourBetween" msgstr "" msgid "options_weekDayShort_0" msgstr "Søn" msgid "options_weekDayShort_1" msgstr "Man" msgid "options_weekDayShort_2" msgstr "Tirs" msgid "options_weekDayShort_3" msgstr "Ons" msgid "options_weekDayShort_4" msgstr "Tors" msgid "options_weekDayShort_5" msgstr "Fre" msgid "options_weekDayShort_6" msgstr "Lør" msgid "options_group_conditionHelp" msgstr "" msgid "options_group_attachProfile" msgstr "" msgid "options_attachProfile" msgstr "Legg til en regelliste" msgid "options_attachProfileHelp" msgstr "" msgid "options_modalHeader_welcome" msgstr "Velkommen til SwitchyOmega" msgid "options_welcomeNormal" msgstr "" msgid "options_welcomeNormalGuide" msgstr "" msgid "options_welcomeUpgrade" msgstr "" msgid "options_welcomeUpgradeGuide" msgstr "" msgid "options_guideNext" msgstr "Neste" msgid "options_guideDone" msgstr "Ferdig" msgid "options_guideSkip" msgstr "Hopp over guide" msgid "options_modalHeader_applyOptions" msgstr "Legg til valg" msgid "options_optionsNotSaved" msgstr "" msgid "options_applyOptionsRequired" msgstr "" msgid "options_applyOptionsConfirm" msgstr "" msgid "options_modalHeader_renameProfile" msgstr "Gi profil nytt navn" msgid "options_renameProfileName" msgstr "Nytt profilnavn" msgid "options_profileNameConflict" msgstr "En profil ved dette navnet finnes allerede." msgid "options_profileNameReserved" msgstr "Profilnavn som begynner med dobbel understrek er reservert." msgid "options_profileNameHidden" msgstr "" msgid "options_modalHeader_replaceProfile" msgstr "Erstatt profil" msgid "options_replaceProfile" msgstr "Erstatt profil" msgid "options_replaceProfileConfirm" msgstr "Ønsker du virkelig å erstatte $FromProfile$ med $ToProfile$?" msgid "options_replaceProfileHelp" msgstr "" msgid "options_replaceProfileSuccess" msgstr "" msgid "options_modalHeader_deleteProfile" msgstr "Slett profil" msgid "options_deleteProfileConfirm" msgstr "Ønsker du virkelig å slette følgende profil?" msgid "options_modalHeader_cannotDeleteProfile" msgstr "Kunne ikke slette profil" msgid "options_profileReferredBy" msgstr "" "Denne profilen kunne ikke slettes fordi den vises til av følgende profiler:" msgid "options_modifyReferringProfiles" msgstr "" msgid "options_profileNameEmpty" msgstr "" msgid "popup_title" msgstr "Oppsprettsvindu for SwitchyOmega" msgid "options_modalHeader_proxyAuth" msgstr "Identitetsbekreftelse for mellomtjener" msgid "options_proxyAuthUsername" msgstr "Brukernavn" msgid "options_proxyAuthPassword" msgstr "Passord" msgid "options_proxyAuthShowPassword" msgstr "Show password" msgid "options_proxyAuthHidePassword" msgstr "Hide password" msgid "options_proxyAuthNone" msgstr "Ingen identitetsbekreftelse" msgid "options_modalHeader_deleteRule" msgstr "Slett regel" msgid "options_deleteRuleConfirm" msgstr "Ønsker du virkelig å slette følgende regel?" msgid "options_deleteRule" msgstr "Slett" msgid "options_modalHeader_resetRules" msgstr "Tilbakestill regler" msgid "options_resetRulesConfirm" msgstr "" msgid "options_resetRules" msgstr "Tilbakestill regler" msgid "options_resetRules_help" msgstr "Sett profil for alle regler" msgid "options_modalHeader_deleteAttached" msgstr "Fjern regelliste" msgid "options_deleteAttachedConfirm" msgstr "Ønsker du virkelig å slette regellisten fra gjeldende profil?" msgid "options_ruleListLineCount" msgstr "$COUNT$ linje(r) med regler" msgid "options_deleteAttached" msgstr "Slett regelliste" msgid "options_modalHeader_newProfile" msgstr "Ny profil" msgid "options_newProfileName" msgstr "Profilnavn" msgid "options_profileType" msgstr "" msgid "options_profileTypeFixedProfile" msgstr "Mellomtjenerprofil" msgid "options_profileDescFixedProfile" msgstr "" msgid "options_profileTypePacProfile" msgstr "PAC-profil" msgid "options_profileDescPacProfile" msgstr "" msgid "options_profileDescMorePacProfile" msgstr "" msgid "options_profileTypeSwitchProfile" msgstr "Bytt profil" msgid "options_profileDescSwitchProfile" msgstr "" msgid "options_profileTypeRuleListProfile" msgstr "" msgid "options_profileDescRuleListProfile" msgstr "" msgid "options_profileTypeVirtualProfile" msgstr "Virtuell profil" msgid "options_profileDescVirtualProfile" msgstr "" msgid "options_createProfile" msgstr "Opprett" msgid "options_modalHeader_resetOptions" msgstr "Tilbakestill valg" msgid "options_resetOptionsConfirm" msgstr "" "Lnsker du virkelig å tilbakestille valgene? Alle profiler og innstillinger " "vil gå TAPT!" msgid "options_formInvalid" msgstr "Korriger feilene på denne siden." msgid "options_profileNotFound" msgstr "Profilen $PROFILE$ finnes ikke! Valgene kan være skadet." msgid "options_resetSuccess" msgstr "Valg tilbakestilt." msgid "options_saveSuccess" msgstr "Valg lagret." msgid "options_importSuccess" msgstr "Valg importert." msgid "options_importFormatError" msgstr "Ugyldig sikkerhetskopifil!" msgid "options_importDownloadError" msgstr "" msgid "options_profileDownloadSuccess" msgstr "Vellykket oppdatering av profil." msgid "options_profileDownloadError" msgstr "Feil ved nedlasting av profildata!" msgid "options_profileDownloadError_NetworkError" msgstr "A network error occurred when updating." msgid "options_profileDownloadError_HttpError" msgstr "An HTTP error ($STATUS$) occurred when updating." msgid "options_profileDownloadError_HttpNotFoundError" msgstr "The Profile URL was not found on the server. Please double-check." msgid "options_profileDownloadError_HttpServerError" msgstr "The remote server responded with error ($STATUS$) when updating." msgid "options_profileDownloadError_ContentTypeRejectedError" msgstr "The downloaded data is invalid! " "You may open the Profile URL in your browser to inspect it." msgid "options_downloadProfileNow" msgstr "Last ned profil nå" msgid "options_guide_fixedProfileStep" msgstr "" msgid "options_guide_fixedServersStep" msgstr "" msgid "options_guide_autoSwitchProfileStep" msgstr "" msgid "options_guide_addMoreProfilesStep" msgstr "" msgid "options_guide_conditionStep" msgstr "" msgid "options_guide_conditionTypeStep" msgstr "" msgid "options_guide_conditionProfileStep" msgstr "" msgid "options_guide_switchDefaultStep" msgstr "" msgid "options_guide_applySwitchProfileStep" msgstr "" msgid "popup_externalProfile" msgstr "(Ekstern profil)" msgid "popup_externalProfileName" msgstr "profilnavn" msgid "popup_proxyNotControllable_app" msgstr "" msgid "popup_proxyNotControllable_policy" msgstr "" msgid "popup_proxyNotControllable_unknown" msgstr "" msgid "popup_proxyNotControllable_disabled" msgstr "" msgid "popup_proxyNotControllable_upgrade" msgstr "" msgid "popup_proxyNotControllableDetails" msgstr "" msgid "popup_proxyNotControllableDetails_upgrade" msgstr "" msgid "popup_proxyNotControllableManage" msgstr "Behandle tillegg" msgid "popup_addConditionTo" msgstr "" msgid "popup_addCondition" msgstr "" msgid "popup_showOptions" msgstr "Valg" msgid "popup_reportIssues" msgstr "Rapporter feil" msgid "popup_errorLog" msgstr "Lagre feilrettingslogg" msgid "popup_requestErrorCount" msgstr "$COUNT$ failede ressurser" msgid "popup_requestErrorHeading" msgstr "Ressurser som ikke kunne lastes inn" msgid "popup_requestErrorWarning" msgstr "" "En del ressurser kunne ikke lastes inn på grunn av feil med ditt nettverk, " "mellomtjeneren eller nettsiden." msgid "popup_requestErrorWarningHelp" msgstr "SwitchyOmega rapporterer bare disse feilene, det er ikke opphavet." msgid "popup_requestErrorAddCondition" msgstr "" "Du kan se over følgende domener og bruke mellomtjener for dem når det høver " "seg." msgid "popup_requestErrorCannotAddCondition" msgstr "" #, fuzzy msgid "popup_configureMonitorWebRequests" msgstr "Sett opp nettverksoversikt" msgid "options_resultProfileForSelectedDomains" msgstr "Bruk denne profilen for alle valgte domener" msgid "options_pac_profile_unsupported_moz" msgstr "PAC Profiles WILL NOT work in Mozilla Firefox due to technical limitations!" msgid "popup_issueTemplate" msgstr "" "\n" "\n" "\n" "\n" "SwitchyOmega $projectVersion$\n" "$userAgent$" msgid "browserAction_profileDetails_PacProfile" msgstr "(PAC-skript)" msgid "browserAction_profileDetails_SystemProfile" msgstr "(styrt av andre tillegg eller miljø)" msgid "browserAction_profileDetails_DirectProfile" msgstr "(bruker ikke noen mellomtjener)" msgid "browserAction_profileDetails_SwitchProfile" msgstr "" msgid "browserAction_profileDetails_RuleListProfile" msgstr "" msgid "browserAction_titleNormal" msgstr "SwitchyOmega:: $PROFILE$" msgid "browserAction_titleWithResult" msgstr "" "SwitchyOmega:: $1:PROFILE$\n" "$3:DETAILS$" msgid "browserAction_titleNewerOptions" msgstr "" "FEIL: En nyere versjon av SwitchOmega kreves for å laste de lagrede valgene." msgid "browserAction_titleOptionError" msgstr "FEIL: Lagrede valg skadet. Klikk her for å TILBAKESTILLE VALG." msgid "browserAction_titleDownloadFail" msgstr "Advarsel: Kunne ikke laste ned PAC-skript og/eller regellister." msgid "browserAction_titleExternalProxy" msgstr "" msgid "browserAction_titleInspect" msgstr "[Se over] $URL$" msgid "browserAction_defaultRuleDetails" msgstr "(forvalg)" #, fuzzy msgid "browserAction_directResult" msgstr "DIREKTE" msgid "browserAction_attachedPrefix" msgstr "" msgid "browserAction_tempRulePrefix" msgstr "(MIDLERTIDIG) " msgid "contextMenu_inspectPage" msgstr "Se over mellomtjenerbruk for denne siden" msgid "contextMenu_inspectFrame" msgstr "" msgid "contextMenu_inspectLink" msgstr "" msgid "contextMenu_inspectElement" msgstr "" msgid "contextMenu_enableQuickSwitch" msgstr "Skru på raskt bytte" msgid "about_title" msgstr "About" msgid "about_app_description" msgstr "A proxy configuration tool" msgid "about_version" msgstr "Version $VERSION$" msgid "about_experimental_warning_moz" msgstr "Mozilla Firefox support is highly experimental! If you encounter issues, please report using the buttons below." msgid "about_disclaimer_networkService" msgstr "SwitchyOmega does not provide proxies, VPNs, or other network services." msgid "about_disclaimer_privacy" msgstr "SwitchyOmega does not track you or insert ads into webpages. Please see" " our privacy policy." msgid "about_help" msgstr "Other questions? Need help with using SwitchyOmega? Please see our " "FAQ." msgid "about_copyright" msgstr "Copyright 2012-2017 The SwitchyOmega Authors. All rights reserved." msgid "about_credits" msgstr "SwitchyOmega is made possible by the SwitchyOmega open source project and other open source software." msgid "about_license" msgstr "SwitchyOmega is free software licensed under GNU General Public License Version 3 or later." ================================================ FILE: omega-locales/nl/LC_MESSAGES/omega-web.po ================================================ msgid "" msgstr "" "Project-Id-Version: SwitchyOmega 2.3.3\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2015-02-13 10:29+0000\n" "PO-Revision-Date: 2017-02-07 11:48+0000\n" "Last-Translator: Heimen Stoffels \n" "Language-Team: Dutch " "\n" "Language: nl\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Generator: Weblate 2.11\n" msgid "appNameShort" msgstr "SwitchyOmega" msgid "manifest_app_name" msgstr "Proxy SwitchyOmega" msgid "manifest_app_description" msgstr "" "Beheer en schakel tussen meerdere proxies tegelijkertijd, gemakkelijk en " "snel." msgid "manifest_icon_default_title" msgstr "Bezig met laden…" msgid "upgrade_profile_auto" msgstr "Automatisch schakelen" msgid "profile_direct" msgstr "[Direct]" msgid "profile_system" msgstr "[Systeemproxy]" msgid "condition_HostWildcardCondition" msgstr "Host-jokerteken" msgid "condition_help_HostWildcardCondition" msgstr "" msgid "condition_HostRegexCondition" msgstr "Host-regex" msgid "condition_help_HostRegexCondition" msgstr "" msgid "condition_HostLevelsCondition" msgstr "Host-niveaus" msgid "condition_help_HostLevelsCondition" msgstr "" msgid "condition_IpCondition" msgstr "IP-letters" msgid "condition_help_IpCondition" msgstr "" msgid "condition_UrlWildcardCondition" msgstr "" msgid "condition_help_UrlWildcardCondition" msgstr "" msgid "condition_UrlRegexCondition" msgstr "" msgid "condition_help_UrlRegexCondition" msgstr "" msgid "condition_KeywordCondition" msgstr "" msgid "condition_help_KeywordCondition" msgstr "" msgid "condition_FalseCondition" msgstr "" msgid "condition_details_FalseCondition" msgstr "" msgid "condition_help_FalseCondition" msgstr "" msgid "condition_TimeCondition" msgstr "" msgid "condition_help_TimeCondition" msgstr "" msgid "condition_WeekdayCondition" msgstr "" msgid "condition_help_WeekdayCondition" msgstr "" msgid "condition_alert_fullUrlLimitation" msgstr "" msgid "condition_alert_fullUrlLimitationLink" msgstr "https://github.com/FelisCatus/SwitchyOmega/wiki/Chromium-Full-URL-Limitation" msgid "condition_group_default" msgstr "" msgid "condition_group_host" msgstr "" msgid "condition_group_url" msgstr "" msgid "condition_group_special" msgstr "" msgid "ruleListFormat_Switchy" msgstr "" msgid "ruleListFormat_AutoProxy" msgstr "" msgid "ruleList_usageUrl" msgstr "" msgid "ruleList_error_resultNotEnabled" msgstr "" msgid "ruleList_error_unknownProfile" msgstr "" msgid "ruleList_error_missingResultProfile" msgstr "" msgid "ruleList_error_invalidRule" msgstr "" msgid "ruleList_error_noDefaultRule" msgstr "" msgid "dialog_close" msgstr "" msgid "dialog_save" msgstr "" msgid "dialog_ok" msgstr "" msgid "dialog_cancel" msgstr "" msgid "inputClear_clear" msgstr "" msgid "inputClear_restore" msgstr "" msgid "options_title" msgstr "" msgid "options_experimental_badge" msgstr "α" msgid "options_navHeader_setting" msgstr "" msgid "options_navHeader_profiles" msgstr "" msgid "options_navHeader_actions" msgstr "" msgid "options_tab_ui" msgstr "" msgid "options_tab_general" msgstr "" msgid "options_tab_importExport" msgstr "" msgid "options_newProfile" msgstr "" msgid "options_apply" msgstr "" msgid "options_discard" msgstr "" msgid "options_reset" msgstr "" msgid "options_group_miscOptions" msgstr "" msgid "options_confirmDeletion" msgstr "" msgid "options_refreshOnProfileChange" msgstr "" msgid "options_showInspectMenu" msgstr "" msgid "options_addConditionsToBottom" msgstr "Put new conditions added using the popup to the bottom of the list." msgid "options_group_keyboardShortcut" msgstr "" msgid "options_menuShortcutHelp" msgstr "" msgid "options_menuShortcutMore" msgstr "" msgid "options_menuShortcutConfigure" msgstr "" msgid "options_group_switchOptions" msgstr "" msgid "options_startupProfile" msgstr "" msgid "options_startupProfile_none" msgstr "" msgid "options_showConditionTypesAdvanced" msgstr "" msgid "options_showConditionTypesAdvancedHelp" msgstr "" msgid "options_quickSwitch" msgstr "" msgid "options_cycledProfiles" msgstr "" msgid "options_cycledProfilesHelp" msgstr "" msgid "options_cycledProfilesTooFew" msgstr "" msgid "options_notCycledProfiles" msgstr "" msgid "options_group_proxyChanges" msgstr "" msgid "options_revertProxyChanges" msgstr "" msgid "options_group_conflicts" msgstr "Conflicts" msgid "options_conflicts_introduction" msgstr "" "Sometimes, other apps will also try to control the proxy settings, resulting " "in conflicts. Note that ad blockers and other extensions may also use proxy " "settings under the hood. Such conflicts cannot be avoided due to how the " "browser works." msgid "options_conflicts_lowerPriority" msgstr "" "A red badge like this on the SwitchyOmega icon indicates that another app has " "higher priority so SwitchyOmega cannot control the settings. Please try to " "uninstall SwitchyOmega and reinstall, which should raise SwitchyOmega's " "priority. If you still see conflicts after reinstallation, please consider " "removing the other app causing the conflict." msgid "options_conflicts_higherPriority" msgstr "" "If SwitchyOmega has higher priority, you can give the control back to other " "apps or system settings by selecting $SYSTEMPROFILE$ in the popup menu." msgid "options_showExternalProfile" msgstr "Show popup menu item to import proxy settings from other apps." msgid "options_showExternalProfileHelp" msgstr "" "When $SYSTEMPROFILE$ is selected, you can import the effective proxy settings " "from other apps by selecting $EXTERNALPROFILE$ on the popup menu. " "The settings will be imported as a profile using the name you provide. " "Please note that the imported profile is a snapshot and will not reflect " "any changes from the source app thereafter." msgid "options_group_networkRequests" msgstr "" msgid "options_monitorWebRequests" msgstr "" msgid "options_monitorWebRequestsHelp" msgstr "" msgid "options_downloadOptions" msgstr "" msgid "options_downloadOptionsHelp" msgstr "" msgid "options_downloadInterval" msgstr "" msgid "options_downloadInterval_15" msgstr "" msgid "options_downloadInterval_60" msgstr "" msgid "options_downloadInterval_180" msgstr "" msgid "options_downloadInterval_360" msgstr "" msgid "options_downloadInterval_720" msgstr "" msgid "options_downloadInterval_1440" msgstr "" msgid "options_downloadInterval_never" msgstr "" msgid "options_group_importExportProfile" msgstr "" msgid "options_exportPacFile" msgstr "" msgid "options_exportPacFileHelp" msgstr "" msgid "options_exportProfileHelp" msgstr "" msgid "options_exportLegacyRuleList" msgstr "" msgid "options_exportLegacyRuleListHelp" msgstr "" msgid "options_group_importExportSettings" msgstr "" msgid "options_makeBackup" msgstr "" msgid "options_makeBackupHelp" msgstr "" msgid "options_restoreLocal" msgstr "" msgid "options_restoreLocalHelp" msgstr "" msgid "options_restoreOnline" msgstr "" msgid "options_restoreOnlinePlaceholder" msgstr "" msgid "options_restoreOnlineSubmit" msgstr "" msgid "options_group_syncing" msgstr "" msgid "options_syncEnable" msgstr "" msgid "options_syncEnableForce" msgstr "" msgid "options_syncDisable" msgstr "" msgid "options_syncReset" msgstr "" msgid "options_syncPristineHelp" msgstr "" msgid "options_syncSyncAlert" msgstr "" msgid "options_syncSyncHelp" msgstr "" msgid "options_syncConflictAlert" msgstr "" msgid "options_syncConflictHelp" msgstr "" msgid "options_syncUnsupportedHelp" msgstr "" msgid "options_profileSyncDisabled" msgstr "" msgid "options_profileSyncDisabled_quotaPerItem" msgstr "" msgid "options_profileTabPrefix" msgstr "" msgid "options_renameProfile" msgstr "" msgid "options_deleteProfile" msgstr "" msgid "options_profileExportRuleList" msgstr "" msgid "options_profileExportRuleListHelp" msgstr "" msgid "options_profileExportPac" msgstr "" msgid "options_profileUnsupported" msgstr "" msgid "options_profileUnsupportedHelp" msgstr "" msgid "options_profileEditSource" msgstr "" msgid "options_profileEditSourceHelp" msgstr "" msgid "options_profileEditSourceHelpUrl" msgstr "" msgid "options_group_proxyServers" msgstr "" msgid "options_proxy_scheme" msgstr "" msgid "options_proxy_protocol" msgstr "" msgid "options_proxy_server" msgstr "" msgid "options_proxy_port" msgstr "" msgid "options_proxy_auth" msgstr "" msgid "options_proxy_authNotSupported" msgstr "Your browser DOES NOT support $PROTOCOLDISP$ proxy authentication! " "Please do not report this issue to SwitchyOmega. Contact the support for " "your browser instead." msgid "options_proxy_authAllWarningPac" msgstr "" msgid "options_proxy_authAllWarningPacUrl" msgstr "" msgid "options_proxy_authAllWarningPacScript" msgstr "" msgid "options_proxy_authReferencedWarning" msgstr "" msgid "options_scheme_default" msgstr "" msgid "options_protocol_direct" msgstr "" msgid "options_protocol_useDefault" msgstr "" msgid "options_proxy_single" msgstr "" msgid "options_proxy_expand" msgstr "" msgid "options_group_bypassList" msgstr "" msgid "options_bypassListHelp" msgstr "" msgid "options_bypassListHelpLinkText" msgstr "" msgid "options_group_pacUrl" msgstr "" msgid "options_pacUrlHelp" msgstr "" msgid "options_pacUrlFile" msgstr "" msgid "options_pacUrlFileDisabled" msgstr "" msgid "options_group_pacScript" msgstr "" msgid "options_pacScriptLastUpdate" msgstr "" msgid "options_pacScriptObsolete" msgstr "" msgid "options_group_virtualProfile" msgstr "" msgid "options_virtualProfileTarget" msgstr "" msgid "options_virtualProfileTargetHelp" msgstr "" msgid "options_group_virtualProfileReplace" msgstr "" msgid "options_virtualProfileReplace" msgstr "" msgid "options_virtualProfileReplaceHelp" msgstr "" msgid "options_group_ruleListConfig" msgstr "" msgid "options_ruleListFormat" msgstr "" msgid "options_group_ruleListResult" msgstr "" msgid "options_ruleListMatchProfile" msgstr "" msgid "options_ruleListDefaultProfile" msgstr "" msgid "options_group_ruleListUrl" msgstr "" msgid "options_ruleListUrlHelp" msgstr "" msgid "options_group_ruleListText" msgstr "" msgid "options_ruleListLastUpdate" msgstr "" msgid "options_ruleListObsolete" msgstr "" msgid "options_group_switchRules" msgstr "" msgid "options_sort" msgstr "" msgid "options_conditionType" msgstr "" msgid "options_showConditionTypeHelp" msgstr "" msgid "options_conditionDetails" msgstr "" msgid "options_resultProfile" msgstr "" msgid "options_conditionActions" msgstr "" msgid "options_addCondition" msgstr "" msgid "options_cloneRule" msgstr "" msgid "options_ruleNote" msgstr "Note" msgid "options_switchAttachedProfileInCondition" msgstr "" msgid "options_switchAttachedProfileInConditionDetails" msgstr "" msgid "options_switchAttachedProfileInConditionDisabled" msgstr "" msgid "options_switchDefaultProfile" msgstr "" msgid "options_hostLevelsBetween" msgstr "" msgid "options_hourBetween" msgstr "" msgid "options_weekDayShort_0" msgstr "" msgid "options_weekDayShort_1" msgstr "" msgid "options_weekDayShort_2" msgstr "" msgid "options_weekDayShort_3" msgstr "" msgid "options_weekDayShort_4" msgstr "" msgid "options_weekDayShort_5" msgstr "" msgid "options_weekDayShort_6" msgstr "" msgid "options_group_conditionHelp" msgstr "" msgid "options_group_attachProfile" msgstr "" msgid "options_attachProfile" msgstr "" msgid "options_attachProfileHelp" msgstr "" msgid "options_modalHeader_welcome" msgstr "" msgid "options_welcomeNormal" msgstr "" msgid "options_welcomeNormalGuide" msgstr "" msgid "options_welcomeUpgrade" msgstr "" msgid "options_welcomeUpgradeGuide" msgstr "" msgid "options_guideNext" msgstr "" msgid "options_guideDone" msgstr "" msgid "options_guideSkip" msgstr "" msgid "options_modalHeader_applyOptions" msgstr "" msgid "options_optionsNotSaved" msgstr "" msgid "options_applyOptionsRequired" msgstr "" msgid "options_applyOptionsConfirm" msgstr "" msgid "options_modalHeader_renameProfile" msgstr "" msgid "options_renameProfileName" msgstr "" msgid "options_profileNameConflict" msgstr "" msgid "options_profileNameReserved" msgstr "" msgid "options_profileNameHidden" msgstr "" msgid "options_modalHeader_replaceProfile" msgstr "" msgid "options_replaceProfile" msgstr "" msgid "options_replaceProfileConfirm" msgstr "" msgid "options_replaceProfileHelp" msgstr "" msgid "options_replaceProfileSuccess" msgstr "" msgid "options_modalHeader_deleteProfile" msgstr "" msgid "options_deleteProfileConfirm" msgstr "" msgid "options_modalHeader_cannotDeleteProfile" msgstr "" msgid "options_profileReferredBy" msgstr "" msgid "options_modifyReferringProfiles" msgstr "" msgid "options_profileNameEmpty" msgstr "" msgid "popup_title" msgstr "" msgid "options_modalHeader_proxyAuth" msgstr "" msgid "options_proxyAuthUsername" msgstr "" msgid "options_proxyAuthPassword" msgstr "" msgid "options_proxyAuthShowPassword" msgstr "Show password" msgid "options_proxyAuthHidePassword" msgstr "Hide password" msgid "options_proxyAuthNone" msgstr "" msgid "options_modalHeader_deleteRule" msgstr "" msgid "options_deleteRuleConfirm" msgstr "" msgid "options_deleteRule" msgstr "" msgid "options_modalHeader_resetRules" msgstr "" msgid "options_resetRulesConfirm" msgstr "" msgid "options_resetRules" msgstr "" msgid "options_resetRules_help" msgstr "" msgid "options_modalHeader_deleteAttached" msgstr "" msgid "options_deleteAttachedConfirm" msgstr "" msgid "options_ruleListLineCount" msgstr "" msgid "options_deleteAttached" msgstr "" msgid "options_modalHeader_newProfile" msgstr "" msgid "options_newProfileName" msgstr "" msgid "options_profileType" msgstr "" msgid "options_profileTypeFixedProfile" msgstr "" msgid "options_profileDescFixedProfile" msgstr "" msgid "options_profileTypePacProfile" msgstr "" msgid "options_profileDescPacProfile" msgstr "" msgid "options_profileDescMorePacProfile" msgstr "" msgid "options_profileTypeSwitchProfile" msgstr "" msgid "options_profileDescSwitchProfile" msgstr "" msgid "options_profileTypeRuleListProfile" msgstr "" msgid "options_profileDescRuleListProfile" msgstr "" msgid "options_profileTypeVirtualProfile" msgstr "" msgid "options_profileDescVirtualProfile" msgstr "" msgid "options_createProfile" msgstr "" msgid "options_modalHeader_resetOptions" msgstr "" msgid "options_resetOptionsConfirm" msgstr "" msgid "options_formInvalid" msgstr "" msgid "options_profileNotFound" msgstr "" msgid "options_resetSuccess" msgstr "" msgid "options_saveSuccess" msgstr "" msgid "options_importSuccess" msgstr "" msgid "options_importFormatError" msgstr "" msgid "options_importDownloadError" msgstr "" msgid "options_profileDownloadSuccess" msgstr "" msgid "options_profileDownloadError" msgstr "" msgid "options_profileDownloadError_NetworkError" msgstr "" msgid "options_profileDownloadError_HttpError" msgstr "" msgid "options_profileDownloadError_HttpNotFoundError" msgstr "" msgid "options_profileDownloadError_HttpServerError" msgstr "" msgid "options_profileDownloadError_ContentTypeRejectedError" msgstr "" msgid "options_downloadProfileNow" msgstr "" msgid "options_guide_fixedProfileStep" msgstr "" msgid "options_guide_fixedServersStep" msgstr "" msgid "options_guide_autoSwitchProfileStep" msgstr "" msgid "options_guide_addMoreProfilesStep" msgstr "" msgid "options_guide_conditionStep" msgstr "" msgid "options_guide_conditionTypeStep" msgstr "" msgid "options_guide_conditionProfileStep" msgstr "" msgid "options_guide_switchDefaultStep" msgstr "" msgid "options_guide_applySwitchProfileStep" msgstr "" msgid "popup_externalProfile" msgstr "" msgid "popup_externalProfileName" msgstr "" msgid "popup_proxyNotControllable_app" msgstr "" msgid "popup_proxyNotControllable_policy" msgstr "" msgid "popup_proxyNotControllable_unknown" msgstr "" msgid "popup_proxyNotControllable_disabled" msgstr "" msgid "popup_proxyNotControllable_upgrade" msgstr "" msgid "popup_proxyNotControllableDetails" msgstr "" msgid "popup_proxyNotControllableDetails_upgrade" msgstr "" msgid "popup_proxyNotControllableManage" msgstr "" msgid "popup_addConditionTo" msgstr "" msgid "popup_addCondition" msgstr "" msgid "popup_showOptions" msgstr "" msgid "popup_reportIssues" msgstr "" msgid "popup_errorLog" msgstr "" msgid "popup_requestErrorCount" msgstr "" msgid "popup_requestErrorHeading" msgstr "" msgid "popup_requestErrorWarning" msgstr "" msgid "popup_requestErrorWarningHelp" msgstr "" msgid "popup_requestErrorAddCondition" msgstr "" msgid "popup_requestErrorCannotAddCondition" msgstr "" msgid "popup_configureMonitorWebRequests" msgstr "" msgid "options_resultProfileForSelectedDomains" msgstr "" msgid "options_pac_profile_unsupported_moz" msgstr "PAC Profiles WILL NOT work in Mozilla Firefox due to technical limitations!" msgid "popup_issueTemplate" msgstr "" msgid "browserAction_profileDetails_PacProfile" msgstr "" msgid "browserAction_profileDetails_SystemProfile" msgstr "" msgid "browserAction_profileDetails_DirectProfile" msgstr "" msgid "browserAction_profileDetails_SwitchProfile" msgstr "" msgid "browserAction_profileDetails_RuleListProfile" msgstr "" msgid "browserAction_titleNormal" msgstr "" msgid "browserAction_titleWithResult" msgstr "" msgid "browserAction_titleNewerOptions" msgstr "" msgid "browserAction_titleOptionError" msgstr "" msgid "browserAction_titleDownloadFail" msgstr "" msgid "browserAction_titleExternalProxy" msgstr "" msgid "browserAction_titleInspect" msgstr "" msgid "browserAction_defaultRuleDetails" msgstr "" msgid "browserAction_directResult" msgstr "" msgid "browserAction_attachedPrefix" msgstr "" msgid "browserAction_tempRulePrefix" msgstr "" msgid "contextMenu_inspectPage" msgstr "" msgid "contextMenu_inspectFrame" msgstr "" msgid "contextMenu_inspectLink" msgstr "" msgid "contextMenu_inspectElement" msgstr "" msgid "contextMenu_enableQuickSwitch" msgstr "" msgid "about_title" msgstr "About" msgid "about_app_description" msgstr "A proxy configuration tool" msgid "about_version" msgstr "Version $VERSION$" msgid "about_experimental_warning_moz" msgstr "Mozilla Firefox support is highly experimental! If you encounter issues, please report using the buttons below." msgid "about_disclaimer_networkService" msgstr "SwitchyOmega does not provide proxies, VPNs, or other network services." msgid "about_disclaimer_privacy" msgstr "SwitchyOmega does not track you or insert ads into webpages. Please see" " our privacy policy." msgid "about_help" msgstr "Other questions? Need help with using SwitchyOmega? Please see our " "FAQ." msgid "about_copyright" msgstr "Copyright 2012-2017 The SwitchyOmega Authors. All rights reserved." msgid "about_credits" msgstr "SwitchyOmega is made possible by the SwitchyOmega open source project and other open source software." msgid "about_license" msgstr "SwitchyOmega is free software licensed under GNU General Public License Version 3 or later." ================================================ FILE: omega-locales/pl/LC_MESSAGES/omega-web.po ================================================ msgid "" msgstr "" "Project-Id-Version: SwitchyOmega 2.3.3\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2015-02-13 10:29+0000\n" "PO-Revision-Date: 2021-05-11 13:37+0000\n" "Last-Translator: Dariusz Dębowski \n" "Language-Team: Polish \n" "Language: pl\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 " "|| n%100>=20) ? 1 : 2;\n" "X-Generator: Weblate 4.7-dev\n" msgid "appNameShort" msgstr "SwitchyOmega" msgid "manifest_app_name" msgstr "SwitchyOmega Proxy" msgid "manifest_app_description" msgstr "Zarządzanie i przełączanie się pomiędzy serwerami proxy." msgid "manifest_icon_default_title" msgstr "Wczytywanie…" msgid "upgrade_profile_auto" msgstr "Automatyczne przełączanie" msgid "profile_direct" msgstr "[Bez proxy]" msgid "profile_system" msgstr "[Proxy systemowe]" msgid "condition_HostWildcardCondition" msgstr "" msgid "condition_help_HostWildcardCondition" msgstr "" msgid "condition_HostRegexCondition" msgstr "" msgid "condition_help_HostRegexCondition" msgstr "" msgid "condition_HostLevelsCondition" msgstr "" msgid "condition_help_HostLevelsCondition" msgstr "" msgid "condition_IpCondition" msgstr "" msgid "condition_help_IpCondition" msgstr "" msgid "condition_UrlWildcardCondition" msgstr "" msgid "condition_help_UrlWildcardCondition" msgstr "" msgid "condition_UrlRegexCondition" msgstr "" msgid "condition_help_UrlRegexCondition" msgstr "" msgid "condition_KeywordCondition" msgstr "" msgid "condition_help_KeywordCondition" msgstr "" msgid "condition_FalseCondition" msgstr "" msgid "condition_details_FalseCondition" msgstr "" msgid "condition_help_FalseCondition" msgstr "" msgid "condition_TimeCondition" msgstr "" msgid "condition_help_TimeCondition" msgstr "" msgid "condition_WeekdayCondition" msgstr "" msgid "condition_help_WeekdayCondition" msgstr "" msgid "condition_alert_fullUrlLimitation" msgstr "" msgid "condition_alert_fullUrlLimitationLink" msgstr "" msgid "condition_group_default" msgstr "" msgid "condition_group_host" msgstr "" msgid "condition_group_url" msgstr "" msgid "condition_group_special" msgstr "" msgid "ruleListFormat_Switchy" msgstr "" msgid "ruleListFormat_AutoProxy" msgstr "" msgid "ruleList_usageUrl" msgstr "" msgid "ruleList_error_resultNotEnabled" msgstr "" msgid "ruleList_error_unknownProfile" msgstr "" msgid "ruleList_error_missingResultProfile" msgstr "" msgid "ruleList_error_invalidRule" msgstr "" msgid "ruleList_error_noDefaultRule" msgstr "" msgid "dialog_close" msgstr "" msgid "dialog_save" msgstr "" msgid "dialog_ok" msgstr "" msgid "dialog_cancel" msgstr "" msgid "inputClear_clear" msgstr "" msgid "inputClear_restore" msgstr "" msgid "options_title" msgstr "" msgid "options_experimental_badge" msgstr "" msgid "options_navHeader_setting" msgstr "" msgid "options_navHeader_profiles" msgstr "" msgid "options_navHeader_actions" msgstr "" msgid "options_tab_ui" msgstr "" msgid "options_tab_general" msgstr "" msgid "options_tab_importExport" msgstr "" msgid "options_newProfile" msgstr "" msgid "options_apply" msgstr "" msgid "options_discard" msgstr "" msgid "options_reset" msgstr "" msgid "options_group_miscOptions" msgstr "" msgid "options_confirmDeletion" msgstr "" msgid "options_refreshOnProfileChange" msgstr "" msgid "options_showInspectMenu" msgstr "" msgid "options_addConditionsToBottom" msgstr "" msgid "options_group_keyboardShortcut" msgstr "" msgid "options_menuShortcutHelp" msgstr "" msgid "options_menuShortcutMore" msgstr "" msgid "options_menuShortcutConfigure" msgstr "" msgid "options_group_switchOptions" msgstr "" msgid "options_startupProfile" msgstr "" msgid "options_startupProfile_none" msgstr "" msgid "options_showConditionTypesAdvanced" msgstr "" msgid "options_showConditionTypesAdvancedHelp" msgstr "" msgid "options_quickSwitch" msgstr "" msgid "options_cycledProfiles" msgstr "" msgid "options_cycledProfilesHelp" msgstr "" msgid "options_cycledProfilesTooFew" msgstr "" msgid "options_notCycledProfiles" msgstr "" msgid "options_group_proxyChanges" msgstr "" msgid "options_revertProxyChanges" msgstr "" msgid "options_group_conflicts" msgstr "" msgid "options_conflicts_introduction" msgstr "" msgid "options_conflicts_lowerPriority" msgstr "" msgid "options_conflicts_higherPriority" msgstr "" msgid "options_showExternalProfile" msgstr "" msgid "options_showExternalProfileHelp" msgstr "" msgid "options_group_networkRequests" msgstr "" msgid "options_monitorWebRequests" msgstr "" msgid "options_monitorWebRequestsHelp" msgstr "" msgid "options_downloadOptions" msgstr "" msgid "options_downloadOptionsHelp" msgstr "" msgid "options_downloadInterval" msgstr "" msgid "options_downloadInterval_15" msgstr "" msgid "options_downloadInterval_60" msgstr "" msgid "options_downloadInterval_180" msgstr "" msgid "options_downloadInterval_360" msgstr "" msgid "options_downloadInterval_720" msgstr "" msgid "options_downloadInterval_1440" msgstr "" msgid "options_downloadInterval_never" msgstr "" msgid "options_group_importExportProfile" msgstr "" msgid "options_exportPacFile" msgstr "" msgid "options_exportPacFileHelp" msgstr "" msgid "options_exportProfileHelp" msgstr "" msgid "options_exportLegacyRuleList" msgstr "" msgid "options_exportLegacyRuleListHelp" msgstr "" msgid "options_group_importExportSettings" msgstr "" msgid "options_makeBackup" msgstr "" msgid "options_makeBackupHelp" msgstr "" msgid "options_restoreLocal" msgstr "" msgid "options_restoreLocalHelp" msgstr "" msgid "options_restoreOnline" msgstr "" msgid "options_restoreOnlinePlaceholder" msgstr "" msgid "options_restoreOnlineSubmit" msgstr "" msgid "options_group_syncing" msgstr "" msgid "options_syncEnable" msgstr "" msgid "options_syncEnableForce" msgstr "" msgid "options_syncDisable" msgstr "" msgid "options_syncReset" msgstr "" msgid "options_syncPristineHelp" msgstr "" msgid "options_syncSyncAlert" msgstr "" msgid "options_syncSyncHelp" msgstr "" msgid "options_syncConflictAlert" msgstr "" msgid "options_syncConflictHelp" msgstr "" msgid "options_syncUnsupportedHelp" msgstr "" msgid "options_profileSyncDisabled" msgstr "" msgid "options_profileSyncDisabled_quotaPerItem" msgstr "" msgid "options_profileTabPrefix" msgstr "" msgid "options_renameProfile" msgstr "" msgid "options_deleteProfile" msgstr "" msgid "options_profileExportRuleList" msgstr "" msgid "options_profileExportRuleListHelp" msgstr "" msgid "options_profileExportPac" msgstr "" msgid "options_profileUnsupported" msgstr "" msgid "options_profileUnsupportedHelp" msgstr "" msgid "options_profileEditSource" msgstr "" msgid "options_profileEditSourceHelp" msgstr "" msgid "options_profileEditSourceHelpUrl" msgstr "" msgid "options_group_proxyServers" msgstr "" msgid "options_proxy_scheme" msgstr "" msgid "options_proxy_protocol" msgstr "" msgid "options_proxy_server" msgstr "" msgid "options_proxy_port" msgstr "" msgid "options_proxy_auth" msgstr "" msgid "options_proxy_authNotSupported" msgstr "" msgid "options_proxy_authAllWarningPac" msgstr "" msgid "options_proxy_authAllWarningPacUrl" msgstr "" msgid "options_proxy_authAllWarningPacScript" msgstr "" msgid "options_proxy_authReferencedWarning" msgstr "" msgid "options_scheme_default" msgstr "" msgid "options_protocol_direct" msgstr "" msgid "options_protocol_useDefault" msgstr "" msgid "options_proxy_single" msgstr "" msgid "options_proxy_expand" msgstr "" msgid "options_group_bypassList" msgstr "" msgid "options_bypassListHelp" msgstr "" msgid "options_bypassListHelpLinkText" msgstr "" msgid "options_group_pacUrl" msgstr "" msgid "options_pacUrlHelp" msgstr "" msgid "options_pacUrlFile" msgstr "" msgid "options_pacUrlFileDisabled" msgstr "" msgid "options_group_pacScript" msgstr "" msgid "options_pacScriptLastUpdate" msgstr "" msgid "options_pacScriptObsolete" msgstr "" msgid "options_group_virtualProfile" msgstr "" msgid "options_virtualProfileTarget" msgstr "" msgid "options_virtualProfileTargetHelp" msgstr "" msgid "options_group_virtualProfileReplace" msgstr "" msgid "options_virtualProfileReplace" msgstr "" msgid "options_virtualProfileReplaceHelp" msgstr "" msgid "options_group_ruleListConfig" msgstr "" msgid "options_ruleListFormat" msgstr "" msgid "options_group_ruleListResult" msgstr "" msgid "options_ruleListMatchProfile" msgstr "" msgid "options_ruleListDefaultProfile" msgstr "" msgid "options_group_ruleListUrl" msgstr "" msgid "options_ruleListUrlHelp" msgstr "" msgid "options_group_ruleListText" msgstr "" msgid "options_ruleListLastUpdate" msgstr "" msgid "options_ruleListObsolete" msgstr "" msgid "options_group_switchRules" msgstr "" msgid "options_sort" msgstr "" msgid "options_conditionType" msgstr "" msgid "options_showConditionTypeHelp" msgstr "" msgid "options_conditionDetails" msgstr "" msgid "options_resultProfile" msgstr "" msgid "options_conditionActions" msgstr "" msgid "options_addCondition" msgstr "" msgid "options_cloneRule" msgstr "" msgid "options_ruleNote" msgstr "" msgid "options_switchAttachedProfileInCondition" msgstr "" msgid "options_switchAttachedProfileInConditionDetails" msgstr "" msgid "options_switchAttachedProfileInConditionDisabled" msgstr "" msgid "options_switchDefaultProfile" msgstr "" msgid "options_hostLevelsBetween" msgstr "" msgid "options_hourBetween" msgstr "" msgid "options_weekDayShort_0" msgstr "" msgid "options_weekDayShort_1" msgstr "" msgid "options_weekDayShort_2" msgstr "" msgid "options_weekDayShort_3" msgstr "" msgid "options_weekDayShort_4" msgstr "" msgid "options_weekDayShort_5" msgstr "" msgid "options_weekDayShort_6" msgstr "" msgid "options_group_conditionHelp" msgstr "" msgid "options_group_attachProfile" msgstr "" msgid "options_attachProfile" msgstr "" msgid "options_attachProfileHelp" msgstr "" msgid "options_modalHeader_welcome" msgstr "" msgid "options_welcomeNormal" msgstr "" msgid "options_welcomeNormalGuide" msgstr "" msgid "options_welcomeUpgrade" msgstr "" msgid "options_welcomeUpgradeGuide" msgstr "" msgid "options_guideNext" msgstr "" msgid "options_guideDone" msgstr "" msgid "options_guideSkip" msgstr "" msgid "options_modalHeader_applyOptions" msgstr "" msgid "options_optionsNotSaved" msgstr "" msgid "options_applyOptionsRequired" msgstr "" msgid "options_applyOptionsConfirm" msgstr "" msgid "options_modalHeader_renameProfile" msgstr "" msgid "options_renameProfileName" msgstr "" msgid "options_profileNameConflict" msgstr "" msgid "options_profileNameReserved" msgstr "" msgid "options_profileNameHidden" msgstr "" msgid "options_modalHeader_replaceProfile" msgstr "" msgid "options_replaceProfile" msgstr "" msgid "options_replaceProfileConfirm" msgstr "" msgid "options_replaceProfileHelp" msgstr "" msgid "options_replaceProfileSuccess" msgstr "" msgid "options_modalHeader_deleteProfile" msgstr "" msgid "options_deleteProfileConfirm" msgstr "" msgid "options_modalHeader_cannotDeleteProfile" msgstr "" msgid "options_profileReferredBy" msgstr "" msgid "options_modifyReferringProfiles" msgstr "" msgid "options_profileNameEmpty" msgstr "" msgid "popup_title" msgstr "" msgid "options_modalHeader_proxyAuth" msgstr "" msgid "options_proxyAuthUsername" msgstr "" msgid "options_proxyAuthPassword" msgstr "" msgid "options_proxyAuthShowPassword" msgstr "" msgid "options_proxyAuthHidePassword" msgstr "" msgid "options_proxyAuthNone" msgstr "" msgid "options_modalHeader_deleteRule" msgstr "" msgid "options_deleteRuleConfirm" msgstr "" msgid "options_deleteRule" msgstr "" msgid "options_modalHeader_resetRules" msgstr "" msgid "options_resetRulesConfirm" msgstr "" msgid "options_resetRules" msgstr "" msgid "options_resetRules_help" msgstr "" msgid "options_modalHeader_deleteAttached" msgstr "" msgid "options_deleteAttachedConfirm" msgstr "" msgid "options_ruleListLineCount" msgstr "" msgid "options_deleteAttached" msgstr "" msgid "options_modalHeader_newProfile" msgstr "" msgid "options_newProfileName" msgstr "" msgid "options_profileType" msgstr "" msgid "options_profileTypeFixedProfile" msgstr "" msgid "options_profileDescFixedProfile" msgstr "" msgid "options_profileTypePacProfile" msgstr "" msgid "options_profileDescPacProfile" msgstr "" msgid "options_profileDescMorePacProfile" msgstr "" msgid "options_profileTypeSwitchProfile" msgstr "" msgid "options_profileDescSwitchProfile" msgstr "" msgid "options_profileTypeRuleListProfile" msgstr "" msgid "options_profileDescRuleListProfile" msgstr "" msgid "options_profileTypeVirtualProfile" msgstr "" msgid "options_profileDescVirtualProfile" msgstr "" msgid "options_createProfile" msgstr "" msgid "options_modalHeader_resetOptions" msgstr "" msgid "options_resetOptionsConfirm" msgstr "" msgid "options_formInvalid" msgstr "" msgid "options_profileNotFound" msgstr "" msgid "options_resetSuccess" msgstr "" msgid "options_saveSuccess" msgstr "" msgid "options_importSuccess" msgstr "" msgid "options_importFormatError" msgstr "" msgid "options_importDownloadError" msgstr "" msgid "options_profileDownloadSuccess" msgstr "" msgid "options_profileDownloadError" msgstr "" msgid "options_profileDownloadError_NetworkError" msgstr "" msgid "options_profileDownloadError_HttpError" msgstr "" msgid "options_profileDownloadError_HttpNotFoundError" msgstr "" msgid "options_profileDownloadError_HttpServerError" msgstr "" msgid "options_profileDownloadError_ContentTypeRejectedError" msgstr "" msgid "options_downloadProfileNow" msgstr "" msgid "options_guide_fixedProfileStep" msgstr "" msgid "options_guide_fixedServersStep" msgstr "" msgid "options_guide_autoSwitchProfileStep" msgstr "" msgid "options_guide_addMoreProfilesStep" msgstr "" msgid "options_guide_conditionStep" msgstr "" msgid "options_guide_conditionTypeStep" msgstr "" msgid "options_guide_conditionProfileStep" msgstr "" msgid "options_guide_switchDefaultStep" msgstr "" msgid "options_guide_applySwitchProfileStep" msgstr "" msgid "popup_externalProfile" msgstr "" msgid "popup_externalProfileName" msgstr "" msgid "popup_proxyNotControllable_app" msgstr "" msgid "popup_proxyNotControllable_policy" msgstr "" msgid "popup_proxyNotControllable_unknown" msgstr "" msgid "popup_proxyNotControllable_disabled" msgstr "" msgid "popup_proxyNotControllable_upgrade" msgstr "" msgid "popup_proxyNotControllableDetails" msgstr "" msgid "popup_proxyNotControllableDetails_upgrade" msgstr "" msgid "popup_proxyNotControllableManage" msgstr "" msgid "popup_addConditionTo" msgstr "" msgid "popup_addCondition" msgstr "" msgid "popup_showOptions" msgstr "" msgid "popup_reportIssues" msgstr "" msgid "popup_errorLog" msgstr "" msgid "popup_requestErrorCount" msgstr "" msgid "popup_requestErrorHeading" msgstr "" msgid "popup_requestErrorWarning" msgstr "" msgid "popup_requestErrorWarningHelp" msgstr "" msgid "popup_requestErrorAddCondition" msgstr "" msgid "popup_requestErrorCannotAddCondition" msgstr "" msgid "popup_configureMonitorWebRequests" msgstr "" msgid "options_resultProfileForSelectedDomains" msgstr "" msgid "options_pac_profile_unsupported_moz" msgstr "" msgid "popup_issueTemplate" msgstr "" msgid "browserAction_profileDetails_PacProfile" msgstr "" msgid "browserAction_profileDetails_SystemProfile" msgstr "" msgid "browserAction_profileDetails_DirectProfile" msgstr "" msgid "browserAction_profileDetails_SwitchProfile" msgstr "" msgid "browserAction_profileDetails_RuleListProfile" msgstr "" msgid "browserAction_titleNormal" msgstr "" msgid "browserAction_titleWithResult" msgstr "" msgid "browserAction_titleNewerOptions" msgstr "" msgid "browserAction_titleOptionError" msgstr "" msgid "browserAction_titleDownloadFail" msgstr "" msgid "browserAction_titleExternalProxy" msgstr "" msgid "browserAction_titleInspect" msgstr "" msgid "browserAction_defaultRuleDetails" msgstr "" msgid "browserAction_directResult" msgstr "" msgid "browserAction_attachedPrefix" msgstr "" msgid "browserAction_tempRulePrefix" msgstr "" msgid "contextMenu_inspectPage" msgstr "" msgid "contextMenu_inspectFrame" msgstr "" msgid "contextMenu_inspectLink" msgstr "" msgid "contextMenu_inspectElement" msgstr "" msgid "contextMenu_enableQuickSwitch" msgstr "" msgid "about_title" msgstr "" msgid "about_app_description" msgstr "" msgid "about_version" msgstr "" msgid "about_experimental_warning_moz" msgstr "" msgid "about_disclaimer_networkService" msgstr "" msgid "about_disclaimer_privacy" msgstr "" msgid "about_help" msgstr "" msgid "about_copyright" msgstr "" msgid "about_credits" msgstr "" msgid "about_license" msgstr "" ================================================ FILE: omega-locales/pt/LC_MESSAGES/omega-web.po ================================================ msgid "" msgstr "" "Project-Id-Version: SwitchyOmega 2.3.3\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2015-02-13 10:29+0000\n" "PO-Revision-Date: 2024-10-08 09:16+0000\n" "Last-Translator: ssantos \n" "Language-Team: Portuguese \n" "Language: pt\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n > 1;\n" "X-Generator: Weblate 5.8-dev\n" msgid "appNameShort" msgstr "SwitchyOmega" msgid "manifest_app_name" msgstr "Proxy SwitchyOmega" msgid "manifest_app_description" msgstr "Gira e troque entre vários proxies rápida e facilmente." msgid "manifest_icon_default_title" msgstr "A carregar…" msgid "upgrade_profile_auto" msgstr "Auto Troca" msgid "profile_direct" msgstr "[Direto]" msgid "profile_system" msgstr "[Proxy do Sistema]" msgid "condition_HostWildcardCondition" msgstr "Host curinga" msgid "condition_help_HostWildcardCondition" msgstr "" "Matches de hosts (domínios) por curinga.
O asterisco * match de zero ou mais caracteres.
O ponto de interrogação " "? match de exatamente um carácter.

Note que regras a " "começar com *. são especialmente tratadas apenas num host com " "condições curinga.
Exemplo: *.exemplo.com vai dar match em " "www.exemplo.com E também exemplo.com.
Para apenas " "subdomínios , use dois asteriscos como: **.exemplo.com." msgid "condition_HostRegexCondition" msgstr "" msgid "condition_help_HostRegexCondition" msgstr "" "Parecido com a condição curinga, mas dá matchs em hosts (nomes de domínios) " "por regular expression.
As expressões " "regulares podem ser difíceis de construir (e ler).
É recomendado usar " "curingas para a maioria dos casos e usar regex apenas em condições que não " "pode ser conseguido em nenhum outro tipo de condição." msgid "condition_HostLevelsCondition" msgstr "" msgid "condition_help_HostLevelsCondition" msgstr "" msgid "condition_IpCondition" msgstr "" msgid "condition_help_IpCondition" msgstr "" msgid "condition_UrlWildcardCondition" msgstr "URL wildcard" msgid "condition_help_UrlWildcardCondition" msgstr "" msgid "condition_UrlRegexCondition" msgstr "URL regex" msgid "condition_help_UrlRegexCondition" msgstr "" msgid "condition_KeywordCondition" msgstr "Palavra chave" msgid "condition_help_KeywordCondition" msgstr "" msgid "condition_FalseCondition" msgstr "(Desativado)" msgid "condition_details_FalseCondition" msgstr "" msgid "condition_help_FalseCondition" msgstr "" msgid "condition_TimeCondition" msgstr "" msgid "condition_help_TimeCondition" msgstr "" msgid "condition_WeekdayCondition" msgstr "" msgid "condition_help_WeekdayCondition" msgstr "" msgid "condition_alert_fullUrlLimitation" msgstr "" msgid "condition_alert_fullUrlLimitationLink" msgstr "" "https://github.com/FelisCatus/SwitchyOmega/wiki/Chromium-Full-URL-Limitation" msgid "condition_group_default" msgstr " " msgid "condition_group_host" msgstr "Host" msgid "condition_group_url" msgstr "Url" msgid "condition_group_special" msgstr "Special" msgid "ruleListFormat_Switchy" msgstr "" msgid "ruleListFormat_AutoProxy" msgstr "" msgid "ruleList_usageUrl" msgstr "https://github.com/FelisCatus/SwitchyOmega/wiki/RuleListUsage" msgid "ruleList_error_resultNotEnabled" msgstr "" msgid "ruleList_error_unknownProfile" msgstr "" msgid "ruleList_error_missingResultProfile" msgstr "" msgid "ruleList_error_invalidRule" msgstr "" msgid "ruleList_error_noDefaultRule" msgstr "" msgid "dialog_close" msgstr "" msgid "dialog_save" msgstr "" msgid "dialog_ok" msgstr "OK" msgid "dialog_cancel" msgstr "" msgid "inputClear_clear" msgstr "" msgid "inputClear_restore" msgstr "" msgid "options_title" msgstr "SwitchyOmega Options" msgid "options_experimental_badge" msgstr "α" msgid "options_navHeader_setting" msgstr "" msgid "options_navHeader_profiles" msgstr "" msgid "options_navHeader_actions" msgstr "Actions" msgid "options_tab_ui" msgstr "Interface" msgid "options_tab_general" msgstr "General" msgid "options_tab_importExport" msgstr "Import/Export" msgid "options_newProfile" msgstr "" msgid "options_apply" msgstr "" msgid "options_discard" msgstr "" msgid "options_reset" msgstr "Reset options" msgid "options_group_miscOptions" msgstr "" msgid "options_confirmDeletion" msgstr "" msgid "options_refreshOnProfileChange" msgstr "" msgid "options_showInspectMenu" msgstr "" msgid "options_addConditionsToBottom" msgstr "" msgid "options_group_keyboardShortcut" msgstr "" msgid "options_menuShortcutHelp" msgstr "" msgid "options_menuShortcutMore" msgstr "" msgid "options_menuShortcutConfigure" msgstr "Configurar atalho" msgid "options_group_switchOptions" msgstr "Opções de alteração" msgid "options_startupProfile" msgstr "Perfil de inicialização" msgid "options_startupProfile_none" msgstr "(Perfil atual)" msgid "options_showConditionTypesAdvanced" msgstr "" msgid "options_showConditionTypesAdvancedHelp" msgstr "" "Desbloqueia novos tipos de avançadas, porém complicadas, condições de " "mudança. Para a maioria dos cenários, as condições básicas devem ser " "suficientes, logo esta opção não é recomendada." msgid "options_quickSwitch" msgstr "" msgid "options_cycledProfiles" msgstr "" msgid "options_cycledProfilesHelp" msgstr "" msgid "options_cycledProfilesTooFew" msgstr "" msgid "options_notCycledProfiles" msgstr "" msgid "options_group_proxyChanges" msgstr "" msgid "options_revertProxyChanges" msgstr "" msgid "options_group_conflicts" msgstr "" msgid "options_conflicts_introduction" msgstr "" msgid "options_conflicts_lowerPriority" msgstr "" msgid "options_conflicts_higherPriority" msgstr "" msgid "options_showExternalProfile" msgstr "" msgid "options_showExternalProfileHelp" msgstr "" msgid "options_group_networkRequests" msgstr "" msgid "options_monitorWebRequests" msgstr "" msgid "options_monitorWebRequestsHelp" msgstr "" msgid "options_downloadOptions" msgstr "Opções des descarrega" msgid "options_downloadOptionsHelp" msgstr "" msgid "options_downloadInterval" msgstr "" msgid "options_downloadInterval_15" msgstr "15 Minutes" msgid "options_downloadInterval_60" msgstr "" msgid "options_downloadInterval_180" msgstr "" msgid "options_downloadInterval_360" msgstr "" msgid "options_downloadInterval_720" msgstr "" msgid "options_downloadInterval_1440" msgstr "" msgid "options_downloadInterval_never" msgstr "" msgid "options_group_importExportProfile" msgstr "" msgid "options_exportPacFile" msgstr "" msgid "options_exportPacFileHelp" msgstr "" msgid "options_exportProfileHelp" msgstr "" msgid "options_exportLegacyRuleList" msgstr "" msgid "options_exportLegacyRuleListHelp" msgstr "" msgid "options_group_importExportSettings" msgstr "" msgid "options_makeBackup" msgstr "" msgid "options_makeBackupHelp" msgstr "" msgid "options_restoreLocal" msgstr "" msgid "options_restoreLocalHelp" msgstr "" msgid "options_restoreOnline" msgstr "" msgid "options_restoreOnlinePlaceholder" msgstr "Options file URL (e.g. 'http://example.com/switchy.bak')" msgid "options_restoreOnlineSubmit" msgstr "" msgid "options_group_syncing" msgstr "" msgid "options_syncEnable" msgstr "" msgid "options_syncEnableForce" msgstr "" msgid "options_syncDisable" msgstr "" msgid "options_syncReset" msgstr "" msgid "options_syncPristineHelp" msgstr "" msgid "options_syncSyncAlert" msgstr "" msgid "options_syncSyncHelp" msgstr "" msgid "options_syncConflictAlert" msgstr "" msgid "options_syncConflictHelp" msgstr "" msgid "options_syncUnsupportedHelp" msgstr "" msgid "options_profileSyncDisabled" msgstr "" msgid "options_profileSyncDisabled_quotaPerItem" msgstr "" msgid "options_profileTabPrefix" msgstr "" msgid "options_renameProfile" msgstr "" msgid "options_deleteProfile" msgstr "Delete" msgid "options_profileExportRuleList" msgstr "" msgid "options_profileExportRuleListHelp" msgstr "" msgid "options_profileExportPac" msgstr "" msgid "options_profileUnsupported" msgstr "" msgid "options_profileUnsupportedHelp" msgstr "" msgid "options_profileEditSource" msgstr "" msgid "options_profileEditSourceHelp" msgstr "" msgid "options_profileEditSourceHelpUrl" msgstr "" "https://github.com/FelisCatus/SwitchyOmega/wiki/SwitchyOmega-conditions-" "format#result-profile" msgid "options_group_proxyServers" msgstr "Proxy servers" msgid "options_proxy_scheme" msgstr "" msgid "options_proxy_protocol" msgstr "Protocol" msgid "options_proxy_server" msgstr "Server" msgid "options_proxy_port" msgstr "Port" msgid "options_proxy_auth" msgstr "Authentication" msgid "options_proxy_authNotSupported" msgstr "" msgid "options_proxy_authAllWarningPac" msgstr "" msgid "options_proxy_authAllWarningPacUrl" msgstr "" msgid "options_proxy_authAllWarningPacScript" msgstr "" msgid "options_proxy_authReferencedWarning" msgstr "" msgid "options_scheme_default" msgstr "(default)" msgid "options_protocol_direct" msgstr "DIRECT" msgid "options_protocol_useDefault" msgstr "" msgid "options_proxy_single" msgstr "" msgid "options_proxy_expand" msgstr "" msgid "options_group_bypassList" msgstr "" msgid "options_bypassListHelp" msgstr "" msgid "options_bypassListHelpLinkText" msgstr "" msgid "options_group_pacUrl" msgstr "PAC URL" msgid "options_pacUrlHelp" msgstr "" msgid "options_pacUrlFile" msgstr "" msgid "options_pacUrlFileDisabled" msgstr "" msgid "options_group_pacScript" msgstr "" msgid "options_pacScriptLastUpdate" msgstr "" msgid "options_pacScriptObsolete" msgstr "" msgid "options_group_virtualProfile" msgstr "" msgid "options_virtualProfileTarget" msgstr "" msgid "options_virtualProfileTargetHelp" msgstr "" msgid "options_group_virtualProfileReplace" msgstr "" msgid "options_virtualProfileReplace" msgstr "" msgid "options_virtualProfileReplaceHelp" msgstr "" msgid "options_group_ruleListConfig" msgstr "" msgid "options_ruleListFormat" msgstr "" msgid "options_group_ruleListResult" msgstr "" msgid "options_ruleListMatchProfile" msgstr "" msgid "options_ruleListDefaultProfile" msgstr "" msgid "options_group_ruleListUrl" msgstr "" msgid "options_ruleListUrlHelp" msgstr "" msgid "options_group_ruleListText" msgstr "" msgid "options_ruleListLastUpdate" msgstr "" msgid "options_ruleListObsolete" msgstr "" msgid "options_group_switchRules" msgstr "" msgid "options_sort" msgstr "" msgid "options_conditionType" msgstr "" msgid "options_showConditionTypeHelp" msgstr "" msgid "options_conditionDetails" msgstr "" msgid "options_resultProfile" msgstr "" msgid "options_conditionActions" msgstr "Actions" msgid "options_addCondition" msgstr "" msgid "options_cloneRule" msgstr "" msgid "options_ruleNote" msgstr "Note" msgid "options_switchAttachedProfileInCondition" msgstr "" msgid "options_switchAttachedProfileInConditionDetails" msgstr "" msgid "options_switchAttachedProfileInConditionDisabled" msgstr "" msgid "options_switchDefaultProfile" msgstr "Default" msgid "options_hostLevelsBetween" msgstr "" msgid "options_hourBetween" msgstr "" msgid "options_weekDayShort_0" msgstr "Su" msgid "options_weekDayShort_1" msgstr "Mo" msgid "options_weekDayShort_2" msgstr "Tu" msgid "options_weekDayShort_3" msgstr "We" msgid "options_weekDayShort_4" msgstr "Th" msgid "options_weekDayShort_5" msgstr "Fr" msgid "options_weekDayShort_6" msgstr "Sa" msgid "options_group_conditionHelp" msgstr "" msgid "options_group_attachProfile" msgstr "" msgid "options_attachProfile" msgstr "" msgid "options_attachProfileHelp" msgstr "" msgid "options_modalHeader_welcome" msgstr "" msgid "options_welcomeNormal" msgstr "" msgid "options_welcomeNormalGuide" msgstr "" msgid "options_welcomeUpgrade" msgstr "" msgid "options_welcomeUpgradeGuide" msgstr "" msgid "options_guideNext" msgstr "Next" msgid "options_guideDone" msgstr "" msgid "options_guideSkip" msgstr "" msgid "options_modalHeader_applyOptions" msgstr "" msgid "options_optionsNotSaved" msgstr "" msgid "options_applyOptionsRequired" msgstr "" msgid "options_applyOptionsConfirm" msgstr "" msgid "options_modalHeader_renameProfile" msgstr "" msgid "options_renameProfileName" msgstr "" msgid "options_profileNameConflict" msgstr "" msgid "options_profileNameReserved" msgstr "" msgid "options_profileNameHidden" msgstr "" msgid "options_modalHeader_replaceProfile" msgstr "" msgid "options_replaceProfile" msgstr "" msgid "options_replaceProfileConfirm" msgstr "" msgid "options_replaceProfileHelp" msgstr "" msgid "options_replaceProfileSuccess" msgstr "" msgid "options_modalHeader_deleteProfile" msgstr "" msgid "options_deleteProfileConfirm" msgstr "" msgid "options_modalHeader_cannotDeleteProfile" msgstr "" msgid "options_profileReferredBy" msgstr "" msgid "options_modifyReferringProfiles" msgstr "" msgid "options_profileNameEmpty" msgstr "" msgid "popup_title" msgstr "" msgid "options_modalHeader_proxyAuth" msgstr "Proxy Authentication" msgid "options_proxyAuthUsername" msgstr "" msgid "options_proxyAuthPassword" msgstr "Password" msgid "options_proxyAuthShowPassword" msgstr "" msgid "options_proxyAuthHidePassword" msgstr "" msgid "options_proxyAuthNone" msgstr "No Authentication" msgid "options_modalHeader_deleteRule" msgstr "" msgid "options_deleteRuleConfirm" msgstr "" msgid "options_deleteRule" msgstr "Delete" msgid "options_modalHeader_resetRules" msgstr "" msgid "options_resetRulesConfirm" msgstr "" msgid "options_resetRules" msgstr "" msgid "options_resetRules_help" msgstr "" msgid "options_modalHeader_deleteAttached" msgstr "" msgid "options_deleteAttachedConfirm" msgstr "" msgid "options_ruleListLineCount" msgstr "" msgid "options_deleteAttached" msgstr "" msgid "options_modalHeader_newProfile" msgstr "" msgid "options_newProfileName" msgstr "" msgid "options_profileType" msgstr "" msgid "options_profileTypeFixedProfile" msgstr "" msgid "options_profileDescFixedProfile" msgstr "" msgid "options_profileTypePacProfile" msgstr "" msgid "options_profileDescPacProfile" msgstr "" msgid "options_profileDescMorePacProfile" msgstr "" msgid "options_profileTypeSwitchProfile" msgstr "" msgid "options_profileDescSwitchProfile" msgstr "" msgid "options_profileTypeRuleListProfile" msgstr "" msgid "options_profileDescRuleListProfile" msgstr "" msgid "options_profileTypeVirtualProfile" msgstr "" msgid "options_profileDescVirtualProfile" msgstr "" msgid "options_createProfile" msgstr "" msgid "options_modalHeader_resetOptions" msgstr "Reset Options" msgid "options_resetOptionsConfirm" msgstr "" msgid "options_formInvalid" msgstr "" msgid "options_profileNotFound" msgstr "" msgid "options_resetSuccess" msgstr "Options reset." msgid "options_saveSuccess" msgstr "" msgid "options_importSuccess" msgstr "" msgid "options_importFormatError" msgstr "" msgid "options_importDownloadError" msgstr "" msgid "options_profileDownloadSuccess" msgstr "" msgid "options_profileDownloadError" msgstr "" msgid "options_profileDownloadError_NetworkError" msgstr "" msgid "options_profileDownloadError_HttpError" msgstr "" msgid "options_profileDownloadError_HttpNotFoundError" msgstr "" msgid "options_profileDownloadError_HttpServerError" msgstr "" msgid "options_profileDownloadError_ContentTypeRejectedError" msgstr "" msgid "options_downloadProfileNow" msgstr "" msgid "options_guide_fixedProfileStep" msgstr "" msgid "options_guide_fixedServersStep" msgstr "" msgid "options_guide_autoSwitchProfileStep" msgstr "" msgid "options_guide_addMoreProfilesStep" msgstr "" msgid "options_guide_conditionStep" msgstr "" msgid "options_guide_conditionTypeStep" msgstr "" msgid "options_guide_conditionProfileStep" msgstr "" msgid "options_guide_switchDefaultStep" msgstr "" msgid "options_guide_applySwitchProfileStep" msgstr "" msgid "popup_externalProfile" msgstr "" msgid "popup_externalProfileName" msgstr "" msgid "popup_proxyNotControllable_app" msgstr "" msgid "popup_proxyNotControllable_policy" msgstr "" msgid "popup_proxyNotControllable_unknown" msgstr "" msgid "popup_proxyNotControllable_disabled" msgstr "" msgid "popup_proxyNotControllable_upgrade" msgstr "" msgid "popup_proxyNotControllableDetails" msgstr "" msgid "popup_proxyNotControllableDetails_upgrade" msgstr "" msgid "popup_proxyNotControllableManage" msgstr "" msgid "popup_addConditionTo" msgstr "" msgid "popup_addCondition" msgstr "" msgid "popup_showOptions" msgstr "Options" msgid "popup_reportIssues" msgstr "" msgid "popup_errorLog" msgstr "" msgid "popup_requestErrorCount" msgstr "" msgid "popup_requestErrorHeading" msgstr "" msgid "popup_requestErrorWarning" msgstr "" msgid "popup_requestErrorWarningHelp" msgstr "" msgid "popup_requestErrorAddCondition" msgstr "" msgid "popup_requestErrorCannotAddCondition" msgstr "" msgid "popup_configureMonitorWebRequests" msgstr "" msgid "options_resultProfileForSelectedDomains" msgstr "" msgid "options_pac_profile_unsupported_moz" msgstr "" msgid "popup_issueTemplate" msgstr "" msgid "browserAction_profileDetails_PacProfile" msgstr "" msgid "browserAction_profileDetails_SystemProfile" msgstr "" msgid "browserAction_profileDetails_DirectProfile" msgstr "" msgid "browserAction_profileDetails_SwitchProfile" msgstr "" msgid "browserAction_profileDetails_RuleListProfile" msgstr "" msgid "browserAction_titleNormal" msgstr "" msgid "browserAction_titleWithResult" msgstr "" msgid "browserAction_titleNewerOptions" msgstr "" msgid "browserAction_titleOptionError" msgstr "" msgid "browserAction_titleDownloadFail" msgstr "" msgid "browserAction_titleExternalProxy" msgstr "" msgid "browserAction_titleInspect" msgstr "" msgid "browserAction_defaultRuleDetails" msgstr "(default)" msgid "browserAction_directResult" msgstr "DIRECT" msgid "browserAction_attachedPrefix" msgstr "(RL) " msgid "browserAction_tempRulePrefix" msgstr "(TEMP) " msgid "contextMenu_inspectPage" msgstr "" msgid "contextMenu_inspectFrame" msgstr "" msgid "contextMenu_inspectLink" msgstr "" msgid "contextMenu_inspectElement" msgstr "" msgid "contextMenu_enableQuickSwitch" msgstr "" msgid "about_title" msgstr "" msgid "about_app_description" msgstr "" msgid "about_version" msgstr "" msgid "about_experimental_warning_moz" msgstr "" msgid "about_disclaimer_networkService" msgstr "" msgid "about_disclaimer_privacy" msgstr "" msgid "about_help" msgstr "" msgid "about_copyright" msgstr "" msgid "about_credits" msgstr "" msgid "about_license" msgstr "" "SwitchyOmega é um software gratuito licenciado sob Licença Pública Geral GNU Versão 3 ou posterior." ================================================ FILE: omega-locales/pt_BR/LC_MESSAGES/omega-web.po ================================================ msgid "" msgstr "" "Project-Id-Version: SwitchyOmega 2.3.3\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2015-02-13 10:29+0000\n" "PO-Revision-Date: 2021-07-05 03:34+0000\n" "Last-Translator: Vinicius \n" "Language-Team: Portuguese (Brazil) \n" "Language: pt_BR\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n > 1;\n" "X-Generator: Weblate 4.8-dev\n" msgid "appNameShort" msgstr "SwitchyOmega" msgid "manifest_app_name" msgstr "Proxy SwitchyOmega" msgid "manifest_app_description" msgstr "Gerencie e alterne entre vários proxies com rapidez e facilidade." msgid "manifest_icon_default_title" msgstr "Carregando…" msgid "upgrade_profile_auto" msgstr "Troca Automática" msgid "profile_direct" msgstr "[Direct]" msgid "profile_system" msgstr "[Proxy do Sistema]" msgid "condition_HostWildcardCondition" msgstr "Host curinga" msgid "condition_help_HostWildcardCondition" msgstr "" "Matches de hosts (domínios) por curinga.
O asterisco *" " match de zero ou mais caracteres.
O ponto de interrogação " "? match de exatamente um carácter.

Note que regras " "começando com *. são especialmente tratadas apenas em um host " "com condições curinga.
Exemplo: *.exemplo.com vai dar match " "em www.exemplo.com E também exemplo.com.
Para apenas " "subdomínios , use dois asteriscos como: **.exemplo.com." msgid "condition_HostRegexCondition" msgstr "Host regex" msgid "condition_help_HostRegexCondition" msgstr "" "Parecido com a condição curinga, mas dá matchs em hosts (nomes de domínios) " "por " "regular expression.
As expressões regulares podem ser difíceis de " "construir (e ler).
É recomendado usar curingas para a maioria dos casos " "e usar regex apenas em condições que não pode ser conseguido em nenhum outro " "tipo de condição." msgid "condition_HostLevelsCondition" msgstr "Host levels" msgid "condition_help_HostLevelsCondition" msgstr "" "Matches the request if and only if the host level in within the given range." "
Host level is defined as the number of dot-separated segments of " "the host (domain name).
Example: www.example.com is with a " "host level of 3, while internal is of host level 1." msgid "condition_IpCondition" msgstr "IP Literals" msgid "condition_help_IpCondition" msgstr "" "Matches the request if and only if the host is a literal IP address and" " in the subnet as specified by " "CIDR notation.
For example, given the rule 127.0.0.1/16, " "it matches all IP addresses like 127.0.*.*.
" "So 127.0.0.1 matches while 127.1.0.0 does not. " "Host names like localhost will never match because they are " "not IP literals." msgid "condition_UrlWildcardCondition" msgstr "URL wildcard" msgid "condition_help_UrlWildcardCondition" msgstr "" "Matches URLs of the request by wildcard.
See the Host wildcard section " "above for a quick wildcard reference.
Note that URL wildcards are not " "specially treated (no subdomain magic as in Host wildcard).
So *://" "*.example.com/* matches http://www.example.com/ but does not " "match http://example.com/." msgid "condition_UrlRegexCondition" msgstr "URL regex" msgid "condition_help_UrlRegexCondition" msgstr "" "Matches URL by extremely powerful regular expression.
However, regular " "expressions can be hard to construct (and read).
It is recommended to use " "wildcards for most cases and only use regex for conditions that cannot be " "achieved by any other condition type." msgid "condition_KeywordCondition" msgstr "Palavra chave" msgid "condition_help_KeywordCondition" msgstr "" "A keyword condition matches if the URL protocol is HTTP, and the pattern is " "an exact sub-string of the URL.
It behaves like the URL wildcard pattern " "http://*pattern*, where pattern is the keyword " "pattern.
Keyword conditions are useful if you want to bypass a firewall " "blocking some keywords in the URL, by requesting such URLs through a proxy." msgid "condition_FalseCondition" msgstr "(Desativado)" msgid "condition_details_FalseCondition" msgstr "(Condition ignored when matching)" msgid "condition_help_FalseCondition" msgstr "" "You can disable a condition by setting its type to (Disabled). " "A Disabled condition act as if it does not exist.
This feature can be " "used to disable conditions temporarily.
Disabled conditions still hold " "the previous information (like patterns) and can be re-enabled by setting " "the condition type back to the previous type." msgid "condition_TimeCondition" msgstr "Current Time" msgid "condition_help_TimeCondition" msgstr "" "Matches if the current local time is in the range defined by " "starting hour and ending hour, both inclusive.
" "Local time, starting hour and ending hour are all calculated in " "24-hour format (from 0 to 23).
" "The calculation happens roughly at the moment when the request is sent." msgid "condition_WeekdayCondition" msgstr "Day of the Week" msgid "condition_help_WeekdayCondition" msgstr "" "Matches if the current day of week is selected in condition details. " "Day is calculated according to local timezone.
" "The request and its URL don't matter to this condition. " "The result is solely based on the day of the week when the request is sent." msgid "condition_alert_fullUrlLimitation" msgstr "" "Full URL matching is no longer possible for https:// " "URLs as of Chrome 52. " "" "Learn more..." msgid "condition_alert_fullUrlLimitationLink" msgstr "https://github.com/FelisCatus/SwitchyOmega/wiki/Chromium-Full-URL-Limitation" msgid "condition_group_default" msgstr " " msgid "condition_group_host" msgstr "Host" msgid "condition_group_url" msgstr "Url" msgid "condition_group_special" msgstr "Special" msgid "ruleListFormat_Switchy" msgstr "Switchy" msgid "ruleListFormat_AutoProxy" msgstr "AutoProxy" msgid "ruleList_usageUrl" msgstr "https://github.com/FelisCatus/SwitchyOmega/wiki/RuleListUsage" msgid "ruleList_error_resultNotEnabled" msgstr "Missing '@with result' directive!" msgid "ruleList_error_unknownProfile" msgstr "Unknown profile: $PROFILE$" msgid "ruleList_error_missingResultProfile" msgstr "Missing result profile name at Line $LNO$: $SOURCE$" msgid "ruleList_error_invalidRule" msgstr "Invalid rule at Line $LNO$: $SOURCE$" msgid "ruleList_error_noDefaultRule" msgstr "Missing default rule with catch-all '*' condition!" msgid "dialog_close" msgstr "Close" msgid "dialog_save" msgstr "Save changes" msgid "dialog_ok" msgstr "OK" msgid "dialog_cancel" msgstr "Cancel" msgid "inputClear_clear" msgstr "Clear" msgid "inputClear_restore" msgstr "Restore" msgid "options_title" msgstr "SwitchyOmega Options" msgid "options_experimental_badge" msgstr "α" msgid "options_navHeader_setting" msgstr "Settings" msgid "options_navHeader_profiles" msgstr "Profiles" msgid "options_navHeader_actions" msgstr "Actions" msgid "options_tab_ui" msgstr "Interface" msgid "options_tab_general" msgstr "General" msgid "options_tab_importExport" msgstr "Import/Export" msgid "options_newProfile" msgstr "New profile…" msgid "options_apply" msgstr "Apply changes" msgid "options_discard" msgstr "Discard changes" msgid "options_reset" msgstr "Reset options" msgid "options_group_miscOptions" msgstr "Misc Options" msgid "options_confirmDeletion" msgstr "Confirm on condition deletion." msgid "options_refreshOnProfileChange" msgstr "Refresh current tab on profile change." msgid "options_showInspectMenu" msgstr "Allow inspecting proxy used for page elements via context menu." msgid "options_addConditionsToBottom" msgstr "Put new conditions added using the popup to the bottom of the list." msgid "options_group_keyboardShortcut" msgstr "Keyboard Shortcut" msgid "options_menuShortcutHelp" msgstr "" "Pressing the shortcut will open the switch popup menu. (Defaults to Alt+Shift" "+O)." msgid "options_menuShortcutMore" msgstr "" "The items in the popup menu can also be accessed using the keyboard. Press ? " "(or /) in the menu to learn more." msgid "options_menuShortcutConfigure" msgstr "Configurar atalho" msgid "options_group_switchOptions" msgstr "Opções de alteração" msgid "options_startupProfile" msgstr "Perfil de inicialização" msgid "options_startupProfile_none" msgstr "(Perfil atual)" msgid "options_showConditionTypesAdvanced" msgstr "Show advanced condition types" msgid "options_showConditionTypesAdvancedHelp" msgstr "" "Desbloqueia novos tipos de avançadas, porém complicadas, condições de " "mudança. Para a maioria dos cenários, as condições básicas devem ser " "suficientes, logo esta opção não é recomendada." msgid "options_quickSwitch" msgstr "Quick Switch" msgid "options_cycledProfiles" msgstr "Cycled Profiles" msgid "options_cycledProfilesHelp" msgstr "" "When you click on the icon (or use the shortcut above), the following " "profiles will be applied in their order." msgid "options_cycledProfilesTooFew" msgstr "" "You need to select at least 2 profiles to enable this function! You can drag " "them from the box below." msgid "options_notCycledProfiles" msgstr "Not Cycled Profiles" msgid "options_group_proxyChanges" msgstr "Proxy Changes" msgid "options_revertProxyChanges" msgstr "Revert proxy changes done by other apps." msgid "options_group_conflicts" msgstr "Conflicts" msgid "options_conflicts_introduction" msgstr "" "Sometimes, other apps will also try to control the proxy settings, resulting " "in conflicts. Note that ad blockers and other extensions may also use proxy " "settings under the hood. Such conflicts cannot be avoided due to how the " "browser works." msgid "options_conflicts_lowerPriority" msgstr "" "A red badge like this on the SwitchyOmega icon indicates that another app has " "higher priority so SwitchyOmega cannot control the settings. Please try to " "uninstall SwitchyOmega and reinstall, which should raise SwitchyOmega's " "priority. If you still see conflicts after reinstallation, please consider " "removing the other app causing the conflict." msgid "options_conflicts_higherPriority" msgstr "" "If SwitchyOmega has higher priority, you can give the control back to other " "apps or system settings by selecting $SYSTEMPROFILE$ in the popup menu." msgid "options_showExternalProfile" msgstr "Show popup menu item to import proxy settings from other apps." msgid "options_showExternalProfileHelp" msgstr "" "When $SYSTEMPROFILE$ is selected, you can import the effective proxy settings " "from other apps by selecting $EXTERNALPROFILE$ on the popup menu. " "The settings will be imported as a profile using the name you provide. " "Please note that the imported profile is a snapshot and will not reflect " "any changes from the source app thereafter." msgid "options_group_networkRequests" msgstr "Network Requests" msgid "options_monitorWebRequests" msgstr "Show count of failed web requests for resources in the current tab." msgid "options_monitorWebRequestsHelp" msgstr "" "A yellow badge will be displayed on the icon if some resources fail to load," "
and you can set the profile for such resources conveniently via the " "popup menu." msgid "options_downloadOptions" msgstr "Download Options" msgid "options_downloadOptionsHelp" msgstr "Configure the update frequency of online rule lists and PAC scripts." msgid "options_downloadInterval" msgstr "Download Interval" msgid "options_downloadInterval_15" msgstr "15 Minutes" msgid "options_downloadInterval_60" msgstr "1 Hour" msgid "options_downloadInterval_180" msgstr "3 Hours" msgid "options_downloadInterval_360" msgstr "6 Hours" msgid "options_downloadInterval_720" msgstr "12 Hours" msgid "options_downloadInterval_1440" msgstr "Every day" msgid "options_downloadInterval_never" msgstr "Never" msgid "options_group_importExportProfile" msgstr "Profile" msgid "options_exportPacFile" msgstr "Export as PAC File" msgid "options_exportPacFileHelp" msgstr "" "Export the current profile as a PAC file, so you can use it in other " "browsers." msgid "options_exportProfileHelp" msgstr "To export a profile, use the top-right action bar on the profile page." msgid "options_exportLegacyRuleList" msgstr "" "Export rule lists using Proxy Switchy!/SwitchyPlus/SwitchySharp compatible " "format when possible." msgid "options_exportLegacyRuleListHelp" msgstr "" "Enable this option only if you publish rule lists for users of those " "projects.
Please consider advising your audience to upgrade to " "SwitchyOmega for the improvements." msgid "options_group_importExportSettings" msgstr "Settings" msgid "options_makeBackup" msgstr "Make backup" msgid "options_makeBackupHelp" msgstr "" "Make a full backup of your options (including profiles and all other " "options)." msgid "options_restoreLocal" msgstr "Restore from file" msgid "options_restoreLocalHelp" msgstr "Restore your SwitchyOmega options from a local file." msgid "options_restoreOnline" msgstr "Restore from online" msgid "options_restoreOnlinePlaceholder" msgstr "Options file URL (e.g. 'http://example.com/switchy.bak')" msgid "options_restoreOnlineSubmit" msgstr "Restore" msgid "options_group_syncing" msgstr "Syncing (Experimental)" msgid "options_syncEnable" msgstr "Enable Syncing" msgid "options_syncEnableForce" msgstr "Download from Syncing" msgid "options_syncDisable" msgstr "Disable syncing" msgid "options_syncReset" msgstr "Clear remote copy" msgid "options_syncPristineHelp" msgstr "" "You can now automatically synchronize your settings and profiles across all " "your desktop devices running Chrome browser." msgid "options_syncSyncAlert" msgstr "Your options are automatically synchronized with your other devices." msgid "options_syncSyncHelp" msgstr "" "Please note that you must sign in to Chrome on each of your devices " "(including this one) for the syncing to actually work.
You may check " "this section on other devices to ensure that it is working." msgid "options_syncConflictAlert" msgstr "" "You have uploaded a copy of your options on another device via syncing." msgid "options_syncConflictHelp" msgstr "" "You may download the remote copy to your device if you like.
However, " "doing so would overwrite your existing settings and profiles on this " "device." msgid "options_syncUnsupportedHelp" msgstr "" "Options syncing is not supported on your platform or browser. For now, only " "Chrome browser on desktop is supported." msgid "options_profileSyncDisabled" msgstr "Syncing is disabled for this profile." msgid "options_profileSyncDisabled_quotaPerItem" msgstr "Syncing is disabled for this profile for using too much storage space." msgid "options_profileTabPrefix" msgstr "Profile :: " msgid "options_renameProfile" msgstr "Rename" msgid "options_deleteProfile" msgstr "Delete" msgid "options_profileExportRuleList" msgstr "Publish rule list" msgid "options_profileExportRuleListHelp" msgstr "Export Switch Rules as text format for publishing." msgid "options_profileExportPac" msgstr "Export PAC" msgid "options_profileUnsupported" msgstr "Unsupported profile type $TYPE$!" msgid "options_profileUnsupportedHelp" msgstr "The options could be broken, or from a newer version of this program." msgid "options_profileEditSource" msgstr "Edit source code" msgid "options_profileEditSourceHelp" msgstr "Show help about the source code format" msgid "options_profileEditSourceHelpUrl" msgstr "" "https://github.com/FelisCatus/SwitchyOmega/wiki/SwitchyOmega-conditions-" "format#result-profile" msgid "options_group_proxyServers" msgstr "Proxy servers" msgid "options_proxy_scheme" msgstr "Scheme" msgid "options_proxy_protocol" msgstr "Protocol" msgid "options_proxy_server" msgstr "Server" msgid "options_proxy_port" msgstr "Port" msgid "options_proxy_auth" msgstr "Authentication" msgid "options_proxy_authNotSupported" msgstr "Your browser DOES NOT support $PROTOCOLDISP$ proxy authentication! " "Please do not report this issue to SwitchyOmega. Contact the support for " "your browser instead." msgid "options_proxy_authAllWarningPac" msgstr "" "Warning: The username/password may be sent to unexpected servers returned by " "the PAC script." msgid "options_proxy_authAllWarningPacUrl" msgstr "" "Please make sure that you trust the script provided via the URL above before " "entering sensitive credentials." msgid "options_proxy_authAllWarningPacScript" msgstr "" "Please make sure that you trust the script below before providing sensitive " "credentials." msgid "options_proxy_authReferencedWarning" msgstr "" "Additionally, using this profile in other profiles (e.g. Switch Profile) may " "cause the username/password to be sent to proxy servers configured in other " "profiles." msgid "options_scheme_default" msgstr "(default)" msgid "options_protocol_direct" msgstr "DIRECT" msgid "options_protocol_useDefault" msgstr "(use default)" msgid "options_proxy_single" msgstr "Use the proxy above for all protocols." msgid "options_proxy_expand" msgstr "Show Advanced" msgid "options_group_bypassList" msgstr "Bypass List" msgid "options_bypassListHelp" msgstr "" "Servers for which you do not want to use any proxy: (One server on each " "line.)" msgid "options_bypassListHelpLinkText" msgstr "(Wildcards and more available…)" msgid "options_group_pacUrl" msgstr "PAC URL" msgid "options_pacUrlHelp" msgstr "" "The PAC script will be updated from this URL. If it is left blank, the " "following script will be used directly instead." msgid "options_pacUrlFile" msgstr "" "PAC profiles with file: URLs can only be applied directly. They cannot be " "used as result profiles because local files cannot be accessed due to " "browser limitation." msgid "options_pacUrlFileDisabled" msgstr "" "Therefore, you cannot use local PAC file for this profile. You can create a " "new PAC profile for that if you really want that." msgid "options_group_pacScript" msgstr "PAC Script" msgid "options_pacScriptLastUpdate" msgstr "PAC script downloaded at $TIME$:" msgid "options_pacScriptObsolete" msgstr "" "PAC script is obsolete due to URL change. Press the download button above to " "update." msgid "options_group_virtualProfile" msgstr "Virtual Profile" msgid "options_virtualProfileTarget" msgstr "Target" msgid "options_virtualProfileTargetHelp" msgstr "" "When this profile is applied, it acts exactly the same as the profile " "selected below." msgid "options_group_virtualProfileReplace" msgstr "Migrate to Virtual Profile" msgid "options_virtualProfileReplace" msgstr "Replace target profile" msgid "options_virtualProfileReplaceHelp" msgstr "" "You can migrate existing options to use this virtual profile instead of " "$PROFILE$. Doing so will update all existing rules concerning $PROFILE$ and " "point them to this virtual profile, so that their result profile can be " "controlled here." msgid "options_group_ruleListConfig" msgstr "Rule List Config" msgid "options_ruleListFormat" msgstr "Rule List Format" msgid "options_group_ruleListResult" msgstr "Rule list result profiles" msgid "options_ruleListMatchProfile" msgstr "Match profile" msgid "options_ruleListDefaultProfile" msgstr "Default profile" msgid "options_group_ruleListUrl" msgstr "Rule List URL" msgid "options_ruleListUrlHelp" msgstr "" "The rule list will be updated from this URL. If it is left blank, the " "following text will be parsed instead." msgid "options_group_ruleListText" msgstr "Rule List Text" msgid "options_ruleListLastUpdate" msgstr "Rule list downloaded at $TIME$:" msgid "options_ruleListObsolete" msgstr "" "Rule list is obsolete due to URL change. Press the download button above to " "update." msgid "options_group_switchRules" msgstr "Switch rules" msgid "options_sort" msgstr "Sort" msgid "options_conditionType" msgstr "Condition Type" msgid "options_showConditionTypeHelp" msgstr "Show help" msgid "options_conditionDetails" msgstr "Condition Details" msgid "options_resultProfile" msgstr "Profile" msgid "options_conditionActions" msgstr "Actions" msgid "options_addCondition" msgstr "Add condition" msgid "options_cloneRule" msgstr "Clone" msgid "options_ruleNote" msgstr "Note" msgid "options_switchAttachedProfileInCondition" msgstr "Rule list rules" msgid "options_switchAttachedProfileInConditionDetails" msgstr "(Any request matching the rule list below)" msgid "options_switchAttachedProfileInConditionDisabled" msgstr "(Rule list rules are DISABLED)" msgid "options_switchDefaultProfile" msgstr "Default" msgid "options_hostLevelsBetween" msgstr "≤ host levels ≤" msgid "options_hourBetween" msgstr "≤ current hour ≤" msgid "options_weekDayShort_0" msgstr "Su" msgid "options_weekDayShort_1" msgstr "Mo" msgid "options_weekDayShort_2" msgstr "Tu" msgid "options_weekDayShort_3" msgstr "We" msgid "options_weekDayShort_4" msgstr "Th" msgid "options_weekDayShort_5" msgstr "Fr" msgid "options_weekDayShort_6" msgstr "Sa" msgid "options_group_conditionHelp" msgstr "About Condition Types" msgid "options_group_attachProfile" msgstr "Import online rule lists" msgid "options_attachProfile" msgstr "Add a rule list" msgid "options_attachProfileHelp" msgstr "" "You can reuse an online collection of conditions published by others by " "adding a rule list." msgid "options_modalHeader_welcome" msgstr "Welcome to SwitchyOmega" msgid "options_welcomeNormal" msgstr "" "You have successfully installed SwitchyOmega, the ultimate proxy switcher." msgid "options_welcomeNormalGuide" msgstr "" "Please tell SwitchyOmega about your proxies through the options page. Let's " "see how." msgid "options_welcomeUpgrade" msgstr "" "You have successfully upgraded to SwitchyOmega. Don't panic, your existing " "options are fully preserved." msgid "options_welcomeUpgradeGuide" msgstr "Now let's go through a quick guide of the new options page." msgid "options_guideNext" msgstr "Next" msgid "options_guideDone" msgstr "Done" msgid "options_guideSkip" msgstr "Skip guide" msgid "options_modalHeader_applyOptions" msgstr "Apply Options" msgid "options_optionsNotSaved" msgstr "" "Your modifications to the options have not been saved and will be lost if " "you proceed!" msgid "options_applyOptionsRequired" msgstr "Your changes to the options must be applied before you proceed." msgid "options_applyOptionsConfirm" msgstr "Do you want to save and apply the options?" msgid "options_modalHeader_renameProfile" msgstr "Rename Profile" msgid "options_renameProfileName" msgstr "New profile name" msgid "options_profileNameConflict" msgstr "A profile with this name already exists." msgid "options_profileNameReserved" msgstr "Profile names beginning with double-underscore are reserved." msgid "options_profileNameHidden" msgstr "" "Profiles with names starting with underscore will be hidden on the popup " "menu. However, they can still be used in places like switch profile results." msgid "options_modalHeader_replaceProfile" msgstr "Replace Profile" msgid "options_replaceProfile" msgstr "Replace Profile" msgid "options_replaceProfileConfirm" msgstr "Do you really want to replace $FromProfile$ with $ToProfile$?" msgid "options_replaceProfileHelp" msgstr "" "If you proceed, all rules pointing to $FromProfile$ will be updated to use " "$ToProfile$ instead. Other options, such as startup profile and Quick Switch " "will also be modified as appropriate. However, the two profile themselves " "will NOT be changed or deleted." msgid "options_replaceProfileSuccess" msgstr "Options updated." msgid "options_modalHeader_deleteProfile" msgstr "Delete Profile" msgid "options_deleteProfileConfirm" msgstr "Do you really want to delete the following profile?" msgid "options_modalHeader_cannotDeleteProfile" msgstr "Unable to Delete Profile" msgid "options_profileReferredBy" msgstr "" "This profile cannot be deleted because it is referred by the following " "profiles:" msgid "options_modifyReferringProfiles" msgstr "" "You must modify these profiles and make them stop referring to this profile " "before you can delete it." msgid "options_profileNameEmpty" msgstr "The name of the profile must not be empty." msgid "popup_title" msgstr "SwitchyOmega Popup" msgid "options_modalHeader_proxyAuth" msgstr "Proxy Authentication" msgid "options_proxyAuthUsername" msgstr "Username" msgid "options_proxyAuthPassword" msgstr "Password" msgid "options_proxyAuthShowPassword" msgstr "Show password" msgid "options_proxyAuthHidePassword" msgstr "Hide password" msgid "options_proxyAuthNone" msgstr "No Authentication" msgid "options_modalHeader_deleteRule" msgstr "Delete Rule" msgid "options_deleteRuleConfirm" msgstr "Do you really want to delete the following rule?" msgid "options_deleteRule" msgstr "Delete" msgid "options_modalHeader_resetRules" msgstr "Reset rules" msgid "options_resetRulesConfirm" msgstr "" "Are you sure to set the result profile of ALL rules to the following profile?" msgid "options_resetRules" msgstr "Reset rules" msgid "options_resetRules_help" msgstr "Set profile for all rules" msgid "options_modalHeader_deleteAttached" msgstr "Remove Rule List" msgid "options_deleteAttachedConfirm" msgstr "Do you really want to remove the rule list from the current profile?" msgid "options_ruleListLineCount" msgstr "$COUNT$ line(s) of rules" msgid "options_deleteAttached" msgstr "Remove rule list" msgid "options_modalHeader_newProfile" msgstr "New Profile" msgid "options_newProfileName" msgstr "Profile name" msgid "options_profileType" msgstr "Please select the type of the profile:" msgid "options_profileTypeFixedProfile" msgstr "Proxy Profile" msgid "options_profileDescFixedProfile" msgstr "Tunneling traffic through proxy servers." msgid "options_profileTypePacProfile" msgstr "PAC Profile" msgid "options_profileDescPacProfile" msgstr "Choosing proxies using an online/local PAC script." msgid "options_profileDescMorePacProfile" msgstr "" "You will only need this if you have a PAC script or a URL to it. Don't try " "to create one unless you have knowledge about PAC." msgid "options_profileTypeSwitchProfile" msgstr "Switch Profile" msgid "options_profileDescSwitchProfile" msgstr "" "Applying different profiles automatically on various conditions such as " "domains or patterns.\n" " You can also import rules published online for easier switching. (Replaces " "AutoSwitch mode + Rule List.)" msgid "options_profileTypeRuleListProfile" msgstr "Rule List Profile" msgid "options_profileDescRuleListProfile" msgstr "Reusing an online collection of conditions published by others." msgid "options_profileTypeVirtualProfile" msgstr "Virtual Profile" msgid "options_profileDescVirtualProfile" msgstr "" "A virtual profile can act as any of the other profiles on demand. It works " "well with SwitchProfile, allowing you to change the result of multiple " "conditions by one click." msgid "options_createProfile" msgstr "Create" msgid "options_modalHeader_resetOptions" msgstr "Reset Options" msgid "options_resetOptionsConfirm" msgstr "" "Do you really want to reset the options? All profiles and settings will be " "LOST!" msgid "options_formInvalid" msgstr "Please correct the errors in this page." msgid "options_profileNotFound" msgstr "Profile $PROFILE$ does not exist! The options may be corrupted." msgid "options_resetSuccess" msgstr "Options reset." msgid "options_saveSuccess" msgstr "Options saved." msgid "options_importSuccess" msgstr "Options imported." msgid "options_importFormatError" msgstr "Invalid backup file!" msgid "options_importDownloadError" msgstr "Error downloading backup file!" msgid "options_profileDownloadSuccess" msgstr "Successfully updated profile." msgid "options_profileDownloadError" msgstr "Error downloading profile data!" msgid "options_profileDownloadError_NetworkError" msgstr "A network error occurred when updating." msgid "options_profileDownloadError_HttpError" msgstr "An HTTP error ($STATUS$) occurred when updating." msgid "options_profileDownloadError_HttpNotFoundError" msgstr "The Profile URL was not found on the server. Please double-check." msgid "options_profileDownloadError_HttpServerError" msgstr "The remote server responded with error ($STATUS$) when updating." msgid "options_profileDownloadError_ContentTypeRejectedError" msgstr "The downloaded data is invalid! " "You may open the Profile URL in your browser to inspect it." msgid "options_downloadProfileNow" msgstr "Download Profile Now" msgid "options_guide_fixedProfileStep" msgstr "" "A Proxy Profile contains settings like server ip & port for proxy." "
Profiles are the the basic configuration units in SwitchyOmega.
We " "have already created an example profile for you. Try opening it." msgid "options_guide_fixedServersStep" msgstr "" "You can fill in your proxy server and port here as you like.
SwitchyOmega " "does not come with any proxy servers.
Please consult your network " "provider or proxy software manual if you don't know what should be filled in " "here." msgid "options_guide_autoSwitchProfileStep" msgstr "" "You can tell SwitchyOmega to switch between proxies automatically through " "the mighty Switch Profile.
However, its features cannot be covered " "in this quick guide.
You can open this profile to unlock its power some " "time later." msgid "options_guide_addMoreProfilesStep" msgstr "" "Need more profiles? You can always add more Proxy, Switch and other " "profiles
for all your proxying needs.
Enjoy proxying!" msgid "options_guide_conditionStep" msgstr "" "SwitchyOmega can apply different profiles to requests based on " "conditions.
For example, the Host wildcard condition " "allows you to set the profile for all URLs in a domain." msgid "options_guide_conditionTypeStep" msgstr "" "You can use various condition types to match the host or full URL.
" "Click on the question mark to open the type reference." msgid "options_guide_conditionProfileStep" msgstr "" "SwitchyOmega applies the selected profile here to any request matching " "the condition.
The special \"[Direct]\" profile will cause " "the request to be sent without any proxy." msgid "options_guide_switchDefaultStep" msgstr "" "If no condition applies to some request, the \"Default\" profile will be " "used.
Conditions are always considered from top to bottom in " "order.
You can change their order by dragging the sort icon." msgid "options_guide_applySwitchProfileStep" msgstr "" "When you are done setting the switch profile, don't forget to switch to " "it in the popup menu.
The icon will show you the final result profile applied for the current tab.
Hovering on the icon " "will reveal a tooltip with details." msgid "popup_externalProfile" msgstr "(External Profile)" msgid "popup_externalProfileName" msgstr "profile name" msgid "popup_proxyNotControllable_app" msgstr "" "The proxy settings are controlled by other app(s) or extension(s). Please " "disable or uninstall the apps or extensions in conflict." msgid "popup_proxyNotControllable_policy" msgstr "" "The proxy settings are overruled by policies. Please contact your " "administrator." msgid "popup_proxyNotControllable_unknown" msgstr "" "The proxy settings cannot be controlled. Please check your system and " "browser settings." msgid "popup_proxyNotControllable_disabled" msgstr "" "The proxy settings are disabled by explicit request from other app(s) or " "extension(s)." msgid "popup_proxyNotControllable_upgrade" msgstr "Proxy settings are now controlled by a newer version of SwitchyOmega." msgid "popup_proxyNotControllableDetails" msgstr "" "You cannot switch profiles with SwitchyOmega unless you fix the problem " "above." msgid "popup_proxyNotControllableDetails_upgrade" msgstr "" "You can't enable two (or more) versions of SwitchyOmega at the same time. " "Please disable one of them." msgid "popup_proxyNotControllableManage" msgstr "Manage extensions" msgid "popup_addConditionTo" msgstr "Add condition to" msgid "popup_addCondition" msgstr "Add condition" msgid "popup_showOptions" msgstr "Options" msgid "popup_reportIssues" msgstr "Report issues" msgid "popup_errorLog" msgstr "Save error log" msgid "popup_requestErrorCount" msgstr "$COUNT$ failed resources" msgid "popup_requestErrorHeading" msgstr "Resources that failed to load" msgid "popup_requestErrorWarning" msgstr "" "A few resources failed to load due to issues with your network, proxy server " "or the webpage." msgid "popup_requestErrorWarningHelp" msgstr "" "SwitchyOmega is just the reporter of these issues, not the cause of them." msgid "popup_requestErrorAddCondition" msgstr "" "You can review the following domains and use proxy for them when appropriate." msgid "popup_requestErrorCannotAddCondition" msgstr "" "You can add switch conditions for them only when using a Switch Profile." msgid "popup_configureMonitorWebRequests" msgstr "Configure Network Monitor" msgid "options_resultProfileForSelectedDomains" msgstr "Use this profile for all selected domains" msgid "options_pac_profile_unsupported_moz" msgstr "PAC Profiles WILL NOT work in Mozilla Firefox due to technical limitations!" msgid "popup_issueTemplate" msgstr "" "\n" "\n" "\n" "\n" "SwitchyOmega $projectVersion$\n" "$userAgent$" msgid "browserAction_profileDetails_PacProfile" msgstr "(PAC script)" msgid "browserAction_profileDetails_SystemProfile" msgstr "(controlled by other extensions or environment)" msgid "browserAction_profileDetails_DirectProfile" msgstr "(not using any proxy)" msgid "browserAction_profileDetails_SwitchProfile" msgstr "(switching based on conditions)" msgid "browserAction_profileDetails_RuleListProfile" msgstr "(switching based on rule list)" msgid "browserAction_titleNormal" msgstr "SwitchyOmega:: $PROFILE$" msgid "browserAction_titleWithResult" msgstr "" "SwitchyOmega:: $1:PROFILE$\n" "$3:DETAILS$" msgid "browserAction_titleNewerOptions" msgstr "" "ERROR: A newer version of SwitchOmega is required to load the stored options." msgid "browserAction_titleOptionError" msgstr "ERROR: The stored options are corrupted. Click here to RESET OPTIONS." msgid "browserAction_titleDownloadFail" msgstr "Warning: Failed to download PAC scripts and/or rule lists." msgid "browserAction_titleExternalProxy" msgstr "Note: The proxy settings are currently controlled by other app(s)." msgid "browserAction_titleInspect" msgstr "[Inspect] $URL$" msgid "browserAction_defaultRuleDetails" msgstr "(default)" msgid "browserAction_directResult" msgstr "DIRECT" msgid "browserAction_attachedPrefix" msgstr "(RL) " msgid "browserAction_tempRulePrefix" msgstr "(TEMP) " msgid "contextMenu_inspectPage" msgstr "Inspect proxy used for this page" msgid "contextMenu_inspectFrame" msgstr "Inspect proxy used for this Frame" msgid "contextMenu_inspectLink" msgstr "Inspect proxy to be used if this Link is opened" msgid "contextMenu_inspectElement" msgstr "Inspect proxy used for this Element" msgid "contextMenu_enableQuickSwitch" msgstr "Enable Quick Switch" msgid "about_title" msgstr "About" msgid "about_app_description" msgstr "A proxy configuration tool" msgid "about_version" msgstr "Version $VERSION$" msgid "about_experimental_warning_moz" msgstr "Mozilla Firefox support is highly experimental! If you encounter issues, please report using the buttons below." msgid "about_disclaimer_networkService" msgstr "SwitchyOmega does not provide proxies, VPNs, or other network services." msgid "about_disclaimer_privacy" msgstr "SwitchyOmega does not track you or insert ads into webpages. Please see" " our privacy policy." msgid "about_help" msgstr "Other questions? Need help with using SwitchyOmega? Please see our " "FAQ." msgid "about_copyright" msgstr "Copyright 2012-2017 The SwitchyOmega Authors. All rights reserved." msgid "about_credits" msgstr "SwitchyOmega is made possible by the SwitchyOmega open source project and other open source software." msgid "about_license" msgstr "" "SwitchyOmega é um software gratuito licenciado sob Licença Pública Geral GNU Versão 3 ou posterior." ================================================ FILE: omega-locales/ru/LC_MESSAGES/omega-web.po ================================================ msgid "" msgstr "" "Project-Id-Version: Russian (SwitchyOmega)\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2017-11-21 02:34+0200\n" "PO-Revision-Date: 2022-07-13 08:19+0000\n" "Last-Translator: MΛX \n" "Language-Team: Russian \n" "Language: ru\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" "%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" "X-Generator: Weblate 4.14-dev\n" msgid "appNameShort" msgstr "SwitchyOmega" msgid "manifest_app_name" msgstr "Прокси SwitchyOmega" msgid "manifest_app_description" msgstr "Управляйте и переключайтесь между прокси-серверами быстро и легко." msgid "manifest_icon_default_title" msgstr "Загрузка…" msgid "upgrade_profile_auto" msgstr "Автопереключение" msgid "profile_direct" msgstr "[Напрямую]" msgid "profile_system" msgstr "[Системный прокси]" msgid "condition_HostWildcardCondition" msgstr "Шаблон хоста" msgid "condition_help_HostWildcardCondition" msgstr "" "Проверяет хосты (доменные имена) на соответствие шаблону.
Звёздочка " "* заменяет нуль или более символов.
Знак вопроса " "? заменяет ровно один символ.

Обратите внимание, что " "правила, начинающиеся с *., обрабатываются особо только в " "шаблонах хоста.
Пример: *.example.com сопоставит как " "www.example.com, ТАК И example.com.
Для того, чтобы сопоставить " "только поддомены, используйте две звёздочки: **.example." "com." msgid "condition_HostRegexCondition" msgstr "Регулярное выражение хоста" msgid "condition_help_HostRegexCondition" msgstr "" "Подобно шаблону хоста, но проверяет на совпадение хосты (доменные имена) с " "регулярным " "выражением.
Регулярные выражения бывает трудно составить (и прочитать)" ".
Поэтому регулярные выражения рекомендуется использовать только для тех " "условий, которые не могут быть выражены другими методами." msgid "condition_HostLevelsCondition" msgstr "Уровни хоста" msgid "condition_help_HostLevelsCondition" msgstr "" "Соответствует запросу только тогда, когда уровень хоста находится в заданном " "диапазоне.
Уровень хоста определяется как число разделённых точками " "сегментов хоста (доменного имени).
Пример: www.example.com имеет уровень хоста 3, а internal имеет уровень хоста 1." msgid "condition_IpCondition" msgstr "Маска IP" msgid "condition_help_IpCondition" msgstr "" "Соответствует запросу только тогда, если хост является числовым " "представлением IP-адресом и находится в подсети, как указано в записи CIDR.
Например, правило 127.0.0.1/16 соответствует всем IP-адресам как 127.0.*.*.
Таким " "образом 127.0.0.1 соответствует запросу, а 127.1.0.0 – нет. Имена хостов, такие как localhost, никогда не " "будут соответствовать запросу, потому что они не заданы числом IP." msgid "condition_UrlWildcardCondition" msgstr "Шаблон URL" msgid "condition_help_UrlWildcardCondition" msgstr "" "Проверяет URL-адреса запроса на соответствие шаблону.
Смотрите пример " "шаблона хоста в разделе выше для быстрого создания шаблона для " "ссылки.
Обратите внимание, что шаблон URL-адреса не обрабатываются " "специальным образом (нет «магии» с поддоменами, как в шаблоне хоста)" ".
Таким образом шаблон *://*.example.com/* соответствует " "http://www.example.com/ но не соответствует http://example.com/." msgid "condition_UrlRegexCondition" msgstr "Регулярное выражение URL" msgid "condition_help_UrlRegexCondition" msgstr "" "Сопоставляет URL-адрес с помощью чрезвычайно мощных регулярных выражений.
Однако, регулярные выражения сложно составлять (и читать).
В " "большинстве случаев рекомендуется использовать шаблоны, а регулярные " "выражения использовать только для тех случаев, где без них невозможно " "обойтись." msgid "condition_KeywordCondition" msgstr "Ключевое слово" msgid "condition_help_KeywordCondition" msgstr "" "Соответствует значению ключевого слова для URL с протоколом HTTP, а слово " "является частью URL-адреса.
Он ведёт себя подобно шаблону URL. Пример: " "http://*ключевое слово*.
Ключевые слова полезны, если " "вы хотите обойти брандмауэр, блокирующий некоторые ключевые слова в URL-" "адресе, запрашивая такие URL-адреса через прокси." msgid "condition_FalseCondition" msgstr "(Отключено)" msgid "condition_details_FalseCondition" msgstr "(Условие игнорируется при сопоставлении)" msgid "condition_help_FalseCondition" msgstr "" "Вы можете отключить условие, установив его тип в состояние " "(Отключено). Отключённое условие действует так, как если бы его " "не существовало.
Эту функцию можно использовать для временного отключения " "условий.
Отключённые условия по-прежнему содержат информацию (например, " "шаблоны) и могут быть повторно включены путём возврата к предыдущему типу." msgid "condition_TimeCondition" msgstr "Текущее время" msgid "condition_help_TimeCondition" msgstr "" "Соответствует, если текущее местное время находится в диапазоне, " "определяемом начальным часом и конечным часом, " "включительно.
Местное время, начальный час и конечный час рассчитываются " "в 24-часовом формате (от 0 до 23).
Расчёт происходит " "примерно в момент отправки запроса." msgid "condition_WeekdayCondition" msgstr "День недели" msgid "condition_help_WeekdayCondition" msgstr "" "Соответствует, если текущий день недели выбран в деталях условия. " "День рассчитывается в соответствии с местным часовым поясом.
Запрос и его " "URL-адрес не имеют значения для этого условия. Результат основывается " "исключительно на дне недели, когда отправляется запрос." msgid "condition_alert_fullUrlLimitation" msgstr "" "Полное соответствие URL-адреса больше не возможно для https://, " "начиная с Chrome 52.
Узнать больше…" msgid "condition_alert_fullUrlLimitationLink" msgstr "https://github.com/FelisCatus/SwitchyOmega/wiki/Chromium-Full-URL-Limitation" msgid "condition_group_default" msgstr " " msgid "condition_group_host" msgstr "Хост" msgid "condition_group_url" msgstr "URL-адрес" msgid "condition_group_special" msgstr "Особые" msgid "ruleListFormat_Switchy" msgstr "Переключающийся" msgid "ruleListFormat_AutoProxy" msgstr "Автопрокси" msgid "ruleList_usageUrl" msgstr "https://github.com/FelisCatus/SwitchyOmega/wiki/RuleListUsage" msgid "ruleList_error_resultNotEnabled" msgstr "Отсутствует директива «@with result»!" msgid "ruleList_error_unknownProfile" msgstr "Неизвестный профиль: $PROFILE$" msgid "ruleList_error_missingResultProfile" msgstr "Отсутствует имя профиля в строке $LNO$: $SOURCE$" msgid "ruleList_error_invalidRule" msgstr "Некорректное правило в строке $LNO$: $SOURCE$" msgid "ruleList_error_noDefaultRule" msgstr "Отсутствует правило для условия «*»!" msgid "dialog_close" msgstr "Закрыть" msgid "dialog_save" msgstr "Сохранить изменения" msgid "dialog_ok" msgstr "ОК" msgid "dialog_cancel" msgstr "Отмена" msgid "inputClear_clear" msgstr "Очистить" msgid "inputClear_restore" msgstr "Восстановить" msgid "options_title" msgstr "Параметры SwitchyOmega" msgid "options_experimental_badge" msgstr "α" msgid "options_navHeader_setting" msgstr "Настройки" msgid "options_navHeader_profiles" msgstr "Профили" msgid "options_navHeader_actions" msgstr "Действия" msgid "options_tab_ui" msgstr "Интерфейс" msgid "options_tab_general" msgstr "Основные" msgid "options_tab_importExport" msgstr "Импорт и экспорт" msgid "options_newProfile" msgstr "Новый профиль…" msgid "options_apply" msgstr "Применить изменения" msgid "options_discard" msgstr "Отклонить изменения" msgid "options_reset" msgstr "Сбросить параметры" msgid "options_group_miscOptions" msgstr "Прочие настройки" msgid "options_confirmDeletion" msgstr "Требовать подтверждения при удалении условия." msgid "options_refreshOnProfileChange" msgstr "Обновить текущую вкладку при изменении профиля." msgid "options_showInspectMenu" msgstr "" "Узнавать прокси, использованный для элемента страницы, через контекстное " "меню." msgid "options_addConditionsToBottom" msgstr "" "Помещать новые условия, добавленные через всплывающее окно, в низ списка." msgid "options_group_keyboardShortcut" msgstr "Горячая клавиша" msgid "options_menuShortcutHelp" msgstr "" "Нажатие горячей клавиши откроет всплывающее меню SwitchyOmega. (По умолчанию " "Alt+Shift+O)." msgid "options_menuShortcutMore" msgstr "" "Элементы всплывающего меню также доступны с клавиатуры. Находясь в меню, " "нажмите ? (или /) , чтобы узнать больше." msgid "options_menuShortcutConfigure" msgstr "Настройка горячей клавиши" msgid "options_group_switchOptions" msgstr "Настройки переключения" msgid "options_startupProfile" msgstr "Профиль при запуске" msgid "options_startupProfile_none" msgstr "(Текущий профиль)" msgid "options_showConditionTypesAdvanced" msgstr "Показывать расширенные типы условий" msgid "options_showConditionTypesAdvancedHelp" msgstr "" "Разблокирует новые типы передовых, но сложных условий переключения. Для " "большинства сценариев основных типов условий должно быть достаточно, поэтому " "включать этот параметр не рекомендуется." msgid "options_quickSwitch" msgstr "Быстрое переключение" msgid "options_cycledProfiles" msgstr "Задействованные профили" msgid "options_cycledProfilesHelp" msgstr "" "Когда вы нажмёте на значок (или используете горячую клавишу), следующие " "профили будут применяться в заданном порядке." msgid "options_cycledProfilesTooFew" msgstr "" "Вам нужно выбрать минимум 2 профиля, чтобы включить эту функцию! Вы можете " "перетащить их из поля ниже." msgid "options_notCycledProfiles" msgstr "Незадействованные профили" msgid "options_group_proxyChanges" msgstr "Изменения прокси" msgid "options_revertProxyChanges" msgstr "Отменить изменения прокси, сделанные другими приложениями." msgid "options_group_conflicts" msgstr "Конфликты" msgid "options_conflicts_introduction" msgstr "" "Иногда другие приложения также пытаются управлять настройками прокси, что " "приводит к конфликтам. Обратите внимание, что блокировщики рекламы и другие " "расширения тоже могут задавать свои настройки прокси. Таких конфликтов " "избежать невозможно в силу глубинной природы браузера." msgid "options_conflicts_lowerPriority" msgstr "" "Такая красная метка на значке SwitchyOmega указывает, что другое приложение " "имеет более высокий приоритет, поэтому SwitchyOmega не может управлять " "настройками. Попробуйте удалить и переустановить SwitchyOmega. Это должно " "повысить его приоритет. Если после переустановки вы все ещё видите " "предупреждение, рассмотрите возможность удаления другого приложения, " "вызывающего конфликт." msgid "options_conflicts_higherPriority" msgstr "" "Если SwitchyOmega имеет более высокий приоритет, вы можете вернуть " "управление другим приложениям или системным настройкам, выбрав " "$SYSTEMPROFILE$ в всплывающем меню." msgid "options_showExternalProfile" msgstr "" "Показывать пункт всплывающего меню для импорта настроек прокси из других " "приложений." msgid "options_showExternalProfileHelp" msgstr "" "Когда выбран $SYSTEMPROFILE$, вы можете импортировать действующие настройки " "прокси из других приложений, выбрав $EXTERNALPROFILE$ в всплывающем меню. " "Настройки будут импортированы, как профиль, с указанным вами именем. " "Обратите внимание, что импортированный профиль является слепком, и не будет " "отражать какие-либо изменения, сделанные после импорта в исходном приложении." msgid "options_group_networkRequests" msgstr "Сетевые запросы" msgid "options_monitorWebRequests" msgstr "Показывать счётчик неудавшихся веб-запросов на текущей вкладке." msgid "options_monitorWebRequestsHelp" msgstr "" "Если какие-то ресурсы не удалось загрузить, на значке появится жёлтый " "счётчик.
Вы можете настроить профиль для таких ресурсов через всплывающее " "меню." msgid "options_downloadOptions" msgstr "Параметры загрузки" msgid "options_downloadOptionsHelp" msgstr "Настройка частоты обновления онлайн-списков правил и сценариев PAC." msgid "options_downloadInterval" msgstr "Интервал загрузки" msgid "options_downloadInterval_15" msgstr "15 минут" msgid "options_downloadInterval_60" msgstr "1 час" msgid "options_downloadInterval_180" msgstr "3 часа" msgid "options_downloadInterval_360" msgstr "6 часов" msgid "options_downloadInterval_720" msgstr "12 часов" msgid "options_downloadInterval_1440" msgstr "Ежедневно" msgid "options_downloadInterval_never" msgstr "Никогда" msgid "options_group_importExportProfile" msgstr "Профиль" msgid "options_exportPacFile" msgstr "Экспортировать как PAC-файл" msgid "options_exportPacFileHelp" msgstr "" "Экспортируйте текущий профиль как PAC-файл, чтобы использовать его в других " "браузерах." msgid "options_exportProfileHelp" msgstr "" "Чтобы экспортировать профиль, используйте панель действий в верхнем правом " "углу страницы профиля." msgid "options_exportLegacyRuleList" msgstr "" "Экспортировать списки правил, используя совместимый с Proxy Switchy!/" "SwitchyPlus/SwitchySharp формат, когда это возможно." msgid "options_exportLegacyRuleListHelp" msgstr "" "Включайте эту функцию, только если вы публикуете списки правил для " "пользователей этих проектов.
Не стесняйтесь советовать вашим знакомым " "перейти на SwitchyOmega." msgid "options_group_importExportSettings" msgstr "Настройки" msgid "options_makeBackup" msgstr "Создать резервную копию" msgid "options_makeBackupHelp" msgstr "" "Создание полной резервной копии ваших параметров (включая профили и все " "другие настройки)." msgid "options_restoreLocal" msgstr "Восстановить из файла" msgid "options_restoreLocalHelp" msgstr "" "Восстановление настроек SwitchyOmega из локального файла резервной копии." msgid "options_restoreOnline" msgstr "Восстановить по сети" msgid "options_restoreOnlinePlaceholder" msgstr "URL-адрес файла параметров (например, http://example.com/switchy.bak)" msgid "options_restoreOnlineSubmit" msgstr "Восстановить" msgid "options_group_syncing" msgstr "Синхронизация (экспериментально)" msgid "options_syncEnable" msgstr "Включить синхронизацию" msgid "options_syncEnableForce" msgstr "Скачать синхронизированное" msgid "options_syncDisable" msgstr "Отключить синхронизацию" msgid "options_syncReset" msgstr "Очистить сетевую копию" msgid "options_syncPristineHelp" msgstr "" "Теперь вы можете автоматически синхронизировать ваши настройки и профили на " "всех своих компьютерах с браузером Chrome." msgid "options_syncSyncAlert" msgstr "" "Ваши параметры автоматически синхронизируются с другими вашими устройствами." msgid "options_syncSyncHelp" msgstr "" "Обратите внимание, что вы должны войти в Chrome на каждом из ваших устройств " "(включая это), чтобы синхронизация действительно работала.
Вы можете " "проверить этот раздел на других устройствах, чтобы убедиться, что он " "работает." msgid "options_syncConflictAlert" msgstr "" "Вы загрузили копию ваших параметров на другое устройство с помощью " "синхронизации." msgid "options_syncConflictHelp" msgstr "" "Вы можете загрузить сетевую копию на своё устройство, если " "хотите.
Учтите, что это приведёт к перезаписи существующих настроек и " "профилей на данном устройстве." msgid "options_syncUnsupportedHelp" msgstr "" "Параметры синхронизации не поддерживаются на вашей платформе или в браузере. " "На данный момент поддерживается только браузер Chrome для настольных " "устройств." msgid "options_profileSyncDisabled" msgstr "Синхронизация отключена для этого профиля." msgid "options_profileSyncDisabled_quotaPerItem" msgstr "" "Синхронизация отключена для этого профиля из-за использования слишком " "большого объёма памяти." msgid "options_profileTabPrefix" msgstr "Профиль: " msgid "options_renameProfile" msgstr "Переименовать" msgid "options_deleteProfile" msgstr "Удалить" msgid "options_profileExportRuleList" msgstr "Опубликовать список правил" msgid "options_profileExportRuleListHelp" msgstr "Экспортировать правила переключения в текстовом формате для публикации." msgid "options_profileExportPac" msgstr "Экспортировать PAC" msgid "options_profileUnsupported" msgstr "Тип профиля $TYPE$ не поддерживается!" msgid "options_profileUnsupportedHelp" msgstr "Возможно, параметр испорчен, или он из новой версии программы." msgid "options_profileEditSource" msgstr "Изменить исходный код" msgid "options_profileEditSourceHelp" msgstr "Показать справку о формате исходного кода" msgid "options_profileEditSourceHelpUrl" msgstr "" "https://github.com/FelisCatus/SwitchyOmega/wiki/SwitchyOmega-conditions-" "format#result-profile" msgid "options_group_proxyServers" msgstr "Прокси-сервера" msgid "options_proxy_scheme" msgstr "Схема" msgid "options_proxy_protocol" msgstr "Протокол" msgid "options_proxy_server" msgstr "Сервер" msgid "options_proxy_port" msgstr "Порт" msgid "options_proxy_auth" msgstr "Аутентификация" msgid "options_proxy_authNotSupported" msgstr "" "Ваш браузер НЕ поддерживает аутентификацию прокси $PROTOCOLDISP$! " "Пожалуйста, не сообщайте об этой проблеме в SwitchyOmega. Вместо этого " "обратитесь в службу поддержки вашего браузера." msgid "options_proxy_authAllWarningPac" msgstr "" "Внимание: имя пользователя/пароль могут быть отправлены на непредсказуемые " "серверы, возвращённые PAC-скриптом." msgid "options_proxy_authAllWarningPacUrl" msgstr "" "Убедитесь, что вы доверяете скрипту по указанному выше URL-адресу, перед " "вводом конфиденциальных учётных данных." msgid "options_proxy_authAllWarningPacScript" msgstr "" "Убедитесь, что вы доверяете приведённому ниже скрипту, прежде чем " "предоставлять конфиденциальные учётные данные." msgid "options_proxy_authReferencedWarning" msgstr "" "К тому же, использование этого профиля в других профилях (например, «" "Переключаемого профиля») может привести к отправке имени пользователя/пароля " "на прокси-сервера, настроенные в других профилях." msgid "options_scheme_default" msgstr "(по умолчанию)" msgid "options_protocol_direct" msgstr "НАПРЯМУЮ" msgid "options_protocol_useDefault" msgstr "(настройки по умолчанию)" msgid "options_proxy_single" msgstr "Использовать прокси выше для всех протоколов." msgid "options_proxy_expand" msgstr "Показать расширенный вид" msgid "options_group_bypassList" msgstr "Список исключений" msgid "options_bypassListHelp" msgstr "" "Сервера, для которых не надо использовать прокси (один сервер на строку):" msgid "options_bypassListHelpLinkText" msgstr "(Доступны шаблоны и прочее…)" msgid "options_group_pacUrl" msgstr "URL-адрес PAC" msgid "options_pacUrlHelp" msgstr "" "PAC-скрипт будет обновляться с этого URL-адреса. Если его оставить пустым, " "будет использоваться следующий скрипт." msgid "options_pacUrlFile" msgstr "" "Профили PAC с файлом: URL-адреса могут применяться только напрямую. Они не " "могут использоваться в качестве профилей результатов, так как доступ к " "локальным файлам невозможен из-за ограничений браузера." msgid "options_pacUrlFileDisabled" msgstr "" "Поэтому вы не можете использовать локальный файл PAC для данного профиля. Вы " "можете создать новый профиль PAC, если это действительно нужно." msgid "options_group_pacScript" msgstr "PAC-скрипт" msgid "options_pacScriptLastUpdate" msgstr "PAC-скрипт загружен $TIME$:" msgid "options_pacScriptObsolete" msgstr "" "PAC-скрипт устарел так как URL был изменён. Нажмите кнопку загрузки выше для " "обновления." msgid "options_group_virtualProfile" msgstr "Виртуальный профиль" msgid "options_virtualProfileTarget" msgstr "Цель" msgid "options_virtualProfileTargetHelp" msgstr "" "Когда этот профиль применяется, он действует точно так же, как профиль, " "выбранный ниже." msgid "options_group_virtualProfileReplace" msgstr "Перенести в виртуальный профиль" msgid "options_virtualProfileReplace" msgstr "Заменить целевой профиль" msgid "options_virtualProfileReplaceHelp" msgstr "" "Вы можете перенести существующие параметры, чтобы использовать этот " "виртуальный профиль вместо $PROFILE$. Это обновит все существующие правила, " "относящиеся к $PROFILE$, и укажет их на этот виртуальный профиль, чтобы их " "профиль результатов можно было контролировать здесь." msgid "options_group_ruleListConfig" msgstr "Настройка списка правил" msgid "options_ruleListFormat" msgstr "Формат списка правил" msgid "options_group_ruleListResult" msgstr "Итоговые профили списка правил" msgid "options_ruleListMatchProfile" msgstr "Сопоставить профиль" msgid "options_ruleListDefaultProfile" msgstr "Профиль по умолчанию" msgid "options_group_ruleListUrl" msgstr "URL-адрес списка правил" msgid "options_ruleListUrlHelp" msgstr "" "Список правил будет обновлён с этого URL-адреса. Если оставить его пустым, " "будет анализироваться следующий текст." msgid "options_group_ruleListText" msgstr "Текст списка правил" msgid "options_ruleListLastUpdate" msgstr "Список правил загружен $TIME$:" msgid "options_ruleListObsolete" msgstr "" "Список правил устарел из-за изменения URL-адреса. Нажмите кнопку загрузки " "выше, чтобы обновить." msgid "options_group_switchRules" msgstr "Правила переключения" msgid "options_sort" msgstr "Сортировка" msgid "options_conditionType" msgstr "Тип условия" msgid "options_showConditionTypeHelp" msgstr "Показать справку" msgid "options_conditionDetails" msgstr "Подробности условия" msgid "options_resultProfile" msgstr "Профиль" msgid "options_conditionActions" msgstr "Действия" msgid "options_addCondition" msgstr "Добавить условие" msgid "options_cloneRule" msgstr "Копировать" msgid "options_ruleNote" msgstr "Заметка" msgid "options_switchAttachedProfileInCondition" msgstr "Правила списка правил" msgid "options_switchAttachedProfileInConditionDetails" msgstr "(Любой запрос, соответствующий списку правил ниже)" msgid "options_switchAttachedProfileInConditionDisabled" msgstr "(Правила списка правил ОТКЛЮЧЕНЫ)" msgid "options_switchDefaultProfile" msgstr "По умолчанию" msgid "options_hostLevelsBetween" msgstr "≤ уровни хоста ≤" msgid "options_hourBetween" msgstr "≤ текущий час ≤" msgid "options_weekDayShort_0" msgstr "Вс" msgid "options_weekDayShort_1" msgstr "Пн" msgid "options_weekDayShort_2" msgstr "Вт" msgid "options_weekDayShort_3" msgstr "Ср" msgid "options_weekDayShort_4" msgstr "Чт" msgid "options_weekDayShort_5" msgstr "Пт" msgid "options_weekDayShort_6" msgstr "Сб" msgid "options_group_conditionHelp" msgstr "О типах условий" msgid "options_group_attachProfile" msgstr "Импортировать онлайн-список правил" msgid "options_attachProfile" msgstr "Добавить список правил" msgid "options_attachProfileHelp" msgstr "" "Вы можете повторно использовать онлайн-набор условий, опубликованных " "другими, добавив список правил." msgid "options_modalHeader_welcome" msgstr "Добро пожаловать в SwitchyOmega" msgid "options_welcomeNormal" msgstr "" "Вы успешно установили SwitchyOmega, лучший инструмент для настройки прокси." msgid "options_welcomeNormalGuide" msgstr "" "Пожалуйста, сообщите SwitchyOmega ваши прокси на странице параметров. Это " "делается так." msgid "options_welcomeUpgrade" msgstr "" "Вы успешно обновились до SwitchyOmega. Не волнуйтесь, ваши настройки в " "целости и сохранности." msgid "options_welcomeUpgradeGuide" msgstr "" "Теперь давайте пройдёмся по краткому руководству на странице новых " "параметров." msgid "options_guideNext" msgstr "Далее" msgid "options_guideDone" msgstr "Готово" msgid "options_guideSkip" msgstr "Пропустить руководство" msgid "options_modalHeader_applyOptions" msgstr "Применить параметры" msgid "options_optionsNotSaved" msgstr "" "Ваши изменения параметров не были сохранены и будут потеряны, если вы " "продолжите!" msgid "options_applyOptionsRequired" msgstr "Вы должны применить изменения настроек, прежде чем продолжить." msgid "options_applyOptionsConfirm" msgstr "Сохранить и применить параметры?" msgid "options_modalHeader_renameProfile" msgstr "Переименовать профиль" msgid "options_renameProfileName" msgstr "Новое имя профиля" msgid "options_profileNameConflict" msgstr "Профиль с данным именем уже существует." msgid "options_profileNameReserved" msgstr "Имена профилей, начинающиеся с двойного подчёркивания, зарезервированы." msgid "options_profileNameHidden" msgstr "" "Профили с именами, начинающимися с подчёркивания, будут скрыты во " "всплывающем меню. Тем не менее, они могут использоваться, например, в " "переключаемом профиле." msgid "options_modalHeader_replaceProfile" msgstr "Заменить профиль" msgid "options_replaceProfile" msgstr "Заменить профиль" msgid "options_replaceProfileConfirm" msgstr "Заменить $FromProfile$ на $ToProfile$?" msgid "options_replaceProfileHelp" msgstr "" "Если вы продолжите, все правила, указывающие на $FromProfile$, будут " "обновлены для использования $ToProfile$. Другие параметры, такие как профиль " "при запуске и быстрое переключение, также будут изменены соответствующим " "образом. Однако сами два профиля НЕ будут изменены или удалены." msgid "options_replaceProfileSuccess" msgstr "Параметры обновлены." msgid "options_modalHeader_deleteProfile" msgstr "Удалить профиль" msgid "options_deleteProfileConfirm" msgstr "Удалить следующий профиль?" msgid "options_modalHeader_cannotDeleteProfile" msgstr "Невозможно удалить профиль" msgid "options_profileReferredBy" msgstr "" "Этот профиль нельзя удалить, так как на него ссылаются следующие профили:" msgid "options_modifyReferringProfiles" msgstr "" "Вы должны изменить эти профили и заставить их перестать ссылаться на этот " "профиль, прежде чем сможете его удалить." msgid "options_profileNameEmpty" msgstr "Имя профиля не может быть пустым." msgid "popup_title" msgstr "Всплывающее окно SwitchyOmega" msgid "options_modalHeader_proxyAuth" msgstr "Аутентификация прокси" msgid "options_proxyAuthUsername" msgstr "Имя пользователя" msgid "options_proxyAuthPassword" msgstr "Пароль" msgid "options_proxyAuthShowPassword" msgstr "Показать пароль" msgid "options_proxyAuthHidePassword" msgstr "Скрыть пароль" msgid "options_proxyAuthNone" msgstr "Без аутентификации" msgid "options_modalHeader_deleteRule" msgstr "Удалить правило" msgid "options_deleteRuleConfirm" msgstr "Вы действительно хотите удалить следующее правило?" msgid "options_deleteRule" msgstr "Удалить" msgid "options_modalHeader_resetRules" msgstr "Сбросить правила" msgid "options_resetRulesConfirm" msgstr "Установить итоговый профиль ВСЕХ правил для следующего профиля?" msgid "options_resetRules" msgstr "Сбросить правила" msgid "options_resetRules_help" msgstr "Установить профиль для всех правил" msgid "options_modalHeader_deleteAttached" msgstr "Удалить список правил" msgid "options_deleteAttachedConfirm" msgstr "Удалить список правил из текущего профиля?" msgid "options_ruleListLineCount" msgstr "$COUNT$ строк(и) правил" msgid "options_deleteAttached" msgstr "Удалить список правил" msgid "options_modalHeader_newProfile" msgstr "Новый профиль" msgid "options_newProfileName" msgstr "Имя профиля" msgid "options_profileType" msgstr "Выберете тип профиля:" msgid "options_profileTypeFixedProfile" msgstr "Профиль прокси" msgid "options_profileDescFixedProfile" msgstr "Туннелирование трафика через прокси-сервера." msgid "options_profileTypePacProfile" msgstr "Профиль PAC" msgid "options_profileDescPacProfile" msgstr "Выбор прокси на основе онлайн/локального PAC-скрипта." msgid "options_profileDescMorePacProfile" msgstr "" "Это может понадобится только если у вас есть PAC-скрипт или его URL-адрес. " "Не пытайтесь создать скрипт, если у вас нет знаний о PAC." msgid "options_profileTypeSwitchProfile" msgstr "Переключаемый профиль" msgid "options_profileDescSwitchProfile" msgstr "" "Автоматическое применение различных профилей в различных условиях, таких как " "домены или шаблоны.\n" " Вы также можете импортировать опубликованные в онлайн правила для более " "удобного переключения. (Заменяет режим автопереключение + список правил.)" msgid "options_profileTypeRuleListProfile" msgstr "Профиль списка правил" msgid "options_profileDescRuleListProfile" msgstr "" "Используется онлайн-набор условий, опубликованных другими пользователями." msgid "options_profileTypeVirtualProfile" msgstr "Виртуальный профиль" msgid "options_profileDescVirtualProfile" msgstr "" "Виртуальный профиль может действовать, при необходимости, как любой другой " "профиль. Он хорошо работает с «Переключаемым профилем», позволяя вам " "изменить результат нескольких условий одним щелчком мыши." msgid "options_createProfile" msgstr "Создать" msgid "options_modalHeader_resetOptions" msgstr "Сбросить параметры" msgid "options_resetOptionsConfirm" msgstr "Сбросить параметры? Все профили и настройки будут потеряны!" msgid "options_formInvalid" msgstr "Пожалуйста, исправьте ошибки на этой странице." msgid "options_profileNotFound" msgstr "Профиль $PROFILE$ не существует! Параметры могут быть повреждены." msgid "options_resetSuccess" msgstr "Параметры сброшены." msgid "options_saveSuccess" msgstr "Параметры сохранены." msgid "options_importSuccess" msgstr "Параметры импортированы." msgid "options_importFormatError" msgstr "Некорректная резервная копия!" msgid "options_importDownloadError" msgstr "Ошибка при загрузке резервной копии!" msgid "options_profileDownloadSuccess" msgstr "Профиль успешно обновлён." msgid "options_profileDownloadError" msgstr "Ошибка при загрузке данных профиля!" msgid "options_profileDownloadError_NetworkError" msgstr "При обновлении произошла сетевая ошибка." msgid "options_profileDownloadError_HttpError" msgstr "При обновлении произошла ошибка HTTP ($STATUS$)." msgid "options_profileDownloadError_HttpNotFoundError" msgstr "URL-адрес профиля не найден на сервере. Пожалуйста, перепроверьте его." msgid "options_profileDownloadError_HttpServerError" msgstr "При обновлении удалённый сервер сообщил ошибку ($STATUS$)." msgid "options_profileDownloadError_ContentTypeRejectedError" msgstr "" "Загруженные данные неверны! Вы можете открыть URL-адрес профиля в своём " "браузере, чтобы проверить его." msgid "options_downloadProfileNow" msgstr "Загрузить профиль сейчас" msgid "options_guide_fixedProfileStep" msgstr "" "Профиль прокси содержит настройки, такие как IP-адрес и порт сервера " "для прокси.
Профили – это основные элементы конфигурации в " "SwitchyOmega.
Мы уже создали пример профиля для вас. Попробуйте открыть " "его." msgid "options_guide_fixedServersStep" msgstr "" "Вы можете здесь указать свой прокси-сервер и порт.
SwitchyOmega не " "поставляется с какими-либо прокси серверами.
Обратитесь к своему " "сетевому провайдеру или к руководству по настройки прокси, если не знаете, " "что делать дальше." msgid "options_guide_autoSwitchProfileStep" msgstr "" "Вы можете попросить SwitchyOmega автоматически переключаться между прокси-" "серверами с помощью мощного Переключаемого профиля.
Однако, его " "функции не могут быть рассмотрены в этом кратком руководстве.
Вы можете " "открыть этот профиль, чтобы познать его мощь чуть позже." msgid "options_guide_addMoreProfilesStep" msgstr "" "Нужно больше профилей? Вы всегда можете добавить больше прокси, " "переключений и других профилей
для удовлетворения всех своих " "потребностей проксирования.
Наслаждайтесь прокси!" msgid "options_guide_conditionStep" msgstr "" "SwitchyOmega может применять различные профили к запросам на основе " "условий.
Например, условие Шаблон хоста позволяет вам " "установить профиль для всех URL-адресов в домене." msgid "options_guide_conditionTypeStep" msgstr "" "Вы можете использовать различные типы условий, чтобы соответствовать хосту " "или полному URL-адресу.
Нажмите на знак вопроса, чтобы открыть ссылку на " "тип." msgid "options_guide_conditionProfileStep" msgstr "" "SwitchyOmega применяет выбранный профиль здесь к любому запросу, " "соответствующему условию.
Специальный профиль [Напрямую] " "приведёт к отправке запроса без какого-либо прокси." msgid "options_guide_switchDefaultStep" msgstr "" "Если к какому-либо запросу не применяются никакие условия, будет " "использоваться профиль «По умолчанию».
Условия всегда рассматриваются по " "порядку сверху вниз.
Вы можете изменить их порядок, перетаскивая " "значок сортировки." msgid "options_guide_applySwitchProfileStep" msgstr "" "Завершив настройку профиля переключения, не забудьте переключиться на " "него во всплывающем меню.
Значок покажет вам применённый " "профиль для текущей вкладки.
Наведение курсора на значок откроет " "всплывающую подсказку с подробностями." msgid "popup_externalProfile" msgstr "(Внешний профиль)" msgid "popup_externalProfileName" msgstr "имя профиля" msgid "popup_proxyNotControllable_app" msgstr "" "Настройки прокси контролируются другими приложениями или расширениями. " "Отключите или удалите эти приложения или расширения." msgid "popup_proxyNotControllable_policy" msgstr "" "Настройки прокси отменяются системой. Свяжитесь с вашим администратором." msgid "popup_proxyNotControllable_unknown" msgstr "" "Не удалось выставить настройки прокси. Проверьте вашу систему и настройки " "браузера." msgid "popup_proxyNotControllable_disabled" msgstr "" "Настройки прокси отключены явным запросом других приложений или расширений." msgid "popup_proxyNotControllable_upgrade" msgstr "" "Настройки прокси теперь контролируются более новой версией SwitchyOmega." msgid "popup_proxyNotControllableDetails" msgstr "" "Вы не можете переключать профили с помощью SwitchyOmega, пока не решите " "описанную проблему." msgid "popup_proxyNotControllableDetails_upgrade" msgstr "" "Вы не можете включить две (или более) версии SwitchyOmega одновременно. " "Отключите одну из них." msgid "popup_proxyNotControllableManage" msgstr "Управление расширениям" msgid "popup_addConditionTo" msgstr "Добавить условие к" msgid "popup_addCondition" msgstr "Добавить условие" msgid "popup_showOptions" msgstr "Параметры" msgid "popup_reportIssues" msgstr "Сообщить о неполадках" msgid "popup_errorLog" msgstr "Сохранить журнал ошибок" msgid "popup_requestErrorCount" msgstr "$COUNT$ неудачных ресурсов" msgid "popup_requestErrorHeading" msgstr "Ресурсы, которые не удалось загрузить" msgid "popup_requestErrorWarning" msgstr "" "Невозможно загрузить несколько ресурсов из-за проблем с сетью, прокси-" "сервером или веб-страницей." msgid "popup_requestErrorWarningHelp" msgstr "SwitchyOmega просто сообщает о них, а не является причиной." msgid "popup_requestErrorAddCondition" msgstr "" "Вы можете просмотреть следующие домены и использовать прокси для них при " "необходимости." msgid "popup_requestErrorCannotAddCondition" msgstr "" "Вы можете добавить условия переключения для них только при использовании «" "Переключаемого профиля»." msgid "popup_configureMonitorWebRequests" msgstr "Настроить монитор сети" msgid "options_resultProfileForSelectedDomains" msgstr "Использовать этот профиль для всех выбранных доменов" msgid "options_pac_profile_unsupported_moz" msgstr "" "Профили PAC НЕ будут работать в Mozilla Firefox из-за технических " "ограничений!" msgid "popup_issueTemplate" msgstr "" "\n" "\n" "\n" "\n" "SwitchyOmega $projectVersion$\n" "$userAgent$" msgid "browserAction_profileDetails_PacProfile" msgstr "(PAC-скрипт)" msgid "browserAction_profileDetails_SystemProfile" msgstr "(управляется другими расширениями или окружением)" msgid "browserAction_profileDetails_DirectProfile" msgstr "(не использовать никаких прокси)" msgid "browserAction_profileDetails_SwitchProfile" msgstr "(переключение на основе условий)" msgid "browserAction_profileDetails_RuleListProfile" msgstr "(переключение на основе правил)" msgid "browserAction_titleNormal" msgstr "SwitchyOmega:: $PROFILE$" msgid "browserAction_titleWithResult" msgstr "" "SwitchyOmega:: $1:PROFILE$\n" "$3:DETAILS$" msgid "browserAction_titleNewerOptions" msgstr "" "ОШИБКА: для загрузки сохранённых параметров требуется более новая версия " "SwitchOmega." msgid "browserAction_titleOptionError" msgstr "" "ОШИБКА: сохранённые параметры повреждены. Нажмите здесь, чтобы СБРОСИТЬ " "ПАРАМЕТРЫ." msgid "browserAction_titleDownloadFail" msgstr "Предупреждение: невозможно загрузить PAC-скрипт и/или список правил." msgid "browserAction_titleExternalProxy" msgstr "" "Замечание: в данный момент, настройки прокси контролируются другим " "приложением." msgid "browserAction_titleInspect" msgstr "[Проверить] $URL$" msgid "browserAction_defaultRuleDetails" msgstr "(по умолчанию)" msgid "browserAction_directResult" msgstr "НАПРЯМУЮ" msgid "browserAction_attachedPrefix" msgstr "(RL) " msgid "browserAction_tempRulePrefix" msgstr "(TEMP) " msgid "contextMenu_inspectPage" msgstr "Проверить прокси, использованный для этой страницы" msgid "contextMenu_inspectFrame" msgstr "Проверить прокси, использованный для этого фрейма" msgid "contextMenu_inspectLink" msgstr "Проверить прокси для открытия этой ссылки" msgid "contextMenu_inspectElement" msgstr "Проверить прокси, использованный для этого элемента" msgid "contextMenu_enableQuickSwitch" msgstr "Включить быстрое переключение" msgid "about_title" msgstr "О расширении" msgid "about_app_description" msgstr "Инструмент настройки прокси" msgid "about_version" msgstr "Версия $VERSION$" msgid "about_experimental_warning_moz" msgstr "" "Поддержка Mozilla Firefox экспериментальная! Если у вас возникли проблемы, " "сообщите о них с помощью кнопок ниже." msgid "about_disclaimer_networkService" msgstr "SwitchyOmega не предоставляет прокси, VPN или другие сетевые сервисы." msgid "about_disclaimer_privacy" msgstr "" "SwitchyOmega не отслеживает вас и не вставляет рекламу в веб-страницы. " "Пожалуйста, ознакомьтесь с нашей политикой конфиденциальности." msgid "about_help" msgstr "" "Остались вопросы? Нужна помощь с использованием SwitchyOmega? Смотрите наш " "ЧаВО." msgid "about_copyright" msgstr "" "Авторское право 2012-2017 Авторы SwitchyOmega. Все права " "защищены." msgid "about_credits" msgstr "" "SwitchyOmega стала возможной благодаря проекту SwitchyOmega с открытым исходным кодом и " "другому программному обеспечению с открытым исходным кодом." msgid "about_license" msgstr "" "SwitchyOmega – это бесплатное программное обеспечение, лицензируемое на " "условиях GNU General Public " "License Версии 3 или более поздней." ================================================ FILE: omega-locales/si/LC_MESSAGES/omega-web.po ================================================ msgid "" msgstr "" "Project-Id-Version: SwitchyOmega 2.3.3\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2015-02-13 10:29+0000\n" "PO-Revision-Date: 2021-02-27 11:50+0000\n" "Last-Translator: HelaBasa \n" "Language-Team: Sinhala \n" "Language: si\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n > 1;\n" "X-Generator: Weblate 4.5\n" msgid "appNameShort" msgstr "" msgid "manifest_app_name" msgstr "" msgid "manifest_app_description" msgstr "" msgid "manifest_icon_default_title" msgstr "පූරණය වෙමින්…" msgid "upgrade_profile_auto" msgstr "" msgid "profile_direct" msgstr "" msgid "profile_system" msgstr "" msgid "condition_HostWildcardCondition" msgstr "" msgid "condition_help_HostWildcardCondition" msgstr "" msgid "condition_HostRegexCondition" msgstr "" msgid "condition_help_HostRegexCondition" msgstr "" msgid "condition_HostLevelsCondition" msgstr "" msgid "condition_help_HostLevelsCondition" msgstr "" msgid "condition_IpCondition" msgstr "" msgid "condition_help_IpCondition" msgstr "" msgid "condition_UrlWildcardCondition" msgstr "" msgid "condition_help_UrlWildcardCondition" msgstr "" msgid "condition_UrlRegexCondition" msgstr "" msgid "condition_help_UrlRegexCondition" msgstr "" msgid "condition_KeywordCondition" msgstr "" msgid "condition_help_KeywordCondition" msgstr "" msgid "condition_FalseCondition" msgstr "" msgid "condition_details_FalseCondition" msgstr "" msgid "condition_help_FalseCondition" msgstr "" msgid "condition_TimeCondition" msgstr "දැන් වේලාව" msgid "condition_help_TimeCondition" msgstr "" msgid "condition_WeekdayCondition" msgstr "" msgid "condition_help_WeekdayCondition" msgstr "" msgid "condition_alert_fullUrlLimitation" msgstr "" msgid "condition_alert_fullUrlLimitationLink" msgstr "" msgid "condition_group_default" msgstr "" msgid "condition_group_host" msgstr "" msgid "condition_group_url" msgstr "" msgid "condition_group_special" msgstr "" msgid "ruleListFormat_Switchy" msgstr "" msgid "ruleListFormat_AutoProxy" msgstr "" msgid "ruleList_usageUrl" msgstr "" msgid "ruleList_error_resultNotEnabled" msgstr "" msgid "ruleList_error_unknownProfile" msgstr "" msgid "ruleList_error_missingResultProfile" msgstr "" msgid "ruleList_error_invalidRule" msgstr "" msgid "ruleList_error_noDefaultRule" msgstr "" msgid "dialog_close" msgstr "" msgid "dialog_save" msgstr "" msgid "dialog_ok" msgstr "" msgid "dialog_cancel" msgstr "" msgid "inputClear_clear" msgstr "" msgid "inputClear_restore" msgstr "" msgid "options_title" msgstr "" msgid "options_experimental_badge" msgstr "" msgid "options_navHeader_setting" msgstr "" msgid "options_navHeader_profiles" msgstr "" msgid "options_navHeader_actions" msgstr "" msgid "options_tab_ui" msgstr "" msgid "options_tab_general" msgstr "" msgid "options_tab_importExport" msgstr "" msgid "options_newProfile" msgstr "" msgid "options_apply" msgstr "" msgid "options_discard" msgstr "" msgid "options_reset" msgstr "" msgid "options_group_miscOptions" msgstr "" msgid "options_confirmDeletion" msgstr "" msgid "options_refreshOnProfileChange" msgstr "" msgid "options_showInspectMenu" msgstr "" msgid "options_addConditionsToBottom" msgstr "" msgid "options_group_keyboardShortcut" msgstr "" msgid "options_menuShortcutHelp" msgstr "" msgid "options_menuShortcutMore" msgstr "" msgid "options_menuShortcutConfigure" msgstr "" msgid "options_group_switchOptions" msgstr "" msgid "options_startupProfile" msgstr "" msgid "options_startupProfile_none" msgstr "" msgid "options_showConditionTypesAdvanced" msgstr "" msgid "options_showConditionTypesAdvancedHelp" msgstr "" msgid "options_quickSwitch" msgstr "" msgid "options_cycledProfiles" msgstr "" msgid "options_cycledProfilesHelp" msgstr "" msgid "options_cycledProfilesTooFew" msgstr "" msgid "options_notCycledProfiles" msgstr "" msgid "options_group_proxyChanges" msgstr "" msgid "options_revertProxyChanges" msgstr "" msgid "options_group_conflicts" msgstr "" msgid "options_conflicts_introduction" msgstr "" msgid "options_conflicts_lowerPriority" msgstr "" msgid "options_conflicts_higherPriority" msgstr "" msgid "options_showExternalProfile" msgstr "" msgid "options_showExternalProfileHelp" msgstr "" msgid "options_group_networkRequests" msgstr "" msgid "options_monitorWebRequests" msgstr "" msgid "options_monitorWebRequestsHelp" msgstr "" msgid "options_downloadOptions" msgstr "" msgid "options_downloadOptionsHelp" msgstr "" msgid "options_downloadInterval" msgstr "" msgid "options_downloadInterval_15" msgstr "" msgid "options_downloadInterval_60" msgstr "" msgid "options_downloadInterval_180" msgstr "" msgid "options_downloadInterval_360" msgstr "" msgid "options_downloadInterval_720" msgstr "" msgid "options_downloadInterval_1440" msgstr "" msgid "options_downloadInterval_never" msgstr "" msgid "options_group_importExportProfile" msgstr "" msgid "options_exportPacFile" msgstr "" msgid "options_exportPacFileHelp" msgstr "" msgid "options_exportProfileHelp" msgstr "" msgid "options_exportLegacyRuleList" msgstr "" msgid "options_exportLegacyRuleListHelp" msgstr "" msgid "options_group_importExportSettings" msgstr "" msgid "options_makeBackup" msgstr "" msgid "options_makeBackupHelp" msgstr "" msgid "options_restoreLocal" msgstr "" msgid "options_restoreLocalHelp" msgstr "" msgid "options_restoreOnline" msgstr "" msgid "options_restoreOnlinePlaceholder" msgstr "" msgid "options_restoreOnlineSubmit" msgstr "" msgid "options_group_syncing" msgstr "" msgid "options_syncEnable" msgstr "" msgid "options_syncEnableForce" msgstr "" msgid "options_syncDisable" msgstr "" msgid "options_syncReset" msgstr "" msgid "options_syncPristineHelp" msgstr "" msgid "options_syncSyncAlert" msgstr "" msgid "options_syncSyncHelp" msgstr "" msgid "options_syncConflictAlert" msgstr "" msgid "options_syncConflictHelp" msgstr "" msgid "options_syncUnsupportedHelp" msgstr "" msgid "options_profileSyncDisabled" msgstr "" msgid "options_profileSyncDisabled_quotaPerItem" msgstr "" msgid "options_profileTabPrefix" msgstr "" msgid "options_renameProfile" msgstr "" msgid "options_deleteProfile" msgstr "" msgid "options_profileExportRuleList" msgstr "" msgid "options_profileExportRuleListHelp" msgstr "" msgid "options_profileExportPac" msgstr "" msgid "options_profileUnsupported" msgstr "" msgid "options_profileUnsupportedHelp" msgstr "" msgid "options_profileEditSource" msgstr "" msgid "options_profileEditSourceHelp" msgstr "" msgid "options_profileEditSourceHelpUrl" msgstr "" msgid "options_group_proxyServers" msgstr "" msgid "options_proxy_scheme" msgstr "" msgid "options_proxy_protocol" msgstr "" msgid "options_proxy_server" msgstr "" msgid "options_proxy_port" msgstr "" msgid "options_proxy_auth" msgstr "" msgid "options_proxy_authNotSupported" msgstr "" msgid "options_proxy_authAllWarningPac" msgstr "" msgid "options_proxy_authAllWarningPacUrl" msgstr "" msgid "options_proxy_authAllWarningPacScript" msgstr "" msgid "options_proxy_authReferencedWarning" msgstr "" msgid "options_scheme_default" msgstr "" msgid "options_protocol_direct" msgstr "" msgid "options_protocol_useDefault" msgstr "" msgid "options_proxy_single" msgstr "" msgid "options_proxy_expand" msgstr "" msgid "options_group_bypassList" msgstr "" msgid "options_bypassListHelp" msgstr "" msgid "options_bypassListHelpLinkText" msgstr "" msgid "options_group_pacUrl" msgstr "" msgid "options_pacUrlHelp" msgstr "" msgid "options_pacUrlFile" msgstr "" msgid "options_pacUrlFileDisabled" msgstr "" msgid "options_group_pacScript" msgstr "" msgid "options_pacScriptLastUpdate" msgstr "" msgid "options_pacScriptObsolete" msgstr "" msgid "options_group_virtualProfile" msgstr "" msgid "options_virtualProfileTarget" msgstr "" msgid "options_virtualProfileTargetHelp" msgstr "" msgid "options_group_virtualProfileReplace" msgstr "" msgid "options_virtualProfileReplace" msgstr "" msgid "options_virtualProfileReplaceHelp" msgstr "" msgid "options_group_ruleListConfig" msgstr "" msgid "options_ruleListFormat" msgstr "" msgid "options_group_ruleListResult" msgstr "" msgid "options_ruleListMatchProfile" msgstr "" msgid "options_ruleListDefaultProfile" msgstr "" msgid "options_group_ruleListUrl" msgstr "" msgid "options_ruleListUrlHelp" msgstr "" msgid "options_group_ruleListText" msgstr "" msgid "options_ruleListLastUpdate" msgstr "" msgid "options_ruleListObsolete" msgstr "" msgid "options_group_switchRules" msgstr "" msgid "options_sort" msgstr "" msgid "options_conditionType" msgstr "" msgid "options_showConditionTypeHelp" msgstr "" msgid "options_conditionDetails" msgstr "" msgid "options_resultProfile" msgstr "" msgid "options_conditionActions" msgstr "" msgid "options_addCondition" msgstr "" msgid "options_cloneRule" msgstr "" msgid "options_ruleNote" msgstr "" msgid "options_switchAttachedProfileInCondition" msgstr "" msgid "options_switchAttachedProfileInConditionDetails" msgstr "" msgid "options_switchAttachedProfileInConditionDisabled" msgstr "" msgid "options_switchDefaultProfile" msgstr "" msgid "options_hostLevelsBetween" msgstr "" msgid "options_hourBetween" msgstr "" msgid "options_weekDayShort_0" msgstr "" msgid "options_weekDayShort_1" msgstr "" msgid "options_weekDayShort_2" msgstr "" msgid "options_weekDayShort_3" msgstr "" msgid "options_weekDayShort_4" msgstr "" msgid "options_weekDayShort_5" msgstr "" msgid "options_weekDayShort_6" msgstr "" msgid "options_group_conditionHelp" msgstr "" msgid "options_group_attachProfile" msgstr "" msgid "options_attachProfile" msgstr "" msgid "options_attachProfileHelp" msgstr "" msgid "options_modalHeader_welcome" msgstr "" msgid "options_welcomeNormal" msgstr "" msgid "options_welcomeNormalGuide" msgstr "" msgid "options_welcomeUpgrade" msgstr "" msgid "options_welcomeUpgradeGuide" msgstr "" msgid "options_guideNext" msgstr "" msgid "options_guideDone" msgstr "" msgid "options_guideSkip" msgstr "" msgid "options_modalHeader_applyOptions" msgstr "" msgid "options_optionsNotSaved" msgstr "" msgid "options_applyOptionsRequired" msgstr "" msgid "options_applyOptionsConfirm" msgstr "" msgid "options_modalHeader_renameProfile" msgstr "" msgid "options_renameProfileName" msgstr "" msgid "options_profileNameConflict" msgstr "" msgid "options_profileNameReserved" msgstr "" msgid "options_profileNameHidden" msgstr "" msgid "options_modalHeader_replaceProfile" msgstr "" msgid "options_replaceProfile" msgstr "" msgid "options_replaceProfileConfirm" msgstr "" msgid "options_replaceProfileHelp" msgstr "" msgid "options_replaceProfileSuccess" msgstr "" msgid "options_modalHeader_deleteProfile" msgstr "" msgid "options_deleteProfileConfirm" msgstr "" msgid "options_modalHeader_cannotDeleteProfile" msgstr "" msgid "options_profileReferredBy" msgstr "" msgid "options_modifyReferringProfiles" msgstr "" msgid "options_profileNameEmpty" msgstr "" msgid "popup_title" msgstr "" msgid "options_modalHeader_proxyAuth" msgstr "" msgid "options_proxyAuthUsername" msgstr "" msgid "options_proxyAuthPassword" msgstr "" msgid "options_proxyAuthShowPassword" msgstr "" msgid "options_proxyAuthHidePassword" msgstr "" msgid "options_proxyAuthNone" msgstr "" msgid "options_modalHeader_deleteRule" msgstr "" msgid "options_deleteRuleConfirm" msgstr "" msgid "options_deleteRule" msgstr "" msgid "options_modalHeader_resetRules" msgstr "" msgid "options_resetRulesConfirm" msgstr "" msgid "options_resetRules" msgstr "" msgid "options_resetRules_help" msgstr "" msgid "options_modalHeader_deleteAttached" msgstr "" msgid "options_deleteAttachedConfirm" msgstr "" msgid "options_ruleListLineCount" msgstr "" msgid "options_deleteAttached" msgstr "" msgid "options_modalHeader_newProfile" msgstr "" msgid "options_newProfileName" msgstr "" msgid "options_profileType" msgstr "" msgid "options_profileTypeFixedProfile" msgstr "" msgid "options_profileDescFixedProfile" msgstr "" msgid "options_profileTypePacProfile" msgstr "" msgid "options_profileDescPacProfile" msgstr "" msgid "options_profileDescMorePacProfile" msgstr "" msgid "options_profileTypeSwitchProfile" msgstr "" msgid "options_profileDescSwitchProfile" msgstr "" msgid "options_profileTypeRuleListProfile" msgstr "" msgid "options_profileDescRuleListProfile" msgstr "" msgid "options_profileTypeVirtualProfile" msgstr "" msgid "options_profileDescVirtualProfile" msgstr "" msgid "options_createProfile" msgstr "" msgid "options_modalHeader_resetOptions" msgstr "" msgid "options_resetOptionsConfirm" msgstr "" msgid "options_formInvalid" msgstr "" msgid "options_profileNotFound" msgstr "" msgid "options_resetSuccess" msgstr "" msgid "options_saveSuccess" msgstr "" msgid "options_importSuccess" msgstr "" msgid "options_importFormatError" msgstr "" msgid "options_importDownloadError" msgstr "" msgid "options_profileDownloadSuccess" msgstr "" msgid "options_profileDownloadError" msgstr "" msgid "options_profileDownloadError_NetworkError" msgstr "" msgid "options_profileDownloadError_HttpError" msgstr "" msgid "options_profileDownloadError_HttpNotFoundError" msgstr "" msgid "options_profileDownloadError_HttpServerError" msgstr "" msgid "options_profileDownloadError_ContentTypeRejectedError" msgstr "" msgid "options_downloadProfileNow" msgstr "" msgid "options_guide_fixedProfileStep" msgstr "" msgid "options_guide_fixedServersStep" msgstr "" msgid "options_guide_autoSwitchProfileStep" msgstr "" msgid "options_guide_addMoreProfilesStep" msgstr "" msgid "options_guide_conditionStep" msgstr "" msgid "options_guide_conditionTypeStep" msgstr "" msgid "options_guide_conditionProfileStep" msgstr "" msgid "options_guide_switchDefaultStep" msgstr "" msgid "options_guide_applySwitchProfileStep" msgstr "" msgid "popup_externalProfile" msgstr "" msgid "popup_externalProfileName" msgstr "" msgid "popup_proxyNotControllable_app" msgstr "" msgid "popup_proxyNotControllable_policy" msgstr "" msgid "popup_proxyNotControllable_unknown" msgstr "" msgid "popup_proxyNotControllable_disabled" msgstr "" msgid "popup_proxyNotControllable_upgrade" msgstr "" msgid "popup_proxyNotControllableDetails" msgstr "" msgid "popup_proxyNotControllableDetails_upgrade" msgstr "" msgid "popup_proxyNotControllableManage" msgstr "" msgid "popup_addConditionTo" msgstr "" msgid "popup_addCondition" msgstr "" msgid "popup_showOptions" msgstr "" msgid "popup_reportIssues" msgstr "" msgid "popup_errorLog" msgstr "" msgid "popup_requestErrorCount" msgstr "" msgid "popup_requestErrorHeading" msgstr "" msgid "popup_requestErrorWarning" msgstr "" msgid "popup_requestErrorWarningHelp" msgstr "" msgid "popup_requestErrorAddCondition" msgstr "" msgid "popup_requestErrorCannotAddCondition" msgstr "" msgid "popup_configureMonitorWebRequests" msgstr "" msgid "options_resultProfileForSelectedDomains" msgstr "" msgid "options_pac_profile_unsupported_moz" msgstr "" msgid "popup_issueTemplate" msgstr "" msgid "browserAction_profileDetails_PacProfile" msgstr "" msgid "browserAction_profileDetails_SystemProfile" msgstr "" msgid "browserAction_profileDetails_DirectProfile" msgstr "" msgid "browserAction_profileDetails_SwitchProfile" msgstr "" msgid "browserAction_profileDetails_RuleListProfile" msgstr "" msgid "browserAction_titleNormal" msgstr "" msgid "browserAction_titleWithResult" msgstr "" msgid "browserAction_titleNewerOptions" msgstr "" msgid "browserAction_titleOptionError" msgstr "" msgid "browserAction_titleDownloadFail" msgstr "" msgid "browserAction_titleExternalProxy" msgstr "" msgid "browserAction_titleInspect" msgstr "" msgid "browserAction_defaultRuleDetails" msgstr "" msgid "browserAction_directResult" msgstr "" msgid "browserAction_attachedPrefix" msgstr "" msgid "browserAction_tempRulePrefix" msgstr "" msgid "contextMenu_inspectPage" msgstr "" msgid "contextMenu_inspectFrame" msgstr "" msgid "contextMenu_inspectLink" msgstr "" msgid "contextMenu_inspectElement" msgstr "" msgid "contextMenu_enableQuickSwitch" msgstr "" msgid "about_title" msgstr "" msgid "about_app_description" msgstr "" msgid "about_version" msgstr "" msgid "about_experimental_warning_moz" msgstr "" msgid "about_disclaimer_networkService" msgstr "" msgid "about_disclaimer_privacy" msgstr "" msgid "about_help" msgstr "" msgid "about_copyright" msgstr "" msgid "about_credits" msgstr "" msgid "about_license" msgstr "" ================================================ FILE: omega-locales/sk/LC_MESSAGES/omega-web.po ================================================ msgid "" msgstr "" "Project-Id-Version: SwitchyOmega 2.3.3\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2015-02-13 10:29+0000\n" "PO-Revision-Date: 2021-03-05 14:50+0000\n" "Last-Translator: Patrik Kollár \n" "Language-Team: Slovak \n" "Language: sk\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n" "X-Generator: Weblate 4.5.1-dev\n" #, fuzzy msgid "appNameShort" msgstr "SwitchyOmega" #, fuzzy msgid "manifest_app_name" msgstr "Proxy SwitchyOmega" msgid "manifest_app_description" msgstr "Spravuj a prepínaj medzi viacerými proxy rýchlo a jednoducho." msgid "manifest_icon_default_title" msgstr "Načítavanie…" msgid "upgrade_profile_auto" msgstr "" msgid "profile_direct" msgstr "" msgid "profile_system" msgstr "" msgid "condition_HostWildcardCondition" msgstr "" msgid "condition_help_HostWildcardCondition" msgstr "" msgid "condition_HostRegexCondition" msgstr "" msgid "condition_help_HostRegexCondition" msgstr "" msgid "condition_HostLevelsCondition" msgstr "" msgid "condition_help_HostLevelsCondition" msgstr "" msgid "condition_IpCondition" msgstr "IP Literals" msgid "condition_help_IpCondition" msgstr "" "Matches the request if and only if the host is a literal IP address and" " in the subnet as specified by " "CIDR notation.
For example, given the rule 127.0.0.1/16, " "it matches all IP addresses like 127.0.*.*.
" "So 127.0.0.1 matches while 127.1.0.0 does not. " "Host names like localhost will never match because they are " "not IP literals." msgid "condition_UrlWildcardCondition" msgstr "" msgid "condition_help_UrlWildcardCondition" msgstr "" msgid "condition_UrlRegexCondition" msgstr "" msgid "condition_help_UrlRegexCondition" msgstr "" msgid "condition_KeywordCondition" msgstr "" msgid "condition_help_KeywordCondition" msgstr "" msgid "condition_FalseCondition" msgstr "" msgid "condition_details_FalseCondition" msgstr "" msgid "condition_help_FalseCondition" msgstr "" msgid "condition_TimeCondition" msgstr "" msgid "condition_help_TimeCondition" msgstr "" msgid "condition_WeekdayCondition" msgstr "" msgid "condition_help_WeekdayCondition" msgstr "" msgid "condition_alert_fullUrlLimitation" msgstr "" "Full URL matching is no longer possible for https:// " "URLs as of Chrome 52. " "" "Learn more..." msgid "condition_alert_fullUrlLimitationLink" msgstr "https://github.com/FelisCatus/SwitchyOmega/wiki/Chromium-Full-URL-Limitation" msgid "condition_group_default" msgstr "" msgid "condition_group_host" msgstr "" msgid "condition_group_url" msgstr "" msgid "condition_group_special" msgstr "" msgid "ruleListFormat_Switchy" msgstr "" msgid "ruleListFormat_AutoProxy" msgstr "" msgid "ruleList_usageUrl" msgstr "" msgid "ruleList_error_resultNotEnabled" msgstr "" msgid "ruleList_error_unknownProfile" msgstr "" msgid "ruleList_error_missingResultProfile" msgstr "" msgid "ruleList_error_invalidRule" msgstr "" msgid "ruleList_error_noDefaultRule" msgstr "" msgid "dialog_close" msgstr "" msgid "dialog_save" msgstr "" msgid "dialog_ok" msgstr "" msgid "dialog_cancel" msgstr "" msgid "inputClear_clear" msgstr "" msgid "inputClear_restore" msgstr "" msgid "options_title" msgstr "" msgid "options_experimental_badge" msgstr "α" msgid "options_navHeader_setting" msgstr "" msgid "options_navHeader_profiles" msgstr "" msgid "options_navHeader_actions" msgstr "" msgid "options_tab_ui" msgstr "" msgid "options_tab_general" msgstr "" msgid "options_tab_importExport" msgstr "" msgid "options_newProfile" msgstr "" msgid "options_apply" msgstr "" msgid "options_discard" msgstr "" msgid "options_reset" msgstr "" msgid "options_group_miscOptions" msgstr "" msgid "options_confirmDeletion" msgstr "" msgid "options_refreshOnProfileChange" msgstr "" msgid "options_showInspectMenu" msgstr "" msgid "options_addConditionsToBottom" msgstr "Put new conditions added using the popup to the bottom of the list." msgid "options_group_keyboardShortcut" msgstr "" msgid "options_menuShortcutHelp" msgstr "" msgid "options_menuShortcutMore" msgstr "" msgid "options_menuShortcutConfigure" msgstr "" msgid "options_group_switchOptions" msgstr "" msgid "options_startupProfile" msgstr "" msgid "options_startupProfile_none" msgstr "" msgid "options_showConditionTypesAdvanced" msgstr "" msgid "options_showConditionTypesAdvancedHelp" msgstr "" msgid "options_quickSwitch" msgstr "" msgid "options_cycledProfiles" msgstr "" msgid "options_cycledProfilesHelp" msgstr "" msgid "options_cycledProfilesTooFew" msgstr "" msgid "options_notCycledProfiles" msgstr "" msgid "options_group_proxyChanges" msgstr "" msgid "options_revertProxyChanges" msgstr "" msgid "options_group_conflicts" msgstr "Conflicts" msgid "options_conflicts_introduction" msgstr "" "Sometimes, other apps will also try to control the proxy settings, resulting " "in conflicts. Note that ad blockers and other extensions may also use proxy " "settings under the hood. Such conflicts cannot be avoided due to how the " "browser works." msgid "options_conflicts_lowerPriority" msgstr "" "A red badge like this on the SwitchyOmega icon indicates that another app has " "higher priority so SwitchyOmega cannot control the settings. Please try to " "uninstall SwitchyOmega and reinstall, which should raise SwitchyOmega's " "priority. If you still see conflicts after reinstallation, please consider " "removing the other app causing the conflict." msgid "options_conflicts_higherPriority" msgstr "" "If SwitchyOmega has higher priority, you can give the control back to other " "apps or system settings by selecting $SYSTEMPROFILE$ in the popup menu." msgid "options_showExternalProfile" msgstr "Show popup menu item to import proxy settings from other apps." msgid "options_showExternalProfileHelp" msgstr "" "When $SYSTEMPROFILE$ is selected, you can import the effective proxy settings " "from other apps by selecting $EXTERNALPROFILE$ on the popup menu. " "The settings will be imported as a profile using the name you provide. " "Please note that the imported profile is a snapshot and will not reflect " "any changes from the source app thereafter." msgid "options_group_networkRequests" msgstr "" msgid "options_monitorWebRequests" msgstr "" msgid "options_monitorWebRequestsHelp" msgstr "" msgid "options_downloadOptions" msgstr "" msgid "options_downloadOptionsHelp" msgstr "" msgid "options_downloadInterval" msgstr "" msgid "options_downloadInterval_15" msgstr "" msgid "options_downloadInterval_60" msgstr "" msgid "options_downloadInterval_180" msgstr "" msgid "options_downloadInterval_360" msgstr "" msgid "options_downloadInterval_720" msgstr "" msgid "options_downloadInterval_1440" msgstr "" msgid "options_downloadInterval_never" msgstr "" msgid "options_group_importExportProfile" msgstr "" msgid "options_exportPacFile" msgstr "" msgid "options_exportPacFileHelp" msgstr "" msgid "options_exportProfileHelp" msgstr "" msgid "options_exportLegacyRuleList" msgstr "" msgid "options_exportLegacyRuleListHelp" msgstr "" msgid "options_group_importExportSettings" msgstr "" msgid "options_makeBackup" msgstr "" msgid "options_makeBackupHelp" msgstr "" msgid "options_restoreLocal" msgstr "" msgid "options_restoreLocalHelp" msgstr "" msgid "options_restoreOnline" msgstr "" msgid "options_restoreOnlinePlaceholder" msgstr "" msgid "options_restoreOnlineSubmit" msgstr "" msgid "options_group_syncing" msgstr "" msgid "options_syncEnable" msgstr "" msgid "options_syncEnableForce" msgstr "" msgid "options_syncDisable" msgstr "" msgid "options_syncReset" msgstr "" msgid "options_syncPristineHelp" msgstr "" msgid "options_syncSyncAlert" msgstr "" msgid "options_syncSyncHelp" msgstr "" msgid "options_syncConflictAlert" msgstr "" msgid "options_syncConflictHelp" msgstr "" msgid "options_syncUnsupportedHelp" msgstr "" msgid "options_profileSyncDisabled" msgstr "" msgid "options_profileSyncDisabled_quotaPerItem" msgstr "" msgid "options_profileTabPrefix" msgstr "" msgid "options_renameProfile" msgstr "" msgid "options_deleteProfile" msgstr "" msgid "options_profileExportRuleList" msgstr "" msgid "options_profileExportRuleListHelp" msgstr "" msgid "options_profileExportPac" msgstr "" msgid "options_profileUnsupported" msgstr "" msgid "options_profileUnsupportedHelp" msgstr "" msgid "options_profileEditSource" msgstr "" msgid "options_profileEditSourceHelp" msgstr "" msgid "options_profileEditSourceHelpUrl" msgstr "" msgid "options_group_proxyServers" msgstr "" msgid "options_proxy_scheme" msgstr "" msgid "options_proxy_protocol" msgstr "" msgid "options_proxy_server" msgstr "" msgid "options_proxy_port" msgstr "" msgid "options_proxy_auth" msgstr "" msgid "options_proxy_authNotSupported" msgstr "Your browser DOES NOT support $PROTOCOLDISP$ proxy authentication! " "Please do not report this issue to SwitchyOmega. Contact the support for " "your browser instead." msgid "options_proxy_authAllWarningPac" msgstr "" msgid "options_proxy_authAllWarningPacUrl" msgstr "" msgid "options_proxy_authAllWarningPacScript" msgstr "" msgid "options_proxy_authReferencedWarning" msgstr "" msgid "options_scheme_default" msgstr "" msgid "options_protocol_direct" msgstr "" msgid "options_protocol_useDefault" msgstr "" msgid "options_proxy_single" msgstr "" msgid "options_proxy_expand" msgstr "" msgid "options_group_bypassList" msgstr "" msgid "options_bypassListHelp" msgstr "" msgid "options_bypassListHelpLinkText" msgstr "" msgid "options_group_pacUrl" msgstr "" msgid "options_pacUrlHelp" msgstr "" msgid "options_pacUrlFile" msgstr "" msgid "options_pacUrlFileDisabled" msgstr "" msgid "options_group_pacScript" msgstr "" msgid "options_pacScriptLastUpdate" msgstr "" msgid "options_pacScriptObsolete" msgstr "" msgid "options_group_virtualProfile" msgstr "" msgid "options_virtualProfileTarget" msgstr "" msgid "options_virtualProfileTargetHelp" msgstr "" msgid "options_group_virtualProfileReplace" msgstr "" msgid "options_virtualProfileReplace" msgstr "" msgid "options_virtualProfileReplaceHelp" msgstr "" msgid "options_group_ruleListConfig" msgstr "" msgid "options_ruleListFormat" msgstr "" msgid "options_group_ruleListResult" msgstr "" msgid "options_ruleListMatchProfile" msgstr "" msgid "options_ruleListDefaultProfile" msgstr "" msgid "options_group_ruleListUrl" msgstr "" msgid "options_ruleListUrlHelp" msgstr "" msgid "options_group_ruleListText" msgstr "" msgid "options_ruleListLastUpdate" msgstr "" msgid "options_ruleListObsolete" msgstr "" msgid "options_group_switchRules" msgstr "" msgid "options_sort" msgstr "" msgid "options_conditionType" msgstr "" msgid "options_showConditionTypeHelp" msgstr "" msgid "options_conditionDetails" msgstr "" msgid "options_resultProfile" msgstr "" msgid "options_conditionActions" msgstr "" msgid "options_addCondition" msgstr "" msgid "options_cloneRule" msgstr "" msgid "options_ruleNote" msgstr "Note" msgid "options_switchAttachedProfileInCondition" msgstr "" msgid "options_switchAttachedProfileInConditionDetails" msgstr "" msgid "options_switchAttachedProfileInConditionDisabled" msgstr "" msgid "options_switchDefaultProfile" msgstr "" msgid "options_hostLevelsBetween" msgstr "" msgid "options_hourBetween" msgstr "" msgid "options_weekDayShort_0" msgstr "" msgid "options_weekDayShort_1" msgstr "" msgid "options_weekDayShort_2" msgstr "" msgid "options_weekDayShort_3" msgstr "" msgid "options_weekDayShort_4" msgstr "" msgid "options_weekDayShort_5" msgstr "" msgid "options_weekDayShort_6" msgstr "" msgid "options_group_conditionHelp" msgstr "" msgid "options_group_attachProfile" msgstr "" msgid "options_attachProfile" msgstr "" msgid "options_attachProfileHelp" msgstr "" msgid "options_modalHeader_welcome" msgstr "" msgid "options_welcomeNormal" msgstr "" msgid "options_welcomeNormalGuide" msgstr "" msgid "options_welcomeUpgrade" msgstr "" msgid "options_welcomeUpgradeGuide" msgstr "" msgid "options_guideNext" msgstr "" msgid "options_guideDone" msgstr "" msgid "options_guideSkip" msgstr "" msgid "options_modalHeader_applyOptions" msgstr "" msgid "options_optionsNotSaved" msgstr "" msgid "options_applyOptionsRequired" msgstr "" msgid "options_applyOptionsConfirm" msgstr "" msgid "options_modalHeader_renameProfile" msgstr "" msgid "options_renameProfileName" msgstr "" msgid "options_profileNameConflict" msgstr "" msgid "options_profileNameReserved" msgstr "" msgid "options_profileNameHidden" msgstr "" msgid "options_modalHeader_replaceProfile" msgstr "" msgid "options_replaceProfile" msgstr "" msgid "options_replaceProfileConfirm" msgstr "" msgid "options_replaceProfileHelp" msgstr "" msgid "options_replaceProfileSuccess" msgstr "" msgid "options_modalHeader_deleteProfile" msgstr "" msgid "options_deleteProfileConfirm" msgstr "" msgid "options_modalHeader_cannotDeleteProfile" msgstr "" msgid "options_profileReferredBy" msgstr "" msgid "options_modifyReferringProfiles" msgstr "" msgid "options_profileNameEmpty" msgstr "" msgid "popup_title" msgstr "" msgid "options_modalHeader_proxyAuth" msgstr "" msgid "options_proxyAuthUsername" msgstr "" msgid "options_proxyAuthPassword" msgstr "" msgid "options_proxyAuthShowPassword" msgstr "Show password" msgid "options_proxyAuthHidePassword" msgstr "Hide password" msgid "options_proxyAuthNone" msgstr "" msgid "options_modalHeader_deleteRule" msgstr "" msgid "options_deleteRuleConfirm" msgstr "" msgid "options_deleteRule" msgstr "" msgid "options_modalHeader_resetRules" msgstr "" msgid "options_resetRulesConfirm" msgstr "" msgid "options_resetRules" msgstr "" msgid "options_resetRules_help" msgstr "" msgid "options_modalHeader_deleteAttached" msgstr "" msgid "options_deleteAttachedConfirm" msgstr "" msgid "options_ruleListLineCount" msgstr "" msgid "options_deleteAttached" msgstr "" msgid "options_modalHeader_newProfile" msgstr "" msgid "options_newProfileName" msgstr "" msgid "options_profileType" msgstr "" msgid "options_profileTypeFixedProfile" msgstr "" msgid "options_profileDescFixedProfile" msgstr "" msgid "options_profileTypePacProfile" msgstr "" msgid "options_profileDescPacProfile" msgstr "" msgid "options_profileDescMorePacProfile" msgstr "" msgid "options_profileTypeSwitchProfile" msgstr "" msgid "options_profileDescSwitchProfile" msgstr "" msgid "options_profileTypeRuleListProfile" msgstr "" msgid "options_profileDescRuleListProfile" msgstr "" msgid "options_profileTypeVirtualProfile" msgstr "" msgid "options_profileDescVirtualProfile" msgstr "" msgid "options_createProfile" msgstr "" msgid "options_modalHeader_resetOptions" msgstr "" msgid "options_resetOptionsConfirm" msgstr "" msgid "options_formInvalid" msgstr "" msgid "options_profileNotFound" msgstr "" msgid "options_resetSuccess" msgstr "" msgid "options_saveSuccess" msgstr "" msgid "options_importSuccess" msgstr "" msgid "options_importFormatError" msgstr "" msgid "options_importDownloadError" msgstr "" msgid "options_profileDownloadSuccess" msgstr "" msgid "options_profileDownloadError" msgstr "" msgid "options_profileDownloadError_NetworkError" msgstr "A network error occurred when updating." msgid "options_profileDownloadError_HttpError" msgstr "An HTTP error ($STATUS$) occurred when updating." msgid "options_profileDownloadError_HttpNotFoundError" msgstr "The Profile URL was not found on the server. Please double-check." msgid "options_profileDownloadError_HttpServerError" msgstr "The remote server responded with error ($STATUS$) when updating." msgid "options_profileDownloadError_ContentTypeRejectedError" msgstr "The downloaded data is invalid! " "You may open the Profile URL in your browser to inspect it." msgid "options_downloadProfileNow" msgstr "" msgid "options_guide_fixedProfileStep" msgstr "" msgid "options_guide_fixedServersStep" msgstr "" msgid "options_guide_autoSwitchProfileStep" msgstr "" msgid "options_guide_addMoreProfilesStep" msgstr "" msgid "options_guide_conditionStep" msgstr "" msgid "options_guide_conditionTypeStep" msgstr "" msgid "options_guide_conditionProfileStep" msgstr "" msgid "options_guide_switchDefaultStep" msgstr "" msgid "options_guide_applySwitchProfileStep" msgstr "" msgid "popup_externalProfile" msgstr "" msgid "popup_externalProfileName" msgstr "" msgid "popup_proxyNotControllable_app" msgstr "" msgid "popup_proxyNotControllable_policy" msgstr "" msgid "popup_proxyNotControllable_unknown" msgstr "" msgid "popup_proxyNotControllable_disabled" msgstr "" msgid "popup_proxyNotControllable_upgrade" msgstr "" msgid "popup_proxyNotControllableDetails" msgstr "" msgid "popup_proxyNotControllableDetails_upgrade" msgstr "" msgid "popup_proxyNotControllableManage" msgstr "" msgid "popup_addConditionTo" msgstr "" msgid "popup_addCondition" msgstr "" msgid "popup_showOptions" msgstr "" msgid "popup_reportIssues" msgstr "" msgid "popup_errorLog" msgstr "" msgid "popup_requestErrorCount" msgstr "" msgid "popup_requestErrorHeading" msgstr "" msgid "popup_requestErrorWarning" msgstr "" msgid "popup_requestErrorWarningHelp" msgstr "" msgid "popup_requestErrorAddCondition" msgstr "" msgid "popup_requestErrorCannotAddCondition" msgstr "" msgid "popup_configureMonitorWebRequests" msgstr "" msgid "options_resultProfileForSelectedDomains" msgstr "" msgid "options_pac_profile_unsupported_moz" msgstr "PAC Profiles WILL NOT work in Mozilla Firefox due to technical limitations!" msgid "popup_issueTemplate" msgstr "" msgid "browserAction_profileDetails_PacProfile" msgstr "" msgid "browserAction_profileDetails_SystemProfile" msgstr "" msgid "browserAction_profileDetails_DirectProfile" msgstr "" msgid "browserAction_profileDetails_SwitchProfile" msgstr "" msgid "browserAction_profileDetails_RuleListProfile" msgstr "" msgid "browserAction_titleNormal" msgstr "" msgid "browserAction_titleWithResult" msgstr "" msgid "browserAction_titleNewerOptions" msgstr "" msgid "browserAction_titleOptionError" msgstr "" msgid "browserAction_titleDownloadFail" msgstr "" msgid "browserAction_titleExternalProxy" msgstr "" msgid "browserAction_titleInspect" msgstr "" msgid "browserAction_defaultRuleDetails" msgstr "" msgid "browserAction_directResult" msgstr "" msgid "browserAction_attachedPrefix" msgstr "" msgid "browserAction_tempRulePrefix" msgstr "" msgid "contextMenu_inspectPage" msgstr "" msgid "contextMenu_inspectFrame" msgstr "" msgid "contextMenu_inspectLink" msgstr "" msgid "contextMenu_inspectElement" msgstr "" msgid "contextMenu_enableQuickSwitch" msgstr "" msgid "about_title" msgstr "About" msgid "about_app_description" msgstr "A proxy configuration tool" msgid "about_version" msgstr "Version $VERSION$" msgid "about_experimental_warning_moz" msgstr "Mozilla Firefox support is highly experimental! If you encounter issues, please report using the buttons below." msgid "about_disclaimer_networkService" msgstr "SwitchyOmega does not provide proxies, VPNs, or other network services." msgid "about_disclaimer_privacy" msgstr "SwitchyOmega does not track you or insert ads into webpages. Please see" " our privacy policy." msgid "about_help" msgstr "Other questions? Need help with using SwitchyOmega? Please see our " "FAQ." msgid "about_copyright" msgstr "Copyright 2012-2017 The SwitchyOmega Authors. All rights reserved." msgid "about_credits" msgstr "SwitchyOmega is made possible by the SwitchyOmega open source project and other open source software." msgid "about_license" msgstr "SwitchyOmega is free software licensed under GNU General Public License Version 3 or later." ================================================ FILE: omega-locales/sl/LC_MESSAGES/omega-web.po ================================================ msgid "" msgstr "" "Project-Id-Version: SwitchyOmega 2.3.3\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2015-02-13 10:29+0000\n" "PO-Revision-Date: 2016-05-12 10:47+0000\n" "Last-Translator: Štefan Baebler \n" "Language-Team: Slovenian " "\n" "Language: sl\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=4; plural=n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || " "n%100==4 ? 2 : 3;\n" "X-Generator: Weblate 2.7-dev\n" msgid "appNameShort" msgstr "SwitchyOmega" msgid "manifest_app_name" msgstr "" msgid "manifest_app_description" msgstr "" msgid "manifest_icon_default_title" msgstr "Nalaganje…" msgid "upgrade_profile_auto" msgstr "Samodejna izbira" msgid "profile_direct" msgstr "[Neposredno]" msgid "profile_system" msgstr "" msgid "condition_HostWildcardCondition" msgstr "" msgid "condition_help_HostWildcardCondition" msgstr "" msgid "condition_HostRegexCondition" msgstr "" msgid "condition_help_HostRegexCondition" msgstr "" msgid "condition_HostLevelsCondition" msgstr "" msgid "condition_help_HostLevelsCondition" msgstr "" msgid "condition_IpCondition" msgstr "IP Literals" msgid "condition_help_IpCondition" msgstr "" "Matches the request if and only if the host is a literal IP address and" " in the subnet as specified by " "CIDR notation.
For example, given the rule 127.0.0.1/16, " "it matches all IP addresses like 127.0.*.*.
" "So 127.0.0.1 matches while 127.1.0.0 does not. " "Host names like localhost will never match because they are " "not IP literals." msgid "condition_UrlWildcardCondition" msgstr "" msgid "condition_help_UrlWildcardCondition" msgstr "" msgid "condition_UrlRegexCondition" msgstr "" msgid "condition_help_UrlRegexCondition" msgstr "" msgid "condition_KeywordCondition" msgstr "" msgid "condition_help_KeywordCondition" msgstr "" msgid "condition_FalseCondition" msgstr "" msgid "condition_details_FalseCondition" msgstr "" msgid "condition_help_FalseCondition" msgstr "" msgid "condition_TimeCondition" msgstr "" msgid "condition_help_TimeCondition" msgstr "" msgid "condition_WeekdayCondition" msgstr "" msgid "condition_help_WeekdayCondition" msgstr "" msgid "condition_alert_fullUrlLimitation" msgstr "" "Full URL matching is no longer possible for https:// " "URLs as of Chrome 52. " "" "Learn more..." msgid "condition_alert_fullUrlLimitationLink" msgstr "https://github.com/FelisCatus/SwitchyOmega/wiki/Chromium-Full-URL-Limitation" msgid "condition_group_default" msgstr "" msgid "condition_group_host" msgstr "" msgid "condition_group_url" msgstr "" msgid "condition_group_special" msgstr "" msgid "ruleListFormat_Switchy" msgstr "" msgid "ruleListFormat_AutoProxy" msgstr "" msgid "ruleList_usageUrl" msgstr "" msgid "ruleList_error_resultNotEnabled" msgstr "" msgid "ruleList_error_unknownProfile" msgstr "" msgid "ruleList_error_missingResultProfile" msgstr "" msgid "ruleList_error_invalidRule" msgstr "" msgid "ruleList_error_noDefaultRule" msgstr "" msgid "dialog_close" msgstr "" msgid "dialog_save" msgstr "" msgid "dialog_ok" msgstr "" msgid "dialog_cancel" msgstr "" msgid "inputClear_clear" msgstr "" msgid "inputClear_restore" msgstr "" msgid "options_title" msgstr "" msgid "options_experimental_badge" msgstr "α" msgid "options_navHeader_setting" msgstr "" msgid "options_navHeader_profiles" msgstr "" msgid "options_navHeader_actions" msgstr "" msgid "options_tab_ui" msgstr "" msgid "options_tab_general" msgstr "" msgid "options_tab_importExport" msgstr "" msgid "options_newProfile" msgstr "" msgid "options_apply" msgstr "" msgid "options_discard" msgstr "" msgid "options_reset" msgstr "" msgid "options_group_miscOptions" msgstr "" msgid "options_confirmDeletion" msgstr "" msgid "options_refreshOnProfileChange" msgstr "" msgid "options_showInspectMenu" msgstr "" msgid "options_addConditionsToBottom" msgstr "Put new conditions added using the popup to the bottom of the list." msgid "options_group_keyboardShortcut" msgstr "" msgid "options_menuShortcutHelp" msgstr "" msgid "options_menuShortcutMore" msgstr "" msgid "options_menuShortcutConfigure" msgstr "" msgid "options_group_switchOptions" msgstr "" msgid "options_startupProfile" msgstr "" msgid "options_startupProfile_none" msgstr "" msgid "options_showConditionTypesAdvanced" msgstr "" msgid "options_showConditionTypesAdvancedHelp" msgstr "" msgid "options_quickSwitch" msgstr "" msgid "options_cycledProfiles" msgstr "" msgid "options_cycledProfilesHelp" msgstr "" msgid "options_cycledProfilesTooFew" msgstr "" msgid "options_notCycledProfiles" msgstr "" msgid "options_group_proxyChanges" msgstr "" msgid "options_revertProxyChanges" msgstr "" msgid "options_group_conflicts" msgstr "Conflicts" msgid "options_conflicts_introduction" msgstr "" "Sometimes, other apps will also try to control the proxy settings, resulting " "in conflicts. Note that ad blockers and other extensions may also use proxy " "settings under the hood. Such conflicts cannot be avoided due to how the " "browser works." msgid "options_conflicts_lowerPriority" msgstr "" "A red badge like this on the SwitchyOmega icon indicates that another app has " "higher priority so SwitchyOmega cannot control the settings. Please try to " "uninstall SwitchyOmega and reinstall, which should raise SwitchyOmega's " "priority. If you still see conflicts after reinstallation, please consider " "removing the other app causing the conflict." msgid "options_conflicts_higherPriority" msgstr "" "If SwitchyOmega has higher priority, you can give the control back to other " "apps or system settings by selecting $SYSTEMPROFILE$ in the popup menu." msgid "options_showExternalProfile" msgstr "Show popup menu item to import proxy settings from other apps." msgid "options_showExternalProfileHelp" msgstr "" "When $SYSTEMPROFILE$ is selected, you can import the effective proxy settings " "from other apps by selecting $EXTERNALPROFILE$ on the popup menu. " "The settings will be imported as a profile using the name you provide. " "Please note that the imported profile is a snapshot and will not reflect " "any changes from the source app thereafter." msgid "options_group_networkRequests" msgstr "" msgid "options_monitorWebRequests" msgstr "" msgid "options_monitorWebRequestsHelp" msgstr "" msgid "options_downloadOptions" msgstr "" msgid "options_downloadOptionsHelp" msgstr "" msgid "options_downloadInterval" msgstr "" msgid "options_downloadInterval_15" msgstr "" msgid "options_downloadInterval_60" msgstr "" msgid "options_downloadInterval_180" msgstr "" msgid "options_downloadInterval_360" msgstr "" msgid "options_downloadInterval_720" msgstr "" msgid "options_downloadInterval_1440" msgstr "" msgid "options_downloadInterval_never" msgstr "" msgid "options_group_importExportProfile" msgstr "" msgid "options_exportPacFile" msgstr "" msgid "options_exportPacFileHelp" msgstr "" msgid "options_exportProfileHelp" msgstr "" msgid "options_exportLegacyRuleList" msgstr "" msgid "options_exportLegacyRuleListHelp" msgstr "" msgid "options_group_importExportSettings" msgstr "" msgid "options_makeBackup" msgstr "" msgid "options_makeBackupHelp" msgstr "" msgid "options_restoreLocal" msgstr "" msgid "options_restoreLocalHelp" msgstr "" msgid "options_restoreOnline" msgstr "" msgid "options_restoreOnlinePlaceholder" msgstr "" msgid "options_restoreOnlineSubmit" msgstr "" msgid "options_group_syncing" msgstr "" msgid "options_syncEnable" msgstr "" msgid "options_syncEnableForce" msgstr "" msgid "options_syncDisable" msgstr "" msgid "options_syncReset" msgstr "" msgid "options_syncPristineHelp" msgstr "" msgid "options_syncSyncAlert" msgstr "" msgid "options_syncSyncHelp" msgstr "" msgid "options_syncConflictAlert" msgstr "" msgid "options_syncConflictHelp" msgstr "" msgid "options_syncUnsupportedHelp" msgstr "" msgid "options_profileSyncDisabled" msgstr "" msgid "options_profileSyncDisabled_quotaPerItem" msgstr "" msgid "options_profileTabPrefix" msgstr "" msgid "options_renameProfile" msgstr "" msgid "options_deleteProfile" msgstr "" msgid "options_profileExportRuleList" msgstr "" msgid "options_profileExportRuleListHelp" msgstr "" msgid "options_profileExportPac" msgstr "" msgid "options_profileUnsupported" msgstr "" msgid "options_profileUnsupportedHelp" msgstr "" msgid "options_profileEditSource" msgstr "" msgid "options_profileEditSourceHelp" msgstr "" msgid "options_profileEditSourceHelpUrl" msgstr "" msgid "options_group_proxyServers" msgstr "" msgid "options_proxy_scheme" msgstr "" msgid "options_proxy_protocol" msgstr "" msgid "options_proxy_server" msgstr "" msgid "options_proxy_port" msgstr "" msgid "options_proxy_auth" msgstr "" msgid "options_proxy_authNotSupported" msgstr "Your browser DOES NOT support $PROTOCOLDISP$ proxy authentication! " "Please do not report this issue to SwitchyOmega. Contact the support for " "your browser instead." msgid "options_proxy_authAllWarningPac" msgstr "" msgid "options_proxy_authAllWarningPacUrl" msgstr "" msgid "options_proxy_authAllWarningPacScript" msgstr "" msgid "options_proxy_authReferencedWarning" msgstr "" msgid "options_scheme_default" msgstr "" msgid "options_protocol_direct" msgstr "" msgid "options_protocol_useDefault" msgstr "" msgid "options_proxy_single" msgstr "" msgid "options_proxy_expand" msgstr "" msgid "options_group_bypassList" msgstr "" msgid "options_bypassListHelp" msgstr "" msgid "options_bypassListHelpLinkText" msgstr "" msgid "options_group_pacUrl" msgstr "" msgid "options_pacUrlHelp" msgstr "" msgid "options_pacUrlFile" msgstr "" msgid "options_pacUrlFileDisabled" msgstr "" msgid "options_group_pacScript" msgstr "" msgid "options_pacScriptLastUpdate" msgstr "" msgid "options_pacScriptObsolete" msgstr "" msgid "options_group_virtualProfile" msgstr "" msgid "options_virtualProfileTarget" msgstr "" msgid "options_virtualProfileTargetHelp" msgstr "" msgid "options_group_virtualProfileReplace" msgstr "" msgid "options_virtualProfileReplace" msgstr "" msgid "options_virtualProfileReplaceHelp" msgstr "" msgid "options_group_ruleListConfig" msgstr "" msgid "options_ruleListFormat" msgstr "" msgid "options_group_ruleListResult" msgstr "" msgid "options_ruleListMatchProfile" msgstr "" msgid "options_ruleListDefaultProfile" msgstr "" msgid "options_group_ruleListUrl" msgstr "" msgid "options_ruleListUrlHelp" msgstr "" msgid "options_group_ruleListText" msgstr "" msgid "options_ruleListLastUpdate" msgstr "" msgid "options_ruleListObsolete" msgstr "" msgid "options_group_switchRules" msgstr "" msgid "options_sort" msgstr "" msgid "options_conditionType" msgstr "" msgid "options_showConditionTypeHelp" msgstr "" msgid "options_conditionDetails" msgstr "" msgid "options_resultProfile" msgstr "" msgid "options_conditionActions" msgstr "" msgid "options_addCondition" msgstr "" msgid "options_cloneRule" msgstr "" msgid "options_ruleNote" msgstr "Note" msgid "options_switchAttachedProfileInCondition" msgstr "" msgid "options_switchAttachedProfileInConditionDetails" msgstr "" msgid "options_switchAttachedProfileInConditionDisabled" msgstr "" msgid "options_switchDefaultProfile" msgstr "" msgid "options_hostLevelsBetween" msgstr "" msgid "options_hourBetween" msgstr "" msgid "options_weekDayShort_0" msgstr "" msgid "options_weekDayShort_1" msgstr "" msgid "options_weekDayShort_2" msgstr "" msgid "options_weekDayShort_3" msgstr "" msgid "options_weekDayShort_4" msgstr "" msgid "options_weekDayShort_5" msgstr "" msgid "options_weekDayShort_6" msgstr "" msgid "options_group_conditionHelp" msgstr "" msgid "options_group_attachProfile" msgstr "" msgid "options_attachProfile" msgstr "" msgid "options_attachProfileHelp" msgstr "" msgid "options_modalHeader_welcome" msgstr "" msgid "options_welcomeNormal" msgstr "" msgid "options_welcomeNormalGuide" msgstr "" msgid "options_welcomeUpgrade" msgstr "" msgid "options_welcomeUpgradeGuide" msgstr "" msgid "options_guideNext" msgstr "" msgid "options_guideDone" msgstr "" msgid "options_guideSkip" msgstr "" msgid "options_modalHeader_applyOptions" msgstr "" msgid "options_optionsNotSaved" msgstr "" msgid "options_applyOptionsRequired" msgstr "" msgid "options_applyOptionsConfirm" msgstr "" msgid "options_modalHeader_renameProfile" msgstr "" msgid "options_renameProfileName" msgstr "" msgid "options_profileNameConflict" msgstr "" msgid "options_profileNameReserved" msgstr "" msgid "options_profileNameHidden" msgstr "" msgid "options_modalHeader_replaceProfile" msgstr "" msgid "options_replaceProfile" msgstr "" msgid "options_replaceProfileConfirm" msgstr "" msgid "options_replaceProfileHelp" msgstr "" msgid "options_replaceProfileSuccess" msgstr "" msgid "options_modalHeader_deleteProfile" msgstr "" msgid "options_deleteProfileConfirm" msgstr "" msgid "options_modalHeader_cannotDeleteProfile" msgstr "" msgid "options_profileReferredBy" msgstr "" msgid "options_modifyReferringProfiles" msgstr "" msgid "options_profileNameEmpty" msgstr "" msgid "popup_title" msgstr "" msgid "options_modalHeader_proxyAuth" msgstr "" msgid "options_proxyAuthUsername" msgstr "Uporabniško ime" msgid "options_proxyAuthPassword" msgstr "Geslo" msgid "options_proxyAuthShowPassword" msgstr "Show password" msgid "options_proxyAuthHidePassword" msgstr "Hide password" msgid "options_proxyAuthNone" msgstr "Brez preverjanja pristnosti" msgid "options_modalHeader_deleteRule" msgstr "Izbriši pravilo" msgid "options_deleteRuleConfirm" msgstr "Ali res želite izbrisati to pravilo?" msgid "options_deleteRule" msgstr "Izbriši" msgid "options_modalHeader_resetRules" msgstr "Ponastavitev pravil" msgid "options_resetRulesConfirm" msgstr "" msgid "options_resetRules" msgstr "Ponastavitev pravil" msgid "options_resetRules_help" msgstr "" msgid "options_modalHeader_deleteAttached" msgstr "" msgid "options_deleteAttachedConfirm" msgstr "" msgid "options_ruleListLineCount" msgstr "" msgid "options_deleteAttached" msgstr "" msgid "options_modalHeader_newProfile" msgstr "Nov profil" msgid "options_newProfileName" msgstr "Ime profila" msgid "options_profileType" msgstr "Izberite vrsto profila:" msgid "options_profileTypeFixedProfile" msgstr "" msgid "options_profileDescFixedProfile" msgstr "" msgid "options_profileTypePacProfile" msgstr "" msgid "options_profileDescPacProfile" msgstr "" msgid "options_profileDescMorePacProfile" msgstr "" msgid "options_profileTypeSwitchProfile" msgstr "" msgid "options_profileDescSwitchProfile" msgstr "" msgid "options_profileTypeRuleListProfile" msgstr "" msgid "options_profileDescRuleListProfile" msgstr "" msgid "options_profileTypeVirtualProfile" msgstr "" msgid "options_profileDescVirtualProfile" msgstr "" msgid "options_createProfile" msgstr "" msgid "options_modalHeader_resetOptions" msgstr "" msgid "options_resetOptionsConfirm" msgstr "" msgid "options_formInvalid" msgstr "" msgid "options_profileNotFound" msgstr "" msgid "options_resetSuccess" msgstr "" msgid "options_saveSuccess" msgstr "" msgid "options_importSuccess" msgstr "" msgid "options_importFormatError" msgstr "" msgid "options_importDownloadError" msgstr "" msgid "options_profileDownloadSuccess" msgstr "" msgid "options_profileDownloadError" msgstr "" msgid "options_profileDownloadError_NetworkError" msgstr "A network error occurred when updating." msgid "options_profileDownloadError_HttpError" msgstr "An HTTP error ($STATUS$) occurred when updating." msgid "options_profileDownloadError_HttpNotFoundError" msgstr "The Profile URL was not found on the server. Please double-check." msgid "options_profileDownloadError_HttpServerError" msgstr "The remote server responded with error ($STATUS$) when updating." msgid "options_profileDownloadError_ContentTypeRejectedError" msgstr "The downloaded data is invalid! " "You may open the Profile URL in your browser to inspect it." msgid "options_downloadProfileNow" msgstr "" msgid "options_guide_fixedProfileStep" msgstr "" msgid "options_guide_fixedServersStep" msgstr "" msgid "options_guide_autoSwitchProfileStep" msgstr "" msgid "options_guide_addMoreProfilesStep" msgstr "" msgid "options_guide_conditionStep" msgstr "" msgid "options_guide_conditionTypeStep" msgstr "" msgid "options_guide_conditionProfileStep" msgstr "" msgid "options_guide_switchDefaultStep" msgstr "" msgid "options_guide_applySwitchProfileStep" msgstr "" msgid "popup_externalProfile" msgstr "" msgid "popup_externalProfileName" msgstr "" msgid "popup_proxyNotControllable_app" msgstr "" msgid "popup_proxyNotControllable_policy" msgstr "" msgid "popup_proxyNotControllable_unknown" msgstr "" msgid "popup_proxyNotControllable_disabled" msgstr "" msgid "popup_proxyNotControllable_upgrade" msgstr "" msgid "popup_proxyNotControllableDetails" msgstr "" msgid "popup_proxyNotControllableDetails_upgrade" msgstr "" msgid "popup_proxyNotControllableManage" msgstr "" msgid "popup_addConditionTo" msgstr "" msgid "popup_addCondition" msgstr "" msgid "popup_showOptions" msgstr "" msgid "popup_reportIssues" msgstr "" msgid "popup_errorLog" msgstr "" msgid "popup_requestErrorCount" msgstr "" msgid "popup_requestErrorHeading" msgstr "" msgid "popup_requestErrorWarning" msgstr "" msgid "popup_requestErrorWarningHelp" msgstr "" msgid "popup_requestErrorAddCondition" msgstr "" msgid "popup_requestErrorCannotAddCondition" msgstr "" msgid "popup_configureMonitorWebRequests" msgstr "" msgid "options_resultProfileForSelectedDomains" msgstr "" msgid "options_pac_profile_unsupported_moz" msgstr "PAC Profiles WILL NOT work in Mozilla Firefox due to technical limitations!" msgid "popup_issueTemplate" msgstr "" msgid "browserAction_profileDetails_PacProfile" msgstr "" msgid "browserAction_profileDetails_SystemProfile" msgstr "" msgid "browserAction_profileDetails_DirectProfile" msgstr "" msgid "browserAction_profileDetails_SwitchProfile" msgstr "" msgid "browserAction_profileDetails_RuleListProfile" msgstr "" msgid "browserAction_titleNormal" msgstr "" msgid "browserAction_titleWithResult" msgstr "" msgid "browserAction_titleNewerOptions" msgstr "" msgid "browserAction_titleOptionError" msgstr "" msgid "browserAction_titleDownloadFail" msgstr "" msgid "browserAction_titleExternalProxy" msgstr "" msgid "browserAction_titleInspect" msgstr "" msgid "browserAction_defaultRuleDetails" msgstr "" msgid "browserAction_directResult" msgstr "" msgid "browserAction_attachedPrefix" msgstr "" msgid "browserAction_tempRulePrefix" msgstr "" msgid "contextMenu_inspectPage" msgstr "" msgid "contextMenu_inspectFrame" msgstr "" msgid "contextMenu_inspectLink" msgstr "" msgid "contextMenu_inspectElement" msgstr "" msgid "contextMenu_enableQuickSwitch" msgstr "" msgid "about_title" msgstr "About" msgid "about_app_description" msgstr "A proxy configuration tool" msgid "about_version" msgstr "Version $VERSION$" msgid "about_experimental_warning_moz" msgstr "Mozilla Firefox support is highly experimental! If you encounter issues, please report using the buttons below." msgid "about_disclaimer_networkService" msgstr "SwitchyOmega does not provide proxies, VPNs, or other network services." msgid "about_disclaimer_privacy" msgstr "SwitchyOmega does not track you or insert ads into webpages. Please see" " our privacy policy." msgid "about_help" msgstr "Other questions? Need help with using SwitchyOmega? Please see our " "FAQ." msgid "about_copyright" msgstr "Copyright 2012-2017 The SwitchyOmega Authors. All rights reserved." msgid "about_credits" msgstr "SwitchyOmega is made possible by the SwitchyOmega open source project and other open source software." msgid "about_license" msgstr "SwitchyOmega is free software licensed under GNU General Public License Version 3 or later." ================================================ FILE: omega-locales/tr/LC_MESSAGES/omega-web.po ================================================ msgid "" msgstr "" "Project-Id-Version: SwitchyOmega 2.3.3\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2015-02-13 10:29+0000\n" "PO-Revision-Date: 2020-08-03 04:41+0000\n" "Last-Translator: ozgurulukir \n" "Language-Team: Turkish \n" "Language: tr\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n > 1;\n" "X-Generator: Weblate 4.2-dev\n" msgid "appNameShort" msgstr "SwitchyOmega" msgid "manifest_app_name" msgstr "Proxy SwitchyOmega" msgid "manifest_app_description" msgstr "" "Birden çok vekil sunucuyu yönet ve aralarında kolayca ve hızlıca geçiş yap." msgid "manifest_icon_default_title" msgstr "Yükleniyor…" msgid "upgrade_profile_auto" msgstr "Otomatik Geçiş" msgid "profile_direct" msgstr "[Doğrudan]" msgid "profile_system" msgstr "[Sistem Vekil Sunucusu]" msgid "condition_HostWildcardCondition" msgstr "Sunucu joker karakteri" msgid "condition_help_HostWildcardCondition" msgstr "" "Sunucuları (alan adlarını) joker karakteriyle eşler.
Yıldız karakteri " "* sıfır ya da daha fazla karaktere denk gelir.
Soru " "işareti ? tam olarak tek karaktere denk gelir.

Şu " "şekilde *. başlayan kurallar sadece Sunucu joker eşleme " "koşulları için geçerlidir.
Örnek: *.ornek.com www.ornek.com " "VE ornek.com için eşlenecektir.
Sadece altalan adlarını eşlemek " "için only, iki yıldız karakteri kullanın: " "**.ornek.com." msgid "condition_HostRegexCondition" msgstr "Sunucu düzenli ifadesi" msgid "condition_help_HostRegexCondition" msgstr "" msgid "condition_HostLevelsCondition" msgstr "Sunucu seviyeleri" msgid "condition_help_HostLevelsCondition" msgstr "" "İstek sadece sunucu seviyesi(host level) belirtilen aralıkta ise eşleşir .\n" "
Tanımlanan sunucu seviyesi nokta ile ayrılmış bölümlerin sayısı " "sunucu (domain adı).
Örnek: www.example.com kodunun sunucu " "seviyesi 3 iken, internal kodunun sunucu seviyesi 1'dir ." msgid "condition_IpCondition" msgstr "IP Değişmezleri" msgid "condition_help_IpCondition" msgstr "" "Gönderilen istek, sunucu istenilen şartlarda bir IP adresine sahipse ve alt " "ağda ise yaniCIDR notationadresinde belirtilen " "özelliklere sahipse eşleşme gerçekleşir.
Örneğin, 127.0.0.1/" "16şartı mevcut olsun. Bu şarta 127.0.*.* ile başlayan " "tüm IP'ler uyar yani eşleşme başarılı olur.
Bu " "yüzden127.0.0.1 IP'si belirtilen kurala uyarken " "127.1.0.0 IP'si kurala uymaz. localhost Şeklinde " "bir ada sahip olan sunucularda ise asla eşleşme gerçekleşmez çünkü istenilen " "şartlarda bir IP adresine sahip değillerdir." msgid "condition_UrlWildcardCondition" msgstr "URL wildcard" msgid "condition_help_UrlWildcardCondition" msgstr "" msgid "condition_UrlRegexCondition" msgstr "" msgid "condition_help_UrlRegexCondition" msgstr "" "URL eşlemesi " "düzenli ifadeler ile güçlüdür.
Ancak, düzenli ifadelerin " "oluşturulması (ve okunması) zor olabilir.
Çoğu durumda joker karakter " "kullanmanız ve yalnızca başka bir koşul türüyle elde edilemeyen koşullar " "için kurallı ifade kullanmanız önerilir." msgid "condition_KeywordCondition" msgstr "Anahtar Kelime" msgid "condition_help_KeywordCondition" msgstr "" msgid "condition_FalseCondition" msgstr "(Devre dışı)" msgid "condition_details_FalseCondition" msgstr "(Eşleme sırasında koşul görmezden gelindi)" msgid "condition_help_FalseCondition" msgstr "" msgid "condition_TimeCondition" msgstr "Mevcut Zaman" msgid "condition_help_TimeCondition" msgstr "" msgid "condition_WeekdayCondition" msgstr "Haftanın Günü" msgid "condition_help_WeekdayCondition" msgstr "" msgid "condition_alert_fullUrlLimitation" msgstr "" msgid "condition_alert_fullUrlLimitationLink" msgstr "https://github.com/FelisCatus/SwitchyOmega/wiki/Chromium-Full-URL-Limitation" msgid "condition_group_default" msgstr " " msgid "condition_group_host" msgstr "Sunucu" msgid "condition_group_url" msgstr "Url" msgid "condition_group_special" msgstr "Özel" msgid "ruleListFormat_Switchy" msgstr "Değiştirilebilir" msgid "ruleListFormat_AutoProxy" msgstr "AutoProxy" msgid "ruleList_usageUrl" msgstr "https://github.com/FelisCatus/SwitchyOmega/wiki/RuleListUsage" msgid "ruleList_error_resultNotEnabled" msgstr "" msgid "ruleList_error_unknownProfile" msgstr "Bilinmeyen profil: $PROFILE$" msgid "ruleList_error_missingResultProfile" msgstr "" msgid "ruleList_error_invalidRule" msgstr "$LNO$ nolu satırda geçersiz kural: $SOURCE$" msgid "ruleList_error_noDefaultRule" msgstr "" msgid "dialog_close" msgstr "Kapat" msgid "dialog_save" msgstr "Değişikleri Kaydet" msgid "dialog_ok" msgstr "Tamam" msgid "dialog_cancel" msgstr "İptal" msgid "inputClear_clear" msgstr "Temizle" msgid "inputClear_restore" msgstr "Eski Haline Getir" msgid "options_title" msgstr "SwitchyOmega Seçenekler" msgid "options_experimental_badge" msgstr "α" msgid "options_navHeader_setting" msgstr "Ayarlar" msgid "options_navHeader_profiles" msgstr "Profiller" msgid "options_navHeader_actions" msgstr "Hareketler" msgid "options_tab_ui" msgstr "Arayüz" msgid "options_tab_general" msgstr "General" msgid "options_tab_importExport" msgstr "İçe veya Dışa Aktar" msgid "options_newProfile" msgstr "Yeni profil…" msgid "options_apply" msgstr "Değişiklikleri uygula" msgid "options_discard" msgstr "Değişiklikleri yoksay" msgid "options_reset" msgstr "Seçenekleri sıfırla" msgid "options_group_miscOptions" msgstr "Diğer Seçenekler" msgid "options_confirmDeletion" msgstr "Koşula bağlı silinmeyi onayla." msgid "options_refreshOnProfileChange" msgstr "Profil güncellendiğinde mevcut sekmeyi yenile." msgid "options_showInspectMenu" msgstr "" msgid "options_addConditionsToBottom" msgstr "" msgid "options_group_keyboardShortcut" msgstr "Klavye Kısayolu" msgid "options_menuShortcutHelp" msgstr "" msgid "options_menuShortcutMore" msgstr "" msgid "options_menuShortcutConfigure" msgstr "Kısayolu ayarla" msgid "options_group_switchOptions" msgstr "Geçiş Seçenekleri" msgid "options_startupProfile" msgstr "Başlangıç Hesabı" msgid "options_startupProfile_none" msgstr "(Geçerli profil)" msgid "options_showConditionTypesAdvanced" msgstr "Gelişmiş koşul tiplerini göster" msgid "options_showConditionTypesAdvancedHelp" msgstr "" "Yeni tip gelişmiş ancak karmaşık geçiş koşullarının kilidini açar. Çoğu " "senaryoda, temel koşul türleri yeterli olmalıdır, bu yüzden bu seçenek " "önerilmez." msgid "options_quickSwitch" msgstr "Hızlı Geçiş" msgid "options_cycledProfiles" msgstr "" msgid "options_cycledProfilesHelp" msgstr "" msgid "options_cycledProfilesTooFew" msgstr "" msgid "options_notCycledProfiles" msgstr "" msgid "options_group_proxyChanges" msgstr "" msgid "options_revertProxyChanges" msgstr "" msgid "options_group_conflicts" msgstr "Çakışmalar" msgid "options_conflicts_introduction" msgstr "" msgid "options_conflicts_lowerPriority" msgstr "" msgid "options_conflicts_higherPriority" msgstr "" msgid "options_showExternalProfile" msgstr "" msgid "options_showExternalProfileHelp" msgstr "" msgid "options_group_networkRequests" msgstr "Ağ İstekleri" msgid "options_monitorWebRequests" msgstr "" msgid "options_monitorWebRequestsHelp" msgstr "" msgid "options_downloadOptions" msgstr "İndirme Seçenekleri" msgid "options_downloadOptionsHelp" msgstr "" msgid "options_downloadInterval" msgstr "İndirme zaman aralığı" msgid "options_downloadInterval_15" msgstr "15 Dakika" msgid "options_downloadInterval_60" msgstr "1 Saat" msgid "options_downloadInterval_180" msgstr "3 Saat" msgid "options_downloadInterval_360" msgstr "6 Saat" msgid "options_downloadInterval_720" msgstr "12 Saat" msgid "options_downloadInterval_1440" msgstr "Her gün" msgid "options_downloadInterval_never" msgstr "Asla" msgid "options_group_importExportProfile" msgstr "Profil" msgid "options_exportPacFile" msgstr "PAC Dosyası Olarak Dışa Aktar" msgid "options_exportPacFileHelp" msgstr "" "Geçerli profili PAC dosyası olarak dışa aktar, böylece diğer tarayıcılarda " "kullanabilirsin." msgid "options_exportProfileHelp" msgstr "" msgid "options_exportLegacyRuleList" msgstr "" msgid "options_exportLegacyRuleListHelp" msgstr "" msgid "options_group_importExportSettings" msgstr "Ayarlar" msgid "options_makeBackup" msgstr "Yedek oluştur" msgid "options_makeBackupHelp" msgstr "" "Tüm ayarlarının tam bir yedeğini oluştur (profiller ve diğer seçenekler " "dahil)." msgid "options_restoreLocal" msgstr "Dosyadan eski haline getir" msgid "options_restoreLocalHelp" msgstr "SwitchyOmega seçeneklerini bir dosyadan eski haline getir." msgid "options_restoreOnline" msgstr "Çevirimiçi eski haline getir" msgid "options_restoreOnlinePlaceholder" msgstr "Seçenekler dosyası bağlantısı (ör. 'http://example.com/switchy.bak')" msgid "options_restoreOnlineSubmit" msgstr "Eski haline getir" msgid "options_group_syncing" msgstr "Eşitleniyor (Deneysel)" msgid "options_syncEnable" msgstr "Eşitlemeyi Etkinleş" msgid "options_syncEnableForce" msgstr "Eşitlemeden İndir" msgid "options_syncDisable" msgstr "Eşitlemeyi pasifleştir" msgid "options_syncReset" msgstr "Uzak kopyayı temizle" msgid "options_syncPristineHelp" msgstr "" msgid "options_syncSyncAlert" msgstr "" msgid "options_syncSyncHelp" msgstr "" msgid "options_syncConflictAlert" msgstr "" msgid "options_syncConflictHelp" msgstr "" msgid "options_syncUnsupportedHelp" msgstr "" msgid "options_profileSyncDisabled" msgstr "Bu profil için eşitleme pasifleştirildi." msgid "options_profileSyncDisabled_quotaPerItem" msgstr "" "Çok fazla depolama alanı kullanması sebebiyle bu profil için eşleme " "pasifleştirildi." msgid "options_profileTabPrefix" msgstr "Profil :: " msgid "options_renameProfile" msgstr "Yeniden adlandır" msgid "options_deleteProfile" msgstr "Sil" msgid "options_profileExportRuleList" msgstr "Kural listesini yayınla" msgid "options_profileExportRuleListHelp" msgstr "Geçiş kurallarını metin biçiminde yayınlama için dışa aktar." msgid "options_profileExportPac" msgstr "PAC Dışa Aktar" msgid "options_profileUnsupported" msgstr "Desteklenmeyen profil türü $TYPE$!" msgid "options_profileUnsupportedHelp" msgstr "" msgid "options_profileEditSource" msgstr "Kaynak kodunu düzenle" msgid "options_profileEditSourceHelp" msgstr "Kaynak kodu biçimi hakkında yardım göster" msgid "options_profileEditSourceHelpUrl" msgstr "" "https://github.com/FelisCatus/SwitchyOmega/wiki/SwitchyOmega-conditions-" "format#result-profile" msgid "options_group_proxyServers" msgstr "Proxy servers" msgid "options_proxy_scheme" msgstr "Şema" msgid "options_proxy_protocol" msgstr "Protokol" msgid "options_proxy_server" msgstr "Sunucu" msgid "options_proxy_port" msgstr "Port" msgid "options_proxy_auth" msgstr "Kimlik doğrulama" msgid "options_proxy_authNotSupported" msgstr "" msgid "options_proxy_authAllWarningPac" msgstr "" msgid "options_proxy_authAllWarningPacUrl" msgstr "" msgid "options_proxy_authAllWarningPacScript" msgstr "" msgid "options_proxy_authReferencedWarning" msgstr "" msgid "options_scheme_default" msgstr "(varsayılan)" msgid "options_protocol_direct" msgstr "" msgid "options_protocol_useDefault" msgstr "(varsayılanı kullan)" msgid "options_proxy_single" msgstr "" msgid "options_proxy_expand" msgstr "Gelişmişi Göster" msgid "options_group_bypassList" msgstr "Baypas Listesi" msgid "options_bypassListHelp" msgstr "" msgid "options_bypassListHelpLinkText" msgstr "(Joker karakterleri ve daha fazlası…)" msgid "options_group_pacUrl" msgstr "PAC Bağlantısı" msgid "options_pacUrlHelp" msgstr "" msgid "options_pacUrlFile" msgstr "" msgid "options_pacUrlFileDisabled" msgstr "" msgid "options_group_pacScript" msgstr "PAC Betiği" msgid "options_pacScriptLastUpdate" msgstr "PAC betiği indirilme zamanı $TIME$:" msgid "options_pacScriptObsolete" msgstr "" msgid "options_group_virtualProfile" msgstr "Sanal Profil" msgid "options_virtualProfileTarget" msgstr "Hedef" msgid "options_virtualProfileTargetHelp" msgstr "" "Bu profil uygulandığında, aşağıda seçilen profille tamamen aynı şekilde " "hareket eder." msgid "options_group_virtualProfileReplace" msgstr "Sanal Profile Taşı" msgid "options_virtualProfileReplace" msgstr "Hedef profille yer değiştir" msgid "options_virtualProfileReplaceHelp" msgstr "" msgid "options_group_ruleListConfig" msgstr "Kural Listesi Ayarı" msgid "options_ruleListFormat" msgstr "Kural Listesi Biçimi" msgid "options_group_ruleListResult" msgstr "Kural listesi sonuç profilleri" msgid "options_ruleListMatchProfile" msgstr "Profili eşle" msgid "options_ruleListDefaultProfile" msgstr "Varsayılan profil" msgid "options_group_ruleListUrl" msgstr "Kural Listesi Bağlantısı" msgid "options_ruleListUrlHelp" msgstr "" msgid "options_group_ruleListText" msgstr "Kural Listesi Metni" msgid "options_ruleListLastUpdate" msgstr "Kural listesi indirilme zamanı $TIME$:" msgid "options_ruleListObsolete" msgstr "" msgid "options_group_switchRules" msgstr "Geçiş kuralları" msgid "options_sort" msgstr "Sırala" msgid "options_conditionType" msgstr "Koşul Türü" msgid "options_showConditionTypeHelp" msgstr "Yardım göster" msgid "options_conditionDetails" msgstr "Koşul Detayları" msgid "options_resultProfile" msgstr "Profil" msgid "options_conditionActions" msgstr "Actions" msgid "options_addCondition" msgstr "Koşul ekle" msgid "options_cloneRule" msgstr "Kopya" msgid "options_ruleNote" msgstr "Note" msgid "options_switchAttachedProfileInCondition" msgstr "Kural listesi kuralları" msgid "options_switchAttachedProfileInConditionDetails" msgstr "" msgid "options_switchAttachedProfileInConditionDisabled" msgstr "(Kural listesi kuralları PASİFLEŞTİRİLDİ)" msgid "options_switchDefaultProfile" msgstr "Default" msgid "options_hostLevelsBetween" msgstr "" msgid "options_hourBetween" msgstr "≤ geçerli saat ≤" msgid "options_weekDayShort_0" msgstr "Su" msgid "options_weekDayShort_1" msgstr "Mo" msgid "options_weekDayShort_2" msgstr "Tu" msgid "options_weekDayShort_3" msgstr "We" msgid "options_weekDayShort_4" msgstr "Th" msgid "options_weekDayShort_5" msgstr "Fr" msgid "options_weekDayShort_6" msgstr "Sa" msgid "options_group_conditionHelp" msgstr "Koşul Türleri Hakkında" msgid "options_group_attachProfile" msgstr "Çevirimiçi kural listelerini içe aktar" msgid "options_attachProfile" msgstr "Kural listesi ekle" msgid "options_attachProfileHelp" msgstr "" msgid "options_modalHeader_welcome" msgstr "SwitchyOmega'ya Hoşgeldiniz" msgid "options_welcomeNormal" msgstr "" msgid "options_welcomeNormalGuide" msgstr "" msgid "options_welcomeUpgrade" msgstr "" msgid "options_welcomeUpgradeGuide" msgstr "" msgid "options_guideNext" msgstr "Sonraki" msgid "options_guideDone" msgstr "Tamamlandı" msgid "options_guideSkip" msgstr "Kılavuzu geç" msgid "options_modalHeader_applyOptions" msgstr "Seçenekleri Uygula" msgid "options_optionsNotSaved" msgstr "" msgid "options_applyOptionsRequired" msgstr "" msgid "options_applyOptionsConfirm" msgstr "Seçenekleri kaydetmek ve uygulamak istiyor musun?" msgid "options_modalHeader_renameProfile" msgstr "Profili Yeniden Adlandır" msgid "options_renameProfileName" msgstr "Yeni profil adı" msgid "options_profileNameConflict" msgstr "Bu adda bir profil zaten var." msgid "options_profileNameReserved" msgstr "" msgid "options_profileNameHidden" msgstr "" msgid "options_modalHeader_replaceProfile" msgstr "Profili Yer Değiştir" msgid "options_replaceProfile" msgstr "Profili Yer Değiştir" msgid "options_replaceProfileConfirm" msgstr "" "Gerçekten $FromProfile$ profilini $ToProfile$ ile yer değiştirmek istiyor " "musun?" msgid "options_replaceProfileHelp" msgstr "" msgid "options_replaceProfileSuccess" msgstr "Seçenekler güncellendi." msgid "options_modalHeader_deleteProfile" msgstr "Profil Sil" msgid "options_deleteProfileConfirm" msgstr "Aşağıdaki profili gerçekten silmek istiyor musun?" msgid "options_modalHeader_cannotDeleteProfile" msgstr "Profil Silinemedi" msgid "options_profileReferredBy" msgstr "Bu profil silinemez, çünkü aşağıdaki profillerle bağlantılı:" msgid "options_modifyReferringProfiles" msgstr "" "Bu profilleri değiştirmeli ve silmeden önce bu profille bağlantılarını " "durdurmalısınız." msgid "options_profileNameEmpty" msgstr "Profil adı boş olamaz." msgid "popup_title" msgstr "SwitchyOmega Açılır Pencere" msgid "options_modalHeader_proxyAuth" msgstr "Proxy Authentication" msgid "options_proxyAuthUsername" msgstr "Kullanıcı adı" msgid "options_proxyAuthPassword" msgstr "Password" msgid "options_proxyAuthShowPassword" msgstr "Parolayı göster" msgid "options_proxyAuthHidePassword" msgstr "Parolayı gizle" msgid "options_proxyAuthNone" msgstr "No Authentication" msgid "options_modalHeader_deleteRule" msgstr "Kuralı Sil" msgid "options_deleteRuleConfirm" msgstr "Aşağıdaki kuralı silmek istediğine emin misin?" msgid "options_deleteRule" msgstr "Delete" msgid "options_modalHeader_resetRules" msgstr "Kuralları sıfırla" msgid "options_resetRulesConfirm" msgstr "" msgid "options_resetRules" msgstr "Kuralları sıfırla" msgid "options_resetRules_help" msgstr "Tüm kurallar için profil ayarla" msgid "options_modalHeader_deleteAttached" msgstr "Kural Listesini Kaldır" msgid "options_deleteAttachedConfirm" msgstr "Geçerli profilden kural listesini gerçekten kaldırmak istiyor musun?" msgid "options_ruleListLineCount" msgstr "$COUNT$ satır kural" msgid "options_deleteAttached" msgstr "Kural listesini kaldır" msgid "options_modalHeader_newProfile" msgstr "Yeni Profil" msgid "options_newProfileName" msgstr "Profil adı" msgid "options_profileType" msgstr "Lütfen profil türü seç:" msgid "options_profileTypeFixedProfile" msgstr "Proxy Profili" msgid "options_profileDescFixedProfile" msgstr "" msgid "options_profileTypePacProfile" msgstr "PAC Profili" msgid "options_profileDescPacProfile" msgstr "" msgid "options_profileDescMorePacProfile" msgstr "" msgid "options_profileTypeSwitchProfile" msgstr "Profile Geç" msgid "options_profileDescSwitchProfile" msgstr "" msgid "options_profileTypeRuleListProfile" msgstr "Kural Listesi Profili" msgid "options_profileDescRuleListProfile" msgstr "" msgid "options_profileTypeVirtualProfile" msgstr "Sanal Profil" msgid "options_profileDescVirtualProfile" msgstr "" msgid "options_createProfile" msgstr "Oluştur" msgid "options_modalHeader_resetOptions" msgstr "Reset Options" msgid "options_resetOptionsConfirm" msgstr "" "Seçenekleri gerçekten sıfırlamak istiyor musun? Tüm profiller ve ayarlar " "kaybedilecek!" msgid "options_formInvalid" msgstr "Lütfen sayfadaki hataları düzeltin." msgid "options_profileNotFound" msgstr "$PROFILE$ profili yok! Seçenekler bozulmuş olabilir." msgid "options_resetSuccess" msgstr "Options reset." msgid "options_saveSuccess" msgstr "Seçenekler kaydedildi." msgid "options_importSuccess" msgstr "Seçenekler içe aktarıldı." msgid "options_importFormatError" msgstr "Geçersiz yedek dosyası!" msgid "options_importDownloadError" msgstr "Yedek dosyası indirirken hata!" msgid "options_profileDownloadSuccess" msgstr "Profil güncellendi." msgid "options_profileDownloadError" msgstr "Profil verisi indirilirken hata!" msgid "options_profileDownloadError_NetworkError" msgstr "Güncelleme sırasında ağ hatası oluştu." msgid "options_profileDownloadError_HttpError" msgstr "Güncelleme sırasında HTTP ($STATUS$) hatası oluştu." msgid "options_profileDownloadError_HttpNotFoundError" msgstr "Profil bağlantısı sunucuda bulunamadı. Lütfen tekrar kontrol edin." msgid "options_profileDownloadError_HttpServerError" msgstr "Güncelleme sırasında uzak sunucu ($STATUS$) hatası verdi." msgid "options_profileDownloadError_ContentTypeRejectedError" msgstr "" msgid "options_downloadProfileNow" msgstr "Profili Şimdi İndir" msgid "options_guide_fixedProfileStep" msgstr "" msgid "options_guide_fixedServersStep" msgstr "" msgid "options_guide_autoSwitchProfileStep" msgstr "" msgid "options_guide_addMoreProfilesStep" msgstr "" msgid "options_guide_conditionStep" msgstr "" msgid "options_guide_conditionTypeStep" msgstr "" msgid "options_guide_conditionProfileStep" msgstr "" msgid "options_guide_switchDefaultStep" msgstr "" msgid "options_guide_applySwitchProfileStep" msgstr "" msgid "popup_externalProfile" msgstr "(Harici Profil)" msgid "popup_externalProfileName" msgstr "profile adı" msgid "popup_proxyNotControllable_app" msgstr "" msgid "popup_proxyNotControllable_policy" msgstr "" msgid "popup_proxyNotControllable_unknown" msgstr "" msgid "popup_proxyNotControllable_disabled" msgstr "" msgid "popup_proxyNotControllable_upgrade" msgstr "" msgid "popup_proxyNotControllableDetails" msgstr "" msgid "popup_proxyNotControllableDetails_upgrade" msgstr "" msgid "popup_proxyNotControllableManage" msgstr "Uzantıları yönet" msgid "popup_addConditionTo" msgstr "Şuraya koşul ekle" msgid "popup_addCondition" msgstr "Koşul ekle" msgid "popup_showOptions" msgstr "Options" msgid "popup_reportIssues" msgstr "Hataları raporla" msgid "popup_errorLog" msgstr "Hata kayıtlarını kaydet" msgid "popup_requestErrorCount" msgstr "" msgid "popup_requestErrorHeading" msgstr "Yüklemesi başarısız olan kaynaklar" msgid "popup_requestErrorWarning" msgstr "" msgid "popup_requestErrorWarningHelp" msgstr "" msgid "popup_requestErrorAddCondition" msgstr "" msgid "popup_requestErrorCannotAddCondition" msgstr "" msgid "popup_configureMonitorWebRequests" msgstr "Ağ İzleyicisini Yapılandır" msgid "options_resultProfileForSelectedDomains" msgstr "Bu profili seçilen alan adları için kullan" msgid "options_pac_profile_unsupported_moz" msgstr "" msgid "popup_issueTemplate" msgstr "" "\n" "\n" "\n" "\n" "SwitchyOmega $projectVersion$\n" "$userAgent$" msgid "browserAction_profileDetails_PacProfile" msgstr "(PAC betiği)" msgid "browserAction_profileDetails_SystemProfile" msgstr "(diğer uzantılar veya çevre değişkenleri tarafından kontrol ediliyor)" msgid "browserAction_profileDetails_DirectProfile" msgstr "(hiçbir proxy kullanmıyor)" msgid "browserAction_profileDetails_SwitchProfile" msgstr "(şart temelli geçiş yapma)" msgid "browserAction_profileDetails_RuleListProfile" msgstr "(kural listesi temelli geçiş yapma)" msgid "browserAction_titleNormal" msgstr "SwitchyOmega:: $PROFILE$" msgid "browserAction_titleWithResult" msgstr "" "SwitchyOmega:: $1:PROFILE$\n" "$3:DETAILS$" msgid "browserAction_titleNewerOptions" msgstr "" msgid "browserAction_titleOptionError" msgstr "" msgid "browserAction_titleDownloadFail" msgstr "" msgid "browserAction_titleExternalProxy" msgstr "" msgid "browserAction_titleInspect" msgstr "" msgid "browserAction_defaultRuleDetails" msgstr "(default)" msgid "browserAction_directResult" msgstr "DIRECT" msgid "browserAction_attachedPrefix" msgstr "(RL) " msgid "browserAction_tempRulePrefix" msgstr "(TEMP) " msgid "contextMenu_inspectPage" msgstr "" msgid "contextMenu_inspectFrame" msgstr "" msgid "contextMenu_inspectLink" msgstr "" msgid "contextMenu_inspectElement" msgstr "" msgid "contextMenu_enableQuickSwitch" msgstr "Hızlı Geçişi Etkinleştir" msgid "about_title" msgstr "Hakkında" msgid "about_app_description" msgstr "Proxy yapılandırma aracı" msgid "about_version" msgstr "Sürüm $VERSION$" msgid "about_experimental_warning_moz" msgstr "" "Mozilla Firefox seteği yüksek oranda deneyseldir! Hatalar ile " "karşılaşırsanız, aşağıdaki düğmeleri kullanarak lütfen raporlayın." msgid "about_disclaimer_networkService" msgstr "SwitchyOmega proxy, VPN veya diğer ağ servislerini sağlamaz." msgid "about_disclaimer_privacy" msgstr "" "SwitchyOmega sizi takip etmez veya internet sitelerine reklam yerleştirmez. " "Lütfen gizlilik politikası sayfasına bakın." msgid "about_help" msgstr "" "SwitchyOmega kullanımı hakkında yardım ve diğer sorularınız için lütfen " "bakınız: SSS." msgid "about_copyright" msgstr "" "Telif Hakkı 2012-2019 SwitchyOmega Yazarları. Tüm hakları saklıdır." msgid "about_credits" msgstr "" "SwitchyOmega SwitchyOmega açık kaynak kodlu bir projedir ve diğer açık " "kaynak kodlu yazılımlar kulanılarak üretilmiştir." msgid "about_license" msgstr "" "SwitchyOmega özgür " "yazılımdır ve GNU " "General Public License Sürüm 3 ve sonrası ile lisanslanmıştır." ================================================ FILE: omega-locales/uk/LC_MESSAGES/omega-web.po ================================================ msgid "" msgstr "" "Project-Id-Version: SwitchyOmega 2.3.3\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2015-02-13 10:29+0000\n" "PO-Revision-Date: 2024-10-29 13:02+0000\n" "Last-Translator: Сергій Дубик \n" "Language-Team: Ukrainian \n" "Language: uk\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && " "n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" "X-Generator: Weblate 5.8.2-dev\n" msgid "appNameShort" msgstr "SwitchyOmega" msgid "manifest_app_name" msgstr "Проксі SwitchyOmega" msgid "manifest_app_description" msgstr "Керуйте і перемикайтеся між проксі серверами швидко і легко." msgid "manifest_icon_default_title" msgstr "Завантаження…" msgid "upgrade_profile_auto" msgstr "Автоперемикання" msgid "profile_direct" msgstr "[Напряму]" msgid "profile_system" msgstr "[Системний проксі]" msgid "condition_HostWildcardCondition" msgstr "За підстановкою у назві" msgid "condition_help_HostWildcardCondition" msgstr "" "Зіставляє хости (доменні імена) з шаблоном.
Зірочка*зіставляє нуль або більше символів.
Знак питання?зіставляє рівно один символ.

Запримітьте, що правила, що " "починаються з*.обробляються особливо тільки в шаблонах " "хоста.
Приклад:*. example.comзіставити як " "www.example.com,ТАК І example.com.
Для того, щоб " "зіставититількипіддомени, використовуйтедвізірочки:**. " "example.com." msgid "condition_HostRegexCondition" msgstr "Регулярний вираз хоста" msgid "condition_help_HostRegexCondition" msgstr "" "Подібно до шаблонів хоста, але зіставляє хости (доменні імена) з " "регулярним " "виразом.
Регулярні вирази буває важко побудувати (і читати).
Тому " "регулярні вирази рекомендується використовувати тільки для тих умов, що не " "можуть бути виражені іншими методами." msgid "condition_HostLevelsCondition" msgstr "Рівні хоста" msgid "condition_help_HostLevelsCondition" msgstr "" "Відповідає запиту тільки тоді, коли рівень хоста знаходиться в заданому " "діапазоні.
Рівень хоста визначається якчисло розділених точками " "сегментівхоста (доменного імені).
Приклад:www.example.comмає рівень хоста 3, аinternalмає рівень хоста 1." msgid "condition_IpCondition" msgstr "Літерали IP" msgid "condition_help_IpCondition" msgstr "" "Відповідає запиту тільки тоді, якщо хост єлітеральноIP-адресою і " "знаходиться в підмережі, як зазначено в записи CIDR.
Наприклад, правило127.0.0.1/16відповідає всім IP-" "адресами як127.0. *. *.
Таким чином127.0.0.1відповідає запиту, а127.1.0.0- немає. Імена хостів, такі " "якlocalhost, ніколи не будуть відповідати запиту, тому що " "вониIP." msgid "condition_UrlWildcardCondition" msgstr "Шаблон URL" msgid "condition_help_UrlWildcardCondition" msgstr "" "Зіставляє URL-адреси запиту з шаблоном.
Дивіться приклад шаблону хоста в " "розділі вище для швидкого створення шаблону для посилання.
Запримітьте, " "що шаблон URL-адреси не обробляються спеціальним чином (немає «магії» " "піддомена, як в шаблоні хоста).
Таким чином шаблон*://*.example.com/" "*відповідає http://www.example.com/алене " "відповідаєhttp://example.com/." msgid "condition_UrlRegexCondition" msgstr "Регулярний вираз URL" msgid "condition_help_UrlRegexCondition" msgstr "" "Зіставляє URL-адресу за допомогою «надзвичайно потужного» регулярного виразу.
Однак " "регулярні вирази складно створювати (і читати).
У більшості випадків " "рекомендується використовувати шаблони, а регулярні вирази використовувати " "тільки для умов де без них неможливо обійтися." msgid "condition_KeywordCondition" msgstr "Ключове слово" msgid "condition_help_KeywordCondition" msgstr "" "Відповідає значенню ключового слова, якщо URL-адреса належить HTTP-" "протоколу, і зразок слова є частиною URL-адреси.
Він поводиться подібно " "шаблону URL. Приклад:http://*ключове слово*.
Ключові " "слова корисні, якщо Ви хочете обійти брендмауер, який блокує деякі ключові " "слова в URL-адресі, запитуючи такі URL-адреси через проксі." msgid "condition_FalseCondition" msgstr "(вимкнено)" msgid "condition_details_FalseCondition" msgstr "(Умова нехтується при зіставленні)" msgid "condition_help_FalseCondition" msgstr "" "Ви можете вимкнути умову, встановивши її тип у стан(вимкнено). " "Вимкнена умова діє так, ніби її не існує.
Цю можливість можна " "використовувати для тимчасового вимкнення умов.
Вимкнені умови як і " "раніше містять попередню інформацію (наприклад, шаблони) і можуть бути " "повторно увімкнені шляхом повернення до попереднього типу." msgid "condition_TimeCondition" msgstr "Поточний час" msgid "condition_help_TimeCondition" msgstr "" "Спрацьовує, якщо поточний місцевий час є у діапазоні, визначеному між " "початковою годиною та кінцевою годиною включно
Місцевий час, " "починаючи з початкової та кінцевої години розраховано згідно 24 год. " "формату (p 0 до 23).
Розрахунок відбувається приблизно в той " "момент, коли надісланий запит." msgid "condition_WeekdayCondition" msgstr "День тижня" #, fuzzy msgid "condition_help_WeekdayCondition" msgstr "" "Відповідає, якщопоточний день тижняобраний в деталях умови. День " "розраховується відповідно до місцевого часового поясу.
Запит і його URL-" "адресу не мають значення для цього умови. Результат грунтується виключно на " "дні тижня, коли відправляється запит." #, fuzzy msgid "condition_alert_fullUrlLimitation" msgstr "" "Повна відповідність URL-адреси більше не можливо дляhttps://починаючи з Chrome 52. Дізнатися більше..." msgid "condition_alert_fullUrlLimitationLink" msgstr "" "https://github.com/FelisCatus/SwitchyOmega/wiki/Chromium-Full-URL-Limitation" #, fuzzy msgid "condition_group_default" msgstr " " #, fuzzy msgid "condition_group_host" msgstr "Хост" msgid "condition_group_url" msgstr "Адреса" #, fuzzy msgid "condition_group_special" msgstr "Особливі" msgid "ruleListFormat_Switchy" msgstr "Перемикач" msgid "ruleListFormat_AutoProxy" msgstr "Авто проксі" msgid "ruleList_usageUrl" msgstr "https://github.com/FelisCatus/SwitchyOmega/wiki/RuleListUsage" msgid "ruleList_error_resultNotEnabled" msgstr "Не вистачає директиви '@with result'!" msgid "ruleList_error_unknownProfile" msgstr "Невідомий профіль: $PROFILE$" #, fuzzy msgid "ruleList_error_missingResultProfile" msgstr "Відсутня назва профілю в рядку $LNO$: $SOURCE$" #, fuzzy msgid "ruleList_error_invalidRule" msgstr "Некоректне правило в рядку $LNO$: $SOURCE$" #, fuzzy msgid "ruleList_error_noDefaultRule" msgstr "Відсутня правило для умови «*»!" msgid "dialog_close" msgstr "Зачинити" msgid "dialog_save" msgstr "Зберегти зміни" msgid "dialog_ok" msgstr "Згоден" msgid "dialog_cancel" msgstr "Скасувати" msgid "inputClear_clear" msgstr "Очистити" msgid "inputClear_restore" msgstr "Відновити" msgid "options_title" msgstr "Налаштування SwitchyOmega" msgid "options_experimental_badge" msgstr "α" msgid "options_navHeader_setting" msgstr "Налаштування" msgid "options_navHeader_profiles" msgstr "Профілі" msgid "options_navHeader_actions" msgstr "Дії" #, fuzzy msgid "options_tab_ui" msgstr "Інтерфейс" msgid "options_tab_general" msgstr "Загальні" msgid "options_tab_importExport" msgstr "Імпорт/Експорт" msgid "options_newProfile" msgstr "Новий профіль…" msgid "options_apply" msgstr "Задіяти зміни" msgid "options_discard" msgstr "Відхилити зміни" msgid "options_reset" msgstr "Скинути налаштування" msgid "options_group_miscOptions" msgstr "Інші налаштування" msgid "options_confirmDeletion" msgstr "Підтвердити при видаленні умови." msgid "options_refreshOnProfileChange" msgstr "Перезавантажити активну вкладинку при зміні профілю." #, fuzzy msgid "options_showInspectMenu" msgstr "" "Дозволити перевірку проксі, який використовується для елементів сторінки, " "через контекстне меню." msgid "options_addConditionsToBottom" msgstr "Put new conditions added using the popup to the bottom of the list." msgid "options_group_keyboardShortcut" msgstr "Клавіатурні скорочення" #, fuzzy msgid "options_menuShortcutHelp" msgstr "" "Натискання гарячої клавіші відкриє контекстне меню SwitchyOmega. (Типово Alt " "+ Shift + O)." msgid "options_menuShortcutMore" msgstr "" "Елементи спливаючого меню також можуть бути доступні за допомогою " "клавіатури. Натисніть ? (або /) знаходячись у меню, щоб дізнатися більше." msgid "options_menuShortcutConfigure" msgstr "Налаштувати скорочення" #, fuzzy msgid "options_group_switchOptions" msgstr "Налаштування перемикання" msgid "options_startupProfile" msgstr "Стартовий профіль" msgid "options_startupProfile_none" msgstr "(Поточний профіль)" msgid "options_showConditionTypesAdvanced" msgstr "Показувати складніші типи умов" #, fuzzy msgid "options_showConditionTypesAdvancedHelp" msgstr "" "Розблокує нові типи передових, але складних умов перемикання. Для більшості " "сценаріїв основних типів умов має бути достатньо, тому цей параметр не " "рекомендується." msgid "options_quickSwitch" msgstr "Швидке перемикання" #, fuzzy msgid "options_cycledProfiles" msgstr "Задіяні профілі" #, fuzzy msgid "options_cycledProfilesHelp" msgstr "" "Коли ви натискаєте на значок (або використовуєте гарячу клавішу), такі " "профілі будуть застосовуватися в заданому порядку." #, fuzzy msgid "options_cycledProfilesTooFew" msgstr "" "Вам потрібно вибрати як мінімум 2 профілю, щоб увімкнути цю функцію! Ви " "можете перетягнути їх з поля нижче." #, fuzzy msgid "options_notCycledProfiles" msgstr "Чи не задіяні профілі" #, fuzzy msgid "options_group_proxyChanges" msgstr "Зміни проксі" msgid "options_revertProxyChanges" msgstr "Скасувати зміни проксі-серверів, що зроблені іншими застосунками." msgid "options_group_conflicts" msgstr "Конфлікти" msgid "options_conflicts_introduction" msgstr "" "Sometimes, other apps will also try to control the proxy settings, resulting " "in conflicts. Note that ad blockers and other extensions may also use proxy " "settings under the hood. Such conflicts cannot be avoided due to how the " "browser works." msgid "options_conflicts_lowerPriority" msgstr "" "A red badge like this on the SwitchyOmega icon indicates that another app has " "higher priority so SwitchyOmega cannot control the settings. Please try to " "uninstall SwitchyOmega and reinstall, which should raise SwitchyOmega's " "priority. If you still see conflicts after reinstallation, please consider " "removing the other app causing the conflict." msgid "options_conflicts_higherPriority" msgstr "" "If SwitchyOmega has higher priority, you can give the control back to other " "apps or system settings by selecting $SYSTEMPROFILE$ in the popup menu." msgid "options_showExternalProfile" msgstr "Show popup menu item to import proxy settings from other apps." msgid "options_showExternalProfileHelp" msgstr "" "When $SYSTEMPROFILE$ is selected, you can import the effective proxy settings " "from other apps by selecting $EXTERNALPROFILE$ on the popup menu. " "The settings will be imported as a profile using the name you provide. " "Please note that the imported profile is a snapshot and will not reflect " "any changes from the source app thereafter." msgid "options_group_networkRequests" msgstr "Мережеві запити" msgid "options_monitorWebRequests" msgstr "Показувати число невдалих мережевих запитів на поточній вкладинці." msgid "options_monitorWebRequestsHelp" msgstr "" "Жовта позначка відобразиться на піктограмі, якщо деякі з ресурсів не " "вдасться завантажити,
для зручності ви можете призначити профіль таким " "ресурсам через спливаюче меню." msgid "options_downloadOptions" msgstr "Налаштування завантаження" msgid "options_downloadOptionsHelp" msgstr "" "Налаштування частоти, з якою збережені у мережі списки правил та PAC-скрипти " "будуть оновлюватися." msgid "options_downloadInterval" msgstr "Періодичність завантаження" msgid "options_downloadInterval_15" msgstr "15 хвилин" msgid "options_downloadInterval_60" msgstr "1 година" msgid "options_downloadInterval_180" msgstr "3 години" msgid "options_downloadInterval_360" msgstr "6 годин" msgid "options_downloadInterval_720" msgstr "12 годин" msgid "options_downloadInterval_1440" msgstr "Кожен день" msgid "options_downloadInterval_never" msgstr "Ніколи" msgid "options_group_importExportProfile" msgstr "Профіль" msgid "options_exportPacFile" msgstr "Вивантажити як PAC-файл" #, fuzzy msgid "options_exportPacFileHelp" msgstr "" "Експортуйте поточний профіль як файл PAC, щоб ви могли використовувати його " "в інших браузерах." msgid "options_exportProfileHelp" msgstr "" "Щоб вивантажити профіль, використайте панель дій у верхньому правому кутку " "сторінки профіля." msgid "options_exportLegacyRuleList" msgstr "" "Вивантажити список правил у сумісному з Proxy Switchy!/SwitchyPlus/" "SwitchySharp форматі, якщо це можливо." #, fuzzy msgid "options_exportLegacyRuleListHelp" msgstr "" "Увімкніть цю функцію, тільки якщо ви публікуєте списки правил для " "користувачів цих проектів.
Подумайте про те, щоб порадити вашим знайомим " "перейти на SwitchyOmega." #, fuzzy msgid "options_group_importExportSettings" msgstr "налаштування" msgid "options_makeBackup" msgstr "Зробити резервну копію" msgid "options_makeBackupHelp" msgstr "" "Зробити повну резервну копію ваших налаштувань (включно з профілями та усіма " "іншими налаштуваннями)." msgid "options_restoreLocal" msgstr "Відновити з файлу" #, fuzzy msgid "options_restoreLocalHelp" msgstr "Відновити параметри SwitchyOmega з локального файлу." #, fuzzy msgid "options_restoreOnline" msgstr "Відновити з онлайну" msgid "options_restoreOnlinePlaceholder" msgstr "Адреса файла налаштувань (наприклад, 'http://example.com/switchy.bak')" msgid "options_restoreOnlineSubmit" msgstr "Відновити" #, fuzzy msgid "options_group_syncing" msgstr "Синхронізація (експериментально)" msgid "options_syncEnable" msgstr "Вмикнути синхронізацію" msgid "options_syncEnableForce" msgstr "Завантаження синхронізованих налаштувань" msgid "options_syncDisable" msgstr "Вимкнути синхронізацію" #, fuzzy msgid "options_syncReset" msgstr "Очистити віддалену копію" #, fuzzy msgid "options_syncPristineHelp" msgstr "" "Тепер ви можете автоматично синхронізувати ваші настройки і профілі на всіх " "ваших настільних пристроях з браузером Chrome." msgid "options_syncSyncAlert" msgstr "" "Ваші налаштування автоматично синхронізовані поміж усіма вашими пристроями." msgid "options_syncSyncHelp" msgstr "" "Слід завбачити, що ви повинні увійти в Chrome на кожному з ваших пристроїв (" "включаючи це), щоб синхронізація дійсно працювала.
Ви можете перевірити " "цей розділ на інших пристроях, щоб переконатися, що він працює." msgid "options_syncConflictAlert" msgstr "" "Ви вивантажили копію ваших налаштувань до іншого пристрою за допомогою " "синхронізації." #, fuzzy msgid "options_syncConflictHelp" msgstr "" "Ви можете завантажити віддалену копію на свій пристрій, якщо " "хочете.
Однак це призведе доперезапису існуючих налаштувань і " "профілівна цьому пристрої." #, fuzzy msgid "options_syncUnsupportedHelp" msgstr "" "Параметри синхронізації не підтримуються на вашій платформі або в браузері. " "На даний момент підтримується тільки браузер Chrome для настільних пристроїв." #, fuzzy msgid "options_profileSyncDisabled" msgstr "Синхронізація відключена для цього профілю." msgid "options_profileSyncDisabled_quotaPerItem" msgstr "" "Синхронізація вимкнена для цього профіля, тому що він використовує забагато " "місця." msgid "options_profileTabPrefix" msgstr "Профіль :: " msgid "options_renameProfile" msgstr "Змінити назву" msgid "options_deleteProfile" msgstr "Видалити" msgid "options_profileExportRuleList" msgstr "Опублікувати список правил" msgid "options_profileExportRuleListHelp" msgstr "Вивантажити Правила перемикань у текстовому форматі для публікації." msgid "options_profileExportPac" msgstr "Вивантажити PAC" msgid "options_profileUnsupported" msgstr "Непідтримуваний тип профілю $TYPE$!" msgid "options_profileUnsupportedHelp" msgstr "" "Налаштування можуть бути пошкоджені або належати до новішої версії цієї " "програми." #, fuzzy msgid "options_profileEditSource" msgstr "Змінити вихідний код" #, fuzzy msgid "options_profileEditSourceHelp" msgstr "Показати довідку про формат вихідного коду" msgid "options_profileEditSourceHelpUrl" msgstr "" "https://github.com/FelisCatus/SwitchyOmega/wiki/SwitchyOmega-conditions-" "format#result-profile" msgid "options_group_proxyServers" msgstr "Проксі-сервери" msgid "options_proxy_scheme" msgstr "Схема" msgid "options_proxy_protocol" msgstr "Протокол" msgid "options_proxy_server" msgstr "Сервер" msgid "options_proxy_port" msgstr "Порт" #, fuzzy msgid "options_proxy_auth" msgstr "автентифікація" msgid "options_proxy_authNotSupported" msgstr "Your browser DOES NOT support $PROTOCOLDISP$ proxy authentication! " "Please do not report this issue to SwitchyOmega. Contact the support for " "your browser instead." #, fuzzy msgid "options_proxy_authAllWarningPac" msgstr "" "Увага: ім'я користувача /пароль можуть бути відправлені на невідомі сервери, " "спрямовані PAC скриптом." #, fuzzy msgid "options_proxy_authAllWarningPacUrl" msgstr "" "Будь ласка, переконайтеся, що ви довіряєте скрипту за вказаною вище URL-" "адресою, перед введенням конфіденційних облікових даних." #, fuzzy msgid "options_proxy_authAllWarningPacScript" msgstr "" "Будь ласка, переконайтеся, що ви довіряєте наведеним нижче скрипту, перш ніж " "надавати конфіденційні облікові дані." #, fuzzy msgid "options_proxy_authReferencedWarning" msgstr "" "Крім того, використання цього профілю в інших профілях (наприклад, " "перемикати профілю) може привести до відправки імені користувача /пароля на " "проксі сервера налаштовані в інших профілях." msgid "options_scheme_default" msgstr "(за замовчуванням)" #, fuzzy msgid "options_protocol_direct" msgstr "БЕЗПОСЕРЕДНЬО" #, fuzzy msgid "options_protocol_useDefault" msgstr "(Типові налаштування)" msgid "options_proxy_single" msgstr "Використовуати цей проксі для усіх протоколів." msgid "options_proxy_expand" msgstr "Показати розширені налаштування" msgid "options_group_bypassList" msgstr "Список ігнорованих вузлів" #, fuzzy msgid "options_bypassListHelp" msgstr "" "Сервера, для яких ви не хочете використовувати будь-якої проксі: (Один " "сервер в кожному рядку.)" #, fuzzy msgid "options_bypassListHelpLinkText" msgstr "(Доступні варіанти та інше...)" #, fuzzy msgid "options_group_pacUrl" msgstr "URL-адресу PAC" #, fuzzy msgid "options_pacUrlHelp" msgstr "" "Скрипт PAC буде оновлено з цього URL-адреси. Якщо він залишиться порожнім, " "то замість нього буде використовуватися наступний скрипт." #, fuzzy msgid "options_pacUrlFile" msgstr "" "Профілі PAC з файлом: URL-адреси можуть застосовуватися тільки " "безпосередньо. Вони не можуть використовуватися в якості профілів " "результатів, так як доступ до локальних файлів неможливий через обмеження " "браузера." #, fuzzy msgid "options_pacUrlFileDisabled" msgstr "" "Тому ви не можете використовувати локальний файл PAC для цього профілю. Ви " "можете створити новий профіль PAC для цього, якщо ви дійсно цього хочете." msgid "options_group_pacScript" msgstr "PAC-скрипт" #, fuzzy msgid "options_pacScriptLastUpdate" msgstr "Скрипт PAC завантажений $TIME$:" #, fuzzy msgid "options_pacScriptObsolete" msgstr "" "Скрипт PAC застарів через зміни URL-адреси. Натисніть кнопку завантаження " "вище, щоб оновити." msgid "options_group_virtualProfile" msgstr "Віртуальний профіль" msgid "options_virtualProfileTarget" msgstr "Мета" #, fuzzy msgid "options_virtualProfileTargetHelp" msgstr "" "Коли цей профіль застосовується, він діє точно так же, як профіль, обраний " "нижче." #, fuzzy msgid "options_group_virtualProfileReplace" msgstr "Перенести в віртуальний профіль" msgid "options_virtualProfileReplace" msgstr "Замінити цільовий профіль" #, fuzzy msgid "options_virtualProfileReplaceHelp" msgstr "" "Ви можете перенести існуючі параметри, щоб використовувати цей віртуальний " "профіль замість $PROFILE$. Це оновить всі існуючі правила, які стосуються " "$PROFILE$, і вкаже їх на цей віртуальний профіль, щоб їх профіль результатів " "можна було контролювати тут." msgid "options_group_ruleListConfig" msgstr "Налаштування списку правил" msgid "options_ruleListFormat" msgstr "Формат списку правил" #, fuzzy msgid "options_group_ruleListResult" msgstr "Підсумкові профілі списку правил" msgid "options_ruleListMatchProfile" msgstr "Зіставлений профіль" msgid "options_ruleListDefaultProfile" msgstr "Профіль за-замовчуванням" msgid "options_group_ruleListUrl" msgstr "Адреса списку правил" #, fuzzy msgid "options_ruleListUrlHelp" msgstr "" "Список правил буде оновлено з цього URL-адреси. Якщо він залишається " "порожнім, замість нього буде проаналізовано наступний текст." msgid "options_group_ruleListText" msgstr "Текст списку правил" msgid "options_ruleListLastUpdate" msgstr "Список правил завантажено о $TIME$:" #, fuzzy msgid "options_ruleListObsolete" msgstr "" "Список правил застарів через зміни URL-адреси. Натисніть кнопку завантаження " "вище, щоб оновити." msgid "options_group_switchRules" msgstr "Правила перемикання" msgid "options_sort" msgstr "Впорядкувати" msgid "options_conditionType" msgstr "Тип умови" msgid "options_showConditionTypeHelp" msgstr "Показати допомогу" msgid "options_conditionDetails" msgstr "Деталі умови" msgid "options_resultProfile" msgstr "Профіль" msgid "options_conditionActions" msgstr "Дії" msgid "options_addCondition" msgstr "Додати умову" msgid "options_cloneRule" msgstr "Дублювати" msgid "options_ruleNote" msgstr "Note" #, fuzzy msgid "options_switchAttachedProfileInCondition" msgstr "Правила списку правил" msgid "options_switchAttachedProfileInConditionDetails" msgstr "(Будь-який запит, що співпадає зі списком правил нижче)" #, fuzzy msgid "options_switchAttachedProfileInConditionDisabled" msgstr "(Правила списку правил вимкнути)" msgid "options_switchDefaultProfile" msgstr "За замовчуванням" #, fuzzy msgid "options_hostLevelsBetween" msgstr "≤ рівні хоста ≤" #, fuzzy msgid "options_hourBetween" msgstr "≤ поточна година ≤" msgid "options_weekDayShort_0" msgstr "Нд" msgid "options_weekDayShort_1" msgstr "Пн" msgid "options_weekDayShort_2" msgstr "Вв" msgid "options_weekDayShort_3" msgstr "Ср" msgid "options_weekDayShort_4" msgstr "Чт" msgid "options_weekDayShort_5" msgstr "Пт" msgid "options_weekDayShort_6" msgstr "Сб" msgid "options_group_conditionHelp" msgstr "Про типи умов" msgid "options_group_attachProfile" msgstr "Завантажити список правил з мережі" msgid "options_attachProfile" msgstr "Додати список правил" #, fuzzy msgid "options_attachProfileHelp" msgstr "" "Ви можете повторно використовувати онлайн-збірник умов, опублікованих " "іншими, додавши список правил." msgid "options_modalHeader_welcome" msgstr "Вітаємо у SwitchyOmega" #, fuzzy msgid "options_welcomeNormal" msgstr "" "Ви успішно встановили SwitchyOmega, кращий інструмент для налаштування " "проксі." #, fuzzy msgid "options_welcomeNormalGuide" msgstr "" "Будь ласка, повідомте SwitchyOmega ваші проксі в параметрах. Подивимося як." #, fuzzy msgid "options_welcomeUpgrade" msgstr "" "Ви успішно оновилися до SwitchyOmega. Не хвилюйтеся, ваші існуючі параметри " "повністю збережені." #, fuzzy msgid "options_welcomeUpgradeGuide" msgstr "" "Тепер давайте пройдемося по короткому керівництву на сторінці нових " "параметрів." msgid "options_guideNext" msgstr "Далі" msgid "options_guideDone" msgstr "Готово" msgid "options_guideSkip" msgstr "Пропустити навчання" msgid "options_modalHeader_applyOptions" msgstr "Застосувати налаштування" #, fuzzy msgid "options_optionsNotSaved" msgstr "" "Ваші зміни параметрів були збережені і будуть втрачені, якщо ви продовжите!" #, fuzzy msgid "options_applyOptionsRequired" msgstr "Ваші зміни в параметри повинні бути застосовані, перш ніж продовжити." #, fuzzy msgid "options_applyOptionsConfirm" msgstr "Хочете зберегти і застосувати параметри?" msgid "options_modalHeader_renameProfile" msgstr "Перейменувати профіль" msgid "options_renameProfileName" msgstr "Нова назва профілю" msgid "options_profileNameConflict" msgstr "Профіль з такою назвою вже існує." msgid "options_profileNameReserved" msgstr "Назви профілів з подвійним підкреслюванням зарезервовані." #, fuzzy msgid "options_profileNameHidden" msgstr "" "Профілі з іменами, які починаються часткою з підкреслення, будуть приховані " "у спливному меню. Проте, вони можуть використовуватися, наприклад, в " "перемикати профілі." msgid "options_modalHeader_replaceProfile" msgstr "Замінити профіль" msgid "options_replaceProfile" msgstr "Замінити профіль" msgid "options_replaceProfileConfirm" msgstr "Ви дійсно бажаєте замінити $FromProfile$ на $ToProfile$?" #, fuzzy msgid "options_replaceProfileHelp" msgstr "" "Якщо ви продовжите, всі правила, що вказують на $FromProfile$, будуть " "оновлені для використання $ToProfile$. Інші параметри, такі як профіль при " "запуску і швидке перемикання, також будуть змінені відповідним чином. Однак " "самі два профілі НЕ будуть змінені або видалені." msgid "options_replaceProfileSuccess" msgstr "Налаштування оновлено." msgid "options_modalHeader_deleteProfile" msgstr "Видалити профіль" #, fuzzy msgid "options_deleteProfileConfirm" msgstr "Ви дійсно хочете видалити наступний профіль?" msgid "options_modalHeader_cannotDeleteProfile" msgstr "Не вдалося видалити профіль" #, fuzzy msgid "options_profileReferredBy" msgstr "" "Профіль цього не можна видалити, так як на нього посилаються наступні " "профілі:" #, fuzzy msgid "options_modifyReferringProfiles" msgstr "" "Ви повинні змінити ці профілі і змусити їх перестати посилатися на цей " "профіль, перш ніж ви зможете видалити його." #, fuzzy msgid "options_profileNameEmpty" msgstr "Ім'я профілю не може бути порожньо." msgid "popup_title" msgstr "Спиваюче вікно SwitchyOmega" #, fuzzy msgid "options_modalHeader_proxyAuth" msgstr "автентифікація проксі" msgid "options_proxyAuthUsername" msgstr "Ім'я користувача" msgid "options_proxyAuthPassword" msgstr "Пароль" msgid "options_proxyAuthShowPassword" msgstr "Show password" msgid "options_proxyAuthHidePassword" msgstr "Hide password" #, fuzzy msgid "options_proxyAuthNone" msgstr "без автентифікації" msgid "options_modalHeader_deleteRule" msgstr "Видалити правило" #, fuzzy msgid "options_deleteRuleConfirm" msgstr "Ви дійсно хочете видалити наступне правило?" msgid "options_deleteRule" msgstr "Видалити" msgid "options_modalHeader_resetRules" msgstr "Скинути правила" #, fuzzy msgid "options_resetRulesConfirm" msgstr "" "Ви впевнені, що хочете встановити підсумковий профіль ВСІХ правил для " "наступного профілю?" msgid "options_resetRules" msgstr "Скинути правила" msgid "options_resetRules_help" msgstr "Призначити профіль для усіх правил" msgid "options_modalHeader_deleteAttached" msgstr "Видалити список правил" #, fuzzy msgid "options_deleteAttachedConfirm" msgstr "Ви дійсно хочете видалити список правил з поточного профілю?" msgid "options_ruleListLineCount" msgstr "$COUNT$ строчок правил" msgid "options_deleteAttached" msgstr "Видалити список правил" msgid "options_modalHeader_newProfile" msgstr "Новий профіль" msgid "options_newProfileName" msgstr "Назва профілю" msgid "options_profileType" msgstr "Будь ласка, оберіть тип профілю:" msgid "options_profileTypeFixedProfile" msgstr "Профіль проксі-серверів" #, fuzzy msgid "options_profileDescFixedProfile" msgstr "Тунелює трафік через проксі сервера." msgid "options_profileTypePacProfile" msgstr "PAC профіль" #, fuzzy msgid "options_profileDescPacProfile" msgstr "Вибирає профіль, використовуючи онлайн або локальний скрипт PAC." #, fuzzy msgid "options_profileDescMorePacProfile" msgstr "" "Вам це знадобиться тільки в тому випадку, якщо у вас є скрипт PAC або URL-" "адресу до нього. Не намагайтеся створити його, якщо у вас немає знань про " "PAC." msgid "options_profileTypeSwitchProfile" msgstr "Профіль перемикання" msgid "options_profileDescSwitchProfile" msgstr "" "Автоматичне застосування різних профілів в різних умовах, таких як домени " "або шаблони.\n" "Ви також можете імпортувати опубліковані в онлайн правила для зручнішого " "перемикання. (Замінює саморушнє перемикання + список правил.)" msgid "options_profileTypeRuleListProfile" msgstr "Профіль списку правил" #, fuzzy msgid "options_profileDescRuleListProfile" msgstr "Використовує онлайн набір умов, опублікованих іншими користувачами." msgid "options_profileTypeVirtualProfile" msgstr "Віртуальний профіль" #, fuzzy msgid "options_profileDescVirtualProfile" msgstr "" "Віртуальний профіль може діяти, при необхідності, як будь-який інший " "профіль. Він добре працює з перемикається профілем, дозволяючи вам змінити " "результат кількох умов одним клацанням миші." msgid "options_createProfile" msgstr "Створити" msgid "options_modalHeader_resetOptions" msgstr "Скинути налаштування" #, fuzzy msgid "options_resetOptionsConfirm" msgstr "" "Ви дійсно хочете скинути параметри? Всі профілі і налаштування будуть " "втрачені!" #, fuzzy msgid "options_formInvalid" msgstr "Будь ласка, виправте помилки на цій сторінці." #, fuzzy msgid "options_profileNotFound" msgstr "Профіль $PROFILE $не існує! Параметри можуть бути пошкоджені." msgid "options_resetSuccess" msgstr "Налаштування скинуто." msgid "options_saveSuccess" msgstr "Налаштування збережено." msgid "options_importSuccess" msgstr "Налаштування завантажено." msgid "options_importFormatError" msgstr "Некорректний файл резервної копії!" msgid "options_importDownloadError" msgstr "Помилка при заватнаженні файлу резервної копії!" msgid "options_profileDownloadSuccess" msgstr "Профіль успешно оновлено." msgid "options_profileDownloadError" msgstr "Помилка при завантаженні даних профіля!" msgid "options_profileDownloadError_NetworkError" msgstr "При оновленні сталася мережева помилка." msgid "options_profileDownloadError_HttpError" msgstr "Помилка HTTP ($STATUS$) сталася при оновленні." #, fuzzy msgid "options_profileDownloadError_HttpNotFoundError" msgstr "URL-адресу профілю не знайдений на сервері. Будь ласка, перевірте." #, fuzzy msgid "options_profileDownloadError_HttpServerError" msgstr "При оновленні, віддалений сервер повідомив помилку ( $STATUS$)." #, fuzzy msgid "options_profileDownloadError_ContentTypeRejectedError" msgstr "" "Завантажені дані невірні! Ви можете відкрити URL-адресу профілю в своєму " "браузері, щоб перевірити його." msgid "options_downloadProfileNow" msgstr "Завантажити профіль зараз" #, fuzzy msgid "options_guide_fixedProfileStep" msgstr "" "Профіль проксімістить настройки, такі як IP-адреса і порт сервера для " "проксі.
Профілі - це основні одиниці конфігурації в SwitchyOmega.
Ми " "вже створили приклад профілю для вас. Спробуйте відкрити його." #, fuzzy msgid "options_guide_fixedServersStep" msgstr "" "Ви можете тут вказати свій проксі сервер і порт.
SwitchyOmegaне " "поставляється з будь-якими проксі серверами.
ласка, зверніться до " "свого провайдера мережі або до керівництва по настройки проксі, якщо ви не " "знаєте що робити далі." #, fuzzy msgid "options_guide_autoSwitchProfileStep" msgstr "" "Ви можете попросити SwitchyOmega автоматично перемикатися між проксі " "серверами за допомогою потужногоперемикати профілю.
Однак його " "функції не можуть бути розглянуті в цьому короткому посібнику.
Ви можете " "відкрити цей профіль, щоб пізніше розкрити деякі його можливості." #, fuzzy msgid "options_guide_addMoreProfilesStep" msgstr "" "Потрібно більше профілів? Ви завжди можете додати більшепроксі, " "перемикань і інших профілів
для задоволення всіх своїх потреб в " "проксі.
Насолоджуйтесь проксі!" #, fuzzy msgid "options_guide_conditionStep" msgstr "" "SwitchyOmega може застосовувати різні профілі до запитів на основіумов.
Наприклад, умоваШаблон хостадозволяє вам встановити профіль " "для всіх URL-адрес в домені." #, fuzzy msgid "options_guide_conditionTypeStep" msgstr "" "Ви можете використовувати різні типи умов, щоб відповідати хосту або повного " "URL-адресою.
Натисніть на знак питання, щоб відкрити посилання на тип." #, fuzzy msgid "options_guide_conditionProfileStep" msgstr "" "SwitchyOmega застосовує обраний профіль тут добудь-якого запиту, " "відповідного умові.
Спеціальний профіль«[Безпосередньо]»призведе до відправки запиту без будь-якого проксі." #, fuzzy msgid "options_guide_switchDefaultStep" msgstr "" "Якщо до якогось запитом не застосовуються ніякі умови, буде " "використовуватися профіль «Типово».
Умови завжди розглядаються по " "порядкузверху вниз.
Ви можете змінити їх порядок, перетягуючи " "значок сортування." #, fuzzy msgid "options_guide_applySwitchProfileStep" msgstr "" "Завершивши налаштування профілю перемикання, не забудьтепереключитися на " "нього у спливному меню.
Значок покаже вамзастосованийпрофіль " "для поточної вкладки.
Наведення< /b>на значку відкриє підказку з " "подробицями." msgid "popup_externalProfile" msgstr "(Зовнішній профіль)" #, fuzzy msgid "popup_externalProfileName" msgstr "назва профілю" #, fuzzy msgid "popup_proxyNotControllable_app" msgstr "" "Налаштування проксі контролюються іншими застосунками або розширеннями. Будь " "ласка, вимкніть або видаліть ці програми або розширення." #, fuzzy msgid "popup_proxyNotControllable_policy" msgstr "" "Налаштування проксі скасовуються системою. Будь ласка, зв'яжіться з вашим " "адміністратором." msgid "popup_proxyNotControllable_unknown" msgstr "" "Налаштуваннями проксі-серверу наразі керувати неможливо. Будь ласка, " "перевірте налаштування системи та браузеру." #, fuzzy msgid "popup_proxyNotControllable_disabled" msgstr "" "Налаштування проксі відключені явним запитом інших додатків або розширень." msgid "popup_proxyNotControllable_upgrade" msgstr "Налаштування проксі тепер контролюються новішою версією SwitchyOmega." #, fuzzy msgid "popup_proxyNotControllableDetails" msgstr "" "Ви не можете перемикати профілі за допомогою SwitchyOmega, якщо не вирішите " "проблему вище." #, fuzzy msgid "popup_proxyNotControllableDetails_upgrade" msgstr "" "Ви не можете включити дві (або більше) версії SwitchyOmega одночасно. Будь " "ласка, вимкніть одну з них." msgid "popup_proxyNotControllableManage" msgstr "Керувати розширеннями" msgid "popup_addConditionTo" msgstr "Додати умову до" msgid "popup_addCondition" msgstr "Додати умову" msgid "popup_showOptions" msgstr "Налаштування" msgid "popup_reportIssues" msgstr "Повідомити про проблеми" msgid "popup_errorLog" msgstr "Зберегти журнал помилок" msgid "popup_requestErrorCount" msgstr "$COUNT$ невдало завантажених ресурсів" msgid "popup_requestErrorHeading" msgstr "Ресурси, шо не вдалося завантажити" #, fuzzy msgid "popup_requestErrorWarning" msgstr "" "Не вдалося завантажити кілька ресурсів через проблеми з мережею, проксі " "сервером або веб-сторінкою." #, fuzzy msgid "popup_requestErrorWarningHelp" msgstr "SwitchyOmega є просто оглядачем цих проблем, а не їх причиною." #, fuzzy msgid "popup_requestErrorAddCondition" msgstr "" "Ви можете переглянути наступні домени і використовувати проксі для них при " "необхідності." #, fuzzy msgid "popup_requestErrorCannotAddCondition" msgstr "" "Ви можете додати умови перемикання для них тільки при використанні " "перемикати профілю." msgid "popup_configureMonitorWebRequests" msgstr "Налаштувати Network Monitor" msgid "options_resultProfileForSelectedDomains" msgstr "Використати цей профіль для усіх обраних деменів" #, fuzzy msgid "options_pac_profile_unsupported_moz" msgstr "" "Профілі PAC НЕ будуть працювати в Mozilla Firefox через технічні обмежень!" #, fuzzy msgid "popup_issueTemplate" msgstr "" "\n" "\n" "\n" "SwitchyOmega " "$projectVersion$ $userAgent$" msgid "browserAction_profileDetails_PacProfile" msgstr "(PAC-скрипт)" #, fuzzy msgid "browserAction_profileDetails_SystemProfile" msgstr "(Керований іншими розширеннями або оточенням)" msgid "browserAction_profileDetails_DirectProfile" msgstr "(не використовується жоден проксі)" msgid "browserAction_profileDetails_SwitchProfile" msgstr "(перемикання за умовами)" msgid "browserAction_profileDetails_RuleListProfile" msgstr "(перемикання за списком правил)" #, fuzzy msgid "browserAction_titleNormal" msgstr "SwitchyOmega :: $PROFILE$" #, fuzzy msgid "browserAction_titleWithResult" msgstr "SwitchyOmega :: $1: PROFILE$ $3: DETAILS$" msgid "browserAction_titleNewerOptions" msgstr "" "ПОМИЛКА: для завантаження збережених параметрів потрібна новіша версія " "SwitchOmega." #, fuzzy msgid "browserAction_titleOptionError" msgstr "" "ПОМИЛКА: збережені параметри пошкоджені. Натисніть тут, щоб скинути " "ПАРАМЕТРИ." #, fuzzy msgid "browserAction_titleDownloadFail" msgstr "Попередження: не вдалося завантажити скрипт PAC і /або список правил." #, fuzzy msgid "browserAction_titleExternalProxy" msgstr "" "Зауваження: в даний момент, настройки проксі контролюються іншим додатком." msgid "browserAction_titleInspect" msgstr "[Перевірити] $URL$" msgid "browserAction_defaultRuleDetails" msgstr "(за замовчуванням)" msgid "browserAction_directResult" msgstr "НАПРЯМУ" #, fuzzy msgid "browserAction_attachedPrefix" msgstr "(RL) " #, fuzzy msgid "browserAction_tempRulePrefix" msgstr "(TEMP) " #, fuzzy msgid "contextMenu_inspectPage" msgstr "Перевірте проксі, який використовується для цієї сторінки" #, fuzzy msgid "contextMenu_inspectFrame" msgstr "Перевірте проксі, який використовується для цього фрейму" #, fuzzy msgid "contextMenu_inspectLink" msgstr "Перевірити проксі, якщо ця посилання відкрита" msgid "contextMenu_inspectElement" msgstr "Перевірити проксі для цього елементу сторінки" msgid "contextMenu_enableQuickSwitch" msgstr "Включити Швидке перемикання" msgid "about_title" msgstr "Інформація" msgid "about_app_description" msgstr "Інструмент для налаштування проксі-серверів" msgid "about_version" msgstr "Версія $VERSION$" msgid "about_experimental_warning_moz" msgstr "" "Підтримка браузеру Mozilla Firefox вкрай експериментальна! Якщо ви " "стикнетися із проблемами, повідомте про це, використовуючи кнопки нижче." msgid "about_disclaimer_networkService" msgstr "" "SwitchyOmega не надає адреси проксі-серверів, VPN-серверів або інших " "мережевих сервісів." #, fuzzy msgid "about_disclaimer_privacy" msgstr "" "SwitchyOmega не відслідковує вас і не вставляє рекламу в веб-сторінки. Будь " "ласка, ознайомтеся з нашою політикою конфіденційності." #, fuzzy msgid "about_help" msgstr "" "Інші питання? Потрібна допомога з використанням SwitchyOmega? Будь ласка, " "дивіться наш FAQ." #, fuzzy msgid "about_copyright" msgstr "" "Авторське право 2012-2017 Автори SwitchyOmega. Всі права захищені." #, fuzzy msgid "about_credits" msgstr "" "SwitchyOmega стала можливою завдяки проекту SwitchyOmegaз відкритим вихідним кодом і іншому " "програмного забезпечення з відкритим вихідним кодом." #, fuzzy msgid "about_license" msgstr "" "SwitchyOmega - це безкоштовне програмне забезпеченняліцензоване по " "GNU General Public LicenseВерсії 3 або пізнішої." ================================================ FILE: omega-locales/zh_CN/LC_MESSAGES/omega-web.po ================================================ msgid "" msgstr "" "Project-Id-Version: SwitchyOmega 2.3.3\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2015-02-13 11:05+0000\n" "PO-Revision-Date: 2024-12-26 11:48+0000\n" "Last-Translator: Yuzhou Li \n" "Language-Team: Chinese (Simplified Han script) \n" "Language: zh_CN\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" "X-Generator: Weblate 5.10-dev\n" msgid "appNameShort" msgstr "SwitchyOmega" msgid "manifest_app_name" msgstr "Proxy SwitchyOmega" msgid "manifest_app_description" msgstr "轻松快捷地管理和切换多个代理设置。" msgid "manifest_icon_default_title" msgstr "正在加载……" msgid "upgrade_profile_auto" msgstr "自动切换" msgid "profile_direct" msgstr "[直接连接]" msgid "profile_system" msgstr "[系统代理]" msgid "condition_HostWildcardCondition" msgstr "域名通配符" msgid "condition_help_HostWildcardCondition" msgstr "" "根据域名(主机名)匹配请求。
星号 * 匹配零个或者多个字符。
问号 ? 匹配任意一个字符。

请注意以 *. 开头的规则有特别处理,会同时匹配子域名和自身。
例如: *." "example.com 能匹配 www.example.com ,而且也能匹配 example.com 。
如果" "只需要匹配子域名,请使用两个星号开头,如 **.example.com。" msgid "condition_HostRegexCondition" msgstr "域名正则" msgid "condition_help_HostRegexCondition" msgstr "" "类似主机通配符条件,但通过正" "则表达式匹配主机。
正则表达式很难编写,且可读性差。
因此,多数情况下建议使用通配符,只在其他任何条件类型都不能达到的情况下使用正则表" "达式。" msgid "condition_HostLevelsCondition" msgstr "域名层数" msgid "condition_help_HostLevelsCondition" msgstr "" "如果域名层数在设定的范围内则匹配,否则不匹配。
域名层数是指 域名共有几段(以点分隔).
例如: www." "example.com 的域名层数为 3,而 internal 的域名层数为 1." msgid "condition_IpCondition" msgstr "IP 地址字面量" msgid "condition_help_IpCondition" msgstr "" "当且仅当主机是字面的 IP 地址,且地址处于某个子网内时匹配。" "子网使用 CIDR 格式表示。
例如,规则 127.0.0.1/16 会匹配所有类似 " "127.0.*.* 的地址。
" "因此地址 127.0.0.1 匹配而地址 127.1.0.0 不匹配。" "主机名称,例如 localhost 不会被此类规则匹配,因为它们不是 " "IP 地址字面量。" msgid "condition_UrlWildcardCondition" msgstr "网址通配符" msgid "condition_help_UrlWildcardCondition" msgstr "" "根据通配符规则匹配网址。
关于通配符表达式,请参考上方的域名通配符一节的说明。
请注意网址通配符没有任何特殊处理,不会特殊处理子域名等。
" "所以 *://*.example.com/* 能匹配 http://www.example.com/ 但是 不匹配 " "http://example.com/." msgid "condition_UrlRegexCondition" msgstr "网址正则" msgid "condition_help_UrlRegexCondition" msgstr "" "使用功能强大的regular expression正则表达式来匹配URL。
但正则表" "达式很难编写,且可读性差。
因此,建议在大多数情况下使用通配符,只在任何其他条件类型都无法实现的情况下使用正则表达式。" msgid "condition_KeywordCondition" msgstr "关键字" msgid "condition_help_KeywordCondition" msgstr "" "关键字条件的具体匹配规则是:网址协议为HTTP且网址中包含该关键字。
类似于 http://*关键字*, " "其中 关键字 是设定好的关键字。
如果某防火墙根据网址中是否包含关键字来屏蔽网址,那么可以使用关键字条件来通过代理访问这样的请求," "以达到绕过防火墙的目的。" msgid "condition_FalseCondition" msgstr "(禁用)" msgid "condition_details_FalseCondition" msgstr "(匹配请求时无视此条规则)" msgid "condition_help_FalseCondition" msgstr "" "设置规则类型为(禁用)可以临时禁用某个条件。禁用的条件在匹配时视为不存在。
条件被禁用后,仍然保存有之前的数据(" "例如通配符或正则),因此当需要时,可以把条件类型改回之前的类型,以方便地重新启用条件。" msgid "condition_TimeCondition" msgstr "当前时间" msgid "condition_help_TimeCondition" msgstr "" "如果当前本地时间在某个范围内则匹配。此范围由开始小时结束小时" "确定,包含开始的那个小时以及结束的那个小时。
" "本地时间、开始小时和结束小时均按照24小时制计算(从0到23)。
" "此条件大约在请求发出的瞬间,才计算是否匹配。" msgid "condition_WeekdayCondition" msgstr "每周几" msgid "condition_help_WeekdayCondition" msgstr "" "只在每周的某几天才匹配。可以在条件详情中勾选星期几有效。" "根据当地时区来计算现在是星期几,然后再查看当天是否选中。
" "假设在请求发送时是星期X:如果星期X被勾选,则匹配所有请求。否则不匹配任何请求。
" "除了日期以外,在匹配过程中不会参考请求的网址或任何其他信息。" msgid "condition_alert_fullUrlLimitation" msgstr "" "Chrome 52 起,https://协议下的完整网址无法正常匹配。" "" "更多信息..." msgid "condition_alert_fullUrlLimitationLink" msgstr "https://github.com/FelisCatus/SwitchyOmega/wiki/Chromium-%E5%AE%8C%E6%95%B4%E7%BD%91%E5%9D%80%E9%99%90%E5%88%B6" msgid "condition_group_default" msgstr " " msgid "condition_group_host" msgstr "域名" msgid "condition_group_url" msgstr "网址" msgid "condition_group_special" msgstr "特殊" msgid "ruleListFormat_Switchy" msgstr "Switchy" msgid "ruleListFormat_AutoProxy" msgstr "AutoProxy" msgid "ruleList_usageUrl" msgstr "https://github.com/FelisCatus/SwitchyOmega/wiki/RuleListUsage" msgid "ruleList_error_resultNotEnabled" msgstr "语法错误:缺少 '@with result' 指令!" msgid "ruleList_error_unknownProfile" msgstr "未找到此情景模式: $PROFILE$" msgid "ruleList_error_missingResultProfile" msgstr "语法错误:缺少结果情景模式名称。 行号 $LNO$: $SOURCE$" msgid "ruleList_error_invalidRule" msgstr "语法错误:非法规则。行号 $LNO$: $SOURCE$" msgid "ruleList_error_noDefaultRule" msgstr "缺少匹配全部请求的'*'默认规则!" msgid "dialog_close" msgstr "关闭" msgid "dialog_save" msgstr "保存更改" msgid "dialog_ok" msgstr "确定" msgid "dialog_cancel" msgstr "取消" msgid "inputClear_clear" msgstr "清空" msgid "inputClear_restore" msgstr "还原" msgid "options_title" msgstr "SwitchyOmega 选项" msgid "options_experimental_badge" msgstr "测试版" msgid "options_navHeader_setting" msgstr "设置" msgid "options_navHeader_profiles" msgstr "情景模式" msgid "options_navHeader_actions" msgstr "操作" msgid "options_tab_ui" msgstr "界面" msgid "options_tab_general" msgstr "通用" msgid "options_tab_importExport" msgstr "导入/导出" msgid "options_newProfile" msgstr "新建情景模式…" msgid "options_apply" msgstr "应用选项" msgid "options_discard" msgstr "撤销更改" msgid "options_reset" msgstr "重置选项" msgid "options_group_miscOptions" msgstr "其他设置" msgid "options_confirmDeletion" msgstr "删除切换条件时需要确认。" msgid "options_refreshOnProfileChange" msgstr "当更改情景模式时刷新当前标签。" msgid "options_showInspectMenu" msgstr "右键菜单中,可检查网页元素所使用的代理。" msgid "options_addConditionsToBottom" msgstr "把以弹出菜单方式创建的规则添加到列表末尾。" msgid "options_group_keyboardShortcut" msgstr "键盘快捷键" msgid "options_menuShortcutHelp" msgstr "按下快捷键即可打开弹出菜单来切换情景模式。(默认快捷键: Alt+Shift+O)." msgid "options_menuShortcutMore" msgstr "弹出菜单中的菜单项也可以用键盘进行选择。在弹出菜单中按下? (问号键,或/斜杠键) 查看帮助。" msgid "options_menuShortcutConfigure" msgstr "修改快捷键" msgid "options_group_switchOptions" msgstr "切换选项" msgid "options_startupProfile" msgstr "初始情景模式" msgid "options_startupProfile_none" msgstr "(当前情景模式)" msgid "options_showConditionTypesAdvanced" msgstr "显示高级切换条件" msgid "options_showConditionTypesAdvancedHelp" msgstr "解锁一些新种类的、功能强大的但难以掌握的切换条件。对于大多数情况来说,基本条件类型应该就足够,因此不推荐该选项。" msgid "options_quickSwitch" msgstr "快速切换" msgid "options_cycledProfiles" msgstr "循环情景模式" msgid "options_cycledProfilesHelp" msgstr "点击图标或按下快捷键时,依次循环切换到以下情景模式。" msgid "options_cycledProfilesTooFew" msgstr "必须至少选择2个情景模式才能进行切换。请从下方框中拖动情景模式到此框。" msgid "options_notCycledProfiles" msgstr "不循环切换的情景模式 (拖动到上面的框中启用切换)" msgid "options_group_proxyChanges" msgstr "代理设置变化" msgid "options_revertProxyChanges" msgstr "撤消其他扩展对代理的更改。" msgid "options_group_conflicts" msgstr "冲突" msgid "options_conflicts_introduction" msgstr "" "有时其他应用也会试图控制代理设置,从而导致冲突。请注意,去广告等其他扩展也可能" "利用了代理设置来实现功能。此类冲突是由浏览器的工作原理引起的,所以无法避免。" msgid "options_conflicts_lowerPriority" msgstr "" "如果 SwitchyOmega 图标上显示这样的红色徽章,表示另一个应用优先级较高,因此" "SwitchyOmega 无法控制代理设置。请尝试卸载 SwitchyOmega 再重新安装,这样可能可" "以提高 SwitchyOmega 的优先级。如果重装后您仍然看到冲突,那么请考虑移除那个" "导致冲突的应用。" msgid "options_conflicts_higherPriority" msgstr "" "如果 SwitchyOmega 的优先级较高,那么您可以在弹出菜单中选择 $SYSTEMPROFILE$ 来" "把控制权还给其他应用或系统设置。" msgid "options_showExternalProfile" msgstr "在弹出菜单中显示菜单项,以导入其他应用提供的代理设置。" msgid "options_showExternalProfileHelp" msgstr "" "选择了 $SYSTEMPROFILE$ 的情况下,您可以在弹出菜单中选择 $EXTERNALPROFILE$ 来" "导入其他应用提供的代理设置。导入的设置将会成为一个新的情景模式,其名称由您决" "定。请注意导入的情景模式只是当时的一个快照,导入后不会随着原来的应用更新。" msgid "options_group_networkRequests" msgstr "网络请求" msgid "options_monitorWebRequests" msgstr "在图标上显示当前页面中由于网络原因而未加载的资源数量。" msgid "options_monitorWebRequestsHelp" msgstr "启用此选项后,如有资源加载失败,则图标上会显示数字提示。
" "此时,您可以通过弹出菜单一次设置这些资源使用的情景模式,操作十分便捷。" msgid "options_downloadOptions" msgstr "下载选项" msgid "options_downloadOptionsHelp" msgstr "设置规则列表和PAC脚本的更新间隔。" msgid "options_downloadInterval" msgstr "更新间隔" msgid "options_downloadInterval_15" msgstr "15分钟" msgid "options_downloadInterval_60" msgstr "1小时" msgid "options_downloadInterval_180" msgstr "3小时" msgid "options_downloadInterval_360" msgstr "6小时" msgid "options_downloadInterval_720" msgstr "12小时" msgid "options_downloadInterval_1440" msgstr "每天一次" msgid "options_downloadInterval_never" msgstr "从不更新" msgid "options_group_importExportProfile" msgstr "情景模式" msgid "options_exportPacFile" msgstr "导出PAC文件" msgid "options_exportPacFileHelp" msgstr "导出PAC(代理自动设置)文件,以便在其它浏览器使用。" msgid "options_exportProfileHelp" msgstr "如需导出情景模式,请使用情景模式设置页面右上角的工具栏。" msgid "options_exportLegacyRuleList" msgstr "导出规则列表时使用 Proxy Switchy!/SwitchyPlus/SwitchySharp 兼容格式。" msgid "options_exportLegacyRuleListHelp" msgstr "如果您需要发布规则列表给那些软件的用户,请启用此选项。
建议您提醒订阅者升级到 SwitchyOmega 以享受新版功能。" msgid "options_group_importExportSettings" msgstr "选项" msgid "options_makeBackup" msgstr "生成备份文件" msgid "options_makeBackupHelp" msgstr "导出一份包括情景模式和其他所有选项的备份文件。" msgid "options_restoreLocal" msgstr "从备份文件恢复" msgid "options_restoreLocalHelp" msgstr "导入本地的备份文件以恢复所有选项。" msgid "options_restoreOnline" msgstr "在线恢复" msgid "options_restoreOnlinePlaceholder" msgstr "备份文件地址 (如:http://example.com/switchy.bak)" msgid "options_restoreOnlineSubmit" msgstr "恢复" msgid "options_group_syncing" msgstr "选项同步 (测试中)" msgid "options_syncEnable" msgstr "启用同步" msgid "options_syncEnableForce" msgstr "下载云端版本" msgid "options_syncDisable" msgstr "禁用同步" msgid "options_syncReset" msgstr "删除云端版本" msgid "options_syncPristineHelp" msgstr "您可以将设置和情景模式同步到所有使用Chrome浏览器的桌面设备。" msgid "options_syncSyncAlert" msgstr "您的设置将会自动与其他设备进行同步。" msgid "options_syncSyncHelp" msgstr "请注意:您需要在所有设备上(包括此设备)的Chrome浏览器中登录,这样同步的选项才能正常使用。
可以在其他设备上查看此页面,来检查同步是否生效。" msgid "options_syncConflictAlert" msgstr "您已经通过其他设备上传了一份选项用于同步。" msgid "options_syncConflictHelp" msgstr "您可以将云端的选项下载到此设备使用。
一旦选择下载,此设备上的设置和情景模式将会被覆盖。" msgid "options_syncUnsupportedHelp" msgstr "选项同步暂不支持您的平台或浏览器。目前只支持桌面版Chrome的浏览器的同步,请谅解。" msgid "options_profileSyncDisabled" msgstr "此情景模式已经禁用同步。" msgid "options_profileSyncDisabled_quotaPerItem" msgstr "此情景模式使用存储空间过多,因此无法进行同步。" msgid "options_profileTabPrefix" msgstr "情景模式: " msgid "options_renameProfile" msgstr "更改名称" msgid "options_deleteProfile" msgstr "删除" msgid "options_profileExportRuleList" msgstr "发布规则列表" msgid "options_profileExportRuleListHelp" msgstr "将切换规则导出为文本格式以便发布。" msgid "options_profileExportPac" msgstr "导出PAC" msgid "options_profileUnsupported" msgstr "不支持的情景模式类型: $TYPE$!" msgid "options_profileUnsupportedHelp" msgstr "选项文件已经损坏,或者当前版本过低无法处理选项。" msgid "options_profileEditSource" msgstr "编辑源代码" msgid "options_profileEditSourceHelp" msgstr "显示源代码格式相关的帮助" msgid "options_profileEditSourceHelpUrl" msgstr "" "https://github.com/FelisCatus/SwitchyOmega/wiki/SwitchyOmega-conditions-" "format#result-profile" msgid "options_group_proxyServers" msgstr "代理服务器" msgid "options_proxy_scheme" msgstr "网址协议" msgid "options_proxy_protocol" msgstr "代理协议" msgid "options_proxy_server" msgstr "代理服务器" msgid "options_proxy_port" msgstr "代理端口" msgid "options_proxy_auth" msgstr "代理登录" msgid "options_proxy_authNotSupported" msgstr "您的浏览器不支持 $PROTOCOLDISP$ 代理认证!如有问题请联系您的浏览器支持," "请勿反馈此问题给 SwitchyOmega." msgid "options_proxy_authAllWarningPac" msgstr "警告: 用户名密码将会提供给PAC脚本返回的任何服务器,有时目标服务器会出乎您的预料。" msgid "options_proxy_authAllWarningPacUrl" msgstr "在提供用户名和密码时,请先确保您可以信任以上网址提供的PAC脚本。" msgid "options_proxy_authAllWarningPacScript" msgstr "在提供用户名和密码时,请先确保您可以信任以下输入的PAC脚本。" msgid "options_proxy_authReferencedWarning" msgstr "此外,在其他情景模式(如自动切换)中使用此情景时,可能会导致用户名和密码被发送至其他情景模式中设置的服务器。" msgid "options_scheme_default" msgstr "(默认)" msgid "options_protocol_direct" msgstr "直接连接" msgid "options_protocol_useDefault" msgstr "(同默认)" msgid "options_proxy_single" msgstr "对于所有代理使用相同服务器。" msgid "options_proxy_expand" msgstr "显示高级设置" msgid "options_group_bypassList" msgstr "不代理的地址列表" msgid "options_bypassListHelp" msgstr "不经过代理连接的主机列表: (每行一个主机)" msgid "options_bypassListHelpLinkText" msgstr "(可使用通配符等匹配规则…)" msgid "options_group_pacUrl" msgstr "PAC 网址" msgid "options_pacUrlHelp" msgstr "应用将从此网址下载PAC脚本。如果网址留空,则直接使用下方的脚本内容。" msgid "options_pacUrlFile" msgstr "如果您使用本地PAC文件,则该情景模式只能单独使用,无法作为自动切换的结果。这是因为浏览器不允许读取本地文件。" msgid "options_pacUrlFileDisabled" msgstr "此情景模式已被引用,所以不能使用本地PAC文件。如果您真的需要使用本地文件,请另外新建一个PAC情景模式。" msgid "options_group_pacScript" msgstr "PAC 脚本" msgid "options_pacScriptLastUpdate" msgstr "PAC 脚本下载时间 $TIME$:" msgid "options_pacScriptObsolete" msgstr "修改网址后尚未下载更新,因此脚本已经过时。请使用上方的更新按钮进行下载。" msgid "options_group_virtualProfile" msgstr "虚情景模式" msgid "options_virtualProfileTarget" msgstr "目标" msgid "options_virtualProfileTargetHelp" msgstr "应用此配置文件时,它的作用与下面选择的配置文件完全相同。" msgid "options_group_virtualProfileReplace" msgstr "迁移到虚情景模式" msgid "options_virtualProfileReplace" msgstr "取代目标情景模式" msgid "options_virtualProfileReplaceHelp" msgstr "" "通过此功能可以更改现有的选项,使用此虚情景模式来取代 $PROFILE$ 。此功能会把所有和 $PROFILE$ 相关的切换规则改为使用此虚情景模式。" "这样一来,就可以通过此虚情景模式来控制那些切换条件对应的结果。" msgid "options_group_ruleListConfig" msgstr "规则列表设置" msgid "options_ruleListFormat" msgstr "规则列表格式" msgid "options_group_ruleListResult" msgstr "规则列表结果情景模式" msgid "options_ruleListMatchProfile" msgstr "匹配则使用情景模式" msgid "options_ruleListDefaultProfile" msgstr "不匹配则使用情景模式" msgid "options_group_ruleListUrl" msgstr "规则列表网址" msgid "options_ruleListUrlHelp" msgstr "应用将从此网址下载规则列表。如果网址留空,则以下文本会被直接处理后作为规则列表使用。" msgid "options_group_ruleListText" msgstr "规则列表正文" msgid "options_ruleListLastUpdate" msgstr "规则列表下载时间 $TIME$:" msgid "options_ruleListObsolete" msgstr "修改网址后尚未下载更新,因此规则列表已经过时。请使用上方的更新按钮进行下载。" msgid "options_group_switchRules" msgstr "切换规则" msgid "options_sort" msgstr "排序" msgid "options_conditionType" msgstr "条件类型" msgid "options_showConditionTypeHelp" msgstr "显示帮助" msgid "options_conditionDetails" msgstr "条件设置" msgid "options_resultProfile" msgstr "情景模式" msgid "options_conditionActions" msgstr "操作" msgid "options_addCondition" msgstr "添加条件" msgid "options_cloneRule" msgstr "克隆" msgid "options_ruleNote" msgstr "备注" msgid "options_switchAttachedProfileInCondition" msgstr "规则列表规则" msgid "options_switchAttachedProfileInConditionDetails" msgstr "(按照规则列表匹配请求)" msgid "options_switchAttachedProfileInConditionDisabled" msgstr "(规则列表已禁用!)" msgid "options_switchDefaultProfile" msgstr "默认情景模式" msgid "options_hostLevelsBetween" msgstr "≤ 主机层数 ≤" msgid "options_hourBetween" msgstr "≤ 当前小时 ≤" msgid "options_weekDayShort_0" msgstr "日" msgid "options_weekDayShort_1" msgstr "一" msgid "options_weekDayShort_2" msgstr "二" msgid "options_weekDayShort_3" msgstr "三" msgid "options_weekDayShort_4" msgstr "四" msgid "options_weekDayShort_5" msgstr "五" msgid "options_weekDayShort_6" msgstr "六" msgid "options_group_conditionHelp" msgstr "条件类型说明" msgid "options_group_attachProfile" msgstr "导入在线规则列表" msgid "options_attachProfile" msgstr "添加规则列表" msgid "options_attachProfileHelp" msgstr "可以添加规则列表,以便引用他人在线发布的一组规则。" msgid "options_modalHeader_welcome" msgstr "欢迎使用 SwitchyOmega" msgid "options_welcomeNormal" msgstr "您已经成功安装了 SwitchyOmega ,一个强大的代理切换工具。" msgid "options_welcomeNormalGuide" msgstr "您可以通过选项页面设置需要使用的代理服务器,下面我们就来试试看吧。" msgid "options_welcomeUpgrade" msgstr "您已经成功升级到 SwitchyOmega. 别担心,所有设置都已经升级成功,可以继续使用。" msgid "options_welcomeUpgradeGuide" msgstr "现在我们来熟悉一下新的选项页面。" msgid "options_guideNext" msgstr "下一步" msgid "options_guideDone" msgstr "完成" msgid "options_guideSkip" msgstr "跳过教程" msgid "options_modalHeader_applyOptions" msgstr "应用选项" msgid "options_optionsNotSaved" msgstr "当前设置还未保存。如果您继续此操作,则刚才的所有修改都会丢失!" msgid "options_applyOptionsRequired" msgstr "必须保存当前选项才能继续操作。" msgid "options_applyOptionsConfirm" msgstr "是否保存并应用现在的选项?" msgid "options_modalHeader_renameProfile" msgstr "重命名" msgid "options_renameProfileName" msgstr "新的名称" msgid "options_profileNameConflict" msgstr "已经存在相同名称的情景模式。" msgid "options_profileNameReserved" msgstr "以双下划线开头的名称为系统保留,禁止使用。" msgid "options_profileNameHidden" msgstr "以下划线开头的情景模式不会在弹出菜单中显示,但仍可被用作切换的结果等。" msgid "options_modalHeader_replaceProfile" msgstr "替换情景模式" msgid "options_replaceProfile" msgstr "替换" msgid "options_replaceProfileConfirm" msgstr "您确定要使用 $ToProfile 来代替 $FromProfile$ 吗?" msgid "options_replaceProfileHelp" msgstr "" "如果继续操作,则和 $FromProfile$ 有关的切换规则将改为使用 $ToProfile$ 来代替。此外,启动情景模式、快速切换等设置也会做相应调整。" "但请注意,此操作不影响这两个情景模式本身。" msgid "options_replaceProfileSuccess" msgstr "更改选项成功。" msgid "options_modalHeader_deleteProfile" msgstr "删除情景模式" msgid "options_deleteProfileConfirm" msgstr "真的要删除这个情景模式吗?" msgid "options_modalHeader_cannotDeleteProfile" msgstr "情景模式无法删除" msgid "options_profileReferredBy" msgstr "无法删除此配置文件,因为它被以下配置文件引用:" msgid "options_modifyReferringProfiles" msgstr "修改以上所有情景模式并移除对此情景模式的引用后,方可删除此情景模式。" msgid "options_profileNameEmpty" msgstr "情景模式名称不能为空。" msgid "popup_title" msgstr "SwitchyOmega 弹出菜单" msgid "options_modalHeader_deleteRule" msgstr "删除规则" msgid "options_modalHeader_proxyAuth" msgstr "代理登录" msgid "options_proxyAuthUsername" msgstr "用户名" msgid "options_proxyAuthPassword" msgstr "密码" msgid "options_proxyAuthShowPassword" msgstr "显示密码" msgid "options_proxyAuthHidePassword" msgstr "隐藏密码" msgid "options_proxyAuthNone" msgstr "(无密码)" msgid "options_deleteRuleConfirm" msgstr "真的要删除这个规则吗?" msgid "options_deleteRule" msgstr "删除" msgid "options_modalHeader_resetRules" msgstr "重置全部规则" msgid "options_resetRulesConfirm" msgstr "真的要设置所有规则对应的情景模式为以下情景模式吗?" msgid "options_resetRules" msgstr "重置规则" msgid "options_resetRules_help" msgstr "批量设置所有规则的情景模式" msgid "options_modalHeader_deleteAttached" msgstr "移除规则列表" msgid "options_deleteAttachedConfirm" msgstr "真的要移除当前情景模式的在线规则列表吗?" msgid "options_ruleListLineCount" msgstr "共计$COUNT$行规则" msgid "options_deleteAttached" msgstr "移除规则列表" msgid "options_modalHeader_newProfile" msgstr "新建情景模式" msgid "options_newProfileName" msgstr "情景模式名称" msgid "options_profileType" msgstr "请选择情景模式的类型:" msgid "options_profileTypeFixedProfile" msgstr "代理服务器" msgid "options_profileDescFixedProfile" msgstr "经过代理服务器访问网站。" msgid "options_profileTypePacProfile" msgstr "PAC情景模式" msgid "options_profileDescPacProfile" msgstr "根据在线或本地的PAC脚本选择代理。" msgid "options_profileDescMorePacProfile" msgstr "如果您没有任何PAC脚本,也没有脚本的网址,则不必使用此情景模式。不了解PAC的用户不建议自行尝试编写脚本。" msgid "options_profileTypeSwitchProfile" msgstr "自动切换模式" msgid "options_profileDescSwitchProfile" msgstr "" "根据多种条件,如域名或网址等自动选择情景模式。\n" "您也可以导入在线发布的切换规则(如 AutoProxy 列表)以简化设置。" msgid "options_profileTypeRuleListProfile" msgstr "规则列表" msgid "options_profileDescRuleListProfile" msgstr "使用他人发布的在线规则列表来切换情景模式。" msgid "options_profileTypeVirtualProfile" msgstr "虚情景模式" msgid "options_profileDescVirtualProfile" msgstr "虚情景模式可以作为某个其他情景模式使用,并可以根据需要更改对象。一般用在自动切换中,这样就可以一次性更改多个条件对应的代理。" msgid "options_createProfile" msgstr "创建" msgid "options_modalHeader_resetOptions" msgstr "重置选项" msgid "options_resetOptionsConfirm" msgstr "真的确定要重置选项吗?如果继续,现有的所有情景模式和选项将会丢失!" msgid "options_formInvalid" msgstr "请更正这个页面中的错误。" msgid "options_profileNotFound" msgstr "情景模式 $PROFILE$ 不存在!选项可能已经损坏。" msgid "options_resetSuccess" msgstr "选项已经重置。" msgid "options_saveSuccess" msgstr "保存选项成功。" msgid "options_importSuccess" msgstr "导入选项成功。" msgid "options_importFormatError" msgstr "备份文件格式错误!" msgid "options_importDownloadError" msgstr "下载备份文件时出错!" msgid "options_profileDownloadSuccess" msgstr "情景模式已经更新成功。" msgid "options_profileDownloadError" msgstr "下载情景模式数据时出错!" msgid "options_profileDownloadError_NetworkError" msgstr "更新时发生网络错误。" msgid "options_profileDownloadError_HttpError" msgstr "更新时发生网络错误 (HTTP $STATUS$)." msgid "options_profileDownloadError_HttpNotFoundError" msgstr "在远程服务器上找不到情景模式网址对应的文件。请检查网址。" msgid "options_profileDownloadError_HttpServerError" msgstr "更新时远程服务器发生错误 ($STATUS$)。" msgid "options_profileDownloadError_ContentTypeRejectedError" msgstr "下载的数据不符合格式!建议您在浏览器中打开情景模式网址并检查其内容。" msgid "options_downloadProfileNow" msgstr "立即更新情景模式" msgid "options_guide_fixedProfileStep" msgstr "" "代理情景包含了服务器地址、端口等代理的信息。
在 SwitchyOmega 中,情景模式是代理设置的基本单元。
" "默认设置中已经建立了一个代理情景模式作为样例。试着打开它吧。" msgid "options_guide_fixedServersStep" msgstr "" "在这里,您可以填写所需的代理服务器地址和端口。
SwitchyOmega软件本身不提供任何内置代理服务器
" "如果您不清楚应该填写什么,最好咨询下您的网络提供者,或者参考代理软件的设置说明。" msgid "options_guide_autoSwitchProfileStep" msgstr "" "您可以通过强大的自动切换模式在多个代理间切换自如。
不过,在这个简单的教程中无法详尽介绍所有功能。
想要使用此功能时," "可以打开这里的设置界面,来了解如何使用自动切换功能。" msgid "options_guide_addMoreProfilesStep" msgstr "需要更多情景模式?你始终可以添加更多代理、切换和其他情景模式满足你所有" "的代理需要。
教程到此结束,享受代理吧!" msgid "options_guide_conditionStep" msgstr "" "SwitchyOmega 可以根据切换条件对不同的网络请求使用不同的情景模式。
例如域名通配符" "条件可以对某个域名下的所有网址使用特定的情景模式。" msgid "options_guide_conditionTypeStep" msgstr "您可以使用各种条件类型来匹配域名或者整个网址。
点击问号按钮来查看条件类型的说明。" msgid "options_guide_conditionProfileStep" msgstr "" "对于任何匹配该条件的请求,SwitchyOmega 会使用这个情景模式。
如果选择了\"[直接连接]\"情景模式," "则匹配的请求不使用任何代理。" msgid "options_guide_switchDefaultStep" msgstr "如果请求不匹配任何条件,则使用默认情景模式。
条件的匹配顺序总是按此页面从上到下
您可以拖动排序图标来更改条件的顺序。" msgid "options_guide_applySwitchProfileStep" msgstr "" "当您设置完毕后,别忘记在弹出菜单中启用自动切换情景模式
图标将会显示标签页切换的最终结果情景。
" "悬停在图标上则会显示切换相关的详细说明。" msgid "popup_externalProfile" msgstr "(外部情景模式)" msgid "popup_externalProfileName" msgstr "保存名称" msgid "popup_proxyNotControllable_app" msgstr "其他应用正在控制代理设置。请禁用或者卸载发生冲突的应用。" msgid "popup_proxyNotControllable_policy" msgstr "代理设置被本地策略强制指定,无法修改。请联系系统管理员。" msgid "popup_proxyNotControllable_unknown" msgstr "无法设置代理设置。请检查系统和浏览器设置。" msgid "popup_proxyNotControllable_disabled" msgstr "在其他应用或扩展的要求下,SwitchyOmega 已经禁用代理设置。" msgid "popup_proxyNotControllable_upgrade" msgstr "代理设置现在由新版本的 SwitchyOmega 控制。" msgid "popup_proxyNotControllableDetails" msgstr "如果不解决以上问题,则无法使用SwitchyOmega切换代理。" msgid "popup_proxyNotControllableDetails_upgrade" msgstr "两个不同版本的 SwitchyOmega (如稳定版和测试版)不能共存。请禁用其中之一。" msgid "popup_proxyNotControllableManage" msgstr "管理扩展" msgid "popup_addConditionTo" msgstr "添加条件到情景模式" msgid "popup_addCondition" msgstr "添加条件" msgid "popup_showOptions" msgstr "选项" msgid "popup_reportIssues" msgstr "反馈问题" msgid "popup_errorLog" msgstr "保存错误日志" msgid "popup_requestErrorCount" msgstr "$COUNT$个资源未加载" msgid "popup_requestErrorHeading" msgstr "加载失败的资源列表" msgid "popup_requestErrorWarning" msgstr "由于网络原因,此页面部分资源加载失败。这些问题可能是由您的网络、代理服务器或网站本身引起的。" msgid "popup_requestErrorWarningHelp" msgstr "这些问题并非由 SwitchyOmega 自身导致,它只不过检测并报告了错误而已。" msgid "popup_requestErrorAddCondition" msgstr "您可以查看以下域名,并根据实际情况确定是否对其使用代理。" msgid "popup_requestErrorCannotAddCondition" msgstr "在使用自动切换情景时,才可以将这些资源添加为切换条件。" msgid "popup_configureMonitorWebRequests" msgstr "设置网络检测选项" msgid "options_resultProfileForSelectedDomains" msgstr "对所有选中域名使用此情景模式" msgid "options_pac_profile_unsupported_moz" msgstr "由于技术限制,PAC 情景模式无法在 Mozilla Firefox 上工作!" msgid "popup_issueTemplate" msgstr "" "\n" "\n" "\n" "\n" "SwitchyOmega $projectVersion$\n" "$userAgent$" msgid "browserAction_profileDetails_PacProfile" msgstr "(PAC 脚本)" msgid "browserAction_profileDetails_SystemProfile" msgstr "(由其他扩展或系统环境控制)" msgid "browserAction_profileDetails_DirectProfile" msgstr "(不使用任何代理)" msgid "browserAction_profileDetails_SwitchProfile" msgstr "(根据条件切换)" msgid "browserAction_profileDetails_RuleListProfile" msgstr "(根据规则列表切换)" msgid "browserAction_titleNormal" msgstr "SwitchyOmega:: $PROFILE$" msgid "browserAction_titleWithResult" msgstr "" "SwitchyOmega:: $1:PROFILE$\n" "$3:DETAILS$" msgid "browserAction_titleNewerOptions" msgstr "错误:需要新版本的SwitchyOmega才能加载当前选项。" msgid "browserAction_titleOptionError" msgstr "错误:选项文件已经损坏,点击此处重置选项。" msgid "browserAction_titleDownloadFail" msgstr "警告:更新PAC文件或规则列表失败。" msgid "browserAction_titleExternalProxy" msgstr "注意:其他应用正在控制当前代理设置。" msgid "browserAction_titleInspect" msgstr "[检查] $URL$" msgid "browserAction_defaultRuleDetails" msgstr "(默认)" msgid "browserAction_directResult" msgstr "直接连接" msgid "browserAction_attachedPrefix" msgstr "(列表) " msgid "browserAction_tempRulePrefix" msgstr "(临时) " msgid "contextMenu_inspectPage" msgstr "检查此页面使用的代理" msgid "contextMenu_inspectFrame" msgstr "检查此[框架页面]使用的代理" msgid "contextMenu_inspectLink" msgstr "检查此[链接目标]将会使用的代理" msgid "contextMenu_inspectElement" msgstr "检查此[元素]使用的代理" msgid "contextMenu_enableQuickSwitch" msgstr "启用快速切换" msgid "about_title" msgstr "关于" msgid "about_app_description" msgstr "一个代理设置工具" msgid "about_version" msgstr "版本 $VERSION$" msgid "about_experimental_warning_moz" msgstr "Mozilla Firefox 浏览器支持目前仍处于早期实验阶段!如果您遇到任何问题,请使用下方的按钮进行反馈。" msgid "about_disclaimer_networkService" msgstr "SwitchyOmega 不提供代理服务器、VPN等网络服务。" msgid "about_disclaimer_privacy" msgstr "SwitchyOmega 不会跟踪您的上网记录,不在页面中插入广告。请参见我们的" "隐私政策。" msgid "about_help" msgstr "" "有其它问题?在使用 SwitchyOmega 方面需要帮助?请参阅我们的常见问题。" msgid "about_copyright" msgstr "版权所有 2012-2017 The SwitchyOmega Authors. 保留所有权利。" msgid "about_credits" msgstr "SwitchyOmega 的诞生离不开 SwitchyOmega 开源项目和其他开源软件。" msgid "about_license" msgstr "SwitchyOmega 是自由软件,使用GNU General Public License 版本 3 及以上授权。" ================================================ FILE: omega-locales/zh_Hant/LC_MESSAGES/omega-web.po ================================================ msgid "" msgstr "" "Project-Id-Version: SwitchyOmega 2.3.3\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2015-02-13 10:29+0000\n" "PO-Revision-Date: 2022-04-22 05:07+0000\n" "Last-Translator: Still Hsu \n" "Language-Team: Chinese (Traditional) \n" "Language: zh_Hant\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" "X-Generator: Weblate 4.12-dev\n" msgid "appNameShort" msgstr "SwitchyOmega" msgid "manifest_app_name" msgstr "Proxy SwitchyOmega" msgid "manifest_app_description" msgstr "輕鬆快速地管理及切換多個 Proxy 設定。" msgid "manifest_icon_default_title" msgstr "載入中…" msgid "upgrade_profile_auto" msgstr "自動切換" msgid "profile_direct" msgstr "[直接連接]" msgid "profile_system" msgstr "[系統 Proxy]" msgid "condition_HostWildcardCondition" msgstr "域名萬用字元" msgid "condition_help_HostWildcardCondition" msgstr "" "根據域名 (主機名稱) 的萬用字元進行匹配。
星號 * " "將會符合零個或多個字元。
問號 ? " "將會符合任一字元。

請注意,以 *. " "開頭的規則會同時匹配其子域名及自身。
舉例來說:*.example.com " "將會符合 www.example.com 以及 example." "com。
只要符合子域名,請使用兩個星號開頭,如 **." "example.com。" msgid "condition_HostRegexCondition" msgstr "域名正則式" msgid "condition_help_HostRegexCondition" msgstr "" msgid "condition_HostLevelsCondition" msgstr "域名層數" msgid "condition_help_HostLevelsCondition" msgstr "" msgid "condition_IpCondition" msgstr "IP 地址字面量" msgid "condition_help_IpCondition" msgstr "" msgid "condition_UrlWildcardCondition" msgstr "網址萬用字元" msgid "condition_help_UrlWildcardCondition" msgstr "" msgid "condition_UrlRegexCondition" msgstr "URL 正則式" msgid "condition_help_UrlRegexCondition" msgstr "" msgid "condition_KeywordCondition" msgstr "關鍵字" msgid "condition_help_KeywordCondition" msgstr "" msgid "condition_FalseCondition" msgstr "(禁用)" msgid "condition_details_FalseCondition" msgstr "(匹配時無視此規則)" msgid "condition_help_FalseCondition" msgstr "" msgid "condition_TimeCondition" msgstr "目前時間" msgid "condition_help_TimeCondition" msgstr "" msgid "condition_WeekdayCondition" msgstr "每周幾" msgid "condition_help_WeekdayCondition" msgstr "" msgid "condition_alert_fullUrlLimitation" msgstr "" "自 Chrome 52 起,https://下的完整網址將無法正常匹配。更多訊息..." #, fuzzy msgid "condition_alert_fullUrlLimitationLink" msgstr "" "https://github.com/FelisCatus/SwitchyOmega/wiki/Chromium-Full-URL-Limitation" #, fuzzy msgid "condition_group_default" msgstr " " msgid "condition_group_host" msgstr "域名" msgid "condition_group_url" msgstr "網址" msgid "condition_group_special" msgstr "特殊" #, fuzzy msgid "ruleListFormat_Switchy" msgstr "Switchy" #, fuzzy msgid "ruleListFormat_AutoProxy" msgstr "AutoProxy" #, fuzzy msgid "ruleList_usageUrl" msgstr "https://github.com/FelisCatus/SwitchyOmega/wiki/RuleListUsage" msgid "ruleList_error_resultNotEnabled" msgstr "缺少 '@with result' 指令!" msgid "ruleList_error_unknownProfile" msgstr "未知設定檔:$PROFILE$" msgid "ruleList_error_missingResultProfile" msgstr "" msgid "ruleList_error_invalidRule" msgstr "" msgid "ruleList_error_noDefaultRule" msgstr "" msgid "dialog_close" msgstr "關閉" msgid "dialog_save" msgstr "儲存變更" msgid "dialog_ok" msgstr "確定" msgid "dialog_cancel" msgstr "取消" msgid "inputClear_clear" msgstr "清除" msgid "inputClear_restore" msgstr "還原" msgid "options_title" msgstr "SwitchyOmega 選項" msgid "options_experimental_badge" msgstr "α" msgid "options_navHeader_setting" msgstr "設定" msgid "options_navHeader_profiles" msgstr "設定檔" msgid "options_navHeader_actions" msgstr "操作" msgid "options_tab_ui" msgstr "介面" msgid "options_tab_general" msgstr "一般設定" msgid "options_tab_importExport" msgstr "匯入/匯出" msgid "options_newProfile" msgstr "新增設定檔…" msgid "options_apply" msgstr "套用變更" msgid "options_discard" msgstr "放棄變更" msgid "options_reset" msgstr "重置設定" msgid "options_group_miscOptions" msgstr "其他設定" msgid "options_confirmDeletion" msgstr "需確認刪除切換條件。" msgid "options_refreshOnProfileChange" msgstr "" msgid "options_showInspectMenu" msgstr "" msgid "options_addConditionsToBottom" msgstr "" msgid "options_group_keyboardShortcut" msgstr "鍵盤快捷鍵" msgid "options_menuShortcutHelp" msgstr "" msgid "options_menuShortcutMore" msgstr "" msgid "options_menuShortcutConfigure" msgstr "設定快捷鍵" msgid "options_group_switchOptions" msgstr "切換選項" msgid "options_startupProfile" msgstr "初始設定檔" msgid "options_startupProfile_none" msgstr "(當前設定檔)" msgid "options_showConditionTypesAdvanced" msgstr "顯示進階切換條件" msgid "options_showConditionTypesAdvancedHelp" msgstr "" msgid "options_quickSwitch" msgstr "快速切换" msgid "options_cycledProfiles" msgstr "循環切換設定檔" msgid "options_cycledProfilesHelp" msgstr "" msgid "options_cycledProfilesTooFew" msgstr "" msgid "options_notCycledProfiles" msgstr "" msgid "options_group_proxyChanges" msgstr "Proxy 設定變更" msgid "options_revertProxyChanges" msgstr "" msgid "options_group_conflicts" msgstr "衝突" msgid "options_conflicts_introduction" msgstr "" msgid "options_conflicts_lowerPriority" msgstr "" msgid "options_conflicts_higherPriority" msgstr "" msgid "options_showExternalProfile" msgstr "" msgid "options_showExternalProfileHelp" msgstr "" msgid "options_group_networkRequests" msgstr "" msgid "options_monitorWebRequests" msgstr "" msgid "options_monitorWebRequestsHelp" msgstr "" msgid "options_downloadOptions" msgstr "" msgid "options_downloadOptionsHelp" msgstr "" msgid "options_downloadInterval" msgstr "" msgid "options_downloadInterval_15" msgstr "15 分鐘" msgid "options_downloadInterval_60" msgstr "1 小時" msgid "options_downloadInterval_180" msgstr "3 小時" msgid "options_downloadInterval_360" msgstr "6 小時" msgid "options_downloadInterval_720" msgstr "12 小時" msgid "options_downloadInterval_1440" msgstr "每天" msgid "options_downloadInterval_never" msgstr "永不" msgid "options_group_importExportProfile" msgstr "設定檔" msgid "options_exportPacFile" msgstr "匯出 PAC 檔案" msgid "options_exportPacFileHelp" msgstr "" msgid "options_exportProfileHelp" msgstr "" msgid "options_exportLegacyRuleList" msgstr "" msgid "options_exportLegacyRuleListHelp" msgstr "" msgid "options_group_importExportSettings" msgstr "" msgid "options_makeBackup" msgstr "" msgid "options_makeBackupHelp" msgstr "" msgid "options_restoreLocal" msgstr "" msgid "options_restoreLocalHelp" msgstr "" msgid "options_restoreOnline" msgstr "" msgid "options_restoreOnlinePlaceholder" msgstr "" msgid "options_restoreOnlineSubmit" msgstr "" msgid "options_group_syncing" msgstr "" msgid "options_syncEnable" msgstr "" msgid "options_syncEnableForce" msgstr "" msgid "options_syncDisable" msgstr "" msgid "options_syncReset" msgstr "" msgid "options_syncPristineHelp" msgstr "" msgid "options_syncSyncAlert" msgstr "" msgid "options_syncSyncHelp" msgstr "" msgid "options_syncConflictAlert" msgstr "" msgid "options_syncConflictHelp" msgstr "" msgid "options_syncUnsupportedHelp" msgstr "" msgid "options_profileSyncDisabled" msgstr "" msgid "options_profileSyncDisabled_quotaPerItem" msgstr "" msgid "options_profileTabPrefix" msgstr "" msgid "options_renameProfile" msgstr "" msgid "options_deleteProfile" msgstr "" msgid "options_profileExportRuleList" msgstr "" msgid "options_profileExportRuleListHelp" msgstr "" msgid "options_profileExportPac" msgstr "" msgid "options_profileUnsupported" msgstr "" msgid "options_profileUnsupportedHelp" msgstr "" msgid "options_profileEditSource" msgstr "" msgid "options_profileEditSourceHelp" msgstr "" msgid "options_profileEditSourceHelpUrl" msgstr "" msgid "options_group_proxyServers" msgstr "" msgid "options_proxy_scheme" msgstr "" msgid "options_proxy_protocol" msgstr "" msgid "options_proxy_server" msgstr "" msgid "options_proxy_port" msgstr "" msgid "options_proxy_auth" msgstr "" msgid "options_proxy_authNotSupported" msgstr "" msgid "options_proxy_authAllWarningPac" msgstr "" msgid "options_proxy_authAllWarningPacUrl" msgstr "" msgid "options_proxy_authAllWarningPacScript" msgstr "" msgid "options_proxy_authReferencedWarning" msgstr "" msgid "options_scheme_default" msgstr "" msgid "options_protocol_direct" msgstr "直接連接" msgid "options_protocol_useDefault" msgstr "(同預設)" msgid "options_proxy_single" msgstr "" msgid "options_proxy_expand" msgstr "" msgid "options_group_bypassList" msgstr "不使用 Proxy 的位址清單" msgid "options_bypassListHelp" msgstr "" msgid "options_bypassListHelpLinkText" msgstr "" msgid "options_group_pacUrl" msgstr "PAC 網址" msgid "options_pacUrlHelp" msgstr "PAC 腳本將從此網址更新。如果將其留空,則將直接使用以下腳本。" msgid "options_pacUrlFile" msgstr "" msgid "options_pacUrlFileDisabled" msgstr "" msgid "options_group_pacScript" msgstr "PAC 腳本" msgid "options_pacScriptLastUpdate" msgstr "" msgid "options_pacScriptObsolete" msgstr "由於已變更網址,PAC 腳本已過時。按上面的下載按鈕進行更新。" msgid "options_group_virtualProfile" msgstr "虛擬設定檔" msgid "options_virtualProfileTarget" msgstr "目標" msgid "options_virtualProfileTargetHelp" msgstr "" msgid "options_group_virtualProfileReplace" msgstr "遷移到虛擬設定檔" msgid "options_virtualProfileReplace" msgstr "" msgid "options_virtualProfileReplaceHelp" msgstr "" msgid "options_group_ruleListConfig" msgstr "" msgid "options_ruleListFormat" msgstr "" msgid "options_group_ruleListResult" msgstr "" msgid "options_ruleListMatchProfile" msgstr "" msgid "options_ruleListDefaultProfile" msgstr "" msgid "options_group_ruleListUrl" msgstr "" msgid "options_ruleListUrlHelp" msgstr "" msgid "options_group_ruleListText" msgstr "" msgid "options_ruleListLastUpdate" msgstr "" msgid "options_ruleListObsolete" msgstr "" msgid "options_group_switchRules" msgstr "" #, fuzzy msgid "options_sort" msgstr "排序" #, fuzzy msgid "options_conditionType" msgstr "條件類型" #, fuzzy msgid "options_showConditionTypeHelp" msgstr "顯示説明" msgid "options_conditionDetails" msgstr "條件詳情" msgid "options_resultProfile" msgstr "設定檔" msgid "options_conditionActions" msgstr "操作" msgid "options_addCondition" msgstr "新增條件" msgid "options_cloneRule" msgstr "複製" msgid "options_ruleNote" msgstr "備註" msgid "options_switchAttachedProfileInCondition" msgstr "規則清單規則" msgid "options_switchAttachedProfileInConditionDetails" msgstr "" msgid "options_switchAttachedProfileInConditionDisabled" msgstr "" msgid "options_switchDefaultProfile" msgstr "" msgid "options_hostLevelsBetween" msgstr "" msgid "options_hourBetween" msgstr "" msgid "options_weekDayShort_0" msgstr "日" msgid "options_weekDayShort_1" msgstr "一" msgid "options_weekDayShort_2" msgstr "二" msgid "options_weekDayShort_3" msgstr "三" msgid "options_weekDayShort_4" msgstr "四" msgid "options_weekDayShort_5" msgstr "五" msgid "options_weekDayShort_6" msgstr "六" msgid "options_group_conditionHelp" msgstr "關於條件種類" msgid "options_group_attachProfile" msgstr "" msgid "options_attachProfile" msgstr "新增條件清單" msgid "options_attachProfileHelp" msgstr "" msgid "options_modalHeader_welcome" msgstr "" msgid "options_welcomeNormal" msgstr "" msgid "options_welcomeNormalGuide" msgstr "" msgid "options_welcomeUpgrade" msgstr "" msgid "options_welcomeUpgradeGuide" msgstr "" msgid "options_guideNext" msgstr "" msgid "options_guideDone" msgstr "" msgid "options_guideSkip" msgstr "" msgid "options_modalHeader_applyOptions" msgstr "" msgid "options_optionsNotSaved" msgstr "" msgid "options_applyOptionsRequired" msgstr "" msgid "options_applyOptionsConfirm" msgstr "" msgid "options_modalHeader_renameProfile" msgstr "" msgid "options_renameProfileName" msgstr "" msgid "options_profileNameConflict" msgstr "" msgid "options_profileNameReserved" msgstr "" msgid "options_profileNameHidden" msgstr "" msgid "options_modalHeader_replaceProfile" msgstr "" msgid "options_replaceProfile" msgstr "" msgid "options_replaceProfileConfirm" msgstr "" msgid "options_replaceProfileHelp" msgstr "" msgid "options_replaceProfileSuccess" msgstr "" msgid "options_modalHeader_deleteProfile" msgstr "" msgid "options_deleteProfileConfirm" msgstr "" msgid "options_modalHeader_cannotDeleteProfile" msgstr "" msgid "options_profileReferredBy" msgstr "" msgid "options_modifyReferringProfiles" msgstr "" msgid "options_profileNameEmpty" msgstr "" msgid "popup_title" msgstr "" msgid "options_modalHeader_proxyAuth" msgstr "" msgid "options_proxyAuthUsername" msgstr "" msgid "options_proxyAuthPassword" msgstr "" msgid "options_proxyAuthShowPassword" msgstr "" msgid "options_proxyAuthHidePassword" msgstr "" msgid "options_proxyAuthNone" msgstr "" msgid "options_modalHeader_deleteRule" msgstr "" msgid "options_deleteRuleConfirm" msgstr "" msgid "options_deleteRule" msgstr "" msgid "options_modalHeader_resetRules" msgstr "" msgid "options_resetRulesConfirm" msgstr "" msgid "options_resetRules" msgstr "" msgid "options_resetRules_help" msgstr "" msgid "options_modalHeader_deleteAttached" msgstr "" msgid "options_deleteAttachedConfirm" msgstr "" msgid "options_ruleListLineCount" msgstr "" msgid "options_deleteAttached" msgstr "" msgid "options_modalHeader_newProfile" msgstr "" msgid "options_newProfileName" msgstr "" msgid "options_profileType" msgstr "" msgid "options_profileTypeFixedProfile" msgstr "" msgid "options_profileDescFixedProfile" msgstr "" msgid "options_profileTypePacProfile" msgstr "" msgid "options_profileDescPacProfile" msgstr "" msgid "options_profileDescMorePacProfile" msgstr "" msgid "options_profileTypeSwitchProfile" msgstr "" msgid "options_profileDescSwitchProfile" msgstr "" msgid "options_profileTypeRuleListProfile" msgstr "" msgid "options_profileDescRuleListProfile" msgstr "" msgid "options_profileTypeVirtualProfile" msgstr "" msgid "options_profileDescVirtualProfile" msgstr "" msgid "options_createProfile" msgstr "" msgid "options_modalHeader_resetOptions" msgstr "" msgid "options_resetOptionsConfirm" msgstr "" msgid "options_formInvalid" msgstr "" msgid "options_profileNotFound" msgstr "" msgid "options_resetSuccess" msgstr "" msgid "options_saveSuccess" msgstr "" msgid "options_importSuccess" msgstr "" msgid "options_importFormatError" msgstr "" msgid "options_importDownloadError" msgstr "" msgid "options_profileDownloadSuccess" msgstr "" msgid "options_profileDownloadError" msgstr "" msgid "options_profileDownloadError_NetworkError" msgstr "" msgid "options_profileDownloadError_HttpError" msgstr "" msgid "options_profileDownloadError_HttpNotFoundError" msgstr "" msgid "options_profileDownloadError_HttpServerError" msgstr "" msgid "options_profileDownloadError_ContentTypeRejectedError" msgstr "" msgid "options_downloadProfileNow" msgstr "" msgid "options_guide_fixedProfileStep" msgstr "" msgid "options_guide_fixedServersStep" msgstr "" msgid "options_guide_autoSwitchProfileStep" msgstr "" msgid "options_guide_addMoreProfilesStep" msgstr "" msgid "options_guide_conditionStep" msgstr "" msgid "options_guide_conditionTypeStep" msgstr "" msgid "options_guide_conditionProfileStep" msgstr "" msgid "options_guide_switchDefaultStep" msgstr "" msgid "options_guide_applySwitchProfileStep" msgstr "" msgid "popup_externalProfile" msgstr "" msgid "popup_externalProfileName" msgstr "" msgid "popup_proxyNotControllable_app" msgstr "" msgid "popup_proxyNotControllable_policy" msgstr "" msgid "popup_proxyNotControllable_unknown" msgstr "" msgid "popup_proxyNotControllable_disabled" msgstr "" msgid "popup_proxyNotControllable_upgrade" msgstr "" msgid "popup_proxyNotControllableDetails" msgstr "" msgid "popup_proxyNotControllableDetails_upgrade" msgstr "" msgid "popup_proxyNotControllableManage" msgstr "" msgid "popup_addConditionTo" msgstr "" msgid "popup_addCondition" msgstr "" msgid "popup_showOptions" msgstr "" msgid "popup_reportIssues" msgstr "" msgid "popup_errorLog" msgstr "" msgid "popup_requestErrorCount" msgstr "" msgid "popup_requestErrorHeading" msgstr "" msgid "popup_requestErrorWarning" msgstr "" msgid "popup_requestErrorWarningHelp" msgstr "" msgid "popup_requestErrorAddCondition" msgstr "" msgid "popup_requestErrorCannotAddCondition" msgstr "" msgid "popup_configureMonitorWebRequests" msgstr "" msgid "options_resultProfileForSelectedDomains" msgstr "" msgid "options_pac_profile_unsupported_moz" msgstr "" msgid "popup_issueTemplate" msgstr "" msgid "browserAction_profileDetails_PacProfile" msgstr "" msgid "browserAction_profileDetails_SystemProfile" msgstr "" msgid "browserAction_profileDetails_DirectProfile" msgstr "" msgid "browserAction_profileDetails_SwitchProfile" msgstr "" msgid "browserAction_profileDetails_RuleListProfile" msgstr "" msgid "browserAction_titleNormal" msgstr "" msgid "browserAction_titleWithResult" msgstr "" msgid "browserAction_titleNewerOptions" msgstr "" msgid "browserAction_titleOptionError" msgstr "" msgid "browserAction_titleDownloadFail" msgstr "" msgid "browserAction_titleExternalProxy" msgstr "" msgid "browserAction_titleInspect" msgstr "" msgid "browserAction_defaultRuleDetails" msgstr "" msgid "browserAction_directResult" msgstr "" msgid "browserAction_attachedPrefix" msgstr "" msgid "browserAction_tempRulePrefix" msgstr "" msgid "contextMenu_inspectPage" msgstr "" msgid "contextMenu_inspectFrame" msgstr "" msgid "contextMenu_inspectLink" msgstr "" msgid "contextMenu_inspectElement" msgstr "" msgid "contextMenu_enableQuickSwitch" msgstr "" msgid "about_title" msgstr "" msgid "about_app_description" msgstr "" msgid "about_version" msgstr "" msgid "about_experimental_warning_moz" msgstr "" msgid "about_disclaimer_networkService" msgstr "" msgid "about_disclaimer_privacy" msgstr "" msgid "about_help" msgstr "" msgid "about_copyright" msgstr "" msgid "about_credits" msgstr "" msgid "about_license" msgstr "" ================================================ FILE: omega-locales/zh_TW/LC_MESSAGES/omega-web.po ================================================ msgid "" msgstr "" "Project-Id-Version: SwitchyOmega 2.3.3\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2015-02-13 11:15+0000\n" "PO-Revision-Date: 2019-06-18 19:01+0000\n" "Last-Translator: byStarTW \n" "Language-Team: Chinese (Traditional) \n" "Language: zh_TW\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" "X-Generator: Weblate 3.7\n" msgid "appNameShort" msgstr "SwitchyOmega" msgid "manifest_app_name" msgstr "Proxy SwitchyOmega" msgid "manifest_app_description" msgstr "輕鬆簡單地管理並切換多個代理伺服器設定。" msgid "manifest_icon_default_title" msgstr "正在載入……" msgid "upgrade_profile_auto" msgstr "自動切換" msgid "profile_direct" msgstr "[直接連線]" msgid "profile_system" msgstr "[系統代理]" msgid "condition_HostWildcardCondition" msgstr "網域萬用字元" msgid "condition_help_HostWildcardCondition" msgstr "" "依據網域(主機名稱)比對請求。
星號 * 比對零個或者多個字元。
問號 " "? 比對任意一個字元。

請注意以 *. " "開頭的規則有特別處理,會同時比對子網域和自身。
例如: *.example.com 能比對 " "www.example.com ,而且也能比對 example.com " "。
如果只需要比對子網域,請使用兩個星號開頭,如 **.example.com。" msgid "condition_HostRegexCondition" msgstr "網域正規表示式" msgid "condition_help_HostRegexCondition" msgstr "" "類似網域萬用字元,但使用正規表示式.
正規表示式很難編寫,且可讀性差。
因此,一般情況建議使用萬用字元。當其他任" "何條件都不能滿足要求時,才使用正規表示式。" msgid "condition_HostLevelsCondition" msgstr "網域層數" msgid "condition_help_HostLevelsCondition" msgstr "" "如果網域層數在設定的範圍內則比對,否則不比對。
網域層數是指 網域共有幾段(以點分隔).
例如: " "www.example.com 的網域層數為 3,而 internal 的網域層數為 1." msgid "condition_IpCondition" msgstr "IP 位址常值" msgid "condition_help_IpCondition" msgstr "" "當且僅當主機是字面的 IP 位址,且位址處於某個子網內時比對。子網使用 " "CIDR 格式表示。
例如,規則 127.0.0.1/16 " "會比對所有類似127.0.*.* 的位址。
因此位址 127.0.0.1 比對而位址 " "127.1.0.0 不比對。主機名稱,例如 localhost " "不會被此類規則比對,因為它們不是 IP 位址常值。" msgid "condition_UrlWildcardCondition" msgstr "網址萬用字元" msgid "condition_help_UrlWildcardCondition" msgstr "" "依據萬用字元規則比對網址。
關於萬用字元表示式,請參考上方的網域萬用字元一節的說明。
請注意網址萬用字元沒有任何特殊處理,不會特殊處理子網域等" "。
所以 *://*.example.com/* 能比對 http://www.example.com/ 但是 " "不比對 http://example.com/." msgid "condition_UrlRegexCondition" msgstr "網址正規表示式" msgid "condition_help_UrlRegexCondition" msgstr "" "使用功能強大的正規表示式來比對網址。
但正規表示式很難編寫,且可讀性差。
因此,一般情況建議使用萬用字元。當其他" "任何條件都不能滿足要求時,才使用正規表示式。" msgid "condition_KeywordCondition" msgstr "關鍵字" msgid "condition_help_KeywordCondition" msgstr "" "關鍵字條件的具體比對規則是:網址協定為HTTP且網址中包含該關鍵字。
類似於 http://*關鍵字*, " "其中 關鍵字 " "是設定好的關鍵字。
如果某防火牆依據網址中是否包含關鍵字來遮蔽網址,那麼可以使用關鍵字條件來通過代理訪問這樣的請求,以達到繞過防火牆的目的。" msgid "condition_FalseCondition" msgstr "(停用)" msgid "condition_details_FalseCondition" msgstr "(比對請求時無視此條規則)" msgid "condition_help_FalseCondition" msgstr "" "設定規則類型為(停用)可以臨時停用某個條件。停用的條件在比對時視為不存在。
條件被停用後,仍然儲存有之前的資料(例如萬用字" "元或正規表示式),因此當需要時,可以把條件類型改回之前的類型,以方便地重新啟用條件。" msgid "condition_TimeCondition" msgstr "目前時間" msgid "condition_help_TimeCondition" msgstr "" "如果目前本機時間在某個範圍內則比對。此範圍由開始小時結束小時確定,包含開始的那個小時以及結束的那個小時。
本機時間、開" "始小時和結束小時均按照24小時制計算(從0到23)。
此條件大約在請求發出的瞬間,才計算是否比對。" msgid "condition_WeekdayCondition" msgstr "每週幾" msgid "condition_help_WeekdayCondition" msgstr "" "只在每週的某幾天才比對。可以在條件詳情中勾選星期幾有效。依據當地時區來計算現在是星期幾,然後再檢視當天是否選取。
假設在請求傳送時是星" "期X:如果星期X被勾選,則比對所有請求。否則不比對任何請求。
除了日期以外,在比對過程中不會參考請求的網址或任何其他資訊。" msgid "condition_alert_fullUrlLimitation" msgstr "" "Chrome 52 起,https://協定下的完整網址無法正常比對。更多訊息..." msgid "condition_alert_fullUrlLimitationLink" msgstr "https://github.com/FelisCatus/SwitchyOmega/wiki/Chromium-%E5%AE%8C%E6%95%B4%E7%BD%91%E5%9D%80%E9%99%90%E5%88%B6" msgid "condition_group_default" msgstr " " msgid "condition_group_host" msgstr "網域" msgid "condition_group_url" msgstr "網址" msgid "condition_group_special" msgstr "特殊" msgid "ruleListFormat_Switchy" msgstr "Switchy" msgid "ruleListFormat_AutoProxy" msgstr "AutoProxy" msgid "ruleList_usageUrl" msgstr "https://github.com/FelisCatus/SwitchyOmega/wiki/RuleListUsage" msgid "ruleList_error_resultNotEnabled" msgstr "語法錯誤:缺少 '@with result' 指令!" msgid "ruleList_error_unknownProfile" msgstr "未找到此情境模式: $PROFILE$" msgid "ruleList_error_missingResultProfile" msgstr "語法錯誤:缺少結果情境模式名稱。 行號 $LNO$: $SOURCE$" msgid "ruleList_error_invalidRule" msgstr "語法錯誤:非法規則。行號 $LNO$: $SOURCE$" msgid "ruleList_error_noDefaultRule" msgstr "語法錯誤:缺少比對全部請求的預設規則。應在最後新增'*'規則和預設情境模式。" msgid "dialog_close" msgstr "關閉" msgid "dialog_save" msgstr "儲存變更" msgid "dialog_ok" msgstr "確定" msgid "dialog_cancel" msgstr "取消" msgid "inputClear_clear" msgstr "清除" msgid "inputClear_restore" msgstr "還原" msgid "options_title" msgstr "SwitchyOmega 選項" msgid "options_experimental_badge" msgstr "測試版" msgid "options_navHeader_setting" msgstr "設定" msgid "options_navHeader_profiles" msgstr "情境模式" msgid "options_navHeader_actions" msgstr "操作" msgid "options_tab_ui" msgstr "介面" msgid "options_tab_general" msgstr "通用" msgid "options_tab_importExport" msgstr "匯入/匯出" msgid "options_newProfile" msgstr "新增情境模式…" msgid "options_apply" msgstr "套用選項" msgid "options_discard" msgstr "還原變更" msgid "options_reset" msgstr "重設選項" msgid "options_group_miscOptions" msgstr "其他設定" msgid "options_confirmDeletion" msgstr "刪除切換條件時需要確認。" msgid "options_refreshOnProfileChange" msgstr "當變更情境模式時重新整理目前分頁。" msgid "options_showInspectMenu" msgstr "右鍵選單中,可檢查網頁元素所使用的代理。" msgid "options_addConditionsToBottom" msgstr "把以彈出式選單建立的規則加入到清單末尾。" msgid "options_group_keyboardShortcut" msgstr "鍵盤快速鍵" msgid "options_menuShortcutHelp" msgstr "按下快速鍵即可開啟彈出選單來切換情境模式。(預設快速鍵: Alt+Shift+O)." msgid "options_menuShortcutMore" msgstr "彈出選單中的選單項也可以用鍵盤進行選擇。在彈出選單中按下? (問號鍵,或/斜槓鍵) 檢視說明。" msgid "options_menuShortcutConfigure" msgstr "變更快速鍵" msgid "options_group_switchOptions" msgstr "切換選項" msgid "options_startupProfile" msgstr "初始情境模式" msgid "options_startupProfile_none" msgstr "(目前情境模式)" msgid "options_showConditionTypesAdvanced" msgstr "顯示進階切換條件" msgid "options_showConditionTypesAdvancedHelp" msgstr "解鎖一些新種類的、功能強大的但難以掌握的切換條件。對於大多數情況來說,基本條件類型應該就足夠,因此不推薦該選項。" msgid "options_quickSwitch" msgstr "快速切換" msgid "options_cycledProfiles" msgstr "循環切換以下情境模式:" msgid "options_cycledProfilesHelp" msgstr "點選圖示或按下快速鍵時,依次迴圈切換到以下情境模式。" msgid "options_cycledProfilesTooFew" msgstr "必須至少選擇2個情境模式才能進行切換。請從下方框中拖動情境模式到此框。" msgid "options_notCycledProfiles" msgstr "不迴圈切換的情境模式 (拖動到上面的框中啟用切換)" msgid "options_group_proxyChanges" msgstr "代理設定變化" msgid "options_revertProxyChanges" msgstr "還原其他擴充功能對代理的變更。" msgid "options_group_conflicts" msgstr "衝突" msgid "options_conflicts_introduction" msgstr "" "有時其他應用也會試圖控制代理設定,從而導致衝突。請注意,去廣告等其他擴充功能也可能利用了代理設定來實現功能。此類衝突是由瀏覽器的工作原理引起的,所以無法避" "免。" msgid "options_conflicts_lowerPriority" msgstr "" "如果 SwitchyOmega 圖示上顯示這樣的紅色徽章,表示另一個應用優先級較高,因此SwitchyOmega 無法控制代理設定。請嘗試卸載 " "SwitchyOmega 再重新安裝,這樣可能可以提高 SwitchyOmega 的優先級。如果重裝後您仍然看到衝突,那麼請考慮移除那個導致衝突的應用。" msgid "options_conflicts_higherPriority" msgstr "如果 SwitchyOmega 的優先級較高,那麼您可以在彈出式選單中選擇 $SYSTEMPROFILE$ 來把控制權還給其他應用或系統設定。" msgid "options_showExternalProfile" msgstr "在彈出式選單中顯示選單項目,以匯入其他應用提供的代理設定。" msgid "options_showExternalProfileHelp" msgstr "" "選擇了 $SYSTEMPROFILE$ 的情況下,您可以在彈出式選單中選擇 $EXTERNALPROFILE$ " "來匯入其他應用提供的代理設定。匯入的設定將會成為一個新的情境模式,其名稱由您決定。請注意匯入的情境模式只是當時的一個快照,匯入後不會隨著原來的應用更新。" msgid "options_group_networkRequests" msgstr "網路請求" msgid "options_monitorWebRequests" msgstr "在圖示上顯示目前頁面中由於網路原因而未載入的資源數量。" msgid "options_monitorWebRequestsHelp" msgstr "啟用此選項後,如有資源載入失敗,則圖示上會顯示數字提示。
此時,您可以通過彈出選單一次設定這些資源使用的情境模式,操作十分便捷。" msgid "options_downloadOptions" msgstr "下載選項" msgid "options_downloadOptionsHelp" msgstr "設定規則清單和 PAC 指令碼的更新間隔。" msgid "options_downloadInterval" msgstr "更新間隔" msgid "options_downloadInterval_15" msgstr "15分鐘" msgid "options_downloadInterval_60" msgstr "1小時" msgid "options_downloadInterval_180" msgstr "3小時" msgid "options_downloadInterval_360" msgstr "6小時" msgid "options_downloadInterval_720" msgstr "12小時" msgid "options_downloadInterval_1440" msgstr "每天一次" msgid "options_downloadInterval_never" msgstr "從不更新" msgid "options_group_importExportProfile" msgstr "情境模式" msgid "options_exportPacFile" msgstr "匯出 PAC 檔案" msgid "options_exportPacFileHelp" msgstr "匯出 PAC(代理自動設定)檔案,以便在其它瀏覽器使用。" msgid "options_exportProfileHelp" msgstr "如需匯出情境模式,請使用情境模式設定頁面右上角的工具欄。" msgid "options_exportLegacyRuleList" msgstr "匯出規則清單時使用 Proxy Switchy!/SwitchyPlus/SwitchySharp 相容格式。" msgid "options_exportLegacyRuleListHelp" msgstr "如果您需要釋出規則清單給那些軟體的使用者,請啟用此選項。
建議您提醒訂閱者升級到 SwitchyOmega 以享受新版功能。" msgid "options_group_importExportSettings" msgstr "選項" msgid "options_makeBackup" msgstr "輸出備份檔案" msgid "options_makeBackupHelp" msgstr "匯出一份包括情境模式和其他所有選項的備份檔案。" msgid "options_restoreLocal" msgstr "從備份檔案還原" msgid "options_restoreLocalHelp" msgstr "匯入本機的備份檔案以還原所有選項。" msgid "options_restoreOnline" msgstr "線上還原" msgid "options_restoreOnlinePlaceholder" msgstr "備份檔案位址 (如:http://example.com/switchy.bak)" msgid "options_restoreOnlineSubmit" msgstr "還原" msgid "options_group_syncing" msgstr "選項同步 (測試中)" msgid "options_syncEnable" msgstr "啟用同步" msgid "options_syncEnableForce" msgstr "下載雲端版本" msgid "options_syncDisable" msgstr "停用同步" msgid "options_syncReset" msgstr "刪除雲端版本" msgid "options_syncPristineHelp" msgstr "您可以將設定和情境模式同步到所有使用Chrome瀏覽器的桌面裝置。" msgid "options_syncSyncAlert" msgstr "您的設定將會自動與其他裝置進行同步。" msgid "options_syncSyncHelp" msgstr "請注意:您需要在所有裝置上(包括此裝置)的Chrome瀏覽器中登入,這樣同步的選項才能正常使用。
可以在其他裝置上檢視此頁面,來檢查同步是否生效。" msgid "options_syncConflictAlert" msgstr "您已經通過其他裝置上傳了一份選項用於同步。" msgid "options_syncConflictHelp" msgstr "您可以將雲端的選項下載到此裝置使用。
一旦選擇下載,此裝置上的設定和情境模式將會被覆蓋。" msgid "options_syncUnsupportedHelp" msgstr "選項同步暫不支援您的平臺或瀏覽器。目前只支援桌面版Chrome的瀏覽器的同步,請諒解。" msgid "options_profileSyncDisabled" msgstr "此情境模式已經停用同步。" msgid "options_profileSyncDisabled_quotaPerItem" msgstr "此情境模式使用儲存空間過多,因此無法進行同步。" msgid "options_profileTabPrefix" msgstr "情境模式: " msgid "options_renameProfile" msgstr "變更名稱" msgid "options_deleteProfile" msgstr "刪除" msgid "options_profileExportRuleList" msgstr "釋出規則清單" msgid "options_profileExportRuleListHelp" msgstr "將切換規則匯出為文字格式以便釋出。" msgid "options_profileExportPac" msgstr "匯出 PAC" msgid "options_profileUnsupported" msgstr "不支援的情境模式類型: $TYPE$!" msgid "options_profileUnsupportedHelp" msgstr "選項檔案已經損壞,或者目前版本過低無法處理選項。" msgid "options_profileEditSource" msgstr "編輯原始碼" msgid "options_profileEditSourceHelp" msgstr "顯示原始碼格式相關的說明" msgid "options_profileEditSourceHelpUrl" msgstr "" "https://github.com/FelisCatus/SwitchyOmega/wiki/SwitchyOmega-conditions-" "format#result-profile" msgid "options_group_proxyServers" msgstr "代理伺服器" msgid "options_proxy_scheme" msgstr "網址協定" msgid "options_proxy_protocol" msgstr "代理協定" msgid "options_proxy_server" msgstr "代理伺服器" msgid "options_proxy_port" msgstr "連接埠" msgid "options_proxy_auth" msgstr "代理認證" msgid "options_proxy_authNotSupported" msgstr "您的瀏覽器不支持 $PROTOCOLDISP$ 代理認證!如有問題請聯繫您的瀏覽器支持," "請勿反饋此問題給 SwitchyOmega." msgid "options_proxy_authAllWarningPac" msgstr "警告:使用者名稱和密碼將會提供給 PAC 指令碼返回的任何伺服器,有時目標伺服器會出乎您的預料。" msgid "options_proxy_authAllWarningPacUrl" msgstr "在提供使用者名稱和密碼時,請先確保您可以信任以上網址提供的 PAC 指令碼。" msgid "options_proxy_authAllWarningPacScript" msgstr "在提供使用者名稱和密碼時,請先確保您可以信任以下輸入的 PAC 指令碼。" msgid "options_proxy_authReferencedWarning" msgstr "此外,在其他情境模式(如自動切換)中使用此情境時,可能會導致使用者名稱和密碼被傳送至其他情境模式中設定的伺服器。" msgid "options_scheme_default" msgstr "(預設)" msgid "options_protocol_direct" msgstr "直接連線" msgid "options_protocol_useDefault" msgstr "(同預設)" msgid "options_proxy_single" msgstr "對於所有代理使用相同伺服器。" msgid "options_proxy_expand" msgstr "顯示進階設定" msgid "options_group_bypassList" msgstr "不代理的位址清單" msgid "options_bypassListHelp" msgstr "不經過代理連線的主機清單: (每行一個主機)" msgid "options_bypassListHelpLinkText" msgstr "(可使用萬用字元等比對規則…)" msgid "options_group_pacUrl" msgstr "PAC 網址" msgid "options_pacUrlHelp" msgstr "將會從此網址下載 PAC 指令碼。如果網址留空,則直接使用下方的指令碼內容。" msgid "options_pacUrlFile" msgstr "如果您使用本機 PAC 檔案,則該情境模式只能單獨使用,無法作為自動切換的結果。這是因為瀏覽器不允許讀取本機檔案。" msgid "options_pacUrlFileDisabled" msgstr "此情境模式已被引用,所以不能使用本機 PAC 檔案。如果您真的需要使用本機檔案,請另外建立一個 PAC 情境模式。" msgid "options_group_pacScript" msgstr "PAC 指令碼" msgid "options_pacScriptLastUpdate" msgstr "PAC 指令碼最後更新時間:$TIME$" msgid "options_pacScriptObsolete" msgstr "修改網址後尚未下載更新,因此指令碼已經過時。請使用上方的更新按鈕進行下載。" msgid "options_group_virtualProfile" msgstr "虛情境模式" msgid "options_virtualProfileTarget" msgstr "目標" msgid "options_virtualProfileTargetHelp" msgstr "當使用此情境模式時,相當於使用了以下情境模式:" msgid "options_group_virtualProfileReplace" msgstr "遷移到虛情境模式" msgid "options_virtualProfileReplace" msgstr "取代目標情境模式" msgid "options_virtualProfileReplaceHelp" msgstr "" "通過此功能可以變更現有的選項,使用此虛情境模式來取代 $PROFILE$ 。此功能會把所有和 $PROFILE$ " "相關的切換規則改為使用此虛情境模式。這樣一來,就可以通過此虛情境模式來控制那些切換條件對應的結果。" msgid "options_group_ruleListConfig" msgstr "規則清單設定" msgid "options_ruleListFormat" msgstr "規則清單格式" msgid "options_group_ruleListResult" msgstr "規則清單結果情境模式" msgid "options_ruleListMatchProfile" msgstr "比對則使用情境模式" msgid "options_ruleListDefaultProfile" msgstr "不比對則使用情境模式" msgid "options_group_ruleListUrl" msgstr "規則清單網址" msgid "options_ruleListUrlHelp" msgstr "應用將從此網址下載規則清單。如果網址留空,則以下文字會被直接處理後作為規則清單使用。" msgid "options_group_ruleListText" msgstr "規則清單正文" msgid "options_ruleListLastUpdate" msgstr "規則清單最後更新時間:$TIME$" msgid "options_ruleListObsolete" msgstr "修改網址後尚未下載更新,因此規則清單已經過時。請使用上方的更新按鈕進行下載。" msgid "options_group_switchRules" msgstr "切換規則" msgid "options_sort" msgstr "排序" msgid "options_conditionType" msgstr "條件類型" msgid "options_showConditionTypeHelp" msgstr "顯示說明" msgid "options_conditionDetails" msgstr "條件設定" msgid "options_resultProfile" msgstr "情境模式" msgid "options_conditionActions" msgstr "操作" msgid "options_addCondition" msgstr "加入條件" msgid "options_cloneRule" msgstr "複製" msgid "options_ruleNote" msgstr "備註" msgid "options_switchAttachedProfileInCondition" msgstr "規則清單規則" msgid "options_switchAttachedProfileInConditionDetails" msgstr "(按照規則清單比對請求)" msgid "options_switchAttachedProfileInConditionDisabled" msgstr "(規則清單已停用!)" msgid "options_switchDefaultProfile" msgstr "預設情境模式" msgid "options_hostLevelsBetween" msgstr "≤ 主機層數 ≤" msgid "options_hourBetween" msgstr "≤ 目前小時 ≤" msgid "options_weekDayShort_0" msgstr "日" msgid "options_weekDayShort_1" msgstr "一" msgid "options_weekDayShort_2" msgstr "二" msgid "options_weekDayShort_3" msgstr "三" msgid "options_weekDayShort_4" msgstr "四" msgid "options_weekDayShort_5" msgstr "五" msgid "options_weekDayShort_6" msgstr "六" msgid "options_group_conditionHelp" msgstr "條件類型說明" msgid "options_group_attachProfile" msgstr "匯入線上規則清單" msgid "options_attachProfile" msgstr "加入規則清單" msgid "options_attachProfileHelp" msgstr "可以加入規則清單,以便引用他人線上釋出的一組規則。" msgid "options_modalHeader_welcome" msgstr "歡迎使用 SwitchyOmega" msgid "options_welcomeNormal" msgstr "您已經成功安裝了 SwitchyOmega ,一個強大的代理切換工具。" msgid "options_welcomeNormalGuide" msgstr "您可以通過選項頁面設定需要使用的代理伺服器,下面我們就來試試看吧。" msgid "options_welcomeUpgrade" msgstr "您已經成功升級到 SwitchyOmega. 別擔心,所有設定都已經升級成功,可以繼續使用。" msgid "options_welcomeUpgradeGuide" msgstr "現在我們來熟悉一下新的選項頁面。" msgid "options_guideNext" msgstr "下一步" msgid "options_guideDone" msgstr "完成" msgid "options_guideSkip" msgstr "跳過教學" msgid "options_modalHeader_applyOptions" msgstr "套用選項" msgid "options_optionsNotSaved" msgstr "目前設定還未儲存。如果您繼續此操作,則剛才的所有修改都會遺失!" msgid "options_applyOptionsRequired" msgstr "必須儲存目前選項才能繼續操作。" msgid "options_applyOptionsConfirm" msgstr "是否儲存並套用現在的選項?" msgid "options_modalHeader_renameProfile" msgstr "重新命名" msgid "options_renameProfileName" msgstr "新的名稱" msgid "options_profileNameConflict" msgstr "已經存在相同名稱的情境模式。" msgid "options_profileNameReserved" msgstr "以雙下劃線開頭的名稱為系統保留,禁止使用。" msgid "options_profileNameHidden" msgstr "以下劃線開頭的情境模式不會在彈出選單中顯示,但仍可被用作切換的結果等。" msgid "options_modalHeader_replaceProfile" msgstr "取代情境模式" msgid "options_replaceProfile" msgstr "取代" msgid "options_replaceProfileConfirm" msgstr "您確定要使用 $ToProfile 來代替 $FromProfile$ 嗎?" msgid "options_replaceProfileHelp" msgstr "" "如果繼續操作,則和 $FromProfile$ 有關的切換規則將改為使用 $ToProfile$ " "來代替。此外,啟動情境模式、快速切換等設定也會做相應調整。但請注意,此操作不影響這兩個情境模式本身。" msgid "options_replaceProfileSuccess" msgstr "變更選項成功。" msgid "options_modalHeader_deleteProfile" msgstr "刪除情境模式" msgid "options_deleteProfileConfirm" msgstr "真的要刪除這個情境模式嗎?" msgid "options_modalHeader_cannotDeleteProfile" msgstr "情境模式無法刪除" msgid "options_profileReferredBy" msgstr "這個情境模式仍然被以下情境模式使用,所以無法刪除。" msgid "options_modifyReferringProfiles" msgstr "修改以上所有情境模式並移除對此情境模式的引用後,方可刪除此情境模式。" msgid "options_profileNameEmpty" msgstr "情境模式名稱不能為空。" msgid "popup_title" msgstr "SwitchyOmega 彈出選單" msgid "options_modalHeader_deleteRule" msgstr "刪除規則" msgid "options_modalHeader_proxyAuth" msgstr "代理認證" msgid "options_proxyAuthUsername" msgstr "使用者名稱" msgid "options_proxyAuthPassword" msgstr "密碼" msgid "options_proxyAuthShowPassword" msgstr "顯示密碼" msgid "options_proxyAuthHidePassword" msgstr "隱藏密碼" msgid "options_proxyAuthNone" msgstr "(無密碼)" msgid "options_deleteRuleConfirm" msgstr "真的要刪除這個規則嗎?" msgid "options_deleteRule" msgstr "刪除" msgid "options_modalHeader_resetRules" msgstr "重設全部規則" msgid "options_resetRulesConfirm" msgstr "真的要設定所有規則對應的情境模式為以下情境模式嗎?" msgid "options_resetRules" msgstr "重設規則" msgid "options_resetRules_help" msgstr "批量設定所有規則的情境模式" msgid "options_modalHeader_deleteAttached" msgstr "移除規則清單" msgid "options_deleteAttachedConfirm" msgstr "真的要移除目前情境模式的線上規則清單嗎?" msgid "options_ruleListLineCount" msgstr "共計$COUNT$行規則" msgid "options_deleteAttached" msgstr "移除規則清單" msgid "options_modalHeader_newProfile" msgstr "建立情境模式" msgid "options_newProfileName" msgstr "情境模式名稱" msgid "options_profileType" msgstr "請選擇情境模式的類型:" msgid "options_profileTypeFixedProfile" msgstr "代理伺服器" msgid "options_profileDescFixedProfile" msgstr "經過代理伺服器訪問網站。" msgid "options_profileTypePacProfile" msgstr "PAC 情境模式" msgid "options_profileDescPacProfile" msgstr "依據線上或本機的 PAC 指令碼選擇代理。" msgid "options_profileDescMorePacProfile" msgstr "如果您沒有任何 PAC 指令碼,也沒有指令碼的網址,則不必使用此情境模式。不瞭解 PAC 的使用者不建議自行嘗試編寫指令碼。" msgid "options_profileTypeSwitchProfile" msgstr "自動切換模式" msgid "options_profileDescSwitchProfile" msgstr "依據多種條件,如網域或網址等自動選擇情境模式。您也可以匯入線上釋出的切換規則(如 AutoProxy 清單)以簡化設定。" msgid "options_profileTypeRuleListProfile" msgstr "規則清單" msgid "options_profileDescRuleListProfile" msgstr "使用他人釋出的線上規則清單來切換情境模式。" msgid "options_profileTypeVirtualProfile" msgstr "虛擬情境模式" msgid "options_profileDescVirtualProfile" msgstr "虛擬情境模式可以作為某個其他情境模式使用,並可以依據需要變更目標。一般用在自動切換中,這樣就可以一次性變更多個條件對應的代理。" msgid "options_createProfile" msgstr "建立" msgid "options_modalHeader_resetOptions" msgstr "重設選項" msgid "options_resetOptionsConfirm" msgstr "真的確定要重設選項嗎?如果繼續,現有的所有情境模式和選項將會遺失!" msgid "options_formInvalid" msgstr "請更正這個頁面中的錯誤。" msgid "options_profileNotFound" msgstr "情境模式 $PROFILE$ 不存在!選項可能已經損壞。" msgid "options_resetSuccess" msgstr "選項已經重設。" msgid "options_saveSuccess" msgstr "儲存選項成功。" msgid "options_importSuccess" msgstr "匯入選項成功。" msgid "options_importFormatError" msgstr "備份檔案格式錯誤!" msgid "options_importDownloadError" msgstr "下載備份檔案時出錯!" msgid "options_profileDownloadSuccess" msgstr "情境模式已經更新成功。" msgid "options_profileDownloadError" msgstr "下載情境模式資料時出錯!" msgid "options_profileDownloadError_NetworkError" msgstr "更新時發生網路錯誤。" msgid "options_profileDownloadError_HttpError" msgstr "更新時發生網路錯誤 (HTTP $STATUS$)." msgid "options_profileDownloadError_HttpNotFoundError" msgstr "在遠端伺服器上找不到情境模式網址對應的檔案。請檢查網址。" msgid "options_profileDownloadError_HttpServerError" msgstr "更新時遠端伺服器發生錯誤 ($STATUS$)。" msgid "options_profileDownloadError_ContentTypeRejectedError" msgstr "下載的資料不符合格式!建議您在瀏覽器中打開情境模式網址並檢查其內容。" msgid "options_downloadProfileNow" msgstr "立即更新情境模式" msgid "options_guide_fixedProfileStep" msgstr "" "代理情境包含了伺服器位址、埠等代理的資訊。
在 SwitchyOmega " "中,情境模式是代理設定的基本單元。
預設設定中已經建立了一個代理情境模式作為樣例。試著開啟它吧。" msgid "options_guide_fixedServersStep" msgstr "" "在這裡,您可以填寫所需的代理伺服器位址和埠。
SwitchyOmega軟體本身不提供任何內建代理伺服器
如果您不清楚應該填寫什" "麼,最好諮詢下您的網路提供者,或者參考代理軟體的設定說明。" msgid "options_guide_autoSwitchProfileStep" msgstr "" "您可以通過強大的自動切換模式在多個代理間切換自如。
不過,在這個簡單的教學中無法詳盡介紹所有功能。
想要使用此功能時,可以開啟這" "裡的設定介面,來瞭解如何使用自動切換功能。" msgid "options_guide_addMoreProfilesStep" msgstr "如果您需要更多的情境模式,可以隨時在這裡建立代理、切換和其他情境模式
教學到此結束,您可以繼續自訂設定。" msgid "options_guide_conditionStep" msgstr "" "SwitchyOmega " "可以依據切換條件對不同的網路請求使用不同的情境模式。
例如網域萬用字元條件可以對某個網域下的所有網址使用特定的情境模式。" msgid "options_guide_conditionTypeStep" msgstr "您可以使用各種條件類型來比對網域或者整個網址。
點選問號按鈕來檢視條件類型的說明。" msgid "options_guide_conditionProfileStep" msgstr "" "對於任何比對該條件的請求,SwitchyOmega 會使用這個情境模式。
如果選擇了\"[直接連線]\"" "情境模式,則比對的請求不使用任何代理。" msgid "options_guide_switchDefaultStep" msgstr "" "如果請求不比對任何條件,則使用預設情境模式。
條件的比對順序總是按此頁面從上到下
您可以拖動排序圖示來變更條件的順序。" msgid "options_guide_applySwitchProfileStep" msgstr "" "當您設定完畢後,別忘記在彈出選單中啟用自動切換情境模式
圖示將會顯示標籤頁切換的最終結果情境。
" "懸停在圖示上則會顯示切換相關的詳細說明。" msgid "popup_externalProfile" msgstr "(外部情境模式)" msgid "popup_externalProfileName" msgstr "儲存名稱" msgid "popup_proxyNotControllable_app" msgstr "其他應用正在控制代理設定。請停用或者解除安裝發生衝突的應用。" msgid "popup_proxyNotControllable_policy" msgstr "代理設定被本機策略強制指定,無法修改。請聯繫系統管理員。" msgid "popup_proxyNotControllable_unknown" msgstr "無法設定代理設定。請檢查系統和瀏覽器設定。" msgid "popup_proxyNotControllable_disabled" msgstr "在其他程式或擴充功能的要求下,SwitchyOmega 已經停用代理設定。" msgid "popup_proxyNotControllable_upgrade" msgstr "代理設定現在由新版本的 SwitchyOmega 控制。" msgid "popup_proxyNotControllableDetails" msgstr "如果不解決以上問題,則無法使用SwitchyOmega切換代理。" msgid "popup_proxyNotControllableDetails_upgrade" msgstr "兩個不同版本的 SwitchyOmega (如穩定版和測試版)不能共存。請停用其中之一。" msgid "popup_proxyNotControllableManage" msgstr "管理擴充功能" msgid "popup_addConditionTo" msgstr "加入條件到情境模式" msgid "popup_addCondition" msgstr "加入條件" msgid "popup_showOptions" msgstr "選項" msgid "popup_reportIssues" msgstr "回報問題" msgid "popup_errorLog" msgstr "儲存錯誤記錄" msgid "popup_requestErrorCount" msgstr "$COUNT$個資源未載入" msgid "popup_requestErrorHeading" msgstr "載入失敗的資源清單" msgid "popup_requestErrorWarning" msgstr "由於網路原因,此頁面部分資源載入失敗。這些問題可能是由您的網路、代理伺服器或網站本身引起的。" msgid "popup_requestErrorWarningHelp" msgstr "這些問題並非由 SwitchyOmega 自身導致,它只不過偵測並報告了錯誤而已。" msgid "popup_requestErrorAddCondition" msgstr "您可以檢視以下網域,並依據實際情況確定是否對其使用代理。" msgid "popup_requestErrorCannotAddCondition" msgstr "在使用自動切換情境時,才可以將這些資源新增為切換條件。" msgid "popup_configureMonitorWebRequests" msgstr "設定網路偵測選項" msgid "options_resultProfileForSelectedDomains" msgstr "對所有選取網域使用此情境模式:" msgid "options_pac_profile_unsupported_moz" msgstr "由於技術限制,PAC 情境模式無法在 Mozilla Firefox 上工作!" msgid "popup_issueTemplate" msgstr "" "\n" "\n" "\n" "\n" "SwitchyOmega $projectVersion$\n" "$userAgent$" msgid "browserAction_profileDetails_PacProfile" msgstr "(PAC 指令碼)" msgid "browserAction_profileDetails_SystemProfile" msgstr "(由其他擴充功能或系統環境控制)" msgid "browserAction_profileDetails_DirectProfile" msgstr "(不使用任何代理)" msgid "browserAction_profileDetails_SwitchProfile" msgstr "(依據條件切換)" msgid "browserAction_profileDetails_RuleListProfile" msgstr "(依據規則清單切換)" msgid "browserAction_titleNormal" msgstr "SwitchyOmega:: $PROFILE$" msgid "browserAction_titleWithResult" msgstr "" "SwitchyOmega:: $1:PROFILE$\n" "$3:DETAILS$" msgid "browserAction_titleNewerOptions" msgstr "錯誤:需要新版本的SwitchyOmega才能載入目前選項。" msgid "browserAction_titleOptionError" msgstr "錯誤:選項檔案已經損壞,點選此處重設選項。" msgid "browserAction_titleDownloadFail" msgstr "警告:更新 PAC 檔案或規則清單失敗。" msgid "browserAction_titleExternalProxy" msgstr "注意:其他應用正在控制目前代理設定。" msgid "browserAction_titleInspect" msgstr "[檢查] $URL$" msgid "browserAction_defaultRuleDetails" msgstr "(預設)" msgid "browserAction_directResult" msgstr "直接連線" msgid "browserAction_attachedPrefix" msgstr "(清單) " msgid "browserAction_tempRulePrefix" msgstr "(臨時) " msgid "contextMenu_inspectPage" msgstr "檢查此頁面使用的代理" msgid "contextMenu_inspectFrame" msgstr "檢查此[框架頁面]使用的代理" msgid "contextMenu_inspectLink" msgstr "檢查此[連結目標]將會使用的代理" msgid "contextMenu_inspectElement" msgstr "檢查此[元素]使用的代理" msgid "contextMenu_enableQuickSwitch" msgstr "啟用快速切換" msgid "about_title" msgstr "關於" msgid "about_app_description" msgstr "一個代理設定工具" msgid "about_version" msgstr "版本 $VERSION$" msgid "about_experimental_warning_moz" msgstr "Mozilla Firefox 瀏覽器支持目前仍處於早期實驗階段!如果您遇到任何問題,請使用下方的按鈕進行回報。" msgid "about_disclaimer_networkService" msgstr "SwitchyOmega 不提供代理伺服器、VPN等網路服務。" msgid "about_disclaimer_privacy" msgstr "SwitchyOmega 不會跟蹤您的上網記錄,不在頁面中插入廣告。請參見我們的" "隱私政策。" msgid "about_help" msgstr "" "如有其他問題或者需要說明,請參考常見問題。" msgid "about_copyright" msgstr "版權所有 2012-2017 The SwitchyOmega Authors. 保留所有權利。" msgid "about_credits" msgstr "SwitchyOmega 的誕生離不開 SwitchyOmega 開源項目和其他開源軟體。" msgid "about_license" msgstr "SwitchyOmega 是自由軟體,使用GNU General Public License 版本 3 及以上授權。" ================================================ FILE: omega-pac/.gitattributes ================================================ uglifyjs.js linguist-vendored ================================================ FILE: omega-pac/.gitignore ================================================ /index.js /omega_pac.min.js ================================================ FILE: omega-pac/Gruntfile.coffee ================================================ module.exports = require('load-grunt-config') ================================================ FILE: omega-pac/grunt/aliases.coffee ================================================ module.exports = default: [ 'coffeelint' 'browserify' ] test: ['mochaTest'] ================================================ FILE: omega-pac/grunt/browserify.coffee ================================================ module.exports = index: files: 'index.js': 'index.coffee' options: transform: ['coffeeify'] exclude: ['uglify-js', 'ip-address'] browserifyOptions: extensions: '.coffee' builtins: [] standalone: 'index.coffee' debug: true browser: files: 'omega_pac.min.js': './index.coffee' options: alias: [ './index.coffee:OmegaPac' ] transform: ['coffeeify'] plugin: if process.env.BUILD == 'release' [['minifyify', {map: false}]] else [] browserifyOptions: extensions: '.coffee' standalone: 'OmegaPac' ================================================ FILE: omega-pac/grunt/coffeelint.coffee ================================================ module.exports = options: arrow_spacing: level: 'error' colon_assignment_spacing: level: 'error' spacing: left: 0 right: 1 missing_fat_arrows: level: 'warn' no_empty_functions: level: 'error' no_empty_param_list: level: 'error' no_interpolation_in_single_quotes: level: 'error' no_stand_alone_at: level: 'error' space_operators: level: 'error' # https://github.com/clutchski/coffeelint/issues/525 indentation: level: 'ignore' gruntfile: ['Gruntfile.coffee'] tasks: ['grunt/**/*.coffee'] src: ['src/**/*.coffee', 'test/**/*.coffee'] ================================================ FILE: omega-pac/grunt/mochaTest.coffee ================================================ module.exports = test: options: reporter: 'spec' require: 'coffee-script/register' src: ['test/**/*.coffee'] ================================================ FILE: omega-pac/grunt/watch.coffee ================================================ module.exports = grunt: options: reload: true files: 'grunt/*' tasks: ['coffeelint:tasks', 'default'] src: files: ['src/**/*.coffee', 'test/**/*.coffee'] tasks: ['default'] ================================================ FILE: omega-pac/index.coffee ================================================ module.exports = Conditions: require('./src/conditions') PacGenerator: require('./src/pac_generator') Profiles: require('./src/profiles') RuleList: require('./src/rule_list') ShexpUtils: require('./src/shexp_utils') for name, value of require('./src/utils.coffee') module.exports[name] = value ================================================ FILE: omega-pac/package.json ================================================ { "name": "omega-pac", "version": "0.0.1", "private": true, "main": "./index.js", "devDependencies": { "chai": "~1.9.1", "coffee-script": "^1.7.1", "coffeeify": "^0.7.0", "coffeelint": "^1.16.0", "grunt": "^0.4.5", "grunt-browserify": "^3.0.0", "grunt-coffeelint": "^0.0.13", "grunt-contrib-coffee": "^0.11.1", "grunt-contrib-watch": "^0.6.1", "grunt-mocha-test": "~0.11.0", "load-grunt-config": "^0.13.1", "lolex": "^1.4.0", "minifyify": "^4.1.1" }, "dependencies": { "ip-address": "^4.0.0", "tldjs": "^1.5.2", "uglify-js": "^2.4.15" }, "browser": { "uglify-js": "./uglifyjs-shim.js", "uglify-js-real": "./uglifyjs.js" }, "scripts": { "dev": "npm link", "test": "TZ=Europe/London grunt test" } } ================================================ FILE: omega-pac/src/conditions.coffee ================================================ U2 = require 'uglify-js' IP = require 'ip-address' Url = require 'url' {shExp2RegExp, escapeSlash} = require './shexp_utils' {AttachedCache} = require './utils' module.exports = exports = requestFromUrl: (url) -> if typeof url == 'string' url = Url.parse url req = url: Url.format(url) host: url.hostname scheme: url.protocol.replace(':', '') urlWildcard2HostWildcard: (pattern) -> result = pattern.match /// ^\*:\/\/ # Begins with *:// ((?:\w|[?*._\-])+) # The host part follows. \/\*$ # And ends with /* /// result?[1] tag: (condition) -> exports._condCache.tag(condition) analyze: (condition) -> exports._condCache.get condition, -> { analyzed: exports._handler(condition.conditionType).analyze.call( exports, condition) } match: (condition, request) -> cache = exports.analyze(condition) exports._handler(condition.conditionType).match.call(exports, condition, request, cache) compile: (condition) -> cache = exports.analyze(condition) return cache.compiled if cache.compiled handler = exports._handler(condition.conditionType) cache.compiled = handler.compile.call(exports, condition, cache) str: (condition, {abbr} = {abbr: -1}) -> handler = exports._handler(condition.conditionType) if handler.abbrs[0].length == 0 endCode = condition.pattern.charCodeAt(condition.pattern.length - 1) if endCode != exports.colonCharCode and condition.pattern.indexOf(' ') < 0 return condition.pattern str = handler.str typeStr = if typeof abbr == 'number' handler.abbrs[(handler.abbrs.length + abbr) % handler.abbrs.length] else condition.conditionType result = typeStr + ':' part = if str then str.call(exports, condition) else condition.pattern result += ' ' + part if part return result colonCharCode: ':'.charCodeAt(0) fromStr: (str) -> str = str.trim() i = str.indexOf(' ') i = str.length if i < 0 if str.charCodeAt(i - 1) == exports.colonCharCode conditionType = str.substr(0, i - 1) str = str.substr(i + 1).trim() else conditionType = '' conditionType = exports.typeFromAbbr(conditionType) return null unless conditionType condition = {conditionType: conditionType} fromStr = exports._handler(condition.conditionType).fromStr if fromStr return fromStr.call(exports, str, condition) else condition.pattern = str return condition _abbrs: null typeFromAbbr: (abbr) -> if not exports._abbrs exports._abbrs = {} for own type, {abbrs} of exports._conditionTypes exports._abbrs[type.toUpperCase()] = type for ab in abbrs exports._abbrs[ab.toUpperCase()] = type return exports._abbrs[abbr.toUpperCase()] comment: (comment, node) -> return node unless comment node.start ?= {} # This hack is needed to allow dumping comments in repeated print call. Object.defineProperty node.start, '_comments_dumped', get: -> false set: -> false node.start.comments_before ?= [] node.start.comments_before.push {type: 'comment2', value: comment} node safeRegex: (expr) -> try new RegExp(expr) catch _ # Invalid regexp! Fall back to a regexp that does not match anything. /(?!)/ regTest: (expr, regexp) -> if typeof regexp == 'string' # Escape (unescaped) forward slash for use in regex literals. regexp = regexSafe escapeSlash regexp if typeof expr == 'string' expr = new U2.AST_SymbolRef name: expr new U2.AST_Call args: [expr] expression: new U2.AST_Dot( property: 'test' expression: new U2.AST_RegExp value: regexp ) isInt: (num) -> (typeof num == 'number' and !isNaN(num) and parseFloat(num) == parseInt(num, 10)) between: (val, min, max, comment) -> if min == max if typeof min == 'number' min = new U2.AST_Number value: min return exports.comment comment, new U2.AST_Binary( left: val operator: '===' right: min ) if min > max return exports.comment comment, new U2.AST_False if exports.isInt(min) and exports.isInt(max) and max - min < 32 comment ||= "#{min} <= value && value <= #{max}" tmpl = "0123456789abcdefghijklmnopqrstuvwxyz" str = if max < tmpl.length tmpl.substr(min, max - min + 1) else tmpl.substr(0, max - min + 1) pos = if min == 0 then val else new U2.AST_Binary( left: val operator: '-' right: new U2.AST_Number value: min ) return exports.comment comment, new U2.AST_Binary( left: new U2.AST_Call( expression: new U2.AST_Dot( expression: new U2.AST_String value: str property: 'charCodeAt' ) args: [pos] ) operator: '>' right: new U2.AST_Number value: 0 ) if typeof min == 'number' min = new U2.AST_Number value: min if typeof max == 'number' max = new U2.AST_Number value: max exports.comment comment, new U2.AST_Call( args: [val, min, max] expression: new U2.AST_Function ( argnames: [ new U2.AST_SymbolFunarg name: 'value' new U2.AST_SymbolFunarg name: 'min' new U2.AST_SymbolFunarg name: 'max' ] body: [ new U2.AST_Return value: new U2.AST_Binary( left: new U2.AST_Binary( left: new U2.AST_SymbolRef name: 'min' operator: '<=' right: new U2.AST_SymbolRef name: 'value' ) operator: '&&' right: new U2.AST_Binary( left: new U2.AST_SymbolRef name: 'value' operator: '<=' right: new U2.AST_SymbolRef name: 'max' ) ) ] ) ) parseIp: (ip) -> if ip.charCodeAt(0) == '['.charCodeAt(0) ip = ip.substr 1, ip.length - 2 addr = new IP.v4.Address(ip) if not addr.isValid() addr = new IP.v6.Address(ip) if not addr.isValid() return null return addr normalizeIp: (addr) -> return (addr.correctForm ? addr.canonicalForm).call(addr) ipv6Max: new IP.v6.Address('::/0').endAddress().canonicalForm() localHosts: ["127.0.0.1", "[::1]", "localhost"] getWeekdayList: (condition) -> if condition.days condition.days.charCodeAt(i) > 64 for i in [0...7] else condition.startDay <= i <= condition.endDay for i in [0...7] _condCache: new AttachedCache (condition) -> tag = exports._handler(condition.conditionType).tag result = if tag then tag.apply(exports, arguments) else exports.str(condition) condition.conditionType + '$' + result _setProp: (obj, prop, value) -> if not Object::hasOwnProperty.call obj, prop Object.defineProperty obj, prop, writable: true obj[prop] = value _handler: (conditionType) -> if typeof conditionType != 'string' conditionType = conditionType.conditionType handler = exports._conditionTypes[conditionType] if not handler? throw new Error "Unknown condition type: #{conditionType}" return handler _conditionTypes: # These functions are .call()-ed with `this` set to module.exports. # coffeelint: disable=missing_fat_arrows 'TrueCondition': abbrs: ['True'] analyze: (condition) -> null match: -> true compile: (condition) -> new U2.AST_True str: (condition) -> '' fromStr: (str, condition) -> condition 'FalseCondition': abbrs: ['False', 'Disabled'] analyze: (condition) -> null match: -> false compile: (condition) -> new U2.AST_False fromStr: (str, condition) -> if str.length > 0 condition.pattern = str condition 'UrlRegexCondition': abbrs: ['UR', 'URegex', 'UrlR', 'UrlRegex'] analyze: (condition) -> @safeRegex escapeSlash condition.pattern match: (condition, request, cache) -> return cache.analyzed.test(request.url) compile: (condition, cache) -> @regTest 'url', cache.analyzed 'UrlWildcardCondition': abbrs: ['U', 'UW', 'Url', 'UrlW', 'UWild', 'UWildcard', 'UrlWild', 'UrlWildcard'] analyze: (condition) -> parts = for pattern in condition.pattern.split('|') when pattern shExp2RegExp pattern, trimAsterisk: true @safeRegex parts.join('|') match: (condition, request, cache) -> return cache.analyzed.test(request.url) compile: (condition, cache) -> @regTest 'url', cache.analyzed 'HostRegexCondition': abbrs: ['R', 'HR', 'Regex', 'HostR', 'HRegex', 'HostRegex'] analyze: (condition) -> @safeRegex escapeSlash condition.pattern match: (condition, request, cache) -> return cache.analyzed.test(request.host) compile: (condition, cache) -> @regTest 'host', cache.analyzed 'HostWildcardCondition': abbrs: ['', 'H', 'W', 'HW', 'Wild', 'Wildcard', 'Host', 'HostW', 'HWild', 'HWildcard', 'HostWild', 'HostWildcard'] analyze: (condition) -> parts = for pattern in condition.pattern.split('|') when pattern # Get the magical regex of this pattern. See # https://github.com/FelisCatus/SwitchyOmega/wiki/Host-wildcard-condition # for the magic. if pattern.charCodeAt(0) == '.'.charCodeAt(0) pattern = '*' + pattern if pattern.indexOf('**.') == 0 shExp2RegExp pattern.substring(1), trimAsterisk: true else if pattern.indexOf('*.') == 0 shExp2RegExp(pattern.substring(2), trimAsterisk: false) .replace(/./, '(?:^|\\.)').replace(/\.\*\$$/, '') else shExp2RegExp pattern, trimAsterisk: true @safeRegex parts.join('|') match: (condition, request, cache) -> return cache.analyzed.test(request.host) compile: (condition, cache) -> @regTest 'host', cache.analyzed 'BypassCondition': abbrs: ['B', 'Bypass'] analyze: (condition) -> # See https://developer.chrome.com/extensions/proxy#bypass_list cache = host: null ip: null scheme: null url: null normalizedPattern: '' server = condition.pattern if server == '' cache.host = server return cache parts = server.split '://' if parts.length > 1 cache.scheme = parts[0] cache.normalizedPattern = cache.scheme + '://' server = parts[1] parts = server.split '/' if parts.length > 1 addr = @parseIp parts[0] prefixLen = parseInt(parts[1]) if addr and not isNaN(prefixLen) cache.ip = conditionType: 'IpCondition' ip: @normalizeIp addr prefixLength: prefixLen cache.normalizedPattern += cache.ip.ip + '/' + cache.ip.prefixLength return cache # The server can be an IP address with or without brackets. serverIp = @parseIp(server) if not serverIp? pos = server.lastIndexOf(':') if pos >= 0 matchPort = server.substring(pos + 1) server = server.substring(0, pos) serverIp = @parseIp server if serverIp? server = @normalizeIp serverIp if serverIp.v4 cache.normalizedPattern += server else cache.normalizedPattern += '[' + server + ']' else if server.charCodeAt(0) == '.'.charCodeAt(0) server = '*' + server cache.normalizedPattern = server if matchPort cache.port = matchPort cache.normalizedPattern += ':' + cache.port # In URL, IPv6 server addresses need to be bracketed. if serverIp? and not serverIp.v4 server = '[' + server + ']' serverRegex = shExp2RegExp(server) serverRegex = serverRegex.substring(1, serverRegex.length - 1) scheme = cache.scheme ? '[^:]+' cache.url = @safeRegex('^' + scheme + ':\\/\\/' + serverRegex + ':' + matchPort + '\\/') else if server != '*' # In host, IPv6 server addresses are never bracketed. serverRegex = shExp2RegExp server, trimAsterisk: true cache.host = @safeRegex(serverRegex) return cache match: (condition, request, cache) -> cache = cache.analyzed return false if cache.scheme? and cache.scheme != request.scheme return false if cache.ip? and not @match cache.ip, request if cache.host? if cache.host == '' # https://code.google.com/p/chromium/codesearch#chromium/src/net/proxy/proxy_bypass_rules.cc&sq=package:chromium&l=67 # We align with Chromium's behavior of bypassing 127.0.0.1, ::1 as # well as any host without dots. # # This, however, will match IPv6 literals who also don't have dots. return ( request.host == '127.0.0.1' or request.host == '::1' or request.host.indexOf('.') < 0 ) else return false if not cache.host.test(request.host) return false if cache.url? and !cache.url.test(request.url) return true str: (condition) -> analyze = @_handler(condition).analyze cache = analyze.call(exports, condition) if cache.normalizedPattern return cache.normalizedPattern else return condition.pattern compile: (condition, cache) -> cache = cache.analyzed if cache.url? return @regTest 'url', cache.url conditions = [] if cache.host == '' hostEquals = (host) -> new U2.AST_Binary( left: new U2.AST_SymbolRef name: 'host' operator: '===' right: new U2.AST_String value: host ) return new U2.AST_Binary( left: new U2.AST_Binary( left: hostEquals '127.0.0.1' operator: '||' right: hostEquals '::1' ) operator: '||' right: new U2.AST_Binary( left: new U2.AST_Call( expression: new U2.AST_Dot( expression: new U2.AST_SymbolRef name: 'host' property: 'indexOf' ) args: [new U2.AST_String value: '.'] ) operator: '<' right: new U2.AST_Number value: 0 ) ) if cache.scheme? conditions.push new U2.AST_Binary( left: new U2.AST_SymbolRef name: 'scheme' operator: '===' right: new U2.AST_String value: cache.scheme ) if cache.host? conditions.push @regTest 'host', cache.host else if cache.ip? conditions.push @compile cache.ip switch conditions.length when 0 then new U2.AST_True when 1 then conditions[0] when 2 then new U2.AST_Binary( left: conditions[0] operator: '&&' right: conditions[1] ) 'KeywordCondition': abbrs: ['K', 'KW', 'Keyword'] analyze: (condition) -> null match: (condition, request) -> request.scheme == 'http' and request.url.indexOf(condition.pattern) >= 0 compile: (condition) -> new U2.AST_Binary( left: new U2.AST_Binary( left: new U2.AST_SymbolRef name: 'scheme' operator: '===' right: new U2.AST_String value: 'http' ) operator: '&&' right: new U2.AST_Binary( left: new U2.AST_Call( expression: new U2.AST_Dot( expression: new U2.AST_SymbolRef name: 'url' property: 'indexOf' ) args: [new U2.AST_String value: condition.pattern] ) operator: '>=' right: new U2.AST_Number value: 0 ) ) 'IpCondition': abbrs: ['Ip'] analyze: (condition) -> cache = addr: null normalized: null ip = condition.ip if ip.charCodeAt(0) == '['.charCodeAt(0) ip = ip.substr 1, ip.length - 2 addr = ip + '/' + condition.prefixLength cache.addr = @parseIp addr if not cache.addr? throw new Error "Invalid IP address #{addr}" cache.normalized = @normalizeIp cache.addr mask = if cache.addr.v4 new IP.v4.Address('255.255.255.255/' + cache.addr.subnetMask) else new IP.v6.Address(@ipv6Max + '/' + cache.addr.subnetMask) cache.mask = @normalizeIp mask.startAddress() cache match: (condition, request, cache) -> addr = @parseIp request.host return false if not addr? cache = cache.analyzed return false if addr.v4 != cache.addr.v4 return addr.isInSubnet cache.addr compile: (condition, cache) -> cache = cache.analyzed # We want to make sure that host is not a domain name before we pass it # to isInNet. Otherwise an expensive dns lookup might be triggered. hostLooksLikeIp = if cache.addr.v4 # For performance reasons, we just check the last character of host. # If it's a digit, we assume that host is valid IPv4 address. new U2.AST_Binary left: new U2.AST_Sub expression: new U2.AST_SymbolRef name: 'host' property: new U2.AST_Binary left: new U2.AST_Dot( expression: new U2.AST_SymbolRef name: 'host' property: 'length' ) operator: '-' right: new U2.AST_Number value: 1 operator: '>=' right: new U2.AST_Number value: 0 else # Likewise, we assume that host is valid IPv6 if it contains colons. new U2.AST_Binary( left: new U2.AST_Call( expression: new U2.AST_Dot( expression: new U2.AST_SymbolRef name: 'host' property: 'indexOf' ) args: [new U2.AST_String value: ':'] ) operator: '>=' right: new U2.AST_Number value: 0 ) if cache.addr.subnetMask == 0 # 0.0.0.0/0 (matches all IPv4 literals), or ::/0 (all IPv6 literals). # Use hostLooksLikeIp instead of isInNet for better efficiency and # browser support. return hostLooksLikeIp hostIsInNet = new U2.AST_Call( expression: new U2.AST_SymbolRef name: 'isInNet' args: [ new U2.AST_SymbolRef name: 'host' new U2.AST_String value: cache.normalized new U2.AST_String value: cache.mask ] ) if not cache.addr.v4 # Example: isInNetEx(host,"fefe:13::abc/33") # For documentation on the isInNetEx function, see: # https://msdn.microsoft.com/en-us/library/windows/desktop/gg308479(v=vs.85).aspx hostIsInNetEx = new U2.AST_Call( expression: new U2.AST_SymbolRef name: 'isInNetEx' args: [ new U2.AST_SymbolRef name: 'host' new U2.AST_String value: cache.normalized + cache.addr.subnet ] ) # Use isInNetEx if possible. hostIsInNet = new U2.AST_Conditional( condition: new U2.AST_Binary( left: new U2.AST_UnaryPrefix( operator: 'typeof' expression: new U2.AST_SymbolRef name: 'isInNetEx' ) operator: '===' right: new U2.AST_String value: 'function' ) consequent: hostIsInNetEx alternative: hostIsInNet ) return new U2.AST_Binary( left: hostLooksLikeIp operator: '&&' right: hostIsInNet ) str: (condition) -> condition.ip + '/' + condition.prefixLength fromStr: (str, condition) -> addr = @parseIp str if addr? condition.ip = addr.addressMinusSuffix condition.prefixLength = addr.subnetMask else condition.ip = '0.0.0.0' condition.prefixLength = 0 condition 'HostLevelsCondition': abbrs: ['Lv', 'Level', 'Levels', 'HL', 'HLv', 'HLevel', 'HLevels', 'HostL', 'HostLv', 'HostLevel', 'HostLevels'] analyze: (condition) -> '.'.charCodeAt 0 match: (condition, request, cache) -> dotCharCode = cache.analyzed dotCount = 0 for i in [0...request.host.length] if request.host.charCodeAt(i) == dotCharCode dotCount++ return false if dotCount > condition.maxValue return dotCount >= condition.minValue compile: (condition) -> val = new U2.AST_Dot( property: 'length' expression: new U2.AST_Call( args: [new U2.AST_String value: '.'] expression: new U2.AST_Dot( expression: new U2.AST_SymbolRef name: 'host' property: 'split' ) ) ) @between(val, condition.minValue + 1, condition.maxValue + 1, "#{condition.minValue} <= hostLevels <= #{condition.maxValue}") str: (condition) -> condition.minValue + '~' + condition.maxValue fromStr: (str, condition) -> [minValue, maxValue] = str.split('~') condition.minValue = parseInt(minValue, 10) condition.maxValue = parseInt(maxValue, 10) condition.minValue = 1 unless condition.minValue > 0 condition.maxValue = 1 unless condition.maxValue > 0 condition 'WeekdayCondition': abbrs: ['WD', 'Week', 'Day', 'Weekday'] analyze: (condition) -> null match: (condition, request) -> day = new Date().getDay() return condition.days.charCodeAt(day) > 64 if condition.days return condition.startDay <= day and day <= condition.endDay compile: (condition) -> getDay = new U2.AST_Call( args: [] expression: new U2.AST_Dot( property: 'getDay' expression: new U2.AST_New( args: [] expression: new U2.AST_SymbolRef name: 'Date' ) ) ) if condition.days new U2.AST_Binary( left: new U2.AST_Call( expression: new U2.AST_Dot( expression: new U2.AST_String value: condition.days property: 'charCodeAt' ) args: [getDay] ) operator: '>' right: new U2.AST_Number value: 64 ) else @between getDay, condition.startDay, condition.endDay str: (condition) -> if condition.days condition.days else condition.startDay + '~' + condition.endDay fromStr: (str, condition) -> if str.indexOf('~') < 0 and str.length == 7 condition.days = str else [startDay, endDay] = str.split('~') condition.startDay = parseInt(startDay, 10) condition.endDay = parseInt(endDay, 10) condition.startDay = 0 unless 0 <= condition.startDay <= 6 condition.endDay = 0 unless 0 <= condition.endDay <= 6 condition 'TimeCondition': abbrs: ['T', 'Time', 'Hour'] analyze: (condition) -> null match: (condition, request) -> hour = new Date().getHours() return condition.startHour <= hour and hour <= condition.endHour compile: (condition) -> val = new U2.AST_Call( args: [] expression: new U2.AST_Dot( property: 'getHours' expression: new U2.AST_New( args: [] expression: new U2.AST_SymbolRef name: 'Date' ) ) ) @between val, condition.startHour, condition.endHour str: (condition) -> condition.startHour + '~' + condition.endHour fromStr: (str, condition) -> [startHour, endHour] = str.split('~') condition.startHour = parseInt(startHour, 10) condition.endHour = parseInt(endHour, 10) condition.startHour = 0 unless 0 <= condition.startHour < 24 condition.endHour = 0 unless 0 <= condition.endHour < 24 condition # coffeelint: enable=missing_fat_arrows ================================================ FILE: omega-pac/src/pac_generator.coffee ================================================ U2 = require 'uglify-js' Profiles = require './profiles' # PacGenerator is used like a singleton class instance. # coffeelint: disable=missing_fat_arrows module.exports = ascii: (str) -> str.replace /[\u0080-\uffff]/g, (char) -> hex = char.charCodeAt(0).toString(16) result = '\\u' result += '0' for _ in [hex.length...4] result += hex return result compress: (ast) -> ast.figure_out_scope() compressor = U2.Compressor(warnings: false, keep_fargs: true, if_return: false) compressed_ast = ast.transform(compressor) compressed_ast.figure_out_scope() compressed_ast.compute_char_frequency() compressed_ast.mangle_names() compressed_ast script: (options, profile, args) -> if typeof profile == 'string' profile = Profiles.byName(profile, options) refs = Profiles.allReferenceSet(profile, options, profileNotFound: args?.profileNotFound) profiles = new U2.AST_Object properties: for key, name of refs when key != '+direct' p = if typeof profile == 'object' and profile.name == name profile else Profiles.byName(name, options) if not p? p = Profiles.profileNotFound(name, args?.profileNotFound) new U2.AST_ObjectKeyVal(key: key, value: Profiles.compile(p)) factory = new U2.AST_Function( argnames: [ new U2.AST_SymbolFunarg name: 'init' new U2.AST_SymbolFunarg name: 'profiles' ] body: [new U2.AST_Return value: new U2.AST_Function( argnames: [ new U2.AST_SymbolFunarg name: 'url' new U2.AST_SymbolFunarg name: 'host' ] body: [ new U2.AST_Directive value: 'use strict' new U2.AST_Var definitions: [ new U2.AST_VarDef name: new U2.AST_SymbolVar(name: 'result'), value: new U2.AST_SymbolRef name: 'init' new U2.AST_VarDef name: new U2.AST_SymbolVar(name: 'scheme'), value: new U2.AST_Call( expression: new U2.AST_Dot( expression: new U2.AST_SymbolRef name: 'url' property: 'substr' ) args: [ new U2.AST_Number value: 0 new U2.AST_Call( expression: new U2.AST_Dot( expression: new U2.AST_SymbolRef name: 'url' property: 'indexOf' ) args: [new U2.AST_String value: ':'] ) ] ) ] new U2.AST_Do( body: new U2.AST_BlockStatement body: [ new U2.AST_SimpleStatement body: new U2.AST_Assign( left: new U2.AST_SymbolRef name: 'result' operator: '=' right: new U2.AST_Sub( expression: new U2.AST_SymbolRef name: 'profiles' property: new U2.AST_SymbolRef name: 'result' ) ) new U2.AST_If( condition: new U2.AST_Binary( left: new U2.AST_UnaryPrefix( operator: 'typeof' expression: new U2.AST_SymbolRef name: 'result' ) operator: '===' right: new U2.AST_String value: 'function' ) body: new U2.AST_SimpleStatement body: new U2.AST_Assign( left: new U2.AST_SymbolRef name: 'result' operator: '=' right: new U2.AST_Call( expression: new U2.AST_SymbolRef name: 'result' args: [ new U2.AST_SymbolRef name: 'url' new U2.AST_SymbolRef name: 'host' new U2.AST_SymbolRef name: 'scheme' ] ) ) ) ] condition: new U2.AST_Binary( left: new U2.AST_Binary( left: new U2.AST_UnaryPrefix( operator: 'typeof' expression: new U2.AST_SymbolRef name: 'result' ) operator: '!==' right: new U2.AST_String value: 'string' ) operator: '||' right: new U2.AST_Binary( left: new U2.AST_Call( expression: new U2.AST_Dot( expression: new U2.AST_SymbolRef name: 'result' property: 'charCodeAt' ) args: [new U2.AST_Number(value: 0)] ) operator: '===' right: new U2.AST_Number value: '+'.charCodeAt(0) ) ) ) new U2.AST_Return value: new U2.AST_SymbolRef name: 'result' ] )] ) new U2.AST_Toplevel body: [new U2.AST_Var definitions: [ new U2.AST_VarDef( name: new U2.AST_SymbolVar name: 'FindProxyForURL' value: new U2.AST_Call( expression: factory args: [ Profiles.profileResult profile.name profiles ] ) ) ]] # coffeelint: enable=missing_fat_arrows ================================================ FILE: omega-pac/src/profiles.coffee ================================================ U2 = require 'uglify-js' ShexpUtils = require './shexp_utils' Conditions = require './conditions' RuleList = require './rule_list' {AttachedCache, Revision} = require './utils' # coffeelint: disable=camel_case_classes class AST_Raw extends U2.AST_SymbolRef # coffeelint: enable=camel_case_classes constructor: (raw) -> U2.AST_SymbolRef.call(this, name: raw) @aborts = -> false module.exports = exports = builtinProfiles: '+direct': name: 'direct' profileType: 'DirectProfile' color: '#aaaaaa' builtin: true '+system': name: 'system' profileType: 'SystemProfile' color: '#000000' builtin: true schemes: [ {scheme: 'http', prop: 'proxyForHttp'} {scheme: 'https', prop: 'proxyForHttps'} {scheme: 'ftp', prop: 'proxyForFtp'} {scheme: '', prop: 'fallbackProxy'} ] pacProtocols: { 'http': 'PROXY' 'https': 'HTTPS' 'socks4': 'SOCKS' 'socks5': 'SOCKS5' } formatByType: { 'SwitchyRuleListProfile': 'Switchy' 'AutoProxyRuleListProfile': 'AutoProxy' } ruleListFormats: [ 'Switchy' 'AutoProxy' ] parseHostPort: (str, scheme) -> sep = str.lastIndexOf(':') return if sep < 0 port = parseInt(str.substr(sep + 1)) || 80 host = str.substr(0, sep) return unless host return { scheme: scheme host: host port: port } pacResult: (proxy) -> if proxy if proxy.scheme == 'socks5' "SOCKS5 #{proxy.host}:#{proxy.port}; SOCKS #{proxy.host}:#{proxy.port}" else "#{exports.pacProtocols[proxy.scheme]} #{proxy.host}:#{proxy.port}" else 'DIRECT' isFileUrl: (url) -> !!(url?.substr(0, 5).toUpperCase() == 'FILE:') nameAsKey: (profileName) -> if typeof profileName != 'string' profileName = profileName.name '+' + profileName byName: (profileName, options) -> if typeof profileName == 'string' key = exports.nameAsKey(profileName) profileName = exports.builtinProfiles[key] ? options[key] profileName byKey: (key, options) -> if typeof key == 'string' key = exports.builtinProfiles[key] ? options[key] key each: (options, callback) -> charCodePlus = '+'.charCodeAt(0) for key, profile of options when key.charCodeAt(0) == charCodePlus callback(key, profile) for key, profile of exports.builtinProfiles if key.charCodeAt(0) == charCodePlus callback(key, profile) profileResult: (profileName) -> key = exports.nameAsKey(profileName) if key == '+direct' key = exports.pacResult() new U2.AST_String value: key isIncludable: (profile) -> includable = exports._handler(profile).includable if typeof includable == 'function' includable = includable.call(exports, profile) !!includable isInclusive: (profile) -> !!exports._handler(profile).inclusive updateUrl: (profile) -> exports._handler(profile).updateUrl?.call(exports, profile) updateContentTypeHints: (profile) -> exports._handler(profile).updateContentTypeHints?.call(exports, profile) update: (profile, data) -> exports._handler(profile).update.call(exports, profile, data) tag: (profile) -> exports._profileCache.tag(profile) create: (profile, opt_profileType) -> if typeof profile == 'string' profile = name: profile profileType: opt_profileType else if opt_profileType profile.profileType = opt_profileType create = exports._handler(profile).create return profile unless create create.call(exports, profile) profile updateRevision: (profile, revision) -> revision ?= Revision.fromTime() profile.revision = revision replaceRef: (profile, fromName, toName) -> return false if not exports.isInclusive(profile) handler = exports._handler(profile) handler.replaceRef.call(exports, profile, fromName, toName) analyze: (profile) -> cache = exports._profileCache.get profile, {} if not Object::hasOwnProperty.call(cache, 'analyzed') analyze = exports._handler(profile).analyze result = analyze?.call(exports, profile) cache.analyzed = result return cache dropCache: (profile) -> exports._profileCache.drop profile directReferenceSet: (profile) -> return {} if not exports.isInclusive(profile) cache = exports._profileCache.get profile, {} return cache.directReferenceSet if cache.directReferenceSet handler = exports._handler(profile) cache.directReferenceSet = handler.directReferenceSet.call(exports, profile) profileNotFound: (name, action) -> if not action? throw new Error("Profile #{name} does not exist!") if typeof action == 'function' action = action(name) if typeof action == 'object' and action.profileType return action switch action when 'ignore' return null when 'dumb' return exports.create({ name: name profileType: 'VirtualProfile' defaultProfileName: 'direct' }) throw action allReferenceSet: (profile, options, opt_args) -> o_profile = profile profile = exports.byName(profile, options) profile ?= exports.profileNotFound?(o_profile, opt_args.profileNotFound) opt_args ?= {} has_out = opt_args.out? result = opt_args.out ?= {} if profile result[exports.nameAsKey(profile.name)] = profile.name for key, name of exports.directReferenceSet(profile) exports.allReferenceSet(name, options, opt_args) delete opt_args.out if not has_out result referencedBySet: (profile, options, opt_args) -> profileKey = exports.nameAsKey(profile) opt_args ?= {} has_out = opt_args.out? result = opt_args.out ?= {} exports.each options, (key, prof) -> if exports.directReferenceSet(prof)[profileKey] result[key] = prof.name exports.referencedBySet(prof, options, opt_args) delete opt_args.out if not has_out result validResultProfilesFor: (profile, options) -> profile = exports.byName(profile, options) return [] if not exports.isInclusive(profile) profileKey = exports.nameAsKey(profile) ref = exports.referencedBySet(profile, options) ref[profileKey] = profileKey result = [] exports.each options, (key, prof) -> if not ref[key] and exports.isIncludable(prof) result.push(prof) result match: (profile, request, opt_profileType) -> opt_profileType ?= profile.profileType cache = exports.analyze(profile) match = exports._handler(opt_profileType).match match?.call(exports, profile, request, cache) compile: (profile, opt_profileType) -> opt_profileType ?= profile.profileType cache = exports.analyze(profile) return cache.compiled if cache.compiled handler = exports._handler(opt_profileType) cache.compiled = handler.compile.call(exports, profile, cache) _profileCache: new AttachedCache (profile) -> profile.revision _handler: (profileType) -> if typeof profileType != 'string' profileType = profileType.profileType handler = profileType while typeof handler == 'string' handler = exports._profileTypes[handler] if not handler? throw new Error "Unknown profile type: #{profileType}" return handler _profileTypes: # These functions are .call()-ed with `this` set to module.exports. # coffeelint: disable=missing_fat_arrows 'SystemProfile': compile: (profile) -> throw new Error "SystemProfile cannot be used in PAC scripts" 'DirectProfile': includable: true compile: (profile) -> return new U2.AST_String(value: @pacResult()) 'FixedProfile': includable: true create: (profile) -> profile.bypassList ?= [ { conditionType: 'BypassCondition' pattern: '127.0.0.1' } { conditionType: 'BypassCondition' pattern: '[::1]' } { conditionType: 'BypassCondition' pattern: 'localhost' } ] match: (profile, request) -> if profile.bypassList for cond in profile.bypassList if Conditions.match(cond, request) return [@pacResult(), cond, {scheme: 'direct'}, undefined] for s in @schemes when s.scheme == request.scheme and profile[s.prop] return [ @pacResult(profile[s.prop]), s.scheme, profile[s.prop], profile.auth?[s.prop] ? profile.auth?['all'] ] return [ @pacResult(profile.fallbackProxy), '', profile.fallbackProxy, profile.auth?.fallbackProxy ? profile.auth?['all'] ] compile: (profile) -> if ((not profile.bypassList or not profile.fallbackProxy) and not profile.proxyForHttp and not profile.proxyForHttps and not profile.proxyForFtp) return new U2.AST_String value: @pacResult profile.fallbackProxy body = [ new U2.AST_Directive value: 'use strict' ] if profile.bypassList and profile.bypassList.length conditions = null for cond in profile.bypassList condition = Conditions.compile cond if conditions? conditions = new U2.AST_Binary( left: conditions operator: '||' right: condition ) else conditions = condition body.push new U2.AST_If( condition: conditions body: new U2.AST_Return value: new U2.AST_String value: @pacResult() ) if (not profile.proxyForHttp and not profile.proxyForHttps and not profile.proxyForFtp) body.push new U2.AST_Return value: new U2.AST_String value: @pacResult profile.fallbackProxy else body.push new U2.AST_Switch( expression: new U2.AST_SymbolRef name: 'scheme' body: for s in @schemes when not s.scheme or profile[s.prop] ret = [new U2.AST_Return value: new U2.AST_String value: @pacResult profile[s.prop] ] if s.scheme new U2.AST_Case( expression: new U2.AST_String value: s.scheme body: ret ) else new U2.AST_Default body: ret ) new U2.AST_Function( argnames: [ new U2.AST_SymbolFunarg name: 'url' new U2.AST_SymbolFunarg name: 'host' new U2.AST_SymbolFunarg name: 'scheme' ] body: body ) 'PacProfile': includable: (profile) -> !@isFileUrl(profile.pacUrl) create: (profile) -> profile.pacScript ?= ''' function FindProxyForURL(url, host) { return "DIRECT"; } ''' compile: (profile) -> new U2.AST_Call args: [new U2.AST_This], expression: new U2.AST_Dot property: 'call', expression: new U2.AST_Function( argnames: [] body: [ # https://github.com/FelisCatus/SwitchyOmega/issues/390 # 1. Add \n after PAC to terminate line comment in PAC (// ...) # 2. Add another \n with knowledge that the first can be escaped # by trailing backslash in PAC. (// ... \) # 3. Add a multiline-comment block /* ... */ to terminate any # potential unclosed multiline-comment block. (/* ...) # 4. And finally, a semicolon to terminate the final statement. # Wait a moment. Do we really need to go this far? I don't know. # TODO(catus): Remove the hack needed to insert raw code. new AST_Raw ';\n' + profile.pacScript + '\n\n/* End of PAC */;' new U2.AST_Return value: new U2.AST_SymbolRef name: 'FindProxyForURL' ] ) updateUrl: (profile) -> if @isFileUrl(profile.pacUrl) undefined else profile.pacUrl updateContentTypeHints: -> [ '!text/html' '!application/xhtml+xml' 'application/x-ns-proxy-autoconfig' 'application/x-javascript-config' ] update: (profile, data) -> return false if profile.pacScript == data profile.pacScript = data return true 'AutoDetectProfile': 'PacProfile' 'SwitchProfile': includable: true inclusive: true create: (profile) -> profile.defaultProfileName ?= 'direct' profile.rules ?= [] directReferenceSet: (profile) -> refs = {} refs[exports.nameAsKey(profile.defaultProfileName)] = profile.defaultProfileName for rule in profile.rules refs[exports.nameAsKey(rule.profileName)] = rule.profileName refs analyze: (profile) -> profile.rules replaceRef: (profile, fromName, toName) -> changed = false if profile.defaultProfileName == fromName profile.defaultProfileName = toName changed = true for rule in profile.rules if rule.profileName == fromName rule.profileName = toName changed = true return changed match: (profile, request, cache) -> for rule in cache.analyzed if Conditions.match(rule.condition, request) return rule return [exports.nameAsKey(profile.defaultProfileName), null] compile: (profile, cache) -> rules = cache.analyzed if rules.length == 0 return @profileResult profile.defaultProfileName body = [ new U2.AST_Directive value: 'use strict' ] for rule in rules body.push new U2.AST_If condition: Conditions.compile rule.condition body: new U2.AST_Return value: @profileResult(rule.profileName) body.push new U2.AST_Return value: @profileResult profile.defaultProfileName new U2.AST_Function( argnames: [ new U2.AST_SymbolFunarg name: 'url' new U2.AST_SymbolFunarg name: 'host' new U2.AST_SymbolFunarg name: 'scheme' ] body: body ) 'VirtualProfile': 'SwitchProfile' 'RuleListProfile': includable: true inclusive: true create: (profile) -> profile.profileType ?= 'RuleListProfile' profile.format ?= exports.formatByType[profile.profileType] ? 'Switchy' profile.defaultProfileName ?= 'direct' profile.matchProfileName ?= 'direct' profile.ruleList ?= '' directReferenceSet: (profile) -> if profile.ruleList? refs = RuleList[profile.format]?.directReferenceSet?(profile) return refs if refs refs = {} for name in [profile.matchProfileName, profile.defaultProfileName] refs[exports.nameAsKey(name)] = name refs replaceRef: (profile, fromName, toName) -> changed = false if profile.defaultProfileName == fromName profile.defaultProfileName = toName changed = true if profile.matchProfileName == fromName profile.matchProfileName = toName changed = true return changed analyze: (profile) -> format = profile.format ? exports.formatByType[profile.profileType] formatHandler = RuleList[format] if not formatHandler throw new Error "Unsupported rule list format #{format}!" ruleList = profile.ruleList?.trim() || '' if formatHandler.preprocess? ruleList = formatHandler.preprocess(ruleList) return formatHandler.parse(ruleList, profile.matchProfileName, profile.defaultProfileName) match: (profile, request) -> result = exports.match(profile, request, 'SwitchProfile') compile: (profile) -> exports.compile(profile, 'SwitchProfile') updateUrl: (profile) -> profile.sourceUrl updateContentTypeHints: -> [ '!text/html' '!application/xhtml+xml' 'text/plain' '*' ] update: (profile, data) -> data = data.trim() original = profile.format ? exports.formatByType[profile.profileType] profile.profileType = 'RuleListProfile' format = original if RuleList[format].detect?(data) == false # Wrong data for the current format. format = null for own formatName of RuleList result = RuleList[formatName].detect?(data) if result == true or (result != false and not format?) profile.format = format = formatName format ?= original formatHandler = RuleList[format] if formatHandler.preprocess? data = formatHandler.preprocess(data) return false if profile.ruleList == data profile.ruleList = data return true 'SwitchyRuleListProfile': 'RuleListProfile' 'AutoProxyRuleListProfile': 'RuleListProfile' # coffeelint: enable=missing_fat_arrows ================================================ FILE: omega-pac/src/rule_list.coffee ================================================ Buffer = require('buffer').Buffer Conditions = require('./conditions') strStartsWith = (str, prefix) -> str.substr(0, prefix.length) == prefix module.exports = exports = 'AutoProxy': magicPrefix: 'W0F1dG9Qcm94' # Detect base-64 encoded "[AutoProxy". detect: (text) -> if strStartsWith(text, exports['AutoProxy'].magicPrefix) return true else if strStartsWith(text, '[AutoProxy') return true return preprocess: (text) -> if strStartsWith(text, exports['AutoProxy'].magicPrefix) text = new Buffer(text, 'base64').toString('utf8') return text parse: (text, matchProfileName, defaultProfileName) -> normal_rules = [] exclusive_rules = [] for line in text.split(/\n|\r/) line = line.trim() continue if line.length == 0 || line[0] == '!' || line[0] == '[' source = line profile = matchProfileName list = normal_rules if line[0] == '@' and line[1] == '@' profile = defaultProfileName list = exclusive_rules line = line.substring(2) cond = if line[0] == '/' conditionType: 'UrlRegexCondition' pattern: line.substring(1, line.length - 1) else if line[0] == '|' if line[1] == '|' conditionType: 'HostWildcardCondition' pattern: "*." + line.substring(2) else conditionType: 'UrlWildcardCondition' pattern: line.substring(1) + "*" else if line.indexOf('*') < 0 conditionType: 'KeywordCondition' pattern: line else conditionType: 'UrlWildcardCondition' pattern: 'http://*' + line + '*' list.push({condition: cond, profileName: profile, source: source}) # Exclusive rules have higher priority, so they come first. return exclusive_rules.concat normal_rules 'Switchy': omegaPrefix: '[SwitchyOmega Conditions' specialLineStart: "[;#@!" detect: (text) -> if strStartsWith(text, exports['Switchy'].omegaPrefix) return true return parse: (text, matchProfileName, defaultProfileName) -> switchy = exports['Switchy'] parser = switchy.getParser(text) return switchy[parser](text, matchProfileName, defaultProfileName) directReferenceSet: ({ruleList, matchProfileName, defaultProfileName}) -> text = ruleList.trim() switchy = exports['Switchy'] parser = switchy.getParser(text) return unless parser == 'parseOmega' return unless /(^|\n)@with\s+results?(\r|\n|$)/i.test(text) refs = {} for line in text.split(/\n|\r/) line = line.trim() if switchy.specialLineStart.indexOf(line[0]) < 0 iSpace = line.lastIndexOf(' +') if iSpace < 0 profile = defaultProfileName || 'direct' else profile = line.substr(iSpace + 2).trim() refs['+' + profile] = profile refs # For the omega rule list format, please see the following wiki page: # https://github.com/FelisCatus/SwitchyOmega/wiki/SwitchyOmega-conditions-format compose: ({rules, defaultProfileName}, {withResult, useExclusive} = {}) -> eol = '\r\n' ruleList = '[SwitchyOmega Conditions]' + eol useExclusive ?= not withResult if withResult ruleList += '@with result' + eol + eol else ruleList += eol specialLineStart = exports['Switchy'].specialLineStart + '+' for rule in rules if rule.note ruleList += '@note ' + rule.note + eol line = Conditions.str(rule.condition) if useExclusive and rule.profileName == defaultProfileName line = '!' + line else if specialLineStart.indexOf(line[0]) >= 0 line = ': ' + line if withResult # TODO(catus): What if rule.profileName contains ' +' or new lines? line += ' +' + rule.profileName ruleList += line + eol if withResult # TODO(catus): Also special chars and sequences in defaultProfileName. ruleList += eol + '* +' + defaultProfileName + eol return ruleList getParser: (text) -> switchy = exports['Switchy'] parser = 'parseOmega' if not strStartsWith(text, switchy.omegaPrefix) if text[0] == '#' or text.indexOf('\n#') >= 0 parser = 'parseLegacy' return parser conditionFromLegacyWildcard: (pattern) -> if pattern[0] == '@' pattern = pattern.substring(1) else if pattern.indexOf('://') <= 0 and pattern[0] != '*' pattern = '*' + pattern if pattern[pattern.length - 1] != '*' pattern += '*' host = Conditions.urlWildcard2HostWildcard(pattern) if host conditionType: 'HostWildcardCondition' pattern: host else conditionType: 'UrlWildcardCondition' pattern: pattern parseLegacy: (text, matchProfileName, defaultProfileName) -> normal_rules = [] exclusive_rules = [] begin = false section = 'WILDCARD' for line in text.split(/\n|\r/) line = line.trim() continue if line.length == 0 || line[0] == ';' if not begin if line.toUpperCase() == '#BEGIN' begin = true continue if line.toUpperCase() == '#END' break if line[0] == '[' and line[line.length - 1] == ']' section = line.substring(1, line.length - 1).toUpperCase() continue source = line profile = matchProfileName list = normal_rules if line[0] == '!' profile = defaultProfileName list = exclusive_rules line = line.substring(1) cond = switch section when 'WILDCARD' exports['Switchy'].conditionFromLegacyWildcard(line) when 'REGEXP' conditionType: 'UrlRegexCondition' pattern: line else null if cond? list.push({condition: cond, profileName: profile, source: source}) # Exclusive rules have higher priority, so they come first. return exclusive_rules.concat normal_rules parseOmega: (text, matchProfileName, defaultProfileName, args = {}) -> {strict} = args if strict error = (fields) -> err = new Error(fields.message) for own key, value of fields err[key] = value throw err includeSource = args.source ? true rules = [] rulesWithDefaultProfile = [] withResult = false exclusiveProfile = null noteForNextRule = null lno = 0 for line in text.split(/\n|\r/) lno++ line = line.trim() continue if line.length == 0 switch line[0] when '[' # Header line: Ignore. continue when ';' # Comment line: Ignore. continue when '@' # Directive line: iSpace = line.indexOf(' ') iSpace = line.length if iSpace < 0 directive = line.substr(1, iSpace - 1) line = line.substr(iSpace + 1).trim() switch directive.toUpperCase() when 'WITH' feature = line.toUpperCase() if feature == 'RESULT' or feature == 'RESULTS' withResult = true when 'NOTE' noteForNextRule = line continue source = null exclusiveProfile = null if strict if line[0] == '!' profile = if withResult then null else defaultProfileName source = line line = line.substr(1) else if withResult iSpace = line.lastIndexOf(' +') if iSpace < 0 error?({ message: "Missing result profile name: " + line reason: 'missingResultProfile' source: line sourceLineNo: lno }) continue profile = line.substr(iSpace + 2).trim() line = line.substr(0, iSpace).trim() exclusiveProfile = profile if line == '*' else profile = matchProfileName cond = Conditions.fromStr(line) if not cond error?({ message: "Invalid rule: " + line reason: 'invalidRule' source: source ? line sourceLineNo: lno }) continue rule = condition: cond profileName: profile source: if includeSource then source ? line if noteForNextRule? rule.note = noteForNextRule noteForNextRule = null rules.push(rule) if not profile rulesWithDefaultProfile.push(rule) if withResult if not exclusiveProfile if strict error?({ message: "Missing default rule with catch-all '*' condition" reason: 'noDefaultRule' }) exclusiveProfile = defaultProfileName || 'direct' for rule in rulesWithDefaultProfile rule.profileName = exclusiveProfile return rules ================================================ FILE: omega-pac/src/shexp_utils.coffee ================================================ module.exports = exports = regExpMetaChars: do -> chars = '''\\[\^$.|?*+(){}/''' set = {} for i in [0...chars.length] set[chars.charCodeAt(i)] = true set escapeSlash: (pattern) -> charCodeSlash = 47 # / charCodeBackSlash = 92 # \ escaped = false start = 0 result = '' for i in [0...pattern.length] code = pattern.charCodeAt(i) if code == charCodeSlash and not escaped result += pattern.substring start, i result += '\\' start = i escaped = (code == charCodeBackSlash and not escaped) result += pattern.substr start shExp2RegExp: (pattern, options) -> trimAsterisk = options?.trimAsterisk || false start = 0 end = pattern.length charCodeAsterisk = 42 # '*' charCodeQuestion = 63 # '?' if trimAsterisk while start < end && pattern.charCodeAt(start) == charCodeAsterisk start++ while start < end && pattern.charCodeAt(end - 1) == charCodeAsterisk end-- if end - start == 1 && pattern.charCodeAt(start) == charCodeAsterisk return '' regex = '' if start == 0 regex += '^' for i in [start...end] code = pattern.charCodeAt(i) switch code when charCodeAsterisk then regex += '.*' when charCodeQuestion then regex += '.' else if exports.regExpMetaChars[code] >= 0 regex += '\\' regex += pattern[i] if end == pattern.length regex += '$' return regex ================================================ FILE: omega-pac/src/utils.coffee ================================================ Revision = fromTime: (time) -> time = if time then new Date(time) else new Date() return time.getTime().toString(16) compare: (a, b) -> return 0 if not a and not b return -1 if not a return 1 if not b return 1 if a.length > b.length return -1 if a.length < b.length return 1 if a > b return -1 if a < b return 0 exports.Revision = Revision class AttachedCache constructor: (opt_prop, @tag) -> @prop = opt_prop if typeof @tag == 'undefined' @tag = opt_prop @prop = '_cache' get: (obj, otherwise) -> tag = @tag(obj) cache = @_getCache(obj) if cache? and cache.tag == tag return cache.value value = if typeof otherwise == 'function' then otherwise() else otherwise @_setCache(obj, {tag: tag, value: value}) return value drop: (obj) -> if obj[@prop]? obj[@prop] = undefined _getCache: (obj) -> obj[@prop] _setCache: (obj, value) -> if not Object::hasOwnProperty.call obj, @prop Object.defineProperty obj, @prop, writable: true obj[@prop] = value exports.AttachedCache = AttachedCache tld = require('tldjs') exports.isIp = (domain) -> return true if domain.indexOf(':') > 0 # IPv6 lastCharCode = domain.charCodeAt(domain.length - 1) return true if 48 <= lastCharCode <= 57 # IP address ending with number. return false exports.getBaseDomain = (domain) -> return domain if exports.isIp(domain) return tld.getDomain(domain) ? domain exports.wildcardForDomain = (domain) -> return domain if exports.isIp(domain) return '*.' + exports.getBaseDomain(domain) Url = require('url') exports.wildcardForUrl = (url) -> domain = Url.parse(url).hostname return exports.wildcardForDomain(domain) ================================================ FILE: omega-pac/test/conditions.coffee ================================================ chai = require 'chai' should = chai.should() lolex = require 'lolex' describe 'Conditions', -> Conditions = require '../src/conditions' U2 = require 'uglify-js' testCond = (condition, request, should_match) -> o_request = request should_match = !!should_match if typeof request == 'string' request = Conditions.requestFromUrl(request) matchResult = Conditions.match(condition, request) condExpr = Conditions.compile(condition) testFunc = new U2.AST_Function( argnames: [ new U2.AST_SymbolFunarg name: 'url' new U2.AST_SymbolFunarg name: 'host' new U2.AST_SymbolFunarg name: 'scheme' ] body: [ new U2.AST_Return value: condExpr ] ) testFunc = eval '(' + testFunc.print_to_string() + ')' compileResult = testFunc(request.url, request.host, request.scheme) friendlyError = (compiled) -> # Try to give friendly assert messages instead of something like # "expect true to be false". printCond = JSON.stringify(condition) printCompiled = if compiled then 'COMPILED ' else '' printMatch = if should_match then 'to match' else 'not to match' msg = ("expect #{printCompiled}condition #{printCond} " + "#{printMatch} request #{o_request}") chai.assert(false, msg) if matchResult != should_match friendlyError() if compileResult != should_match friendlyError('compiled') return matchResult describe 'TrueCondition', -> it 'should always return true', -> testCond({conditionType: 'TrueCondition'}, {}, 'match') describe 'FalseCondition', -> it 'should always return false', -> testCond({conditionType: 'FalseCondition'}, {}, not 'match') describe 'UrlRegexCondition', -> cond = conditionType: 'UrlRegexCondition' pattern: 'example\\.com' it 'should match requests based on regex pattern', -> testCond(cond, 'http://www.example.com/', 'match') it 'should not match requests not matching the pattern', -> testCond(cond, 'http://www.example.net/', not 'match') it 'should support regex meta chars', -> con = conditionType: 'UrlRegexCondition' pattern: 'exam.*\\.com' testCond(con, 'http://www.example.com/', 'match') it 'should fallback to not match if pattern is invalid', -> con = conditionType: 'UrlRegexCondition' pattern: ')Invalid(' testCond(con, 'http://www.example.com/', not 'match') describe 'UrlWildcardCondition', -> cond = conditionType: 'UrlWildcardCondition' pattern: '*example.com*' it 'should match requests based on wildcard pattern', -> testCond(cond, 'http://www.example.com/', 'match') it 'should not match requests not matching the pattern', -> testCond(cond, 'http://www.example.net/', not 'match') it 'should support wildcard question marks', -> cond = conditionType: 'UrlWildcardCondition' pattern: '*exam???.com*' testCond(cond, 'http://www.example.com/', 'match') it 'should not support regex meta chars', -> cond = conditionType: 'UrlWildcardCondition' pattern: '.*example.com.*' testCond(cond, 'http://example.com/', not 'match') it 'should support multiple patterns in one condition', -> cond = conditionType: 'UrlWildcardCondition' pattern: '*.example.com/*|*.example.net/*' testCond(cond, 'http://a.example.com/abc', 'match') testCond(cond, 'http://b.example.net/def', 'match') testCond(cond, 'http://c.example.org/ghi', not 'match') describe 'HostRegexCondition', -> cond = conditionType: 'HostRegexCondition' pattern: '.*\\.example\\.com' it 'should match requests based on regex pattern', -> testCond(cond, 'http://www.example.com/', 'match') it 'should not match requests not matching the pattern', -> testCond(cond, 'http://example.com/', not 'match') it 'should not match URL parts other than the host', -> testCond(cond, 'http://example.net/www.example.com') .should.be.false describe 'HostWildcardCondition', -> cond = conditionType: 'HostWildcardCondition' pattern: '*.example.com' it 'should match requests based on wildcard pattern', -> testCond(cond, 'http://www.example.com/', 'match') it 'should also match hostname without the optional level', -> # https://github.com/FelisCatus/SwitchyOmega/wiki/Host-wildcard-condition testCond(cond, 'http://example.com/', 'match') it 'should process patterns like *.*example.com correctly', -> # https://github.com/FelisCatus/SwitchyOmega/issues/158 con = conditionType: 'HostWildcardCondition' pattern: '*.*example.com' testCond(con, 'http://example.com/', 'match') testCond(con, 'http://www.example.com/', 'match') testCond(con, 'http://www.some-example.com/', 'match') testCond(con, 'http://xample.com/', not 'match') it 'should allow override of the magical behavior', -> con = conditionType: 'HostWildcardCondition' pattern: '**.example.com' testCond(con, 'http://www.example.com/', 'match') testCond(con, 'http://example.com/', not 'match') it 'should not match URL parts other than the host', -> testCond(cond, 'http://example.net/www.example.com') .should.be.false it 'should support multiple patterns in one condition', -> cond = conditionType: 'HostWildcardCondition' pattern: '*.example.com|*.example.net' testCond(cond, 'http://a.example.com/abc', 'match') testCond(cond, 'http://example.net/def', 'match') testCond(cond, 'http://c.example.org/ghi', not 'match') describe 'BypassCondition', -> # See https://developer.chrome.com/extensions/proxy#bypass_list it 'should correctly support patterns containing hosts', -> cond = conditionType: 'BypassCondition' pattern: '.example.com' testCond(cond, 'http://www.example.com/', 'match') testCond(cond, 'http://example.com/', not 'match') cond.pattern = '*.example.com' testCond(cond, 'http://www.example.com/', 'match') testCond(cond, 'http://example.com/', not 'match') cond.pattern = 'example.com' testCond(cond, 'http://example.com/', 'match') testCond(cond, 'http://www.example.com/', not 'match') cond.pattern = '*example.com' testCond(cond, 'http://example.com/', 'match') testCond(cond, 'http://www.example.com/', 'match') testCond(cond, 'http://anotherexample.com/', 'match') it 'should match the scheme specified in the pattern', -> cond = conditionType: 'BypassCondition' pattern: 'http://example.com' testCond(cond, 'http://example.com/', 'match') testCond(cond, 'https://example.com/', not 'match') it 'should match the port specified in the pattern', -> cond = conditionType: 'BypassCondition' pattern: 'http://example.com:8080' testCond(cond, 'http://example.com:8080/', 'match') testCond(cond, 'http://example.com:888/', not 'match') it 'should correctly support patterns using IPv4 literals', -> cond = conditionType: 'BypassCondition' pattern: 'http://127.0.0.1:8080' testCond(cond, 'http://127.0.0.1:8080/', 'match') testCond(cond, 'http://127.0.0.2:8080/', not 'match') it 'should correctly support IPv6 canonicalization', -> cond = conditionType: 'BypassCondition' pattern: 'http://[0:0::1]:8080' result = Conditions.analyze(cond) testCond(cond, 'http://[::1]:8080/', 'match') testCond(cond, 'http://[1::1]:8080/', not 'match') it 'should correctly support IPv6 canonicalization 2', -> cond = conditionType: 'BypassCondition' pattern: '[::1]' result = Conditions.analyze(cond) testCond(cond, 'http://[::1]:8080/', 'match') testCond(cond, 'http://[1::1]:8080/', not 'match') it 'should parse IPv4 CIDR notation', -> cond = conditionType: 'BypassCondition' pattern: '192.168.0.0/16' result = Conditions.analyze(cond).analyzed should.exist(result.ip) result.ip.should.eql({ conditionType: 'IpCondition' ip: '192.168.0.0' prefixLength: 16 }) it 'should parse IPv6 CIDR notation', -> cond = conditionType: 'BypassCondition' pattern: 'fefe:13::abc/33' result = Conditions.analyze(cond).analyzed should.exist(result.ip) result.ip.should.eql({ conditionType: 'IpCondition' ip: 'fefe:13::abc' prefixLength: 33 }) it 'should parse IPv6 CIDR notation with zero prefixLength', -> cond = conditionType: 'BypassCondition' pattern: '::/0' result = Conditions.analyze(cond).analyzed should.exist(result.ip) result.ip.should.eql({ conditionType: 'IpCondition' ip: '::' prefixLength: 0 }) it 'should match 127.0.0.1 when is used', -> cond = conditionType: 'BypassCondition' pattern: '' testCond(cond, 'http://127.0.0.1:8080/', 'match') it 'should match [::1] when is used', -> cond = conditionType: 'BypassCondition' pattern: '' testCond(cond, 'http://[::1]:8080/', 'match') it 'should match any host without dots when is used', -> cond = conditionType: 'BypassCondition' pattern: '' testCond(cond, 'http://localhost:8080/', 'match') testCond(cond, 'http://intranet:8080/', 'match') testCond(cond, 'http://foobar/', 'match') testCond(cond, 'http://example.com/', not 'match') # Intended, see the corresponding code and comments for the reasoning. testCond(cond, 'http://[::ffff:eeee]/', 'match') testCond(cond, 'http://[::1.2.3.4]/', not 'match') describe 'IpCondition', -> # IpCondition requires isInNetEx or isInNet function provided by the PAC # runner, which is not available in the unit test. So We can't use testCond # here. it 'should support IPv4 subnet', -> cond = conditionType: "IpCondition" ip: '192.168.1.1' prefixLength: 16 request = Conditions.requestFromUrl('http://192.168.4.4/') Conditions.match(cond, request).should.be.true compiled = Conditions.compile(cond).print_to_string() compiled.should.contain('isInNet(host,"192.168.1.1","255.255.0.0")') it 'should support IPv6 subnet', -> cond = conditionType: "IpCondition" ip: 'fefe:13::abc' prefixLength: 33 request = Conditions.requestFromUrl('http://[fefe:13::def]/') Conditions.match(cond, request).should.be.true compiled = Conditions.compile(cond).print_to_string() compiled.should.contain('isInNet(host,"fefe:13::abc","ffff:ffff:8000::")') compiled.should.contain('isInNetEx(host,"fefe:13::abc/33")') it 'should support IPv6 subnet with zero prefixLength', -> cond = conditionType: "IpCondition" ip: '::' prefixLength: 0 request = Conditions.requestFromUrl('http://[fefe:13::def]/') Conditions.match(cond, request).should.be.true compiled = Conditions.compile(cond).print_to_string() compiled.indexOf('indexOf(').should.be.above(0) it 'should not match domain name to IP subnet', -> cond = conditionType: "IpCondition" ip: '::' prefixLength: 0 request = Conditions.requestFromUrl('http://www.example.com/') Conditions.match(cond, request).should.be.false it 'should not pass domain name to isInNet function', -> ipToCompiledFunc = (ip, prefixLen) -> cond = conditionType: "IpCondition" ip: ip prefixLength: prefixLen # In this test case, a dummy isInNet function that always returns true # is used. We only care about whether it is called or not here. dummyIsInNet = new U2.AST_Function( argnames: [] body: [ new U2.AST_Return value: new U2.AST_True ] ) testFunc = new U2.AST_Function( argnames: [ new U2.AST_SymbolFunarg name: 'url' new U2.AST_SymbolFunarg name: 'host' new U2.AST_SymbolFunarg name: 'scheme' ] body: [ new U2.AST_Var definitions: [ new U2.AST_VarDef( name: new U2.AST_SymbolVar(name: 'isInNet') value: dummyIsInNet ) ] new U2.AST_Return value: Conditions.compile(cond) ] ) eval('(' + testFunc.print_to_string() + ')') compiledFunc = ipToCompiledFunc('0.0.0.0', 0) compiledFunc(null, 'www.example.com').should.equal(false) compiledFunc(null, '127.0.0.1').should.equal(true) compiledFunc = ipToCompiledFunc('0.0.0.0', 1) compiledFunc(null, 'www.example.com').should.equal(false) compiledFunc(null, '127.0.0.1').should.equal(true) compiledFunc = ipToCompiledFunc('::', 0) compiledFunc(null, 'www.example.com').should.equal(false) compiledFunc(null, '::1').should.equal(true) compiledFunc = ipToCompiledFunc('::', 1) compiledFunc(null, 'www.example.com').should.equal(false) compiledFunc(null, '::1').should.equal(true) describe 'KeywordCondition', -> cond = conditionType: 'KeywordCondition' pattern: 'example.com' it 'should match requests based on substring', -> testCond(cond, 'http://www.example.com/', 'match') testCond(cond, 'http://www.example.net/', not 'match') it 'should not match HTTPS requests', -> testCond(cond, 'https://example.com/', not 'match') testCond(cond, 'https://example.net/', not 'match') describe 'WeekdayCondition', -> clock = null before -> clock = lolex.install 0, ['Date'] after -> clock.uninstall() testCondDay = (cond, day, match) -> # Feb 2016 Calendar for testing: # Su Mo Tu We Th Fr Sa # .. 01 02 03 04 05 06 # 07 08 09 10 11 12 13 # (...) date = if day > 0 then day else 7 clock.setSystemTime(new Date("2016-02-0#{date}T00:00:00Z").getTime()) testCond(cond, "http://weekday-#{day}/", match) it 'should match requests based on date range', -> cond = conditionType: 'WeekdayCondition' startDay: 3 endDay: 5 testCondDay(cond, 0, not 'match') testCondDay(cond, 1, not 'match') testCondDay(cond, 2, not 'match') testCondDay(cond, 3, 'match') testCondDay(cond, 4, 'match') testCondDay(cond, 5, 'match') testCondDay(cond, 6, not 'match') it 'should match the day if startDay == endDay', -> cond = conditionType: 'WeekdayCondition' startDay: 3 endDay: 3 testCondDay(cond, 0, not 'match') testCondDay(cond, 1, not 'match') testCondDay(cond, 2, not 'match') testCondDay(cond, 3, 'match') testCondDay(cond, 4, not 'match') testCondDay(cond, 5, not 'match') testCondDay(cond, 6, not 'match') it 'should not match anything if startDay > endDay', -> cond = conditionType: 'WeekdayCondition' startDay: 4 endDay: 3 testCondDay(cond, 0, not 'match') testCondDay(cond, 1, not 'match') testCondDay(cond, 2, not 'match') testCondDay(cond, 3, not 'match') testCondDay(cond, 4, not 'match') testCondDay(cond, 5, not 'match') testCondDay(cond, 6, not 'match') it 'should match according to .days', -> cond = conditionType: 'WeekdayCondition' days: 'SMTWtFs' testCondDay(cond, 0, 'match') testCondDay(cond, 1, 'match') testCondDay(cond, 2, 'match') testCondDay(cond, 3, 'match') testCondDay(cond, 4, 'match') testCondDay(cond, 5, 'match') testCondDay(cond, 6, 'match') cond = conditionType: 'WeekdayCondition' days: 'S-TW-F-' testCondDay(cond, 0, 'match') testCondDay(cond, 1, not 'match') testCondDay(cond, 2, 'match') testCondDay(cond, 3, 'match') testCondDay(cond, 4, not 'match') testCondDay(cond, 5, 'match') testCondDay(cond, 6, not 'match') it 'should prefer .days to .startDay and .endDay', -> cond = conditionType: 'WeekdayCondition' days: '--TW---' startDay: 0 endDay: 0 testCondDay(cond, 0, not 'match') testCondDay(cond, 1, not 'match') testCondDay(cond, 2, 'match') testCondDay(cond, 3, 'match') testCondDay(cond, 4, not 'match') testCondDay(cond, 5, not 'match') testCondDay(cond, 6, not 'match') describe 'TimeCondition', -> clock = null before -> clock = lolex.install 0, ['Date'] after -> clock.uninstall() testCondTime = (cond, time, match) -> # This uses RFC2822 format to make it in local time zone. # ISO-8601 should be avoided because ES5 says it assumes UTC. clock.setSystemTime(new Date("01 Feb 2016 #{time}").getTime()) testCond(cond, "http://time-#{time}/", match) it 'should match requests based on hour range', -> cond = conditionType: 'TimeCondition' startHour: 7 endHour: 9 testCondTime(cond, '00:00:00', not 'match') testCondTime(cond, '06:00:00', not 'match') testCondTime(cond, '07:00:00', 'match') testCondTime(cond, '08:00:00', 'match') testCondTime(cond, '09:00:00', 'match') testCondTime(cond, '09:59:59', 'match') testCondTime(cond, '10:00:00', not 'match') testCondTime(cond, '19:00:00', not 'match') testCondTime(cond, '23:00:00', not 'match') it 'should match the hour if startHour == endHour', -> cond = conditionType: 'TimeCondition' startHour: 7 endHour: 7 testCondTime(cond, '00:00:00', not 'match') testCondTime(cond, '06:00:00', not 'match') testCondTime(cond, '07:00:00', 'match') testCondTime(cond, '07:00:01', 'match') testCondTime(cond, '07:59:59', 'match') testCondTime(cond, '08:00:00', not 'match') testCondTime(cond, '19:00:00', not 'match') it 'should not match anything if startHour > endHour', -> cond = conditionType: 'TimeCondition' startHour: 7 endHour: 6 testCondTime(cond, '00:00:00', not 'match') testCondTime(cond, '06:00:00', not 'match') testCondTime(cond, '06:59:59', not 'match') testCondTime(cond, '07:00:00', not 'match') testCondTime(cond, '08:00:00', not 'match') testCondTime(cond, '09:00:00', not 'match') testCondTime(cond, '10:00:00', not 'match') testCondTime(cond, '19:00:00', not 'match') testCondTime(cond, '23:00:00', not 'match') describe '#typeFromAbbr', -> it 'should get condition types by abbrs', -> Conditions.typeFromAbbr('True').should.equal('TrueCondition') Conditions.typeFromAbbr('HR').should.equal('HostRegexCondition') describe '#str and #fromStr', -> it 'should encode & decode TrueCondition correctly', -> condition = conditionType: 'TrueCondition' result = Conditions.str(condition) result.should.equal('True:') cond = Conditions.fromStr(result) cond.should.eql(condition) it 'should encode & decode conditions with pattern correctly', -> condition = conditionType: 'UrlWildcardCondition' pattern: '*://*.example.com/*' result = Conditions.str(condition) result.should.equal('UrlWildcard: ' + condition.pattern) cond = Conditions.fromStr(result) cond.should.eql(condition) it 'should encode & decode False while preserving pattern', -> condition = conditionType: 'FalseCondition' pattern: 'a b c' result = Conditions.str(condition) result.should.equal('Disabled: a b c') cond = Conditions.fromStr(result) cond.should.eql(condition) it 'should encode & decode FalseCondition without any pattern', -> condition = conditionType: 'FalseCondition' result = Conditions.str(condition) result.should.equal('Disabled:') cond = Conditions.fromStr(result) cond.should.eql(condition) it 'should encode & decode HostWildcardCondition using shorthand syntax', -> condition = conditionType: 'HostWildcardCondition' pattern: '*.example.com' result = Conditions.str(condition) result.should.equal(condition.pattern) cond = Conditions.fromStr(result) cond.should.eql(condition) it 'should encode & decode HostWildcardCondition ending with colon', -> condition = conditionType: 'HostWildcardCondition' pattern: 'bogus:' result = Conditions.str(condition) result.should.equal('HostWildcard: ' + condition.pattern) cond = Conditions.fromStr(result) cond.should.eql(condition) it 'should encode & decode BypassCondition correctly', -> condition = conditionType: 'BypassCondition' pattern: '127.0.0.1/16' result = Conditions.str(condition) result.should.equal('Bypass: 127.0.0.1/16') cond = Conditions.fromStr(result) cond.should.eql(condition) it 'should add brackets for IPv6 hosts in BypassCondition', -> condition = conditionType: 'BypassCondition' pattern: '::1' result = Conditions.str(condition) result.should.equal('Bypass: [::1]') cond = Conditions.fromStr(result) cond.conditionType.should.equal('BypassCondition') cond.pattern.should.equal('[::1]') it 'should add brackets for IPv6 hosts with scheme in BypassCondition', -> condition = conditionType: 'BypassCondition' pattern: 'http://::1' result = Conditions.str(condition) result.should.equal('Bypass: http://[::1]') cond = Conditions.fromStr(result) cond.conditionType.should.equal('BypassCondition') cond.pattern.should.equal('http://[::1]') it 'should encode & decode IpCondition correctly', -> condition = conditionType: 'IpCondition' ip: '127.0.0.1' prefixLength: 16 result = Conditions.str(condition) result.should.equal('Ip: 127.0.0.1/16') cond = Conditions.fromStr(result) cond.should.eql(condition) it 'should provide sensible fallbacks for invalid IpCondition', -> cond = Conditions.fromStr('Ip: foo/-233') cond.should.eql( conditionType: 'IpCondition' ip: '0.0.0.0' prefixLength: 0 ) cond = Conditions.fromStr('Ip: nonsense stuff') cond.should.eql( conditionType: 'IpCondition' ip: '0.0.0.0' prefixLength: 0 ) it 'should assume full match for IpCondition without prefixLength', -> cond = Conditions.fromStr('Ip: 127.0.0.1') cond.should.eql( conditionType: 'IpCondition' ip: '127.0.0.1' prefixLength: 32 ) cond = Conditions.fromStr('Ip: ::1') cond.should.eql( conditionType: 'IpCondition' ip: '::1' prefixLength: 128 ) it 'should provide sensible fallbacks for invalid IpCondition', -> cond = Conditions.fromStr('Ip: 0.0.0.0/-233') cond.should.eql( conditionType: 'IpCondition' ip: '0.0.0.0' prefixLength: 0 ) it 'should encode & decode HostLevelsCondition correctly', -> condition = conditionType: 'HostLevelsCondition' minValue: 4 maxValue: 7 result = Conditions.str(condition) result.should.equal('HostLevels: 4~7') cond = Conditions.fromStr(result) cond.should.eql(condition) it 'should provide sensible fallbacks for HostLevels out of range', -> cond = Conditions.fromStr('HostLevels: A~-1') cond.should.eql( conditionType: 'HostLevelsCondition' minValue: 1 maxValue: 1 ) cond = Conditions.fromStr('HostLevels: nonsense') cond.should.eql( conditionType: 'HostLevelsCondition' minValue: 1 maxValue: 1 ) it 'should encode & decode WeekdayCondition correctly', -> condition = conditionType: 'WeekdayCondition' startDay: 3 endDay: 6 result = Conditions.str(condition) result.should.equal('Weekday: 3~6') cond = Conditions.fromStr(result) cond.should.eql(condition) it 'should provide sensible fallbacks for Weekday out of range', -> cond = Conditions.fromStr('Weekday: -1~100') cond.should.eql( conditionType: 'WeekdayCondition' startDay: 0 endDay: 0 ) cond = Conditions.fromStr('Weekday: nonsense') cond.should.eql( conditionType: 'WeekdayCondition' startDay: 0 endDay: 0 ) it 'should encode & decode WeekdayCondition with days', -> condition = conditionType: 'WeekdayCondition' days: 'SMTWtFs' result = Conditions.str(condition) result.should.equal('Weekday: SMTWtFs') cond = Conditions.fromStr(result) cond.should.eql(condition) condition = conditionType: 'WeekdayCondition' days: 'SM-W-Fs' result = Conditions.str(condition) result.should.equal('Weekday: SM-W-Fs') cond = Conditions.fromStr(result) cond.should.eql(condition) it 'should encode & decode TimeCondition correctly', -> condition = conditionType: 'TimeCondition' startHour: 7 endHour: 23 result = Conditions.str(condition) result.should.equal('Hour: 7~23') cond = Conditions.fromStr(result) cond.should.eql(condition) it 'should provide sensible fallbacks for Hour out of range', -> cond = Conditions.fromStr('Hour: -1~100') cond.should.eql( conditionType: 'TimeCondition' startHour: 0 endHour: 0 ) cond = Conditions.fromStr('Hour: nonsense') cond.should.eql( conditionType: 'TimeCondition' startHour: 0 endHour: 0 ) it 'should parse conditions with extra spaces correctly', -> Conditions.fromStr('url: *abcde* ').should.eql({ conditionType: 'UrlWildcardCondition' pattern: '*abcde*' }) it 'should parse abbreviated condition types correctly', -> Conditions.fromStr('url: *://*.example.com/*').should.eql({ conditionType: 'UrlWildcardCondition' pattern: '*://*.example.com/*' }) it 'should parse escaped HostWildcardCondition starting with colon', -> Conditions.fromStr(': :bogus:').should.eql({ conditionType: 'HostWildcardCondition' pattern: ':bogus:' }) ================================================ FILE: omega-pac/test/pac_generator.coffee ================================================ chai = require 'chai' should = chai.should() describe 'PacGenerator', -> PacGenerator = require '../src/pac_generator.coffee' options = '+auto': name: 'auto' profileType: 'SwitchProfile' revision: 'test' defaultProfileName: 'direct' rules: [ {profileName: 'proxy', condition: conditionType: 'UrlRegexCondition' pattern: '^http://(www|www2)\\.example\\.com/' } {profileName: 'direct', condition: conditionType: 'HostLevelsCondition' minValue: 3 maxValue: 8 } { profileName: 'proxy' condition: {conditionType: 'KeywordCondition', pattern: 'keyword'} } {profileName: 'proxy', condition: conditionType: 'UrlWildcardCondition' pattern: 'https://ssl.example.com/*' } ] '+proxy': name: 'proxy' profileType: 'FixedProfile' revision: 'test' fallbackProxy: {scheme: 'http', host: '127.0.0.1', port: 8888} bypassList: [ {conditionType: 'BypassCondition', pattern: '127.0.0.1:8080'} {conditionType: 'BypassCondition', pattern: '127.0.0.1'} {conditionType: 'BypassCondition', pattern: ''} ] it 'should generate pac scripts from options', -> ast = PacGenerator.script(options, 'auto') pac = ast.print_to_string(beautify: true, comments: true) pac.should.not.be.empty func = eval("(function () { #{pac}\n return FindProxyForURL; })()") result = func('http://www.example.com/', 'www.example.com') result.should.equal('PROXY 127.0.0.1:8888') it 'should be able to compress pac scripts', -> ast = PacGenerator.script(options, 'auto') pac = PacGenerator.compress(ast).print_to_string() pac.should.not.be.empty func = eval("(function () { #{pac}\n return FindProxyForURL; })()") result = func('http://www.example.com/', 'www.example.com') result.should.equal('PROXY 127.0.0.1:8888') ================================================ FILE: omega-pac/test/profiles.coffee ================================================ chai = require 'chai' should = chai.should() describe 'Profiles', -> Profiles = require '../src/profiles' Conditions = require '../src/conditions' U2 = require 'uglify-js' ruleListResult = (profileName, source) -> profileName: profileName source: source testProfile = (profile, request, expected, expectedCompiled) -> o_request = request if typeof request == 'string' request = Conditions.requestFromUrl(request) expectedCompiled ?= expected[0] ? Profiles.nameAsKey(expected.profileName) compiled = Profiles.compile(profile) compileResult = eval '(' + compiled.print_to_string() + ')' if typeof compileResult == 'function' compileResult = compileResult(request.url, request.host, request.scheme) if expected? matchResult = Profiles.match(profile, request) try if expected.source? chai.assert.equal(matchResult.profileName, expected.profileName) chai.assert.equal(matchResult.source, expected.source) else chai.assert.deepEqual(matchResult, expected) catch _ printResult = JSON.stringify(matchResult) msg = ("expect profile to return #{JSON.stringify(expected)} " + "instead of #{printResult} for request #{o_request}") chai.assert(false, msg) if compileResult != expectedCompiled msg = ("expect COMPILED profile to return #{expectedCompiled} " + "instead of #{compileResult} for request #{o_request}") chai.assert(false, msg) return expected describe '#pacResult', -> it 'should return DIRECT for no proxy', -> Profiles.pacResult().should.equal("DIRECT") it 'should return a valid PAC result for a proxy', -> proxy = {scheme: "http", host: "127.0.0.1", port: 8888} Profiles.pacResult(proxy).should.equal("PROXY 127.0.0.1:8888") it 'should return special compatible result for SOCKS5', -> proxy = {scheme: "socks5", host: "127.0.0.1", port: 8888} compatibleResult = "SOCKS5 127.0.0.1:8888; SOCKS 127.0.0.1:8888" Profiles.pacResult(proxy).should.equal(compatibleResult) describe '#byName', -> it 'should get profiles from builtin profiles', -> profile = Profiles.byName('direct') profile.should.be.an('object') profile.profileType.should.equal('DirectProfile') it 'should get profiles from given options', -> profile = {} profile = Profiles.byName('profile', {"+profile": profile}) profile.should.equal(profile) describe '#allReferenceSet', -> profile = Profiles.create('test', 'VirtualProfile') profile.defaultProfileName = 'bogus' it 'should throw if referenced profile does not exist', -> getAllReferenceSet = -> Profiles.allReferenceSet(profile, {}) getAllReferenceSet.should.throw(Error) it 'should process a dumb profile for each missing profile if requested', -> profile.defaultProfileName = 'bogus' refs = Profiles.allReferenceSet profile, {}, profileNotFound: 'dumb' refs['+bogus'].should.equal('bogus') describe 'SystemProfile', -> it 'should be builtin with the name "system"', -> profile = Profiles.byName('system') profile.should.be.an('object') profile.profileType.should.equal('SystemProfile') it 'should not match request to profiles', -> profile = Profiles.byName('system') should.not.exist Profiles.match(profile, {}) it 'should throw when trying to compile', -> profile = Profiles.byName('system') should.throw(-> Profiles.compile(profile)) describe 'DirectProfile', -> it 'should be builtin with the name "direct"', -> profile = Profiles.byName('direct') profile.should.be.an('object') profile.profileType.should.equal('DirectProfile') it 'should return "DIRECT" when compiled', -> profile = Profiles.byName('direct') testProfile(profile, {}, null, 'DIRECT') describe 'FixedProfile', -> profile = profileType: 'FixedProfile' bypassList: [{ conditionType: 'BypassCondition' pattern: '' }] proxyForHttp: scheme: 'socks4' host: '127.0.0.1' port: 1234 proxyForHttps: scheme: 'http' host: '127.0.0.1' port: 2345 fallbackProxy: scheme: 'socks4' host: '127.0.0.1' port: 3456 auth: proxyForHttps: username: 'test' password: 'cheesecake' it 'should use protocol-specific proxies if suitable', -> testProfile(profile, 'https://www.example.com/', ['PROXY 127.0.0.1:2345', 'https', profile.proxyForHttps, profile.auth.proxyForHttps]) it 'should use fallback proxies for other protocols', -> testProfile(profile, 'ftp://www.example.com/', ['SOCKS 127.0.0.1:3456', '', profile.fallbackProxy, undefined]) it 'should not return authentication if not provided for protocol', -> testProfile(profile, 'http://www.example.com/', ['SOCKS 127.0.0.1:1234', 'http', profile.proxyForHttp, undefined]) it 'should not use any proxy for requests matching the bypassList', -> testProfile profile, 'ftp://localhost/', ['DIRECT', profile.bypassList[0], {scheme: 'direct'}, undefined] describe 'PacProfile', -> profile = Profiles.create('test', 'PacProfile') profile.pacScript = ''' function FindProxyForURL(url, host) { return "PROXY " + host + ":8080"; } ''' it 'should return the result of the pac script', -> testProfile(profile, 'ftp://www.example.com:9999/abc', null, 'PROXY www.example.com:8080') it 'should not fail for PAC with trailing comments', -> p = Profiles.create('test', 'PacProfile') p.pacScript = profile.pacScript + ''' // This is a trailing line comment. ''' testProfile(p, 'ftp://www.example.com:9999/abc', null, 'PROXY www.example.com:8080') p = Profiles.create('test', 'PacProfile') p.pacScript = profile.pacScript + ''' /* This is a multiline comment which is not properly closed. ''' testProfile(p, 'ftp://www.example.com:9999/abc', null, 'PROXY www.example.com:8080') it 'should return includable for non-file pacUrl', -> Profiles.isIncludable(profile).should.be.true it 'should return not includable for file: pacUrl', -> p = Profiles.create('test', 'PacProfile') p.pacUrl = 'file:///proxy.pac' Profiles.isIncludable(p).should.be.false describe 'SwitchProfile', -> profile = Profiles.create('test', 'SwitchProfile') profile.rules = [ { condition: conditionType: 'HostWildcardCondition' pattern: 'company.abc.example.com' profileName: 'company' }, { condition: conditionType: 'HostWildcardCondition' pattern: '*.example.com' profileName: 'example' }, { condition: conditionType: 'HostWildcardCondition' pattern: '*.abc.example.com' profileName: 'abc' } ] profile.defaultProfileName = 'default' it 'should match requests based on rules', -> testProfile(profile, 'http://company.abc.example.com:998/abc', profile.rules[0]) it 'should respect the order of rules', -> testProfile(profile, 'http://abc.example.com:9999/abc', profile.rules[1]) testProfile(profile, 'http://www.example.com:9999/abc', profile.rules[1]) it 'should return defaultProfileName when no rules match', -> testProfile(profile, 'http://www.example.org:9999/abc', ['+default', null]) it 'should calulate directly referenced profiles correctly', -> set = Profiles.directReferenceSet(profile) set.should.eql( '+company': 'company' '+example': 'example' '+abc': 'abc' '+default': 'default' ) it 'should clear the reference cache on profile revision change', -> profile.revision = 'a' set = Profiles.directReferenceSet(profile) # Remove 'default' from references. profile.defaultProfileName = 'abc' profile.revision = 'b' newSet = Profiles.directReferenceSet(profile) newSet.should.eql( '+company': 'company' '+example': 'example' '+abc': 'abc' ) it 'should clear the reference cache if explicitly requested', -> profile.revision = 'a' set = Profiles.directReferenceSet(profile) # Remove 'default' from references. profile.defaultProfileName = 'abc' Profiles.dropCache(profile) newSet = Profiles.directReferenceSet(profile) newSet.should.eql( '+company': 'company' '+example': 'example' '+abc': 'abc' ) describe 'VirtualProfile', -> profile = Profiles.create('test', 'VirtualProfile') profile.defaultProfileName = 'default' it 'should always return defaultProfileName', -> testProfile(profile, 'http://www.example.com/abc', ['+default', null]) describe 'RulelistProfile', -> profile = Profiles.create('test', 'AutoProxyRuleListProfile') profile.defaultProfileName = 'default' profile.matchProfileName = 'example' profile.ruleList = 'example.com' profile.revision = 'a' it 'should calulate directly referenced profiles correctly', -> set = Profiles.directReferenceSet(profile) set.should.eql( '+example': 'example' '+default': 'default' ) it 'should calulate referenced profiles for rule list with results', -> set = Profiles.directReferenceSet({ profileType: 'RuleListProfile' format: 'Switchy' matchProfileName: 'ignored' defaultProfileName: 'alsoIgnored' ruleList: ''' [SwitchyOmega Conditions] @with result !*.example.org *.example.com +ABC * +DEF ''' }) set.should.eql( '+ABC': 'ABC' '+DEF': 'DEF' ) it 'should match requests based on the rule list', -> testProfile(profile, 'http://localhost/example.com', ruleListResult('example', 'example.com')) testProfile(profile, 'http://localhost/example.org', ['+default', null]) it 'should update rule list on update', -> Profiles.update(profile, 'example.org') profile.revision = 'b' testProfile(profile, 'http://localhost/example.com', ['+default', null]) testProfile(profile, 'http://localhost/example.org', ruleListResult('example', 'example.org')) it 'should not fail when ruleList is not provided', -> p = profileType: 'RuleListProfile' format: 'Switchy' matchProfileName: 'match' defaultProfileName: 'default' Profiles.directReferenceSet(p).should.be.an 'object' testProfile(p, 'http://localhost/example.com', ['+default', null]) it 'should switch to AutoProxy format on update if detected', -> profile = Profiles.create('test2', 'RuleListProfile') profile.format = 'Switchy' profile.defaultProfileName = 'default' profile.matchProfileName = 'example' profile.format.should.equal 'Switchy' Profiles.update(profile, '[AutoProxy]\nexample.org') profile.format.should.equal 'AutoProxy' testProfile(profile, 'http://localhost/example.com', ['+default', null]) testProfile(profile, 'http://localhost/example.org', ruleListResult('example', 'example.org')) ================================================ FILE: omega-pac/test/rule_list.coffee ================================================ chai = require 'chai' should = chai.should() describe 'RuleList', -> RuleList = require '../src/rule_list' describe 'AutoProxy', -> parse = RuleList['AutoProxy'].parse it 'should parse keyword conditions', -> line = 'example.com' result = parse(line, 'match', 'notmatch') result.should.have.length(1) result[0].should.eql( source: line profileName: 'match' condition: conditionType: 'KeywordCondition' pattern: 'example.com' ) it 'should parse keyword conditions with asterisks', -> line = 'example*.com' result = parse(line, 'match', 'notmatch') result.should.have.length(1) result[0].should.eql( source: line profileName: 'match' condition: conditionType: 'UrlWildcardCondition' pattern: 'http://*example*.com*' ) it 'should parse host conditions', -> line = '||example.com' result = parse(line, 'match', 'notmatch') result.should.have.length(1) result[0].should.eql( source: line profileName: 'match' condition: conditionType: 'HostWildcardCondition' pattern: '*.example.com' ) it 'should parse "starts-with" conditions', -> line = '|https://ssl.example.com' result = parse(line, 'match', 'notmatch') result.should.have.length(1) result[0].should.eql( source: line profileName: 'match' condition: conditionType: 'UrlWildcardCondition' pattern: 'https://ssl.example.com*' ) it 'should parse "starts-with" conditions for the HTTP scheme', -> line = '|http://example.com' result = parse(line, 'match', 'notmatch') result.should.have.length(1) result[0].should.eql( source: line profileName: 'match' condition: conditionType: 'UrlWildcardCondition' pattern: 'http://example.com*' ) it 'should parse url regex conditions', -> line = '/^https?:\\/\\/[^\\/]+example\.com/' result = parse(line, 'match', 'notmatch') result.should.have.length(1) result[0].should.eql( source: line profileName: 'match' condition: conditionType: 'UrlRegexCondition' pattern: '^https?:\\/\\/[^\\/]+example\.com' ) it 'should ignore comment lines', -> result = parse('!example.com', 'match', 'notmatch') result.should.have.length(0) it 'should parse multiple lines', -> result = parse 'example.com\n!comment\n||example.com', 'match', 'notmatch' result.should.have.length(2) result[0].should.eql( source: 'example.com' profileName: 'match' condition: conditionType: 'KeywordCondition' pattern: 'example.com' ) result[1].should.eql( source: '||example.com' profileName: 'match' condition: conditionType: 'HostWildcardCondition' pattern: '*.example.com' ) it 'should put exclusive rules first', -> result = parse 'example.com\n@@||example.com', 'match', 'notmatch' result.should.have.length(2) result[0].should.eql( source: '@@||example.com' profileName: 'notmatch' condition: conditionType: 'HostWildcardCondition' pattern: '*.example.com' ) result[1].should.eql( source: 'example.com' profileName: 'match' condition: conditionType: 'KeywordCondition' pattern: 'example.com' ) describe 'Switchy', -> parse = RuleList['Switchy'].parse compose = (sections) -> list = '#BEGIN\r\n\r\n' for sec, rules of sections list += "[#{sec}]\r\n" for rule in rules list += rule list += '\r\n' list += '\r\n\r\n#END\r\n' it 'should parse empty rule lists', -> list = compose {} result = parse(list, 'match', 'notmatch') result.should.have.length(0) it 'should ignore stuff before #BEGIN or after #END.', -> list = compose {} list += '[RegExp]\r\ntest\r\n' list = '[Wildcard]\r\ntest\r\n' + list result = parse(list, 'match', 'notmatch') result.should.have.length(0) it 'should parse wildcard rules', -> list = compose 'Wildcard': [ '*://example.com/abc/*' ] result = parse(list, 'match', 'notmatch') result.should.have.length(1) result[0].should.eql( source: '*://example.com/abc/*' profileName: 'match' condition: conditionType: 'UrlWildcardCondition' pattern: '*://example.com/abc/*' ) it 'should parse RegExp rules', -> list = compose 'RegExp': [ '^http://www\.example\.com/.*' ] result = parse(list, 'match', 'notmatch') result.should.have.length(1) result[0].should.eql( source: '^http://www\.example\.com/.*' profileName: 'match' condition: conditionType: 'UrlRegexCondition' pattern: '^http://www\.example\.com/.*' ) it 'should parse exclusive rules', -> list = compose 'RegExp': [ '!^http://www\.example\.com/.*' ] result = parse(list, 'match', 'notmatch') result.should.have.length(1) result[0].should.eql( source: '!^http://www\.example\.com/.*' profileName: 'notmatch' condition: conditionType: 'UrlRegexCondition' pattern: '^http://www\.example\.com/.*' ) it 'should parse multiple rules in multiple sections', -> list = compose { 'Wildcard': [ 'http://www.example.com/*' 'http://example.com/*' ] 'RegExp': [ '^http://www\.example\.com/.*' '^http://example\.com/.*' ] } result = parse(list, 'match', 'notmatch') result.should.have.length(4) result[0].should.eql( source: 'http://www.example.com/*' profileName: 'match' condition: conditionType: 'UrlWildcardCondition' pattern: 'http://www.example.com/*' ) result[1].should.eql( source: 'http://example.com/*' profileName: 'match' condition: conditionType: 'UrlWildcardCondition' pattern: 'http://example.com/*' ) result[2].should.eql( source: '^http://www\.example\.com/.*' profileName: 'match' condition: conditionType: 'UrlRegexCondition' pattern: '^http://www\.example\.com/.*' ) result[3].should.eql( source: '^http://example\.com/.*' profileName: 'match' condition: conditionType: 'UrlRegexCondition' pattern: '^http://example\.com/.*' ) it 'should put exclusive rules first', -> list = compose { 'Wildcard': [ 'http://www\.example\.com/*' ] 'RegExp': [ '!^http://www\.example\.com/.*' ] } result = parse(list, 'match', 'notmatch') result.should.have.length(2) result[0].should.eql( source: '!^http://www\.example\.com/.*' profileName: 'notmatch' condition: conditionType: 'UrlRegexCondition' pattern: '^http://www.example\.com/.*' ) result[1].should.eql( source: 'http://www\.example\.com/*' profileName: 'match' condition: conditionType: 'UrlWildcardCondition' pattern: 'http://www.example.com/*' ) describe 'Switchy (omega format)', -> parse = RuleList['Switchy'].parse compose = RuleList['Switchy'].compose it 'should parse empty rule lists', -> list = compose {rules: []} result = parse(list, 'match', 'notmatch') result.should.have.length(0) it 'should ignore comment lines.', -> list = compose {rules: []} list += ';*.example.com \r\n' result = parse(list, 'match', 'notmatch') result.should.have.length(0) it 'should compose and parse HostWildcardCondition', -> rule = source: '*.example.com' condition: conditionType: 'HostWildcardCondition', pattern: '*.example.com' profileName: 'match' list = compose({rules: [rule], defaultProfileName: 'notmatch'}) result = parse(list, 'match', 'notmatch') result.should.have.length(1) result[0].should.eql(rule) it 'should compose and parse HostRegexCondition', -> rule = source: 'HostRegex: ^http://www\.example\.com/.*' condition: conditionType: 'HostRegexCondition', pattern: '^http://www\.example\.com/.*' profileName: 'match' list = compose({rules: [rule], defaultProfileName: 'notmatch'}) result = parse(list, 'match', 'notmatch') result.should.have.length(1) result[0].should.eql(rule) it 'should compose and parse disabled rules', -> rule = source: 'Disabled: *.example.com' condition: conditionType: 'FalseCondition', pattern: '*.example.com' profileName: 'match' list = compose({rules: [rule], defaultProfileName: 'notmatch'}) result = parse(list, 'match', 'notmatch') result.should.have.length(1) result[0].should.eql(rule) it 'should compose and parse exclusive rules', -> rule = source: '!*.example.com' condition: conditionType: 'HostWildcardCondition', pattern: '*.example.com' profileName: 'notmatch' list = compose({rules: [rule], defaultProfileName: 'notmatch'}) result = parse(list, 'match', 'notmatch') result.should.have.length(1) result[0].should.eql(rule) it 'should compose and parse conditions starting with special chars', -> rule = source: ': ;abc' condition: conditionType: 'HostWildcardCondition', pattern: ';abc' profileName: 'match' list = compose({rules: [rule], defaultProfileName: 'notmatch'}) result = parse(list, 'match', 'notmatch') result.should.have.length(1) result[0].should.eql(rule) it 'should parse multiple conditions', -> rules = [{ source: '*.example.com' condition: conditionType: 'HostWildcardCondition', pattern: '*.example.com' profileName: 'match' }, { source: '*.example.org' condition: conditionType: 'HostWildcardCondition', pattern: '*.example.org' profileName: 'match' }] list = compose({rules: rules, defaultProfileName: 'notmatch'}) result = parse(list, 'match', 'notmatch') result.should.eql(rules) it 'should respect the top-down order of conditions', -> rules = [{ source: 'b.example.com' condition: conditionType: 'HostWildcardCondition', pattern: 'b.example.com' profileName: 'match' }, { source: '!a.example.org' condition: conditionType: 'HostWildcardCondition', pattern: 'a.example.org' profileName: 'notmatch' }] list = compose({rules: rules, defaultProfileName: 'notmatch'}) result = parse(list, 'match', 'notmatch') result.should.eql(rules) it 'should add a default rule when results are enabled', -> list = compose( {rules: [], defaultProfileName: 'notmatch'} {withResult: true} ) list.split(/\r|\n/).should.contain('@with result') result = parse(list, 'ignored', 'alsoIgnored') result.should.have.length(1) result[0].should.eql({ source: '*' condition: conditionType: 'HostWildcardCondition', pattern: '*' profileName: 'notmatch', }) it 'should compose and parse conditions with results', -> rules = [{ source: 'b.example.com' condition: conditionType: 'HostWildcardCondition', pattern: 'b.example.com' profileName: 'abc' }, { source: 'a.example.org' condition: conditionType: 'HostWildcardCondition', pattern: 'a.example.org' profileName: 'def' }] list = compose( {rules: rules, defaultProfileName: 'ghi'} {withResult: true} ) result = parse(list, 'ignored', 'alsoIgnored') rules.push({ source: '*' condition: conditionType: 'HostWildcardCondition', pattern: '*' profileName: 'ghi', }) result.should.eql(rules) it 'should compose and parse exclusive conditions with results', -> rules = [{ source: '!b.example.com' condition: conditionType: 'HostWildcardCondition', pattern: 'b.example.com' profileName: 'default profile' }, { source: 'a.example.org' condition: conditionType: 'HostWildcardCondition', pattern: 'a.example.org' profileName: 'some profile' }] list = compose( {rules: rules, defaultProfileName: 'default profile'} {withResult: true, useExclusive: true} ) result = parse(list, 'ignored', 'alsoIgnored') rules.push({ source: '*' condition: conditionType: 'HostWildcardCondition', pattern: '*' profileName: 'default profile', }) result.should.eql(rules) ================================================ FILE: omega-pac/test/shexp_utils.coffee ================================================ chai = require 'chai' should = chai.should() describe 'ShexpUtils', -> ShexpUtils = require '../src/shexp_utils' describe '#escapeSlash', -> it 'should escape all forward slashes', -> regex = ShexpUtils.escapeSlash '/test/' regex.should.equal '\\/test\\/' it 'should not escape slashes that are already escaped', -> regex = ShexpUtils.escapeSlash '\\/test\\/' regex.should.equal '\\/test\\/' it 'should know the difference between escaped and unescaped slashes', -> regex = ShexpUtils.escapeSlash '\\\\/\\/test\\/' regex.should.equal '\\\\\\/\\/test\\/' describe '#shExp2RegExp', -> it 'should escape regex meta chars and back slashes', -> regex = ShexpUtils.shExp2RegExp 'this.is|a\\test+' regex.should.equal '^this\\.is\\|a\\\\test\\+$' ================================================ FILE: omega-pac/test/utils.coffee ================================================ chai = require 'chai' should = chai.should() Utils = require '../src/utils' describe 'getBaseDomain', -> {getBaseDomain} = Utils it 'should return domains with zero level unchanged', -> getBaseDomain('someinternaldomain').should.equal('someinternaldomain') it 'should return domains with one level unchanged', -> getBaseDomain('example.com').should.equal('example.com') getBaseDomain('e.test').should.equal('e.test') getBaseDomain('a.b').should.equal('a.b') it 'should treat two-segment TLD as one component', -> getBaseDomain('images.google.co.uk').should.equal('google.co.uk') getBaseDomain('images.google.co.jp').should.equal('google.co.jp') getBaseDomain('example.com.cn').should.equal('example.com.cn') it 'should not mistake short domains with two-segment TLDs', -> getBaseDomain('a.bc.com').should.equal('bc.com') getBaseDomain('i.t.co').should.equal('t.co') it 'should not try to modify IP address literals', -> getBaseDomain('127.0.0.1').should.equal('127.0.0.1') getBaseDomain('[::1]').should.equal('[::1]') getBaseDomain('::f').should.equal('::f') ================================================ FILE: omega-pac/uglifyjs-shim.js ================================================ require('uglify-js-real'); module.exports = UglifyJS; ================================================ FILE: omega-pac/uglifyjs.js ================================================ (function(exports, global) { global["UglifyJS"] = exports; "use strict"; function array_to_hash(a) { var ret = Object.create(null); for (var i = 0; i < a.length; ++i) ret[a[i]] = true; return ret; } function slice(a, start) { return Array.prototype.slice.call(a, start || 0); } function characters(str) { return str.split(""); } function member(name, array) { for (var i = array.length; --i >= 0; ) if (array[i] == name) return true; return false; } function find_if(func, array) { for (var i = 0, n = array.length; i < n; ++i) { if (func(array[i])) return array[i]; } } function repeat_string(str, i) { if (i <= 0) return ""; if (i == 1) return str; var d = repeat_string(str, i >> 1); d += d; if (i & 1) d += str; return d; } function DefaultsError(msg, defs) { Error.call(this, msg); this.msg = msg; this.defs = defs; } DefaultsError.prototype = Object.create(Error.prototype); DefaultsError.prototype.constructor = DefaultsError; DefaultsError.croak = function(msg, defs) { throw new DefaultsError(msg, defs); }; function defaults(args, defs, croak) { if (args === true) args = {}; var ret = args || {}; if (croak) for (var i in ret) if (ret.hasOwnProperty(i) && !defs.hasOwnProperty(i)) DefaultsError.croak("`" + i + "` is not a supported option", defs); for (var i in defs) if (defs.hasOwnProperty(i)) { ret[i] = args && args.hasOwnProperty(i) ? args[i] : defs[i]; } return ret; } function merge(obj, ext) { for (var i in ext) if (ext.hasOwnProperty(i)) { obj[i] = ext[i]; } return obj; } function noop() {} var MAP = function() { function MAP(a, f, backwards) { var ret = [], top = [], i; function doit() { var val = f(a[i], i); var is_last = val instanceof Last; if (is_last) val = val.v; if (val instanceof AtTop) { val = val.v; if (val instanceof Splice) { top.push.apply(top, backwards ? val.v.slice().reverse() : val.v); } else { top.push(val); } } else if (val !== skip) { if (val instanceof Splice) { ret.push.apply(ret, backwards ? val.v.slice().reverse() : val.v); } else { ret.push(val); } } return is_last; } if (a instanceof Array) { if (backwards) { for (i = a.length; --i >= 0; ) if (doit()) break; ret.reverse(); top.reverse(); } else { for (i = 0; i < a.length; ++i) if (doit()) break; } } else { for (i in a) if (a.hasOwnProperty(i)) if (doit()) break; } return top.concat(ret); } MAP.at_top = function(val) { return new AtTop(val); }; MAP.splice = function(val) { return new Splice(val); }; MAP.last = function(val) { return new Last(val); }; var skip = MAP.skip = {}; function AtTop(val) { this.v = val; } function Splice(val) { this.v = val; } function Last(val) { this.v = val; } return MAP; }(); function push_uniq(array, el) { if (array.indexOf(el) < 0) array.push(el); } function string_template(text, props) { return text.replace(/\{(.+?)\}/g, function(str, p) { return props[p]; }); } function remove(array, el) { for (var i = array.length; --i >= 0; ) { if (array[i] === el) array.splice(i, 1); } } function mergeSort(array, cmp) { if (array.length < 2) return array.slice(); function merge(a, b) { var r = [], ai = 0, bi = 0, i = 0; while (ai < a.length && bi < b.length) { cmp(a[ai], b[bi]) <= 0 ? r[i++] = a[ai++] : r[i++] = b[bi++]; } if (ai < a.length) r.push.apply(r, a.slice(ai)); if (bi < b.length) r.push.apply(r, b.slice(bi)); return r; } function _ms(a) { if (a.length <= 1) return a; var m = Math.floor(a.length / 2), left = a.slice(0, m), right = a.slice(m); left = _ms(left); right = _ms(right); return merge(left, right); } return _ms(array); } function set_difference(a, b) { return a.filter(function(el) { return b.indexOf(el) < 0; }); } function set_intersection(a, b) { return a.filter(function(el) { return b.indexOf(el) >= 0; }); } function makePredicate(words) { if (!(words instanceof Array)) words = words.split(" "); if (typeof UglifyJS_NoUnsafeEval !== "undefined") { return function(str) { return words.indexOf(str) >= 0; }; } var f = "", cats = []; out: for (var i = 0; i < words.length; ++i) { for (var j = 0; j < cats.length; ++j) if (cats[j][0].length == words[i].length) { cats[j].push(words[i]); continue out; } cats.push([ words[i] ]); } function compareTo(arr) { if (arr.length == 1) return f += "return str === " + JSON.stringify(arr[0]) + ";"; f += "switch(str){"; for (var i = 0; i < arr.length; ++i) f += "case " + JSON.stringify(arr[i]) + ":"; f += "return true}return false;"; } if (cats.length > 3) { cats.sort(function(a, b) { return b.length - a.length; }); f += "switch(str.length){"; for (var i = 0; i < cats.length; ++i) { var cat = cats[i]; f += "case " + cat[0].length + ":"; compareTo(cat); } f += "}"; } else { compareTo(words); } return new Function("str", f); } function all(array, predicate) { for (var i = array.length; --i >= 0; ) if (!predicate(array[i])) return false; return true; } function Dictionary() { this._values = Object.create(null); this._size = 0; } Dictionary.prototype = { set: function(key, val) { if (!this.has(key)) ++this._size; this._values["$" + key] = val; return this; }, add: function(key, val) { if (this.has(key)) { this.get(key).push(val); } else { this.set(key, [ val ]); } return this; }, get: function(key) { return this._values["$" + key]; }, del: function(key) { if (this.has(key)) { --this._size; delete this._values["$" + key]; } return this; }, has: function(key) { return "$" + key in this._values; }, each: function(f) { for (var i in this._values) f(this._values[i], i.substr(1)); }, size: function() { return this._size; }, map: function(f) { var ret = []; for (var i in this._values) ret.push(f(this._values[i], i.substr(1))); return ret; } }; "use strict"; function DEFNODE(type, props, methods, base) { if (arguments.length < 4) base = AST_Node; if (!props) props = []; else props = props.split(/\s+/); var self_props = props; if (base && base.PROPS) props = props.concat(base.PROPS); var proto = base && new base(); var ctor; if (typeof UglifyJS_NoUnsafeEval === "undefined") { var code = "return function AST_" + type + "(props){ if (props) { "; for (var i = props.length; --i >= 0; ) { code += "this." + props[i] + " = props." + props[i] + ";"; } if (proto && proto.initialize || methods && methods.initialize) code += "this.initialize();"; code += "}}"; ctor = new Function(code)(); } else { ctor = function(values) { if (values) { for (var i = props.length; --i >= 0; ) this[props[i]] = values[props[i]]; if (proto && proto.initialize || methods && methods.initialize) this.initialize(); } }; } if (proto) { ctor.prototype = proto; ctor.BASE = base; } if (base) base.SUBCLASSES.push(ctor); ctor.prototype.CTOR = ctor; ctor.PROPS = props || null; ctor.SELF_PROPS = self_props; ctor.SUBCLASSES = []; if (type) { ctor.prototype.TYPE = ctor.TYPE = type; } if (methods) for (i in methods) if (methods.hasOwnProperty(i)) { if (/^\$/.test(i)) { ctor[i.substr(1)] = methods[i]; } else { ctor.prototype[i] = methods[i]; } } ctor.DEFMETHOD = function(name, method) { this.prototype[name] = method; }; return ctor; } var AST_Token = DEFNODE("Token", "type value line col pos endpos nlb comments_before file", {}, null); var AST_Node = DEFNODE("Node", "start end", { clone: function() { return new this.CTOR(this); }, $documentation: "Base class of all AST nodes", $propdoc: { start: "[AST_Token] The first token of this node", end: "[AST_Token] The last token of this node" }, _walk: function(visitor) { return visitor._visit(this); }, walk: function(visitor) { return this._walk(visitor); } }, null); AST_Node.warn_function = null; AST_Node.warn = function(txt, props) { if (AST_Node.warn_function) AST_Node.warn_function(string_template(txt, props)); }; var AST_Statement = DEFNODE("Statement", null, { $documentation: "Base class of all statements" }); var AST_Debugger = DEFNODE("Debugger", null, { $documentation: "Represents a debugger statement" }, AST_Statement); var AST_Directive = DEFNODE("Directive", "value scope", { $documentation: 'Represents a directive, like "use strict";', $propdoc: { value: "[string] The value of this directive as a plain string (it's not an AST_String!)", scope: "[AST_Scope/S] The scope that this directive affects" } }, AST_Statement); var AST_SimpleStatement = DEFNODE("SimpleStatement", "body", { $documentation: "A statement consisting of an expression, i.e. a = 1 + 2", $propdoc: { body: "[AST_Node] an expression node (should not be instanceof AST_Statement)" }, _walk: function(visitor) { return visitor._visit(this, function() { this.body._walk(visitor); }); } }, AST_Statement); function walk_body(node, visitor) { if (node.body instanceof AST_Statement) { node.body._walk(visitor); } else node.body.forEach(function(stat) { stat._walk(visitor); }); } var AST_Block = DEFNODE("Block", "body", { $documentation: "A body of statements (usually bracketed)", $propdoc: { body: "[AST_Statement*] an array of statements" }, _walk: function(visitor) { return visitor._visit(this, function() { walk_body(this, visitor); }); } }, AST_Statement); var AST_BlockStatement = DEFNODE("BlockStatement", null, { $documentation: "A block statement" }, AST_Block); var AST_EmptyStatement = DEFNODE("EmptyStatement", null, { $documentation: "The empty statement (empty block or simply a semicolon)", _walk: function(visitor) { return visitor._visit(this); } }, AST_Statement); var AST_StatementWithBody = DEFNODE("StatementWithBody", "body", { $documentation: "Base class for all statements that contain one nested body: `For`, `ForIn`, `Do`, `While`, `With`", $propdoc: { body: "[AST_Statement] the body; this should always be present, even if it's an AST_EmptyStatement" }, _walk: function(visitor) { return visitor._visit(this, function() { this.body._walk(visitor); }); } }, AST_Statement); var AST_LabeledStatement = DEFNODE("LabeledStatement", "label", { $documentation: "Statement with a label", $propdoc: { label: "[AST_Label] a label definition" }, _walk: function(visitor) { return visitor._visit(this, function() { this.label._walk(visitor); this.body._walk(visitor); }); } }, AST_StatementWithBody); var AST_IterationStatement = DEFNODE("IterationStatement", null, { $documentation: "Internal class. All loops inherit from it." }, AST_StatementWithBody); var AST_DWLoop = DEFNODE("DWLoop", "condition", { $documentation: "Base class for do/while statements", $propdoc: { condition: "[AST_Node] the loop condition. Should not be instanceof AST_Statement" }, _walk: function(visitor) { return visitor._visit(this, function() { this.condition._walk(visitor); this.body._walk(visitor); }); } }, AST_IterationStatement); var AST_Do = DEFNODE("Do", null, { $documentation: "A `do` statement" }, AST_DWLoop); var AST_While = DEFNODE("While", null, { $documentation: "A `while` statement" }, AST_DWLoop); var AST_For = DEFNODE("For", "init condition step", { $documentation: "A `for` statement", $propdoc: { init: "[AST_Node?] the `for` initialization code, or null if empty", condition: "[AST_Node?] the `for` termination clause, or null if empty", step: "[AST_Node?] the `for` update clause, or null if empty" }, _walk: function(visitor) { return visitor._visit(this, function() { if (this.init) this.init._walk(visitor); if (this.condition) this.condition._walk(visitor); if (this.step) this.step._walk(visitor); this.body._walk(visitor); }); } }, AST_IterationStatement); var AST_ForIn = DEFNODE("ForIn", "init name object", { $documentation: "A `for ... in` statement", $propdoc: { init: "[AST_Node] the `for/in` initialization code", name: "[AST_SymbolRef?] the loop variable, only if `init` is AST_Var", object: "[AST_Node] the object that we're looping through" }, _walk: function(visitor) { return visitor._visit(this, function() { this.init._walk(visitor); this.object._walk(visitor); this.body._walk(visitor); }); } }, AST_IterationStatement); var AST_With = DEFNODE("With", "expression", { $documentation: "A `with` statement", $propdoc: { expression: "[AST_Node] the `with` expression" }, _walk: function(visitor) { return visitor._visit(this, function() { this.expression._walk(visitor); this.body._walk(visitor); }); } }, AST_StatementWithBody); var AST_Scope = DEFNODE("Scope", "directives variables functions uses_with uses_eval parent_scope enclosed cname", { $documentation: "Base class for all statements introducing a lexical scope", $propdoc: { directives: "[string*/S] an array of directives declared in this scope", variables: "[Object/S] a map of name -> SymbolDef for all variables/functions defined in this scope", functions: "[Object/S] like `variables`, but only lists function declarations", uses_with: "[boolean/S] tells whether this scope uses the `with` statement", uses_eval: "[boolean/S] tells whether this scope contains a direct call to the global `eval`", parent_scope: "[AST_Scope?/S] link to the parent scope", enclosed: "[SymbolDef*/S] a list of all symbol definitions that are accessed from this scope or any subscopes", cname: "[integer/S] current index for mangling variables (used internally by the mangler)" } }, AST_Block); var AST_Toplevel = DEFNODE("Toplevel", "globals", { $documentation: "The toplevel scope", $propdoc: { globals: "[Object/S] a map of name -> SymbolDef for all undeclared names" }, wrap_enclose: function(arg_parameter_pairs) { var self = this; var args = []; var parameters = []; arg_parameter_pairs.forEach(function(pair) { var splitAt = pair.lastIndexOf(":"); args.push(pair.substr(0, splitAt)); parameters.push(pair.substr(splitAt + 1)); }); var wrapped_tl = "(function(" + parameters.join(",") + "){ '$ORIG'; })(" + args.join(",") + ")"; wrapped_tl = parse(wrapped_tl); wrapped_tl = wrapped_tl.transform(new TreeTransformer(function before(node) { if (node instanceof AST_Directive && node.value == "$ORIG") { return MAP.splice(self.body); } })); return wrapped_tl; }, wrap_commonjs: function(name, export_all) { var self = this; var to_export = []; if (export_all) { self.figure_out_scope(); self.walk(new TreeWalker(function(node) { if (node instanceof AST_SymbolDeclaration && node.definition().global) { if (!find_if(function(n) { return n.name == node.name; }, to_export)) to_export.push(node); } })); } var wrapped_tl = "(function(exports, global){ global['" + name + "'] = exports; '$ORIG'; '$EXPORTS'; }({}, (function(){return this}())))"; wrapped_tl = parse(wrapped_tl); wrapped_tl = wrapped_tl.transform(new TreeTransformer(function before(node) { if (node instanceof AST_SimpleStatement) { node = node.body; if (node instanceof AST_String) switch (node.getValue()) { case "$ORIG": return MAP.splice(self.body); case "$EXPORTS": var body = []; to_export.forEach(function(sym) { body.push(new AST_SimpleStatement({ body: new AST_Assign({ left: new AST_Sub({ expression: new AST_SymbolRef({ name: "exports" }), property: new AST_String({ value: sym.name }) }), operator: "=", right: new AST_SymbolRef(sym) }) })); }); return MAP.splice(body); } } })); return wrapped_tl; } }, AST_Scope); var AST_Lambda = DEFNODE("Lambda", "name argnames uses_arguments", { $documentation: "Base class for functions", $propdoc: { name: "[AST_SymbolDeclaration?] the name of this function", argnames: "[AST_SymbolFunarg*] array of function arguments", uses_arguments: "[boolean/S] tells whether this function accesses the arguments array" }, _walk: function(visitor) { return visitor._visit(this, function() { if (this.name) this.name._walk(visitor); this.argnames.forEach(function(arg) { arg._walk(visitor); }); walk_body(this, visitor); }); } }, AST_Scope); var AST_Accessor = DEFNODE("Accessor", null, { $documentation: "A setter/getter function. The `name` property is always null." }, AST_Lambda); var AST_Function = DEFNODE("Function", null, { $documentation: "A function expression" }, AST_Lambda); var AST_Defun = DEFNODE("Defun", null, { $documentation: "A function definition" }, AST_Lambda); var AST_Jump = DEFNODE("Jump", null, { $documentation: "Base class for “jumps” (for now that's `return`, `throw`, `break` and `continue`)" }, AST_Statement); var AST_Exit = DEFNODE("Exit", "value", { $documentation: "Base class for “exits” (`return` and `throw`)", $propdoc: { value: "[AST_Node?] the value returned or thrown by this statement; could be null for AST_Return" }, _walk: function(visitor) { return visitor._visit(this, this.value && function() { this.value._walk(visitor); }); } }, AST_Jump); var AST_Return = DEFNODE("Return", null, { $documentation: "A `return` statement" }, AST_Exit); var AST_Throw = DEFNODE("Throw", null, { $documentation: "A `throw` statement" }, AST_Exit); var AST_LoopControl = DEFNODE("LoopControl", "label", { $documentation: "Base class for loop control statements (`break` and `continue`)", $propdoc: { label: "[AST_LabelRef?] the label, or null if none" }, _walk: function(visitor) { return visitor._visit(this, this.label && function() { this.label._walk(visitor); }); } }, AST_Jump); var AST_Break = DEFNODE("Break", null, { $documentation: "A `break` statement" }, AST_LoopControl); var AST_Continue = DEFNODE("Continue", null, { $documentation: "A `continue` statement" }, AST_LoopControl); var AST_If = DEFNODE("If", "condition alternative", { $documentation: "A `if` statement", $propdoc: { condition: "[AST_Node] the `if` condition", alternative: "[AST_Statement?] the `else` part, or null if not present" }, _walk: function(visitor) { return visitor._visit(this, function() { this.condition._walk(visitor); this.body._walk(visitor); if (this.alternative) this.alternative._walk(visitor); }); } }, AST_StatementWithBody); var AST_Switch = DEFNODE("Switch", "expression", { $documentation: "A `switch` statement", $propdoc: { expression: "[AST_Node] the `switch` “discriminant”" }, _walk: function(visitor) { return visitor._visit(this, function() { this.expression._walk(visitor); walk_body(this, visitor); }); } }, AST_Block); var AST_SwitchBranch = DEFNODE("SwitchBranch", null, { $documentation: "Base class for `switch` branches" }, AST_Block); var AST_Default = DEFNODE("Default", null, { $documentation: "A `default` switch branch" }, AST_SwitchBranch); var AST_Case = DEFNODE("Case", "expression", { $documentation: "A `case` switch branch", $propdoc: { expression: "[AST_Node] the `case` expression" }, _walk: function(visitor) { return visitor._visit(this, function() { this.expression._walk(visitor); walk_body(this, visitor); }); } }, AST_SwitchBranch); var AST_Try = DEFNODE("Try", "bcatch bfinally", { $documentation: "A `try` statement", $propdoc: { bcatch: "[AST_Catch?] the catch block, or null if not present", bfinally: "[AST_Finally?] the finally block, or null if not present" }, _walk: function(visitor) { return visitor._visit(this, function() { walk_body(this, visitor); if (this.bcatch) this.bcatch._walk(visitor); if (this.bfinally) this.bfinally._walk(visitor); }); } }, AST_Block); var AST_Catch = DEFNODE("Catch", "argname", { $documentation: "A `catch` node; only makes sense as part of a `try` statement", $propdoc: { argname: "[AST_SymbolCatch] symbol for the exception" }, _walk: function(visitor) { return visitor._visit(this, function() { this.argname._walk(visitor); walk_body(this, visitor); }); } }, AST_Block); var AST_Finally = DEFNODE("Finally", null, { $documentation: "A `finally` node; only makes sense as part of a `try` statement" }, AST_Block); var AST_Definitions = DEFNODE("Definitions", "definitions", { $documentation: "Base class for `var` or `const` nodes (variable declarations/initializations)", $propdoc: { definitions: "[AST_VarDef*] array of variable definitions" }, _walk: function(visitor) { return visitor._visit(this, function() { this.definitions.forEach(function(def) { def._walk(visitor); }); }); } }, AST_Statement); var AST_Var = DEFNODE("Var", null, { $documentation: "A `var` statement" }, AST_Definitions); var AST_Const = DEFNODE("Const", null, { $documentation: "A `const` statement" }, AST_Definitions); var AST_VarDef = DEFNODE("VarDef", "name value", { $documentation: "A variable declaration; only appears in a AST_Definitions node", $propdoc: { name: "[AST_SymbolVar|AST_SymbolConst] name of the variable", value: "[AST_Node?] initializer, or null of there's no initializer" }, _walk: function(visitor) { return visitor._visit(this, function() { this.name._walk(visitor); if (this.value) this.value._walk(visitor); }); } }); var AST_Call = DEFNODE("Call", "expression args", { $documentation: "A function call expression", $propdoc: { expression: "[AST_Node] expression to invoke as function", args: "[AST_Node*] array of arguments" }, _walk: function(visitor) { return visitor._visit(this, function() { this.expression._walk(visitor); this.args.forEach(function(arg) { arg._walk(visitor); }); }); } }); var AST_New = DEFNODE("New", null, { $documentation: "An object instantiation. Derives from a function call since it has exactly the same properties" }, AST_Call); var AST_Seq = DEFNODE("Seq", "car cdr", { $documentation: "A sequence expression (two comma-separated expressions)", $propdoc: { car: "[AST_Node] first element in sequence", cdr: "[AST_Node] second element in sequence" }, $cons: function(x, y) { var seq = new AST_Seq(x); seq.car = x; seq.cdr = y; return seq; }, $from_array: function(array) { if (array.length == 0) return null; if (array.length == 1) return array[0].clone(); var list = null; for (var i = array.length; --i >= 0; ) { list = AST_Seq.cons(array[i], list); } var p = list; while (p) { if (p.cdr && !p.cdr.cdr) { p.cdr = p.cdr.car; break; } p = p.cdr; } return list; }, to_array: function() { var p = this, a = []; while (p) { a.push(p.car); if (p.cdr && !(p.cdr instanceof AST_Seq)) { a.push(p.cdr); break; } p = p.cdr; } return a; }, add: function(node) { var p = this; while (p) { if (!(p.cdr instanceof AST_Seq)) { var cell = AST_Seq.cons(p.cdr, node); return p.cdr = cell; } p = p.cdr; } }, _walk: function(visitor) { return visitor._visit(this, function() { this.car._walk(visitor); if (this.cdr) this.cdr._walk(visitor); }); } }); var AST_PropAccess = DEFNODE("PropAccess", "expression property", { $documentation: 'Base class for property access expressions, i.e. `a.foo` or `a["foo"]`', $propdoc: { expression: "[AST_Node] the “container” expression", property: "[AST_Node|string] the property to access. For AST_Dot this is always a plain string, while for AST_Sub it's an arbitrary AST_Node" } }); var AST_Dot = DEFNODE("Dot", null, { $documentation: "A dotted property access expression", _walk: function(visitor) { return visitor._visit(this, function() { this.expression._walk(visitor); }); } }, AST_PropAccess); var AST_Sub = DEFNODE("Sub", null, { $documentation: 'Index-style property access, i.e. `a["foo"]`', _walk: function(visitor) { return visitor._visit(this, function() { this.expression._walk(visitor); this.property._walk(visitor); }); } }, AST_PropAccess); var AST_Unary = DEFNODE("Unary", "operator expression", { $documentation: "Base class for unary expressions", $propdoc: { operator: "[string] the operator", expression: "[AST_Node] expression that this unary operator applies to" }, _walk: function(visitor) { return visitor._visit(this, function() { this.expression._walk(visitor); }); } }); var AST_UnaryPrefix = DEFNODE("UnaryPrefix", null, { $documentation: "Unary prefix expression, i.e. `typeof i` or `++i`" }, AST_Unary); var AST_UnaryPostfix = DEFNODE("UnaryPostfix", null, { $documentation: "Unary postfix expression, i.e. `i++`" }, AST_Unary); var AST_Binary = DEFNODE("Binary", "left operator right", { $documentation: "Binary expression, i.e. `a + b`", $propdoc: { left: "[AST_Node] left-hand side expression", operator: "[string] the operator", right: "[AST_Node] right-hand side expression" }, _walk: function(visitor) { return visitor._visit(this, function() { this.left._walk(visitor); this.right._walk(visitor); }); } }); var AST_Conditional = DEFNODE("Conditional", "condition consequent alternative", { $documentation: "Conditional expression using the ternary operator, i.e. `a ? b : c`", $propdoc: { condition: "[AST_Node]", consequent: "[AST_Node]", alternative: "[AST_Node]" }, _walk: function(visitor) { return visitor._visit(this, function() { this.condition._walk(visitor); this.consequent._walk(visitor); this.alternative._walk(visitor); }); } }); var AST_Assign = DEFNODE("Assign", null, { $documentation: "An assignment expression — `a = b + 5`" }, AST_Binary); var AST_Array = DEFNODE("Array", "elements", { $documentation: "An array literal", $propdoc: { elements: "[AST_Node*] array of elements" }, _walk: function(visitor) { return visitor._visit(this, function() { this.elements.forEach(function(el) { el._walk(visitor); }); }); } }); var AST_Object = DEFNODE("Object", "properties", { $documentation: "An object literal", $propdoc: { properties: "[AST_ObjectProperty*] array of properties" }, _walk: function(visitor) { return visitor._visit(this, function() { this.properties.forEach(function(prop) { prop._walk(visitor); }); }); } }); var AST_ObjectProperty = DEFNODE("ObjectProperty", "key value", { $documentation: "Base class for literal object properties", $propdoc: { key: "[string] the property name converted to a string for ObjectKeyVal. For setters and getters this is an arbitrary AST_Node.", value: "[AST_Node] property value. For setters and getters this is an AST_Function." }, _walk: function(visitor) { return visitor._visit(this, function() { this.value._walk(visitor); }); } }); var AST_ObjectKeyVal = DEFNODE("ObjectKeyVal", null, { $documentation: "A key: value object property" }, AST_ObjectProperty); var AST_ObjectSetter = DEFNODE("ObjectSetter", null, { $documentation: "An object setter property" }, AST_ObjectProperty); var AST_ObjectGetter = DEFNODE("ObjectGetter", null, { $documentation: "An object getter property" }, AST_ObjectProperty); var AST_Symbol = DEFNODE("Symbol", "scope name thedef", { $propdoc: { name: "[string] name of this symbol", scope: "[AST_Scope/S] the current scope (not necessarily the definition scope)", thedef: "[SymbolDef/S] the definition of this symbol" }, $documentation: "Base class for all symbols" }); var AST_SymbolAccessor = DEFNODE("SymbolAccessor", null, { $documentation: "The name of a property accessor (setter/getter function)" }, AST_Symbol); var AST_SymbolDeclaration = DEFNODE("SymbolDeclaration", "init", { $documentation: "A declaration symbol (symbol in var/const, function name or argument, symbol in catch)", $propdoc: { init: "[AST_Node*/S] array of initializers for this declaration." } }, AST_Symbol); var AST_SymbolVar = DEFNODE("SymbolVar", null, { $documentation: "Symbol defining a variable" }, AST_SymbolDeclaration); var AST_SymbolConst = DEFNODE("SymbolConst", null, { $documentation: "A constant declaration" }, AST_SymbolDeclaration); var AST_SymbolFunarg = DEFNODE("SymbolFunarg", null, { $documentation: "Symbol naming a function argument" }, AST_SymbolVar); var AST_SymbolDefun = DEFNODE("SymbolDefun", null, { $documentation: "Symbol defining a function" }, AST_SymbolDeclaration); var AST_SymbolLambda = DEFNODE("SymbolLambda", null, { $documentation: "Symbol naming a function expression" }, AST_SymbolDeclaration); var AST_SymbolCatch = DEFNODE("SymbolCatch", null, { $documentation: "Symbol naming the exception in catch" }, AST_SymbolDeclaration); var AST_Label = DEFNODE("Label", "references", { $documentation: "Symbol naming a label (declaration)", $propdoc: { references: "[AST_LoopControl*] a list of nodes referring to this label" }, initialize: function() { this.references = []; this.thedef = this; } }, AST_Symbol); var AST_SymbolRef = DEFNODE("SymbolRef", null, { $documentation: "Reference to some symbol (not definition/declaration)" }, AST_Symbol); var AST_LabelRef = DEFNODE("LabelRef", null, { $documentation: "Reference to a label symbol" }, AST_Symbol); var AST_This = DEFNODE("This", null, { $documentation: "The `this` symbol" }, AST_Symbol); var AST_Constant = DEFNODE("Constant", null, { $documentation: "Base class for all constants", getValue: function() { return this.value; } }); var AST_String = DEFNODE("String", "value", { $documentation: "A string literal", $propdoc: { value: "[string] the contents of this string" } }, AST_Constant); var AST_Number = DEFNODE("Number", "value", { $documentation: "A number literal", $propdoc: { value: "[number] the numeric value" } }, AST_Constant); var AST_RegExp = DEFNODE("RegExp", "value", { $documentation: "A regexp literal", $propdoc: { value: "[RegExp] the actual regexp" } }, AST_Constant); var AST_Atom = DEFNODE("Atom", null, { $documentation: "Base class for atoms" }, AST_Constant); var AST_Null = DEFNODE("Null", null, { $documentation: "The `null` atom", value: null }, AST_Atom); var AST_NaN = DEFNODE("NaN", null, { $documentation: "The impossible value", value: 0 / 0 }, AST_Atom); var AST_Undefined = DEFNODE("Undefined", null, { $documentation: "The `undefined` value", value: function() {}() }, AST_Atom); var AST_Hole = DEFNODE("Hole", null, { $documentation: "A hole in an array", value: function() {}() }, AST_Atom); var AST_Infinity = DEFNODE("Infinity", null, { $documentation: "The `Infinity` value", value: 1 / 0 }, AST_Atom); var AST_Boolean = DEFNODE("Boolean", null, { $documentation: "Base class for booleans" }, AST_Atom); var AST_False = DEFNODE("False", null, { $documentation: "The `false` atom", value: false }, AST_Boolean); var AST_True = DEFNODE("True", null, { $documentation: "The `true` atom", value: true }, AST_Boolean); function TreeWalker(callback) { this.visit = callback; this.stack = []; } TreeWalker.prototype = { _visit: function(node, descend) { this.stack.push(node); var ret = this.visit(node, descend ? function() { descend.call(node); } : noop); if (!ret && descend) { descend.call(node); } this.stack.pop(); return ret; }, parent: function(n) { return this.stack[this.stack.length - 2 - (n || 0)]; }, push: function(node) { this.stack.push(node); }, pop: function() { return this.stack.pop(); }, self: function() { return this.stack[this.stack.length - 1]; }, find_parent: function(type) { var stack = this.stack; for (var i = stack.length; --i >= 0; ) { var x = stack[i]; if (x instanceof type) return x; } }, has_directive: function(type) { return this.find_parent(AST_Scope).has_directive(type); }, in_boolean_context: function() { var stack = this.stack; var i = stack.length, self = stack[--i]; while (i > 0) { var p = stack[--i]; if (p instanceof AST_If && p.condition === self || p instanceof AST_Conditional && p.condition === self || p instanceof AST_DWLoop && p.condition === self || p instanceof AST_For && p.condition === self || p instanceof AST_UnaryPrefix && p.operator == "!" && p.expression === self) { return true; } if (!(p instanceof AST_Binary && (p.operator == "&&" || p.operator == "||"))) return false; self = p; } }, loopcontrol_target: function(label) { var stack = this.stack; if (label) for (var i = stack.length; --i >= 0; ) { var x = stack[i]; if (x instanceof AST_LabeledStatement && x.label.name == label.name) { return x.body; } } else for (var i = stack.length; --i >= 0; ) { var x = stack[i]; if (x instanceof AST_Switch || x instanceof AST_IterationStatement) return x; } } }; "use strict"; var KEYWORDS = "break case catch const continue debugger default delete do else finally for function if in instanceof new return switch throw try typeof var void while with"; var KEYWORDS_ATOM = "false null true"; var RESERVED_WORDS = "abstract boolean byte char class double enum export extends final float goto implements import int interface long native package private protected public short static super synchronized this throws transient volatile yield" + " " + KEYWORDS_ATOM + " " + KEYWORDS; var KEYWORDS_BEFORE_EXPRESSION = "return new delete throw else case"; KEYWORDS = makePredicate(KEYWORDS); RESERVED_WORDS = makePredicate(RESERVED_WORDS); KEYWORDS_BEFORE_EXPRESSION = makePredicate(KEYWORDS_BEFORE_EXPRESSION); KEYWORDS_ATOM = makePredicate(KEYWORDS_ATOM); var OPERATOR_CHARS = makePredicate(characters("+-*&%=<>!?|~^")); var RE_HEX_NUMBER = /^0x[0-9a-f]+$/i; var RE_OCT_NUMBER = /^0[0-7]+$/; var RE_DEC_NUMBER = /^\d*\.?\d*(?:e[+-]?\d*(?:\d\.?|\.?\d)\d*)?$/i; var OPERATORS = makePredicate([ "in", "instanceof", "typeof", "new", "void", "delete", "++", "--", "+", "-", "!", "~", "&", "|", "^", "*", "/", "%", ">>", "<<", ">>>", "<", ">", "<=", ">=", "==", "===", "!=", "!==", "?", "=", "+=", "-=", "/=", "*=", "%=", ">>=", "<<=", ">>>=", "|=", "^=", "&=", "&&", "||" ]); var WHITESPACE_CHARS = makePredicate(characters("  \n\r \f ​᠎              ")); var PUNC_BEFORE_EXPRESSION = makePredicate(characters("[{(,.;:")); var PUNC_CHARS = makePredicate(characters("[]{}(),;:")); var REGEXP_MODIFIERS = makePredicate(characters("gmsiy")); var UNICODE = { letter: new RegExp("[\\u0041-\\u005A\\u0061-\\u007A\\u00AA\\u00B5\\u00BA\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02C1\\u02C6-\\u02D1\\u02E0-\\u02E4\\u02EC\\u02EE\\u0370-\\u0374\\u0376\\u0377\\u037A-\\u037D\\u0386\\u0388-\\u038A\\u038C\\u038E-\\u03A1\\u03A3-\\u03F5\\u03F7-\\u0481\\u048A-\\u0523\\u0531-\\u0556\\u0559\\u0561-\\u0587\\u05D0-\\u05EA\\u05F0-\\u05F2\\u0621-\\u064A\\u066E\\u066F\\u0671-\\u06D3\\u06D5\\u06E5\\u06E6\\u06EE\\u06EF\\u06FA-\\u06FC\\u06FF\\u0710\\u0712-\\u072F\\u074D-\\u07A5\\u07B1\\u07CA-\\u07EA\\u07F4\\u07F5\\u07FA\\u0904-\\u0939\\u093D\\u0950\\u0958-\\u0961\\u0971\\u0972\\u097B-\\u097F\\u0985-\\u098C\\u098F\\u0990\\u0993-\\u09A8\\u09AA-\\u09B0\\u09B2\\u09B6-\\u09B9\\u09BD\\u09CE\\u09DC\\u09DD\\u09DF-\\u09E1\\u09F0\\u09F1\\u0A05-\\u0A0A\\u0A0F\\u0A10\\u0A13-\\u0A28\\u0A2A-\\u0A30\\u0A32\\u0A33\\u0A35\\u0A36\\u0A38\\u0A39\\u0A59-\\u0A5C\\u0A5E\\u0A72-\\u0A74\\u0A85-\\u0A8D\\u0A8F-\\u0A91\\u0A93-\\u0AA8\\u0AAA-\\u0AB0\\u0AB2\\u0AB3\\u0AB5-\\u0AB9\\u0ABD\\u0AD0\\u0AE0\\u0AE1\\u0B05-\\u0B0C\\u0B0F\\u0B10\\u0B13-\\u0B28\\u0B2A-\\u0B30\\u0B32\\u0B33\\u0B35-\\u0B39\\u0B3D\\u0B5C\\u0B5D\\u0B5F-\\u0B61\\u0B71\\u0B83\\u0B85-\\u0B8A\\u0B8E-\\u0B90\\u0B92-\\u0B95\\u0B99\\u0B9A\\u0B9C\\u0B9E\\u0B9F\\u0BA3\\u0BA4\\u0BA8-\\u0BAA\\u0BAE-\\u0BB9\\u0BD0\\u0C05-\\u0C0C\\u0C0E-\\u0C10\\u0C12-\\u0C28\\u0C2A-\\u0C33\\u0C35-\\u0C39\\u0C3D\\u0C58\\u0C59\\u0C60\\u0C61\\u0C85-\\u0C8C\\u0C8E-\\u0C90\\u0C92-\\u0CA8\\u0CAA-\\u0CB3\\u0CB5-\\u0CB9\\u0CBD\\u0CDE\\u0CE0\\u0CE1\\u0D05-\\u0D0C\\u0D0E-\\u0D10\\u0D12-\\u0D28\\u0D2A-\\u0D39\\u0D3D\\u0D60\\u0D61\\u0D7A-\\u0D7F\\u0D85-\\u0D96\\u0D9A-\\u0DB1\\u0DB3-\\u0DBB\\u0DBD\\u0DC0-\\u0DC6\\u0E01-\\u0E30\\u0E32\\u0E33\\u0E40-\\u0E46\\u0E81\\u0E82\\u0E84\\u0E87\\u0E88\\u0E8A\\u0E8D\\u0E94-\\u0E97\\u0E99-\\u0E9F\\u0EA1-\\u0EA3\\u0EA5\\u0EA7\\u0EAA\\u0EAB\\u0EAD-\\u0EB0\\u0EB2\\u0EB3\\u0EBD\\u0EC0-\\u0EC4\\u0EC6\\u0EDC\\u0EDD\\u0F00\\u0F40-\\u0F47\\u0F49-\\u0F6C\\u0F88-\\u0F8B\\u1000-\\u102A\\u103F\\u1050-\\u1055\\u105A-\\u105D\\u1061\\u1065\\u1066\\u106E-\\u1070\\u1075-\\u1081\\u108E\\u10A0-\\u10C5\\u10D0-\\u10FA\\u10FC\\u1100-\\u1159\\u115F-\\u11A2\\u11A8-\\u11F9\\u1200-\\u1248\\u124A-\\u124D\\u1250-\\u1256\\u1258\\u125A-\\u125D\\u1260-\\u1288\\u128A-\\u128D\\u1290-\\u12B0\\u12B2-\\u12B5\\u12B8-\\u12BE\\u12C0\\u12C2-\\u12C5\\u12C8-\\u12D6\\u12D8-\\u1310\\u1312-\\u1315\\u1318-\\u135A\\u1380-\\u138F\\u13A0-\\u13F4\\u1401-\\u166C\\u166F-\\u1676\\u1681-\\u169A\\u16A0-\\u16EA\\u1700-\\u170C\\u170E-\\u1711\\u1720-\\u1731\\u1740-\\u1751\\u1760-\\u176C\\u176E-\\u1770\\u1780-\\u17B3\\u17D7\\u17DC\\u1820-\\u1877\\u1880-\\u18A8\\u18AA\\u1900-\\u191C\\u1950-\\u196D\\u1970-\\u1974\\u1980-\\u19A9\\u19C1-\\u19C7\\u1A00-\\u1A16\\u1B05-\\u1B33\\u1B45-\\u1B4B\\u1B83-\\u1BA0\\u1BAE\\u1BAF\\u1C00-\\u1C23\\u1C4D-\\u1C4F\\u1C5A-\\u1C7D\\u1D00-\\u1DBF\\u1E00-\\u1F15\\u1F18-\\u1F1D\\u1F20-\\u1F45\\u1F48-\\u1F4D\\u1F50-\\u1F57\\u1F59\\u1F5B\\u1F5D\\u1F5F-\\u1F7D\\u1F80-\\u1FB4\\u1FB6-\\u1FBC\\u1FBE\\u1FC2-\\u1FC4\\u1FC6-\\u1FCC\\u1FD0-\\u1FD3\\u1FD6-\\u1FDB\\u1FE0-\\u1FEC\\u1FF2-\\u1FF4\\u1FF6-\\u1FFC\\u2071\\u207F\\u2090-\\u2094\\u2102\\u2107\\u210A-\\u2113\\u2115\\u2119-\\u211D\\u2124\\u2126\\u2128\\u212A-\\u212D\\u212F-\\u2139\\u213C-\\u213F\\u2145-\\u2149\\u214E\\u2183\\u2184\\u2C00-\\u2C2E\\u2C30-\\u2C5E\\u2C60-\\u2C6F\\u2C71-\\u2C7D\\u2C80-\\u2CE4\\u2D00-\\u2D25\\u2D30-\\u2D65\\u2D6F\\u2D80-\\u2D96\\u2DA0-\\u2DA6\\u2DA8-\\u2DAE\\u2DB0-\\u2DB6\\u2DB8-\\u2DBE\\u2DC0-\\u2DC6\\u2DC8-\\u2DCE\\u2DD0-\\u2DD6\\u2DD8-\\u2DDE\\u2E2F\\u3005\\u3006\\u3031-\\u3035\\u303B\\u303C\\u3041-\\u3096\\u309D-\\u309F\\u30A1-\\u30FA\\u30FC-\\u30FF\\u3105-\\u312D\\u3131-\\u318E\\u31A0-\\u31B7\\u31F0-\\u31FF\\u3400\\u4DB5\\u4E00\\u9FC3\\uA000-\\uA48C\\uA500-\\uA60C\\uA610-\\uA61F\\uA62A\\uA62B\\uA640-\\uA65F\\uA662-\\uA66E\\uA67F-\\uA697\\uA717-\\uA71F\\uA722-\\uA788\\uA78B\\uA78C\\uA7FB-\\uA801\\uA803-\\uA805\\uA807-\\uA80A\\uA80C-\\uA822\\uA840-\\uA873\\uA882-\\uA8B3\\uA90A-\\uA925\\uA930-\\uA946\\uAA00-\\uAA28\\uAA40-\\uAA42\\uAA44-\\uAA4B\\uAC00\\uD7A3\\uF900-\\uFA2D\\uFA30-\\uFA6A\\uFA70-\\uFAD9\\uFB00-\\uFB06\\uFB13-\\uFB17\\uFB1D\\uFB1F-\\uFB28\\uFB2A-\\uFB36\\uFB38-\\uFB3C\\uFB3E\\uFB40\\uFB41\\uFB43\\uFB44\\uFB46-\\uFBB1\\uFBD3-\\uFD3D\\uFD50-\\uFD8F\\uFD92-\\uFDC7\\uFDF0-\\uFDFB\\uFE70-\\uFE74\\uFE76-\\uFEFC\\uFF21-\\uFF3A\\uFF41-\\uFF5A\\uFF66-\\uFFBE\\uFFC2-\\uFFC7\\uFFCA-\\uFFCF\\uFFD2-\\uFFD7\\uFFDA-\\uFFDC]"), non_spacing_mark: new RegExp("[\\u0300-\\u036F\\u0483-\\u0487\\u0591-\\u05BD\\u05BF\\u05C1\\u05C2\\u05C4\\u05C5\\u05C7\\u0610-\\u061A\\u064B-\\u065E\\u0670\\u06D6-\\u06DC\\u06DF-\\u06E4\\u06E7\\u06E8\\u06EA-\\u06ED\\u0711\\u0730-\\u074A\\u07A6-\\u07B0\\u07EB-\\u07F3\\u0816-\\u0819\\u081B-\\u0823\\u0825-\\u0827\\u0829-\\u082D\\u0900-\\u0902\\u093C\\u0941-\\u0948\\u094D\\u0951-\\u0955\\u0962\\u0963\\u0981\\u09BC\\u09C1-\\u09C4\\u09CD\\u09E2\\u09E3\\u0A01\\u0A02\\u0A3C\\u0A41\\u0A42\\u0A47\\u0A48\\u0A4B-\\u0A4D\\u0A51\\u0A70\\u0A71\\u0A75\\u0A81\\u0A82\\u0ABC\\u0AC1-\\u0AC5\\u0AC7\\u0AC8\\u0ACD\\u0AE2\\u0AE3\\u0B01\\u0B3C\\u0B3F\\u0B41-\\u0B44\\u0B4D\\u0B56\\u0B62\\u0B63\\u0B82\\u0BC0\\u0BCD\\u0C3E-\\u0C40\\u0C46-\\u0C48\\u0C4A-\\u0C4D\\u0C55\\u0C56\\u0C62\\u0C63\\u0CBC\\u0CBF\\u0CC6\\u0CCC\\u0CCD\\u0CE2\\u0CE3\\u0D41-\\u0D44\\u0D4D\\u0D62\\u0D63\\u0DCA\\u0DD2-\\u0DD4\\u0DD6\\u0E31\\u0E34-\\u0E3A\\u0E47-\\u0E4E\\u0EB1\\u0EB4-\\u0EB9\\u0EBB\\u0EBC\\u0EC8-\\u0ECD\\u0F18\\u0F19\\u0F35\\u0F37\\u0F39\\u0F71-\\u0F7E\\u0F80-\\u0F84\\u0F86\\u0F87\\u0F90-\\u0F97\\u0F99-\\u0FBC\\u0FC6\\u102D-\\u1030\\u1032-\\u1037\\u1039\\u103A\\u103D\\u103E\\u1058\\u1059\\u105E-\\u1060\\u1071-\\u1074\\u1082\\u1085\\u1086\\u108D\\u109D\\u135F\\u1712-\\u1714\\u1732-\\u1734\\u1752\\u1753\\u1772\\u1773\\u17B7-\\u17BD\\u17C6\\u17C9-\\u17D3\\u17DD\\u180B-\\u180D\\u18A9\\u1920-\\u1922\\u1927\\u1928\\u1932\\u1939-\\u193B\\u1A17\\u1A18\\u1A56\\u1A58-\\u1A5E\\u1A60\\u1A62\\u1A65-\\u1A6C\\u1A73-\\u1A7C\\u1A7F\\u1B00-\\u1B03\\u1B34\\u1B36-\\u1B3A\\u1B3C\\u1B42\\u1B6B-\\u1B73\\u1B80\\u1B81\\u1BA2-\\u1BA5\\u1BA8\\u1BA9\\u1C2C-\\u1C33\\u1C36\\u1C37\\u1CD0-\\u1CD2\\u1CD4-\\u1CE0\\u1CE2-\\u1CE8\\u1CED\\u1DC0-\\u1DE6\\u1DFD-\\u1DFF\\u20D0-\\u20DC\\u20E1\\u20E5-\\u20F0\\u2CEF-\\u2CF1\\u2DE0-\\u2DFF\\u302A-\\u302F\\u3099\\u309A\\uA66F\\uA67C\\uA67D\\uA6F0\\uA6F1\\uA802\\uA806\\uA80B\\uA825\\uA826\\uA8C4\\uA8E0-\\uA8F1\\uA926-\\uA92D\\uA947-\\uA951\\uA980-\\uA982\\uA9B3\\uA9B6-\\uA9B9\\uA9BC\\uAA29-\\uAA2E\\uAA31\\uAA32\\uAA35\\uAA36\\uAA43\\uAA4C\\uAAB0\\uAAB2-\\uAAB4\\uAAB7\\uAAB8\\uAABE\\uAABF\\uAAC1\\uABE5\\uABE8\\uABED\\uFB1E\\uFE00-\\uFE0F\\uFE20-\\uFE26]"), space_combining_mark: new RegExp("[\\u0903\\u093E-\\u0940\\u0949-\\u094C\\u094E\\u0982\\u0983\\u09BE-\\u09C0\\u09C7\\u09C8\\u09CB\\u09CC\\u09D7\\u0A03\\u0A3E-\\u0A40\\u0A83\\u0ABE-\\u0AC0\\u0AC9\\u0ACB\\u0ACC\\u0B02\\u0B03\\u0B3E\\u0B40\\u0B47\\u0B48\\u0B4B\\u0B4C\\u0B57\\u0BBE\\u0BBF\\u0BC1\\u0BC2\\u0BC6-\\u0BC8\\u0BCA-\\u0BCC\\u0BD7\\u0C01-\\u0C03\\u0C41-\\u0C44\\u0C82\\u0C83\\u0CBE\\u0CC0-\\u0CC4\\u0CC7\\u0CC8\\u0CCA\\u0CCB\\u0CD5\\u0CD6\\u0D02\\u0D03\\u0D3E-\\u0D40\\u0D46-\\u0D48\\u0D4A-\\u0D4C\\u0D57\\u0D82\\u0D83\\u0DCF-\\u0DD1\\u0DD8-\\u0DDF\\u0DF2\\u0DF3\\u0F3E\\u0F3F\\u0F7F\\u102B\\u102C\\u1031\\u1038\\u103B\\u103C\\u1056\\u1057\\u1062-\\u1064\\u1067-\\u106D\\u1083\\u1084\\u1087-\\u108C\\u108F\\u109A-\\u109C\\u17B6\\u17BE-\\u17C5\\u17C7\\u17C8\\u1923-\\u1926\\u1929-\\u192B\\u1930\\u1931\\u1933-\\u1938\\u19B0-\\u19C0\\u19C8\\u19C9\\u1A19-\\u1A1B\\u1A55\\u1A57\\u1A61\\u1A63\\u1A64\\u1A6D-\\u1A72\\u1B04\\u1B35\\u1B3B\\u1B3D-\\u1B41\\u1B43\\u1B44\\u1B82\\u1BA1\\u1BA6\\u1BA7\\u1BAA\\u1C24-\\u1C2B\\u1C34\\u1C35\\u1CE1\\u1CF2\\uA823\\uA824\\uA827\\uA880\\uA881\\uA8B4-\\uA8C3\\uA952\\uA953\\uA983\\uA9B4\\uA9B5\\uA9BA\\uA9BB\\uA9BD-\\uA9C0\\uAA2F\\uAA30\\uAA33\\uAA34\\uAA4D\\uAA7B\\uABE3\\uABE4\\uABE6\\uABE7\\uABE9\\uABEA\\uABEC]"), connector_punctuation: new RegExp("[\\u005F\\u203F\\u2040\\u2054\\uFE33\\uFE34\\uFE4D-\\uFE4F\\uFF3F]") }; function is_letter(code) { return code >= 97 && code <= 122 || code >= 65 && code <= 90 || code >= 170 && UNICODE.letter.test(String.fromCharCode(code)); } function is_digit(code) { return code >= 48 && code <= 57; } function is_alphanumeric_char(code) { return is_digit(code) || is_letter(code); } function is_unicode_combining_mark(ch) { return UNICODE.non_spacing_mark.test(ch) || UNICODE.space_combining_mark.test(ch); } function is_unicode_connector_punctuation(ch) { return UNICODE.connector_punctuation.test(ch); } function is_identifier(name) { return !RESERVED_WORDS(name) && /^[a-z_$][a-z0-9_$]*$/i.test(name); } function is_identifier_start(code) { return code == 36 || code == 95 || is_letter(code); } function is_identifier_char(ch) { var code = ch.charCodeAt(0); return is_identifier_start(code) || is_digit(code) || code == 8204 || code == 8205 || is_unicode_combining_mark(ch) || is_unicode_connector_punctuation(ch); } function is_identifier_string(str) { return /^[a-z_$][a-z0-9_$]*$/i.test(str); } function parse_js_number(num) { if (RE_HEX_NUMBER.test(num)) { return parseInt(num.substr(2), 16); } else if (RE_OCT_NUMBER.test(num)) { return parseInt(num.substr(1), 8); } else if (RE_DEC_NUMBER.test(num)) { return parseFloat(num); } } function JS_Parse_Error(message, line, col, pos) { this.message = message; this.line = line; this.col = col; this.pos = pos; this.stack = new Error().stack; } JS_Parse_Error.prototype.toString = function() { return this.message + " (line: " + this.line + ", col: " + this.col + ", pos: " + this.pos + ")" + "\n\n" + this.stack; }; function js_error(message, filename, line, col, pos) { throw new JS_Parse_Error(message, line, col, pos); } function is_token(token, type, val) { return token.type == type && (val == null || token.value == val); } var EX_EOF = {}; function tokenizer($TEXT, filename, html5_comments) { var S = { text: $TEXT.replace(/\r\n?|[\n\u2028\u2029]/g, "\n").replace(/\uFEFF/g, ""), filename: filename, pos: 0, tokpos: 0, line: 1, tokline: 0, col: 0, tokcol: 0, newline_before: false, regex_allowed: false, comments_before: [] }; function peek() { return S.text.charAt(S.pos); } function next(signal_eof, in_string) { var ch = S.text.charAt(S.pos++); if (signal_eof && !ch) throw EX_EOF; if (ch == "\n") { S.newline_before = S.newline_before || !in_string; ++S.line; S.col = 0; } else { ++S.col; } return ch; } function forward(i) { while (i-- > 0) next(); } function looking_at(str) { return S.text.substr(S.pos, str.length) == str; } function find(what, signal_eof) { var pos = S.text.indexOf(what, S.pos); if (signal_eof && pos == -1) throw EX_EOF; return pos; } function start_token() { S.tokline = S.line; S.tokcol = S.col; S.tokpos = S.pos; } var prev_was_dot = false; function token(type, value, is_comment) { S.regex_allowed = type == "operator" && !UNARY_POSTFIX(value) || type == "keyword" && KEYWORDS_BEFORE_EXPRESSION(value) || type == "punc" && PUNC_BEFORE_EXPRESSION(value); prev_was_dot = type == "punc" && value == "."; var ret = { type: type, value: value, line: S.tokline, col: S.tokcol, pos: S.tokpos, endpos: S.pos, nlb: S.newline_before, file: filename }; if (!is_comment) { ret.comments_before = S.comments_before; S.comments_before = []; for (var i = 0, len = ret.comments_before.length; i < len; i++) { ret.nlb = ret.nlb || ret.comments_before[i].nlb; } } S.newline_before = false; return new AST_Token(ret); } function skip_whitespace() { while (WHITESPACE_CHARS(peek())) next(); } function read_while(pred) { var ret = "", ch, i = 0; while ((ch = peek()) && pred(ch, i++)) ret += next(); return ret; } function parse_error(err) { js_error(err, filename, S.tokline, S.tokcol, S.tokpos); } function read_num(prefix) { var has_e = false, after_e = false, has_x = false, has_dot = prefix == "."; var num = read_while(function(ch, i) { var code = ch.charCodeAt(0); switch (code) { case 120: case 88: return has_x ? false : has_x = true; case 101: case 69: return has_x ? true : has_e ? false : has_e = after_e = true; case 45: return after_e || i == 0 && !prefix; case 43: return after_e; case after_e = false, 46: return !has_dot && !has_x && !has_e ? has_dot = true : false; } return is_alphanumeric_char(code); }); if (prefix) num = prefix + num; var valid = parse_js_number(num); if (!isNaN(valid)) { return token("num", valid); } else { parse_error("Invalid syntax: " + num); } } function read_escaped_char(in_string) { var ch = next(true, in_string); switch (ch.charCodeAt(0)) { case 110: return "\n"; case 114: return "\r"; case 116: return " "; case 98: return "\b"; case 118: return " "; case 102: return "\f"; case 48: return "\x00"; case 120: return String.fromCharCode(hex_bytes(2)); case 117: return String.fromCharCode(hex_bytes(4)); case 10: return ""; default: return ch; } } function hex_bytes(n) { var num = 0; for (;n > 0; --n) { var digit = parseInt(next(true), 16); if (isNaN(digit)) parse_error("Invalid hex-character pattern in string"); num = num << 4 | digit; } return num; } var read_string = with_eof_error("Unterminated string constant", function() { var quote = next(), ret = ""; for (;;) { var ch = next(true); if (ch == "\\") { var octal_len = 0, first = null; ch = read_while(function(ch) { if (ch >= "0" && ch <= "7") { if (!first) { first = ch; return ++octal_len; } else if (first <= "3" && octal_len <= 2) return ++octal_len; else if (first >= "4" && octal_len <= 1) return ++octal_len; } return false; }); if (octal_len > 0) ch = String.fromCharCode(parseInt(ch, 8)); else ch = read_escaped_char(true); } else if (ch == quote) break; ret += ch; } return token("string", ret); }); function skip_line_comment(type) { var regex_allowed = S.regex_allowed; var i = find("\n"), ret; if (i == -1) { ret = S.text.substr(S.pos); S.pos = S.text.length; } else { ret = S.text.substring(S.pos, i); S.pos = i; } S.comments_before.push(token(type, ret, true)); S.regex_allowed = regex_allowed; return next_token(); } var skip_multiline_comment = with_eof_error("Unterminated multiline comment", function() { var regex_allowed = S.regex_allowed; var i = find("*/", true); var text = S.text.substring(S.pos, i); var a = text.split("\n"), n = a.length; S.pos = i + 2; S.line += n - 1; if (n > 1) S.col = a[n - 1].length; else S.col += a[n - 1].length; S.col += 2; var nlb = S.newline_before = S.newline_before || text.indexOf("\n") >= 0; S.comments_before.push(token("comment2", text, true)); S.regex_allowed = regex_allowed; S.newline_before = nlb; return next_token(); }); function read_name() { var backslash = false, name = "", ch, escaped = false, hex; while ((ch = peek()) != null) { if (!backslash) { if (ch == "\\") escaped = backslash = true, next(); else if (is_identifier_char(ch)) name += next(); else break; } else { if (ch != "u") parse_error("Expecting UnicodeEscapeSequence -- uXXXX"); ch = read_escaped_char(); if (!is_identifier_char(ch)) parse_error("Unicode char: " + ch.charCodeAt(0) + " is not valid in identifier"); name += ch; backslash = false; } } if (KEYWORDS(name) && escaped) { hex = name.charCodeAt(0).toString(16).toUpperCase(); name = "\\u" + "0000".substr(hex.length) + hex + name.slice(1); } return name; } var read_regexp = with_eof_error("Unterminated regular expression", function(regexp) { var prev_backslash = false, ch, in_class = false; while (ch = next(true)) if (prev_backslash) { regexp += "\\" + ch; prev_backslash = false; } else if (ch == "[") { in_class = true; regexp += ch; } else if (ch == "]" && in_class) { in_class = false; regexp += ch; } else if (ch == "/" && !in_class) { break; } else if (ch == "\\") { prev_backslash = true; } else { regexp += ch; } var mods = read_name(); return token("regexp", new RegExp(regexp, mods)); }); function read_operator(prefix) { function grow(op) { if (!peek()) return op; var bigger = op + peek(); if (OPERATORS(bigger)) { next(); return grow(bigger); } else { return op; } } return token("operator", grow(prefix || next())); } function handle_slash() { next(); switch (peek()) { case "/": next(); return skip_line_comment("comment1"); case "*": next(); return skip_multiline_comment(); } return S.regex_allowed ? read_regexp("") : read_operator("/"); } function handle_dot() { next(); return is_digit(peek().charCodeAt(0)) ? read_num(".") : token("punc", "."); } function read_word() { var word = read_name(); if (prev_was_dot) return token("name", word); return KEYWORDS_ATOM(word) ? token("atom", word) : !KEYWORDS(word) ? token("name", word) : OPERATORS(word) ? token("operator", word) : token("keyword", word); } function with_eof_error(eof_error, cont) { return function(x) { try { return cont(x); } catch (ex) { if (ex === EX_EOF) parse_error(eof_error); else throw ex; } }; } function next_token(force_regexp) { if (force_regexp != null) return read_regexp(force_regexp); skip_whitespace(); start_token(); if (html5_comments) { if (looking_at("") && S.newline_before) { forward(3); return skip_line_comment("comment4"); } } var ch = peek(); if (!ch) return token("eof"); var code = ch.charCodeAt(0); switch (code) { case 34: case 39: return read_string(); case 46: return handle_dot(); case 47: return handle_slash(); } if (is_digit(code)) return read_num(); if (PUNC_CHARS(ch)) return token("punc", next()); if (OPERATOR_CHARS(ch)) return read_operator(); if (code == 92 || is_identifier_start(code)) return read_word(); parse_error("Unexpected character '" + ch + "'"); } next_token.context = function(nc) { if (nc) S = nc; return S; }; return next_token; } var UNARY_PREFIX = makePredicate([ "typeof", "void", "delete", "--", "++", "!", "~", "-", "+" ]); var UNARY_POSTFIX = makePredicate([ "--", "++" ]); var ASSIGNMENT = makePredicate([ "=", "+=", "-=", "/=", "*=", "%=", ">>=", "<<=", ">>>=", "|=", "^=", "&=" ]); var PRECEDENCE = function(a, ret) { for (var i = 0; i < a.length; ++i) { var b = a[i]; for (var j = 0; j < b.length; ++j) { ret[b[j]] = i + 1; } } return ret; }([ [ "||" ], [ "&&" ], [ "|" ], [ "^" ], [ "&" ], [ "==", "===", "!=", "!==" ], [ "<", ">", "<=", ">=", "in", "instanceof" ], [ ">>", "<<", ">>>" ], [ "+", "-" ], [ "*", "/", "%" ] ], {}); var STATEMENTS_WITH_LABELS = array_to_hash([ "for", "do", "while", "switch" ]); var ATOMIC_START_TOKEN = array_to_hash([ "atom", "num", "string", "regexp", "name" ]); function parse($TEXT, options) { options = defaults(options, { strict: false, filename: null, toplevel: null, expression: false, html5_comments: true }); var S = { input: typeof $TEXT == "string" ? tokenizer($TEXT, options.filename, options.html5_comments) : $TEXT, token: null, prev: null, peeked: null, in_function: 0, in_directives: true, in_loop: 0, labels: [] }; S.token = next(); function is(type, value) { return is_token(S.token, type, value); } function peek() { return S.peeked || (S.peeked = S.input()); } function next() { S.prev = S.token; if (S.peeked) { S.token = S.peeked; S.peeked = null; } else { S.token = S.input(); } S.in_directives = S.in_directives && (S.token.type == "string" || is("punc", ";")); return S.token; } function prev() { return S.prev; } function croak(msg, line, col, pos) { var ctx = S.input.context(); js_error(msg, ctx.filename, line != null ? line : ctx.tokline, col != null ? col : ctx.tokcol, pos != null ? pos : ctx.tokpos); } function token_error(token, msg) { croak(msg, token.line, token.col); } function unexpected(token) { if (token == null) token = S.token; token_error(token, "Unexpected token: " + token.type + " (" + token.value + ")"); } function expect_token(type, val) { if (is(type, val)) { return next(); } token_error(S.token, "Unexpected token " + S.token.type + " «" + S.token.value + "»" + ", expected " + type + " «" + val + "»"); } function expect(punc) { return expect_token("punc", punc); } function can_insert_semicolon() { return !options.strict && (S.token.nlb || is("eof") || is("punc", "}")); } function semicolon() { if (is("punc", ";")) next(); else if (!can_insert_semicolon()) unexpected(); } function parenthesised() { expect("("); var exp = expression(true); expect(")"); return exp; } function embed_tokens(parser) { return function() { var start = S.token; var expr = parser(); var end = prev(); expr.start = start; expr.end = end; return expr; }; } function handle_regexp() { if (is("operator", "/") || is("operator", "/=")) { S.peeked = null; S.token = S.input(S.token.value.substr(1)); } } var statement = embed_tokens(function() { var tmp; handle_regexp(); switch (S.token.type) { case "string": var dir = S.in_directives, stat = simple_statement(); if (dir && stat.body instanceof AST_String && !is("punc", ",")) return new AST_Directive({ value: stat.body.value }); return stat; case "num": case "regexp": case "operator": case "atom": return simple_statement(); case "name": return is_token(peek(), "punc", ":") ? labeled_statement() : simple_statement(); case "punc": switch (S.token.value) { case "{": return new AST_BlockStatement({ start: S.token, body: block_(), end: prev() }); case "[": case "(": return simple_statement(); case ";": next(); return new AST_EmptyStatement(); default: unexpected(); } case "keyword": switch (tmp = S.token.value, next(), tmp) { case "break": return break_cont(AST_Break); case "continue": return break_cont(AST_Continue); case "debugger": semicolon(); return new AST_Debugger(); case "do": return new AST_Do({ body: in_loop(statement), condition: (expect_token("keyword", "while"), tmp = parenthesised(), semicolon(), tmp) }); case "while": return new AST_While({ condition: parenthesised(), body: in_loop(statement) }); case "for": return for_(); case "function": return function_(AST_Defun); case "if": return if_(); case "return": if (S.in_function == 0) croak("'return' outside of function"); return new AST_Return({ value: is("punc", ";") ? (next(), null) : can_insert_semicolon() ? null : (tmp = expression(true), semicolon(), tmp) }); case "switch": return new AST_Switch({ expression: parenthesised(), body: in_loop(switch_body_) }); case "throw": if (S.token.nlb) croak("Illegal newline after 'throw'"); return new AST_Throw({ value: (tmp = expression(true), semicolon(), tmp) }); case "try": return try_(); case "var": return tmp = var_(), semicolon(), tmp; case "const": return tmp = const_(), semicolon(), tmp; case "with": return new AST_With({ expression: parenthesised(), body: statement() }); default: unexpected(); } } }); function labeled_statement() { var label = as_symbol(AST_Label); if (find_if(function(l) { return l.name == label.name; }, S.labels)) { croak("Label " + label.name + " defined twice"); } expect(":"); S.labels.push(label); var stat = statement(); S.labels.pop(); if (!(stat instanceof AST_IterationStatement)) { label.references.forEach(function(ref) { if (ref instanceof AST_Continue) { ref = ref.label.start; croak("Continue label `" + label.name + "` refers to non-IterationStatement.", ref.line, ref.col, ref.pos); } }); } return new AST_LabeledStatement({ body: stat, label: label }); } function simple_statement(tmp) { return new AST_SimpleStatement({ body: (tmp = expression(true), semicolon(), tmp) }); } function break_cont(type) { var label = null, ldef; if (!can_insert_semicolon()) { label = as_symbol(AST_LabelRef, true); } if (label != null) { ldef = find_if(function(l) { return l.name == label.name; }, S.labels); if (!ldef) croak("Undefined label " + label.name); label.thedef = ldef; } else if (S.in_loop == 0) croak(type.TYPE + " not inside a loop or switch"); semicolon(); var stat = new type({ label: label }); if (ldef) ldef.references.push(stat); return stat; } function for_() { expect("("); var init = null; if (!is("punc", ";")) { init = is("keyword", "var") ? (next(), var_(true)) : expression(true, true); if (is("operator", "in")) { if (init instanceof AST_Var && init.definitions.length > 1) croak("Only one variable declaration allowed in for..in loop"); next(); return for_in(init); } } return regular_for(init); } function regular_for(init) { expect(";"); var test = is("punc", ";") ? null : expression(true); expect(";"); var step = is("punc", ")") ? null : expression(true); expect(")"); return new AST_For({ init: init, condition: test, step: step, body: in_loop(statement) }); } function for_in(init) { var lhs = init instanceof AST_Var ? init.definitions[0].name : null; var obj = expression(true); expect(")"); return new AST_ForIn({ init: init, name: lhs, object: obj, body: in_loop(statement) }); } var function_ = function(ctor) { var in_statement = ctor === AST_Defun; var name = is("name") ? as_symbol(in_statement ? AST_SymbolDefun : AST_SymbolLambda) : null; if (in_statement && !name) unexpected(); expect("("); return new ctor({ name: name, argnames: function(first, a) { while (!is("punc", ")")) { if (first) first = false; else expect(","); a.push(as_symbol(AST_SymbolFunarg)); } next(); return a; }(true, []), body: function(loop, labels) { ++S.in_function; S.in_directives = true; S.in_loop = 0; S.labels = []; var a = block_(); --S.in_function; S.in_loop = loop; S.labels = labels; return a; }(S.in_loop, S.labels) }); }; function if_() { var cond = parenthesised(), body = statement(), belse = null; if (is("keyword", "else")) { next(); belse = statement(); } return new AST_If({ condition: cond, body: body, alternative: belse }); } function block_() { expect("{"); var a = []; while (!is("punc", "}")) { if (is("eof")) unexpected(); a.push(statement()); } next(); return a; } function switch_body_() { expect("{"); var a = [], cur = null, branch = null, tmp; while (!is("punc", "}")) { if (is("eof")) unexpected(); if (is("keyword", "case")) { if (branch) branch.end = prev(); cur = []; branch = new AST_Case({ start: (tmp = S.token, next(), tmp), expression: expression(true), body: cur }); a.push(branch); expect(":"); } else if (is("keyword", "default")) { if (branch) branch.end = prev(); cur = []; branch = new AST_Default({ start: (tmp = S.token, next(), expect(":"), tmp), body: cur }); a.push(branch); } else { if (!cur) unexpected(); cur.push(statement()); } } if (branch) branch.end = prev(); next(); return a; } function try_() { var body = block_(), bcatch = null, bfinally = null; if (is("keyword", "catch")) { var start = S.token; next(); expect("("); var name = as_symbol(AST_SymbolCatch); expect(")"); bcatch = new AST_Catch({ start: start, argname: name, body: block_(), end: prev() }); } if (is("keyword", "finally")) { var start = S.token; next(); bfinally = new AST_Finally({ start: start, body: block_(), end: prev() }); } if (!bcatch && !bfinally) croak("Missing catch/finally blocks"); return new AST_Try({ body: body, bcatch: bcatch, bfinally: bfinally }); } function vardefs(no_in, in_const) { var a = []; for (;;) { a.push(new AST_VarDef({ start: S.token, name: as_symbol(in_const ? AST_SymbolConst : AST_SymbolVar), value: is("operator", "=") ? (next(), expression(false, no_in)) : null, end: prev() })); if (!is("punc", ",")) break; next(); } return a; } var var_ = function(no_in) { return new AST_Var({ start: prev(), definitions: vardefs(no_in, false), end: prev() }); }; var const_ = function() { return new AST_Const({ start: prev(), definitions: vardefs(false, true), end: prev() }); }; var new_ = function() { var start = S.token; expect_token("operator", "new"); var newexp = expr_atom(false), args; if (is("punc", "(")) { next(); args = expr_list(")"); } else { args = []; } return subscripts(new AST_New({ start: start, expression: newexp, args: args, end: prev() }), true); }; function as_atom_node() { var tok = S.token, ret; switch (tok.type) { case "name": case "keyword": ret = _make_symbol(AST_SymbolRef); break; case "num": ret = new AST_Number({ start: tok, end: tok, value: tok.value }); break; case "string": ret = new AST_String({ start: tok, end: tok, value: tok.value }); break; case "regexp": ret = new AST_RegExp({ start: tok, end: tok, value: tok.value }); break; case "atom": switch (tok.value) { case "false": ret = new AST_False({ start: tok, end: tok }); break; case "true": ret = new AST_True({ start: tok, end: tok }); break; case "null": ret = new AST_Null({ start: tok, end: tok }); break; } break; } next(); return ret; } var expr_atom = function(allow_calls) { if (is("operator", "new")) { return new_(); } var start = S.token; if (is("punc")) { switch (start.value) { case "(": next(); var ex = expression(true); ex.start = start; ex.end = S.token; expect(")"); return subscripts(ex, allow_calls); case "[": return subscripts(array_(), allow_calls); case "{": return subscripts(object_(), allow_calls); } unexpected(); } if (is("keyword", "function")) { next(); var func = function_(AST_Function); func.start = start; func.end = prev(); return subscripts(func, allow_calls); } if (ATOMIC_START_TOKEN[S.token.type]) { return subscripts(as_atom_node(), allow_calls); } unexpected(); }; function expr_list(closing, allow_trailing_comma, allow_empty) { var first = true, a = []; while (!is("punc", closing)) { if (first) first = false; else expect(","); if (allow_trailing_comma && is("punc", closing)) break; if (is("punc", ",") && allow_empty) { a.push(new AST_Hole({ start: S.token, end: S.token })); } else { a.push(expression(false)); } } next(); return a; } var array_ = embed_tokens(function() { expect("["); return new AST_Array({ elements: expr_list("]", !options.strict, true) }); }); var object_ = embed_tokens(function() { expect("{"); var first = true, a = []; while (!is("punc", "}")) { if (first) first = false; else expect(","); if (!options.strict && is("punc", "}")) break; var start = S.token; var type = start.type; var name = as_property_name(); if (type == "name" && !is("punc", ":")) { if (name == "get") { a.push(new AST_ObjectGetter({ start: start, key: as_atom_node(), value: function_(AST_Accessor), end: prev() })); continue; } if (name == "set") { a.push(new AST_ObjectSetter({ start: start, key: as_atom_node(), value: function_(AST_Accessor), end: prev() })); continue; } } expect(":"); a.push(new AST_ObjectKeyVal({ start: start, key: name, value: expression(false), end: prev() })); } next(); return new AST_Object({ properties: a }); }); function as_property_name() { var tmp = S.token; next(); switch (tmp.type) { case "num": case "string": case "name": case "operator": case "keyword": case "atom": return tmp.value; default: unexpected(); } } function as_name() { var tmp = S.token; next(); switch (tmp.type) { case "name": case "operator": case "keyword": case "atom": return tmp.value; default: unexpected(); } } function _make_symbol(type) { var name = S.token.value; return new (name == "this" ? AST_This : type)({ name: String(name), start: S.token, end: S.token }); } function as_symbol(type, noerror) { if (!is("name")) { if (!noerror) croak("Name expected"); return null; } var sym = _make_symbol(type); next(); return sym; } var subscripts = function(expr, allow_calls) { var start = expr.start; if (is("punc", ".")) { next(); return subscripts(new AST_Dot({ start: start, expression: expr, property: as_name(), end: prev() }), allow_calls); } if (is("punc", "[")) { next(); var prop = expression(true); expect("]"); return subscripts(new AST_Sub({ start: start, expression: expr, property: prop, end: prev() }), allow_calls); } if (allow_calls && is("punc", "(")) { next(); return subscripts(new AST_Call({ start: start, expression: expr, args: expr_list(")"), end: prev() }), true); } return expr; }; var maybe_unary = function(allow_calls) { var start = S.token; if (is("operator") && UNARY_PREFIX(start.value)) { next(); handle_regexp(); var ex = make_unary(AST_UnaryPrefix, start.value, maybe_unary(allow_calls)); ex.start = start; ex.end = prev(); return ex; } var val = expr_atom(allow_calls); while (is("operator") && UNARY_POSTFIX(S.token.value) && !S.token.nlb) { val = make_unary(AST_UnaryPostfix, S.token.value, val); val.start = start; val.end = S.token; next(); } return val; }; function make_unary(ctor, op, expr) { if ((op == "++" || op == "--") && !is_assignable(expr)) croak("Invalid use of " + op + " operator"); return new ctor({ operator: op, expression: expr }); } var expr_op = function(left, min_prec, no_in) { var op = is("operator") ? S.token.value : null; if (op == "in" && no_in) op = null; var prec = op != null ? PRECEDENCE[op] : null; if (prec != null && prec > min_prec) { next(); var right = expr_op(maybe_unary(true), prec, no_in); return expr_op(new AST_Binary({ start: left.start, left: left, operator: op, right: right, end: right.end }), min_prec, no_in); } return left; }; function expr_ops(no_in) { return expr_op(maybe_unary(true), 0, no_in); } var maybe_conditional = function(no_in) { var start = S.token; var expr = expr_ops(no_in); if (is("operator", "?")) { next(); var yes = expression(false); expect(":"); return new AST_Conditional({ start: start, condition: expr, consequent: yes, alternative: expression(false, no_in), end: prev() }); } return expr; }; function is_assignable(expr) { if (!options.strict) return true; if (expr instanceof AST_This) return false; return expr instanceof AST_PropAccess || expr instanceof AST_Symbol; } var maybe_assign = function(no_in) { var start = S.token; var left = maybe_conditional(no_in), val = S.token.value; if (is("operator") && ASSIGNMENT(val)) { if (is_assignable(left)) { next(); return new AST_Assign({ start: start, left: left, operator: val, right: maybe_assign(no_in), end: prev() }); } croak("Invalid assignment"); } return left; }; var expression = function(commas, no_in) { var start = S.token; var expr = maybe_assign(no_in); if (commas && is("punc", ",")) { next(); return new AST_Seq({ start: start, car: expr, cdr: expression(true, no_in), end: peek() }); } return expr; }; function in_loop(cont) { ++S.in_loop; var ret = cont(); --S.in_loop; return ret; } if (options.expression) { return expression(true); } return function() { var start = S.token; var body = []; while (!is("eof")) body.push(statement()); var end = prev(); var toplevel = options.toplevel; if (toplevel) { toplevel.body = toplevel.body.concat(body); toplevel.end = end; } else { toplevel = new AST_Toplevel({ start: start, body: body, end: end }); } return toplevel; }(); } "use strict"; function TreeTransformer(before, after) { TreeWalker.call(this); this.before = before; this.after = after; } TreeTransformer.prototype = new TreeWalker(); (function(undefined) { function _(node, descend) { node.DEFMETHOD("transform", function(tw, in_list) { var x, y; tw.push(this); if (tw.before) x = tw.before(this, descend, in_list); if (x === undefined) { if (!tw.after) { x = this; descend(x, tw); } else { tw.stack[tw.stack.length - 1] = x = this.clone(); descend(x, tw); y = tw.after(x, in_list); if (y !== undefined) x = y; } } tw.pop(); return x; }); } function do_list(list, tw) { return MAP(list, function(node) { return node.transform(tw, true); }); } _(AST_Node, noop); _(AST_LabeledStatement, function(self, tw) { self.label = self.label.transform(tw); self.body = self.body.transform(tw); }); _(AST_SimpleStatement, function(self, tw) { self.body = self.body.transform(tw); }); _(AST_Block, function(self, tw) { self.body = do_list(self.body, tw); }); _(AST_DWLoop, function(self, tw) { self.condition = self.condition.transform(tw); self.body = self.body.transform(tw); }); _(AST_For, function(self, tw) { if (self.init) self.init = self.init.transform(tw); if (self.condition) self.condition = self.condition.transform(tw); if (self.step) self.step = self.step.transform(tw); self.body = self.body.transform(tw); }); _(AST_ForIn, function(self, tw) { self.init = self.init.transform(tw); self.object = self.object.transform(tw); self.body = self.body.transform(tw); }); _(AST_With, function(self, tw) { self.expression = self.expression.transform(tw); self.body = self.body.transform(tw); }); _(AST_Exit, function(self, tw) { if (self.value) self.value = self.value.transform(tw); }); _(AST_LoopControl, function(self, tw) { if (self.label) self.label = self.label.transform(tw); }); _(AST_If, function(self, tw) { self.condition = self.condition.transform(tw); self.body = self.body.transform(tw); if (self.alternative) self.alternative = self.alternative.transform(tw); }); _(AST_Switch, function(self, tw) { self.expression = self.expression.transform(tw); self.body = do_list(self.body, tw); }); _(AST_Case, function(self, tw) { self.expression = self.expression.transform(tw); self.body = do_list(self.body, tw); }); _(AST_Try, function(self, tw) { self.body = do_list(self.body, tw); if (self.bcatch) self.bcatch = self.bcatch.transform(tw); if (self.bfinally) self.bfinally = self.bfinally.transform(tw); }); _(AST_Catch, function(self, tw) { self.argname = self.argname.transform(tw); self.body = do_list(self.body, tw); }); _(AST_Definitions, function(self, tw) { self.definitions = do_list(self.definitions, tw); }); _(AST_VarDef, function(self, tw) { self.name = self.name.transform(tw); if (self.value) self.value = self.value.transform(tw); }); _(AST_Lambda, function(self, tw) { if (self.name) self.name = self.name.transform(tw); self.argnames = do_list(self.argnames, tw); self.body = do_list(self.body, tw); }); _(AST_Call, function(self, tw) { self.expression = self.expression.transform(tw); self.args = do_list(self.args, tw); }); _(AST_Seq, function(self, tw) { self.car = self.car.transform(tw); self.cdr = self.cdr.transform(tw); }); _(AST_Dot, function(self, tw) { self.expression = self.expression.transform(tw); }); _(AST_Sub, function(self, tw) { self.expression = self.expression.transform(tw); self.property = self.property.transform(tw); }); _(AST_Unary, function(self, tw) { self.expression = self.expression.transform(tw); }); _(AST_Binary, function(self, tw) { self.left = self.left.transform(tw); self.right = self.right.transform(tw); }); _(AST_Conditional, function(self, tw) { self.condition = self.condition.transform(tw); self.consequent = self.consequent.transform(tw); self.alternative = self.alternative.transform(tw); }); _(AST_Array, function(self, tw) { self.elements = do_list(self.elements, tw); }); _(AST_Object, function(self, tw) { self.properties = do_list(self.properties, tw); }); _(AST_ObjectProperty, function(self, tw) { self.value = self.value.transform(tw); }); })(); "use strict"; function SymbolDef(scope, index, orig) { this.name = orig.name; this.orig = [ orig ]; this.scope = scope; this.references = []; this.global = false; this.mangled_name = null; this.undeclared = false; this.constant = false; this.index = index; } SymbolDef.prototype = { unmangleable: function(options) { return this.global && !(options && options.toplevel) || this.undeclared || !(options && options.eval) && (this.scope.uses_eval || this.scope.uses_with); }, mangle: function(options) { if (!this.mangled_name && !this.unmangleable(options)) { var s = this.scope; if (!options.screw_ie8 && this.orig[0] instanceof AST_SymbolLambda) s = s.parent_scope; this.mangled_name = s.next_mangled(options, this); } } }; AST_Toplevel.DEFMETHOD("figure_out_scope", function(options) { options = defaults(options, { screw_ie8: false }); var self = this; var scope = self.parent_scope = null; var defun = null; var nesting = 0; var tw = new TreeWalker(function(node, descend) { if (options.screw_ie8 && node instanceof AST_Catch) { var save_scope = scope; scope = new AST_Scope(node); scope.init_scope_vars(nesting); scope.parent_scope = save_scope; descend(); scope = save_scope; return true; } if (node instanceof AST_Scope) { node.init_scope_vars(nesting); var save_scope = node.parent_scope = scope; var save_defun = defun; defun = scope = node; ++nesting; descend(); --nesting; scope = save_scope; defun = save_defun; return true; } if (node instanceof AST_Directive) { node.scope = scope; push_uniq(scope.directives, node.value); return true; } if (node instanceof AST_With) { for (var s = scope; s; s = s.parent_scope) s.uses_with = true; return; } if (node instanceof AST_Symbol) { node.scope = scope; } if (node instanceof AST_SymbolLambda) { defun.def_function(node); } else if (node instanceof AST_SymbolDefun) { (node.scope = defun.parent_scope).def_function(node); } else if (node instanceof AST_SymbolVar || node instanceof AST_SymbolConst) { var def = defun.def_variable(node); def.constant = node instanceof AST_SymbolConst; def.init = tw.parent().value; } else if (node instanceof AST_SymbolCatch) { (options.screw_ie8 ? scope : defun).def_variable(node); } }); self.walk(tw); var func = null; var globals = self.globals = new Dictionary(); var tw = new TreeWalker(function(node, descend) { if (node instanceof AST_Lambda) { var prev_func = func; func = node; descend(); func = prev_func; return true; } if (node instanceof AST_SymbolRef) { var name = node.name; var sym = node.scope.find_variable(name); if (!sym) { var g; if (globals.has(name)) { g = globals.get(name); } else { g = new SymbolDef(self, globals.size(), node); g.undeclared = true; g.global = true; globals.set(name, g); } node.thedef = g; if (name == "eval" && tw.parent() instanceof AST_Call) { for (var s = node.scope; s && !s.uses_eval; s = s.parent_scope) s.uses_eval = true; } if (func && name == "arguments") { func.uses_arguments = true; } } else { node.thedef = sym; } node.reference(); return true; } }); self.walk(tw); }); AST_Scope.DEFMETHOD("init_scope_vars", function(nesting) { this.directives = []; this.variables = new Dictionary(); this.functions = new Dictionary(); this.uses_with = false; this.uses_eval = false; this.parent_scope = null; this.enclosed = []; this.cname = -1; this.nesting = nesting; }); AST_Scope.DEFMETHOD("strict", function() { return this.has_directive("use strict"); }); AST_Lambda.DEFMETHOD("init_scope_vars", function() { AST_Scope.prototype.init_scope_vars.apply(this, arguments); this.uses_arguments = false; }); AST_SymbolRef.DEFMETHOD("reference", function() { var def = this.definition(); def.references.push(this); var s = this.scope; while (s) { push_uniq(s.enclosed, def); if (s === def.scope) break; s = s.parent_scope; } this.frame = this.scope.nesting - def.scope.nesting; }); AST_Scope.DEFMETHOD("find_variable", function(name) { if (name instanceof AST_Symbol) name = name.name; return this.variables.get(name) || this.parent_scope && this.parent_scope.find_variable(name); }); AST_Scope.DEFMETHOD("has_directive", function(value) { return this.parent_scope && this.parent_scope.has_directive(value) || (this.directives.indexOf(value) >= 0 ? this : null); }); AST_Scope.DEFMETHOD("def_function", function(symbol) { this.functions.set(symbol.name, this.def_variable(symbol)); }); AST_Scope.DEFMETHOD("def_variable", function(symbol) { var def; if (!this.variables.has(symbol.name)) { def = new SymbolDef(this, this.variables.size(), symbol); this.variables.set(symbol.name, def); def.global = !this.parent_scope; } else { def = this.variables.get(symbol.name); def.orig.push(symbol); } return symbol.thedef = def; }); AST_Scope.DEFMETHOD("next_mangled", function(options) { var ext = this.enclosed; out: while (true) { var m = base54(++this.cname); if (!is_identifier(m)) continue; if (options.except.indexOf(m) >= 0) continue; for (var i = ext.length; --i >= 0; ) { var sym = ext[i]; var name = sym.mangled_name || sym.unmangleable(options) && sym.name; if (m == name) continue out; } return m; } }); AST_Function.DEFMETHOD("next_mangled", function(options, def) { var tricky_def = def.orig[0] instanceof AST_SymbolFunarg && this.name && this.name.definition(); while (true) { var name = AST_Lambda.prototype.next_mangled.call(this, options, def); if (!(tricky_def && tricky_def.mangled_name == name)) return name; } }); AST_Scope.DEFMETHOD("references", function(sym) { if (sym instanceof AST_Symbol) sym = sym.definition(); return this.enclosed.indexOf(sym) < 0 ? null : sym; }); AST_Symbol.DEFMETHOD("unmangleable", function(options) { return this.definition().unmangleable(options); }); AST_SymbolAccessor.DEFMETHOD("unmangleable", function() { return true; }); AST_Label.DEFMETHOD("unmangleable", function() { return false; }); AST_Symbol.DEFMETHOD("unreferenced", function() { return this.definition().references.length == 0 && !(this.scope.uses_eval || this.scope.uses_with); }); AST_Symbol.DEFMETHOD("undeclared", function() { return this.definition().undeclared; }); AST_LabelRef.DEFMETHOD("undeclared", function() { return false; }); AST_Label.DEFMETHOD("undeclared", function() { return false; }); AST_Symbol.DEFMETHOD("definition", function() { return this.thedef; }); AST_Symbol.DEFMETHOD("global", function() { return this.definition().global; }); AST_Toplevel.DEFMETHOD("_default_mangler_options", function(options) { return defaults(options, { except: [], eval: false, sort: false, toplevel: false, screw_ie8: false }); }); AST_Toplevel.DEFMETHOD("mangle_names", function(options) { options = this._default_mangler_options(options); var lname = -1; var to_mangle = []; var tw = new TreeWalker(function(node, descend) { if (node instanceof AST_LabeledStatement) { var save_nesting = lname; descend(); lname = save_nesting; return true; } if (node instanceof AST_Scope) { var p = tw.parent(), a = []; node.variables.each(function(symbol) { if (options.except.indexOf(symbol.name) < 0) { a.push(symbol); } }); if (options.sort) a.sort(function(a, b) { return b.references.length - a.references.length; }); to_mangle.push.apply(to_mangle, a); return; } if (node instanceof AST_Label) { var name; do name = base54(++lname); while (!is_identifier(name)); node.mangled_name = name; return true; } if (options.screw_ie8 && node instanceof AST_SymbolCatch) { to_mangle.push(node.definition()); return; } }); this.walk(tw); to_mangle.forEach(function(def) { def.mangle(options); }); }); AST_Toplevel.DEFMETHOD("compute_char_frequency", function(options) { options = this._default_mangler_options(options); var tw = new TreeWalker(function(node) { if (node instanceof AST_Constant) base54.consider(node.print_to_string()); else if (node instanceof AST_Return) base54.consider("return"); else if (node instanceof AST_Throw) base54.consider("throw"); else if (node instanceof AST_Continue) base54.consider("continue"); else if (node instanceof AST_Break) base54.consider("break"); else if (node instanceof AST_Debugger) base54.consider("debugger"); else if (node instanceof AST_Directive) base54.consider(node.value); else if (node instanceof AST_While) base54.consider("while"); else if (node instanceof AST_Do) base54.consider("do while"); else if (node instanceof AST_If) { base54.consider("if"); if (node.alternative) base54.consider("else"); } else if (node instanceof AST_Var) base54.consider("var"); else if (node instanceof AST_Const) base54.consider("const"); else if (node instanceof AST_Lambda) base54.consider("function"); else if (node instanceof AST_For) base54.consider("for"); else if (node instanceof AST_ForIn) base54.consider("for in"); else if (node instanceof AST_Switch) base54.consider("switch"); else if (node instanceof AST_Case) base54.consider("case"); else if (node instanceof AST_Default) base54.consider("default"); else if (node instanceof AST_With) base54.consider("with"); else if (node instanceof AST_ObjectSetter) base54.consider("set" + node.key); else if (node instanceof AST_ObjectGetter) base54.consider("get" + node.key); else if (node instanceof AST_ObjectKeyVal) base54.consider(node.key); else if (node instanceof AST_New) base54.consider("new"); else if (node instanceof AST_This) base54.consider("this"); else if (node instanceof AST_Try) base54.consider("try"); else if (node instanceof AST_Catch) base54.consider("catch"); else if (node instanceof AST_Finally) base54.consider("finally"); else if (node instanceof AST_Symbol && node.unmangleable(options)) base54.consider(node.name); else if (node instanceof AST_Unary || node instanceof AST_Binary) base54.consider(node.operator); else if (node instanceof AST_Dot) base54.consider(node.property); }); this.walk(tw); base54.sort(); }); var base54 = function() { var string = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ$_0123456789"; var chars, frequency; function reset() { frequency = Object.create(null); chars = string.split("").map(function(ch) { return ch.charCodeAt(0); }); chars.forEach(function(ch) { frequency[ch] = 0; }); } base54.consider = function(str) { for (var i = str.length; --i >= 0; ) { var code = str.charCodeAt(i); if (code in frequency) ++frequency[code]; } }; base54.sort = function() { chars = mergeSort(chars, function(a, b) { if (is_digit(a) && !is_digit(b)) return 1; if (is_digit(b) && !is_digit(a)) return -1; return frequency[b] - frequency[a]; }); }; base54.reset = reset; reset(); base54.get = function() { return chars; }; base54.freq = function() { return frequency; }; function base54(num) { var ret = "", base = 54; do { ret += String.fromCharCode(chars[num % base]); num = Math.floor(num / base); base = 64; } while (num > 0); return ret; } return base54; }(); AST_Toplevel.DEFMETHOD("scope_warnings", function(options) { options = defaults(options, { undeclared: false, unreferenced: true, assign_to_global: true, func_arguments: true, nested_defuns: true, eval: true }); var tw = new TreeWalker(function(node) { if (options.undeclared && node instanceof AST_SymbolRef && node.undeclared()) { AST_Node.warn("Undeclared symbol: {name} [{file}:{line},{col}]", { name: node.name, file: node.start.file, line: node.start.line, col: node.start.col }); } if (options.assign_to_global) { var sym = null; if (node instanceof AST_Assign && node.left instanceof AST_SymbolRef) sym = node.left; else if (node instanceof AST_ForIn && node.init instanceof AST_SymbolRef) sym = node.init; if (sym && (sym.undeclared() || sym.global() && sym.scope !== sym.definition().scope)) { AST_Node.warn("{msg}: {name} [{file}:{line},{col}]", { msg: sym.undeclared() ? "Accidental global?" : "Assignment to global", name: sym.name, file: sym.start.file, line: sym.start.line, col: sym.start.col }); } } if (options.eval && node instanceof AST_SymbolRef && node.undeclared() && node.name == "eval") { AST_Node.warn("Eval is used [{file}:{line},{col}]", node.start); } if (options.unreferenced && (node instanceof AST_SymbolDeclaration || node instanceof AST_Label) && node.unreferenced()) { AST_Node.warn("{type} {name} is declared but not referenced [{file}:{line},{col}]", { type: node instanceof AST_Label ? "Label" : "Symbol", name: node.name, file: node.start.file, line: node.start.line, col: node.start.col }); } if (options.func_arguments && node instanceof AST_Lambda && node.uses_arguments) { AST_Node.warn("arguments used in function {name} [{file}:{line},{col}]", { name: node.name ? node.name.name : "anonymous", file: node.start.file, line: node.start.line, col: node.start.col }); } if (options.nested_defuns && node instanceof AST_Defun && !(tw.parent() instanceof AST_Scope)) { AST_Node.warn('Function {name} declared in nested statement "{type}" [{file}:{line},{col}]', { name: node.name.name, type: tw.parent().TYPE, file: node.start.file, line: node.start.line, col: node.start.col }); } }); this.walk(tw); }); "use strict"; function OutputStream(options) { options = defaults(options, { indent_start: 0, indent_level: 4, quote_keys: false, space_colon: true, ascii_only: false, unescape_regexps: false, inline_script: false, width: 80, max_line_len: 32e3, beautify: false, source_map: null, bracketize: false, semicolons: true, comments: false, preserve_line: false, screw_ie8: false, preamble: null }, true); var indentation = 0; var current_col = 0; var current_line = 1; var current_pos = 0; var OUTPUT = ""; function to_ascii(str, identifier) { return str.replace(/[\u0080-\uffff]/g, function(ch) { var code = ch.charCodeAt(0).toString(16); if (code.length <= 2 && !identifier) { while (code.length < 2) code = "0" + code; return "\\x" + code; } else { while (code.length < 4) code = "0" + code; return "\\u" + code; } }); } function make_string(str) { var dq = 0, sq = 0; str = str.replace(/[\\\b\f\n\r\t\x22\x27\u2028\u2029\0]/g, function(s) { switch (s) { case "\\": return "\\\\"; case "\b": return "\\b"; case "\f": return "\\f"; case "\n": return "\\n"; case "\r": return "\\r"; case "\u2028": return "\\u2028"; case "\u2029": return "\\u2029"; case '"': ++dq; return '"'; case "'": ++sq; return "'"; case "\x00": return "\\x00"; } return s; }); if (options.ascii_only) str = to_ascii(str); if (dq > sq) return "'" + str.replace(/\x27/g, "\\'") + "'"; else return '"' + str.replace(/\x22/g, '\\"') + '"'; } function encode_string(str) { var ret = make_string(str); if (options.inline_script) ret = ret.replace(/<\x2fscript([>\/\t\n\f\r ])/gi, "<\\/script$1"); return ret; } function make_name(name) { name = name.toString(); if (options.ascii_only) name = to_ascii(name, true); return name; } function make_indent(back) { return repeat_string(" ", options.indent_start + indentation - back * options.indent_level); } var might_need_space = false; var might_need_semicolon = false; var last = null; function last_char() { return last.charAt(last.length - 1); } function maybe_newline() { if (options.max_line_len && current_col > options.max_line_len) print("\n"); } var requireSemicolonChars = makePredicate("( [ + * / - , ."); function print(str) { str = String(str); var ch = str.charAt(0); if (might_need_semicolon) { if ((!ch || ";}".indexOf(ch) < 0) && !/[;]$/.test(last)) { if (options.semicolons || requireSemicolonChars(ch)) { OUTPUT += ";"; current_col++; current_pos++; } else { OUTPUT += "\n"; current_pos++; current_line++; current_col = 0; } if (!options.beautify) might_need_space = false; } might_need_semicolon = false; maybe_newline(); } if (!options.beautify && options.preserve_line && stack[stack.length - 1]) { var target_line = stack[stack.length - 1].start.line; while (current_line < target_line) { OUTPUT += "\n"; current_pos++; current_line++; current_col = 0; might_need_space = false; } } if (might_need_space) { var prev = last_char(); if (is_identifier_char(prev) && (is_identifier_char(ch) || ch == "\\") || /^[\+\-\/]$/.test(ch) && ch == prev) { OUTPUT += " "; current_col++; current_pos++; } might_need_space = false; } var a = str.split(/\r?\n/), n = a.length - 1; current_line += n; if (n == 0) { current_col += a[n].length; } else { current_col = a[n].length; } current_pos += str.length; last = str; OUTPUT += str; } var space = options.beautify ? function() { print(" "); } : function() { might_need_space = true; }; var indent = options.beautify ? function(half) { if (options.beautify) { print(make_indent(half ? .5 : 0)); } } : noop; var with_indent = options.beautify ? function(col, cont) { if (col === true) col = next_indent(); var save_indentation = indentation; indentation = col; var ret = cont(); indentation = save_indentation; return ret; } : function(col, cont) { return cont(); }; var newline = options.beautify ? function() { print("\n"); } : noop; var semicolon = options.beautify ? function() { print(";"); } : function() { might_need_semicolon = true; }; function force_semicolon() { might_need_semicolon = false; print(";"); } function next_indent() { return indentation + options.indent_level; } function with_block(cont) { var ret; print("{"); newline(); with_indent(next_indent(), function() { ret = cont(); }); indent(); print("}"); return ret; } function with_parens(cont) { print("("); var ret = cont(); print(")"); return ret; } function with_square(cont) { print("["); var ret = cont(); print("]"); return ret; } function comma() { print(","); space(); } function colon() { print(":"); if (options.space_colon) space(); } var add_mapping = options.source_map ? function(token, name) { try { if (token) options.source_map.add(token.file || "?", current_line, current_col, token.line, token.col, !name && token.type == "name" ? token.value : name); } catch (ex) { AST_Node.warn("Couldn't figure out mapping for {file}:{line},{col} → {cline},{ccol} [{name}]", { file: token.file, line: token.line, col: token.col, cline: current_line, ccol: current_col, name: name || "" }); } } : noop; function get() { return OUTPUT; } if (options.preamble) { print(options.preamble.replace(/\r\n?|[\n\u2028\u2029]|\s*$/g, "\n")); } var stack = []; return { get: get, toString: get, indent: indent, indentation: function() { return indentation; }, current_width: function() { return current_col - indentation; }, should_break: function() { return options.width && this.current_width() >= options.width; }, newline: newline, print: print, space: space, comma: comma, colon: colon, last: function() { return last; }, semicolon: semicolon, force_semicolon: force_semicolon, to_ascii: to_ascii, print_name: function(name) { print(make_name(name)); }, print_string: function(str) { print(encode_string(str)); }, next_indent: next_indent, with_indent: with_indent, with_block: with_block, with_parens: with_parens, with_square: with_square, add_mapping: add_mapping, option: function(opt) { return options[opt]; }, line: function() { return current_line; }, col: function() { return current_col; }, pos: function() { return current_pos; }, push_node: function(node) { stack.push(node); }, pop_node: function() { return stack.pop(); }, stack: function() { return stack; }, parent: function(n) { return stack[stack.length - 2 - (n || 0)]; } }; } (function() { function DEFPRINT(nodetype, generator) { nodetype.DEFMETHOD("_codegen", generator); } AST_Node.DEFMETHOD("print", function(stream, force_parens) { var self = this, generator = self._codegen; function doit() { self.add_comments(stream); self.add_source_map(stream); generator(self, stream); } stream.push_node(self); if (force_parens || self.needs_parens(stream)) { stream.with_parens(doit); } else { doit(); } stream.pop_node(); }); AST_Node.DEFMETHOD("print_to_string", function(options) { var s = OutputStream(options); this.print(s); return s.get(); }); AST_Node.DEFMETHOD("add_comments", function(output) { var c = output.option("comments"), self = this; if (c) { var start = self.start; if (start && !start._comments_dumped) { start._comments_dumped = true; var comments = start.comments_before || []; if (self instanceof AST_Exit && self.value) { self.value.walk(new TreeWalker(function(node) { if (node.start && node.start.comments_before) { comments = comments.concat(node.start.comments_before); node.start.comments_before = []; } if (node instanceof AST_Function || node instanceof AST_Array || node instanceof AST_Object) { return true; } })); } if (c.test) { comments = comments.filter(function(comment) { return c.test(comment.value); }); } else if (typeof c == "function") { comments = comments.filter(function(comment) { return c(self, comment); }); } comments.forEach(function(c) { if (/comment[134]/.test(c.type)) { output.print("//" + c.value + "\n"); output.indent(); } else if (c.type == "comment2") { output.print("/*" + c.value + "*/"); if (start.nlb) { output.print("\n"); output.indent(); } else { output.space(); } } }); } } }); function PARENS(nodetype, func) { if (Array.isArray(nodetype)) { nodetype.forEach(function(nodetype) { PARENS(nodetype, func); }); } else { nodetype.DEFMETHOD("needs_parens", func); } } PARENS(AST_Node, function() { return false; }); PARENS(AST_Function, function(output) { return first_in_statement(output); }); PARENS(AST_Object, function(output) { return first_in_statement(output); }); PARENS([ AST_Unary, AST_Undefined ], function(output) { var p = output.parent(); return p instanceof AST_PropAccess && p.expression === this; }); PARENS(AST_Seq, function(output) { var p = output.parent(); return p instanceof AST_Call || p instanceof AST_Unary || p instanceof AST_Binary || p instanceof AST_VarDef || p instanceof AST_PropAccess || p instanceof AST_Array || p instanceof AST_ObjectProperty || p instanceof AST_Conditional; }); PARENS(AST_Binary, function(output) { var p = output.parent(); if (p instanceof AST_Call && p.expression === this) return true; if (p instanceof AST_Unary) return true; if (p instanceof AST_PropAccess && p.expression === this) return true; if (p instanceof AST_Binary) { var po = p.operator, pp = PRECEDENCE[po]; var so = this.operator, sp = PRECEDENCE[so]; if (pp > sp || pp == sp && this === p.right) { return true; } } }); PARENS(AST_PropAccess, function(output) { var p = output.parent(); if (p instanceof AST_New && p.expression === this) { try { this.walk(new TreeWalker(function(node) { if (node instanceof AST_Call) throw p; })); } catch (ex) { if (ex !== p) throw ex; return true; } } }); PARENS(AST_Call, function(output) { var p = output.parent(), p1; if (p instanceof AST_New && p.expression === this) return true; return this.expression instanceof AST_Function && p instanceof AST_PropAccess && p.expression === this && (p1 = output.parent(1)) instanceof AST_Assign && p1.left === p; }); PARENS(AST_New, function(output) { var p = output.parent(); if (no_constructor_parens(this, output) && (p instanceof AST_PropAccess || p instanceof AST_Call && p.expression === this)) return true; }); PARENS(AST_Number, function(output) { var p = output.parent(); if (this.getValue() < 0 && p instanceof AST_PropAccess && p.expression === this) return true; }); PARENS(AST_NaN, function(output) { var p = output.parent(); if (p instanceof AST_PropAccess && p.expression === this) return true; }); PARENS([ AST_Assign, AST_Conditional ], function(output) { var p = output.parent(); if (p instanceof AST_Unary) return true; if (p instanceof AST_Binary && !(p instanceof AST_Assign)) return true; if (p instanceof AST_Call && p.expression === this) return true; if (p instanceof AST_Conditional && p.condition === this) return true; if (p instanceof AST_PropAccess && p.expression === this) return true; }); DEFPRINT(AST_Directive, function(self, output) { output.print_string(self.value); output.semicolon(); }); DEFPRINT(AST_Debugger, function(self, output) { output.print("debugger"); output.semicolon(); }); function display_body(body, is_toplevel, output) { var last = body.length - 1; body.forEach(function(stmt, i) { if (!(stmt instanceof AST_EmptyStatement)) { output.indent(); stmt.print(output); if (!(i == last && is_toplevel)) { output.newline(); if (is_toplevel) output.newline(); } } }); } AST_StatementWithBody.DEFMETHOD("_do_print_body", function(output) { force_statement(this.body, output); }); DEFPRINT(AST_Statement, function(self, output) { self.body.print(output); output.semicolon(); }); DEFPRINT(AST_Toplevel, function(self, output) { display_body(self.body, true, output); output.print(""); }); DEFPRINT(AST_LabeledStatement, function(self, output) { self.label.print(output); output.colon(); self.body.print(output); }); DEFPRINT(AST_SimpleStatement, function(self, output) { self.body.print(output); output.semicolon(); }); function print_bracketed(body, output) { if (body.length > 0) output.with_block(function() { display_body(body, false, output); }); else output.print("{}"); } DEFPRINT(AST_BlockStatement, function(self, output) { print_bracketed(self.body, output); }); DEFPRINT(AST_EmptyStatement, function(self, output) { output.semicolon(); }); DEFPRINT(AST_Do, function(self, output) { output.print("do"); output.space(); self._do_print_body(output); output.space(); output.print("while"); output.space(); output.with_parens(function() { self.condition.print(output); }); output.semicolon(); }); DEFPRINT(AST_While, function(self, output) { output.print("while"); output.space(); output.with_parens(function() { self.condition.print(output); }); output.space(); self._do_print_body(output); }); DEFPRINT(AST_For, function(self, output) { output.print("for"); output.space(); output.with_parens(function() { if (self.init && !(self.init instanceof AST_EmptyStatement)) { if (self.init instanceof AST_Definitions) { self.init.print(output); } else { parenthesize_for_noin(self.init, output, true); } output.print(";"); output.space(); } else { output.print(";"); } if (self.condition) { self.condition.print(output); output.print(";"); output.space(); } else { output.print(";"); } if (self.step) { self.step.print(output); } }); output.space(); self._do_print_body(output); }); DEFPRINT(AST_ForIn, function(self, output) { output.print("for"); output.space(); output.with_parens(function() { self.init.print(output); output.space(); output.print("in"); output.space(); self.object.print(output); }); output.space(); self._do_print_body(output); }); DEFPRINT(AST_With, function(self, output) { output.print("with"); output.space(); output.with_parens(function() { self.expression.print(output); }); output.space(); self._do_print_body(output); }); AST_Lambda.DEFMETHOD("_do_print", function(output, nokeyword) { var self = this; if (!nokeyword) { output.print("function"); } if (self.name) { output.space(); self.name.print(output); } output.with_parens(function() { self.argnames.forEach(function(arg, i) { if (i) output.comma(); arg.print(output); }); }); output.space(); print_bracketed(self.body, output); }); DEFPRINT(AST_Lambda, function(self, output) { self._do_print(output); }); AST_Exit.DEFMETHOD("_do_print", function(output, kind) { output.print(kind); if (this.value) { output.space(); this.value.print(output); } output.semicolon(); }); DEFPRINT(AST_Return, function(self, output) { self._do_print(output, "return"); }); DEFPRINT(AST_Throw, function(self, output) { self._do_print(output, "throw"); }); AST_LoopControl.DEFMETHOD("_do_print", function(output, kind) { output.print(kind); if (this.label) { output.space(); this.label.print(output); } output.semicolon(); }); DEFPRINT(AST_Break, function(self, output) { self._do_print(output, "break"); }); DEFPRINT(AST_Continue, function(self, output) { self._do_print(output, "continue"); }); function make_then(self, output) { if (output.option("bracketize")) { make_block(self.body, output); return; } if (!self.body) return output.force_semicolon(); if (self.body instanceof AST_Do && !output.option("screw_ie8")) { make_block(self.body, output); return; } var b = self.body; while (true) { if (b instanceof AST_If) { if (!b.alternative) { make_block(self.body, output); return; } b = b.alternative; } else if (b instanceof AST_StatementWithBody) { b = b.body; } else break; } force_statement(self.body, output); } DEFPRINT(AST_If, function(self, output) { output.print("if"); output.space(); output.with_parens(function() { self.condition.print(output); }); output.space(); if (self.alternative) { make_then(self, output); output.space(); output.print("else"); output.space(); force_statement(self.alternative, output); } else { self._do_print_body(output); } }); DEFPRINT(AST_Switch, function(self, output) { output.print("switch"); output.space(); output.with_parens(function() { self.expression.print(output); }); output.space(); if (self.body.length > 0) output.with_block(function() { self.body.forEach(function(stmt, i) { if (i) output.newline(); output.indent(true); stmt.print(output); }); }); else output.print("{}"); }); AST_SwitchBranch.DEFMETHOD("_do_print_body", function(output) { if (this.body.length > 0) { output.newline(); this.body.forEach(function(stmt) { output.indent(); stmt.print(output); output.newline(); }); } }); DEFPRINT(AST_Default, function(self, output) { output.print("default:"); self._do_print_body(output); }); DEFPRINT(AST_Case, function(self, output) { output.print("case"); output.space(); self.expression.print(output); output.print(":"); self._do_print_body(output); }); DEFPRINT(AST_Try, function(self, output) { output.print("try"); output.space(); print_bracketed(self.body, output); if (self.bcatch) { output.space(); self.bcatch.print(output); } if (self.bfinally) { output.space(); self.bfinally.print(output); } }); DEFPRINT(AST_Catch, function(self, output) { output.print("catch"); output.space(); output.with_parens(function() { self.argname.print(output); }); output.space(); print_bracketed(self.body, output); }); DEFPRINT(AST_Finally, function(self, output) { output.print("finally"); output.space(); print_bracketed(self.body, output); }); AST_Definitions.DEFMETHOD("_do_print", function(output, kind) { output.print(kind); output.space(); this.definitions.forEach(function(def, i) { if (i) output.comma(); def.print(output); }); var p = output.parent(); var in_for = p instanceof AST_For || p instanceof AST_ForIn; var avoid_semicolon = in_for && p.init === this; if (!avoid_semicolon) output.semicolon(); }); DEFPRINT(AST_Var, function(self, output) { self._do_print(output, "var"); }); DEFPRINT(AST_Const, function(self, output) { self._do_print(output, "const"); }); function parenthesize_for_noin(node, output, noin) { if (!noin) node.print(output); else try { node.walk(new TreeWalker(function(node) { if (node instanceof AST_Binary && node.operator == "in") throw output; })); node.print(output); } catch (ex) { if (ex !== output) throw ex; node.print(output, true); } } DEFPRINT(AST_VarDef, function(self, output) { self.name.print(output); if (self.value) { output.space(); output.print("="); output.space(); var p = output.parent(1); var noin = p instanceof AST_For || p instanceof AST_ForIn; parenthesize_for_noin(self.value, output, noin); } }); DEFPRINT(AST_Call, function(self, output) { self.expression.print(output); if (self instanceof AST_New && no_constructor_parens(self, output)) return; output.with_parens(function() { self.args.forEach(function(expr, i) { if (i) output.comma(); expr.print(output); }); }); }); DEFPRINT(AST_New, function(self, output) { output.print("new"); output.space(); AST_Call.prototype._codegen(self, output); }); AST_Seq.DEFMETHOD("_do_print", function(output) { this.car.print(output); if (this.cdr) { output.comma(); if (output.should_break()) { output.newline(); output.indent(); } this.cdr.print(output); } }); DEFPRINT(AST_Seq, function(self, output) { self._do_print(output); }); DEFPRINT(AST_Dot, function(self, output) { var expr = self.expression; expr.print(output); if (expr instanceof AST_Number && expr.getValue() >= 0) { if (!/[xa-f.]/i.test(output.last())) { output.print("."); } } output.print("."); output.add_mapping(self.end); output.print_name(self.property); }); DEFPRINT(AST_Sub, function(self, output) { self.expression.print(output); output.print("["); self.property.print(output); output.print("]"); }); DEFPRINT(AST_UnaryPrefix, function(self, output) { var op = self.operator; output.print(op); if (/^[a-z]/i.test(op) || /[+-]$/.test(op) && self.expression instanceof AST_UnaryPrefix && /^[+-]/.test(self.expression.operator)) { output.space(); } self.expression.print(output); }); DEFPRINT(AST_UnaryPostfix, function(self, output) { self.expression.print(output); output.print(self.operator); }); DEFPRINT(AST_Binary, function(self, output) { self.left.print(output); output.space(); output.print(self.operator); if (self.operator == "<" && self.right instanceof AST_UnaryPrefix && self.right.operator == "!" && self.right.expression instanceof AST_UnaryPrefix && self.right.expression.operator == "--") { output.print(" "); } else { output.space(); } self.right.print(output); }); DEFPRINT(AST_Conditional, function(self, output) { self.condition.print(output); output.space(); output.print("?"); output.space(); self.consequent.print(output); output.space(); output.colon(); self.alternative.print(output); }); DEFPRINT(AST_Array, function(self, output) { output.with_square(function() { var a = self.elements, len = a.length; if (len > 0) output.space(); a.forEach(function(exp, i) { if (i) output.comma(); exp.print(output); if (i === len - 1 && exp instanceof AST_Hole) output.comma(); }); if (len > 0) output.space(); }); }); DEFPRINT(AST_Object, function(self, output) { if (self.properties.length > 0) output.with_block(function() { self.properties.forEach(function(prop, i) { if (i) { output.print(","); output.newline(); } output.indent(); prop.print(output); }); output.newline(); }); else output.print("{}"); }); DEFPRINT(AST_ObjectKeyVal, function(self, output) { var key = self.key; if (output.option("quote_keys")) { output.print_string(key + ""); } else if ((typeof key == "number" || !output.option("beautify") && +key + "" == key) && parseFloat(key) >= 0) { output.print(make_num(key)); } else if (RESERVED_WORDS(key) ? output.option("screw_ie8") : is_identifier_string(key)) { output.print_name(key); } else { output.print_string(key); } output.colon(); self.value.print(output); }); DEFPRINT(AST_ObjectSetter, function(self, output) { output.print("set"); output.space(); self.key.print(output); self.value._do_print(output, true); }); DEFPRINT(AST_ObjectGetter, function(self, output) { output.print("get"); output.space(); self.key.print(output); self.value._do_print(output, true); }); DEFPRINT(AST_Symbol, function(self, output) { var def = self.definition(); output.print_name(def ? def.mangled_name || def.name : self.name); }); DEFPRINT(AST_Undefined, function(self, output) { output.print("void 0"); }); DEFPRINT(AST_Hole, noop); DEFPRINT(AST_Infinity, function(self, output) { output.print("1/0"); }); DEFPRINT(AST_NaN, function(self, output) { output.print("0/0"); }); DEFPRINT(AST_This, function(self, output) { output.print("this"); }); DEFPRINT(AST_Constant, function(self, output) { output.print(self.getValue()); }); DEFPRINT(AST_String, function(self, output) { output.print_string(self.getValue()); }); DEFPRINT(AST_Number, function(self, output) { output.print(make_num(self.getValue())); }); function regexp_safe_literal(code) { return [ 92, 47, 46, 43, 42, 63, 40, 41, 91, 93, 123, 125, 36, 94, 58, 124, 33, 10, 13, 0, 65279, 8232, 8233 ].indexOf(code) < 0; } DEFPRINT(AST_RegExp, function(self, output) { var str = self.getValue().toString(); if (output.option("ascii_only")) { str = output.to_ascii(str); } else if (output.option("unescape_regexps")) { str = str.split("\\\\").map(function(str) { return str.replace(/\\u[0-9a-fA-F]{4}|\\x[0-9a-fA-F]{2}/g, function(s) { var code = parseInt(s.substr(2), 16); return regexp_safe_literal(code) ? String.fromCharCode(code) : s; }); }).join("\\\\"); } output.print(str); var p = output.parent(); if (p instanceof AST_Binary && /^in/.test(p.operator) && p.left === self) output.print(" "); }); function force_statement(stat, output) { if (output.option("bracketize")) { if (!stat || stat instanceof AST_EmptyStatement) output.print("{}"); else if (stat instanceof AST_BlockStatement) stat.print(output); else output.with_block(function() { output.indent(); stat.print(output); output.newline(); }); } else { if (!stat || stat instanceof AST_EmptyStatement) output.force_semicolon(); else stat.print(output); } } function first_in_statement(output) { var a = output.stack(), i = a.length, node = a[--i], p = a[--i]; while (i > 0) { if (p instanceof AST_Statement && p.body === node) return true; if (p instanceof AST_Seq && p.car === node || p instanceof AST_Call && p.expression === node && !(p instanceof AST_New) || p instanceof AST_Dot && p.expression === node || p instanceof AST_Sub && p.expression === node || p instanceof AST_Conditional && p.condition === node || p instanceof AST_Binary && p.left === node || p instanceof AST_UnaryPostfix && p.expression === node) { node = p; p = a[--i]; } else { return false; } } } function no_constructor_parens(self, output) { return self.args.length == 0 && !output.option("beautify"); } function best_of(a) { var best = a[0], len = best.length; for (var i = 1; i < a.length; ++i) { if (a[i].length < len) { best = a[i]; len = best.length; } } return best; } function make_num(num) { var str = num.toString(10), a = [ str.replace(/^0\./, ".").replace("e+", "e") ], m; if (Math.floor(num) === num) { if (num >= 0) { a.push("0x" + num.toString(16).toLowerCase(), "0" + num.toString(8)); } else { a.push("-0x" + (-num).toString(16).toLowerCase(), "-0" + (-num).toString(8)); } if (m = /^(.*?)(0+)$/.exec(num)) { a.push(m[1] + "e" + m[2].length); } } else if (m = /^0?\.(0+)(.*)$/.exec(num)) { a.push(m[2] + "e-" + (m[1].length + m[2].length), str.substr(str.indexOf("."))); } return best_of(a); } function make_block(stmt, output) { if (stmt instanceof AST_BlockStatement) { stmt.print(output); return; } output.with_block(function() { output.indent(); stmt.print(output); output.newline(); }); } function DEFMAP(nodetype, generator) { nodetype.DEFMETHOD("add_source_map", function(stream) { generator(this, stream); }); } DEFMAP(AST_Node, noop); function basic_sourcemap_gen(self, output) { output.add_mapping(self.start); } DEFMAP(AST_Directive, basic_sourcemap_gen); DEFMAP(AST_Debugger, basic_sourcemap_gen); DEFMAP(AST_Symbol, basic_sourcemap_gen); DEFMAP(AST_Jump, basic_sourcemap_gen); DEFMAP(AST_StatementWithBody, basic_sourcemap_gen); DEFMAP(AST_LabeledStatement, noop); DEFMAP(AST_Lambda, basic_sourcemap_gen); DEFMAP(AST_Switch, basic_sourcemap_gen); DEFMAP(AST_SwitchBranch, basic_sourcemap_gen); DEFMAP(AST_BlockStatement, basic_sourcemap_gen); DEFMAP(AST_Toplevel, noop); DEFMAP(AST_New, basic_sourcemap_gen); DEFMAP(AST_Try, basic_sourcemap_gen); DEFMAP(AST_Catch, basic_sourcemap_gen); DEFMAP(AST_Finally, basic_sourcemap_gen); DEFMAP(AST_Definitions, basic_sourcemap_gen); DEFMAP(AST_Constant, basic_sourcemap_gen); DEFMAP(AST_ObjectProperty, function(self, output) { output.add_mapping(self.start, self.key); }); })(); "use strict"; function Compressor(options, false_by_default) { if (!(this instanceof Compressor)) return new Compressor(options, false_by_default); TreeTransformer.call(this, this.before, this.after); this.options = defaults(options, { sequences: !false_by_default, properties: !false_by_default, dead_code: !false_by_default, drop_debugger: !false_by_default, unsafe: false, unsafe_comps: false, conditionals: !false_by_default, comparisons: !false_by_default, evaluate: !false_by_default, booleans: !false_by_default, loops: !false_by_default, unused: !false_by_default, hoist_funs: !false_by_default, keep_fargs: false, hoist_vars: false, if_return: !false_by_default, join_vars: !false_by_default, cascade: !false_by_default, side_effects: !false_by_default, pure_getters: false, pure_funcs: null, negate_iife: !false_by_default, screw_ie8: false, drop_console: false, angular: false, warnings: true, global_defs: {} }, true); } Compressor.prototype = new TreeTransformer(); merge(Compressor.prototype, { option: function(key) { return this.options[key]; }, warn: function() { if (this.options.warnings) AST_Node.warn.apply(AST_Node, arguments); }, before: function(node, descend, in_list) { if (node._squeezed) return node; var was_scope = false; if (node instanceof AST_Scope) { node = node.hoist_declarations(this); was_scope = true; } descend(node, this); node = node.optimize(this); if (was_scope && node instanceof AST_Scope) { node.drop_unused(this); descend(node, this); } node._squeezed = true; return node; } }); (function() { function OPT(node, optimizer) { node.DEFMETHOD("optimize", function(compressor) { var self = this; if (self._optimized) return self; var opt = optimizer(self, compressor); opt._optimized = true; if (opt === self) return opt; return opt.transform(compressor); }); } OPT(AST_Node, function(self, compressor) { return self; }); AST_Node.DEFMETHOD("equivalent_to", function(node) { return this.print_to_string() == node.print_to_string(); }); function make_node(ctor, orig, props) { if (!props) props = {}; if (orig) { if (!props.start) props.start = orig.start; if (!props.end) props.end = orig.end; } return new ctor(props); } function make_node_from_constant(compressor, val, orig) { if (val instanceof AST_Node) return val.transform(compressor); switch (typeof val) { case "string": return make_node(AST_String, orig, { value: val }).optimize(compressor); case "number": return make_node(isNaN(val) ? AST_NaN : AST_Number, orig, { value: val }).optimize(compressor); case "boolean": return make_node(val ? AST_True : AST_False, orig).optimize(compressor); case "undefined": return make_node(AST_Undefined, orig).optimize(compressor); default: if (val === null) { return make_node(AST_Null, orig).optimize(compressor); } if (val instanceof RegExp) { return make_node(AST_RegExp, orig).optimize(compressor); } throw new Error(string_template("Can't handle constant of type: {type}", { type: typeof val })); } } function as_statement_array(thing) { if (thing === null) return []; if (thing instanceof AST_BlockStatement) return thing.body; if (thing instanceof AST_EmptyStatement) return []; if (thing instanceof AST_Statement) return [ thing ]; throw new Error("Can't convert thing to statement array"); } function is_empty(thing) { if (thing === null) return true; if (thing instanceof AST_EmptyStatement) return true; if (thing instanceof AST_BlockStatement) return thing.body.length == 0; return false; } function loop_body(x) { if (x instanceof AST_Switch) return x; if (x instanceof AST_For || x instanceof AST_ForIn || x instanceof AST_DWLoop) { return x.body instanceof AST_BlockStatement ? x.body : x; } return x; } function tighten_body(statements, compressor) { var CHANGED; do { CHANGED = false; if (compressor.option("angular")) { statements = process_for_angular(statements); } statements = eliminate_spurious_blocks(statements); if (compressor.option("dead_code")) { statements = eliminate_dead_code(statements, compressor); } if (compressor.option("if_return")) { statements = handle_if_return(statements, compressor); } if (compressor.option("sequences")) { statements = sequencesize(statements, compressor); } if (compressor.option("join_vars")) { statements = join_consecutive_vars(statements, compressor); } } while (CHANGED); if (compressor.option("negate_iife")) { negate_iifes(statements, compressor); } return statements; function process_for_angular(statements) { function make_injector(func, name) { return make_node(AST_SimpleStatement, func, { body: make_node(AST_Assign, func, { operator: "=", left: make_node(AST_Dot, name, { expression: make_node(AST_SymbolRef, name, name), property: "$inject" }), right: make_node(AST_Array, func, { elements: func.argnames.map(function(sym) { return make_node(AST_String, sym, { value: sym.name }); }) }) }) }); } return statements.reduce(function(a, stat) { a.push(stat); var token = stat.start; var comments = token.comments_before; if (comments && comments.length > 0) { var last = comments.pop(); if (/@ngInject/.test(last.value)) { if (stat instanceof AST_Defun) { a.push(make_injector(stat, stat.name)); } else if (stat instanceof AST_Definitions) { stat.definitions.forEach(function(def) { if (def.value && def.value instanceof AST_Lambda) { a.push(make_injector(def.value, def.name)); } }); } else { compressor.warn("Unknown statement marked with @ngInject [{file}:{line},{col}]", token); } } } return a; }, []); } function eliminate_spurious_blocks(statements) { var seen_dirs = []; return statements.reduce(function(a, stat) { if (stat instanceof AST_BlockStatement) { CHANGED = true; a.push.apply(a, eliminate_spurious_blocks(stat.body)); } else if (stat instanceof AST_EmptyStatement) { CHANGED = true; } else if (stat instanceof AST_Directive) { if (seen_dirs.indexOf(stat.value) < 0) { a.push(stat); seen_dirs.push(stat.value); } else { CHANGED = true; } } else { a.push(stat); } return a; }, []); } function handle_if_return(statements, compressor) { var self = compressor.self(); var in_lambda = self instanceof AST_Lambda; var ret = []; loop: for (var i = statements.length; --i >= 0; ) { var stat = statements[i]; switch (true) { case in_lambda && stat instanceof AST_Return && !stat.value && ret.length == 0: CHANGED = true; continue loop; case stat instanceof AST_If: if (stat.body instanceof AST_Return) { if ((in_lambda && ret.length == 0 || ret[0] instanceof AST_Return && !ret[0].value) && !stat.body.value && !stat.alternative) { CHANGED = true; var cond = make_node(AST_SimpleStatement, stat.condition, { body: stat.condition }); ret.unshift(cond); continue loop; } if (ret[0] instanceof AST_Return && stat.body.value && ret[0].value && !stat.alternative) { CHANGED = true; stat = stat.clone(); stat.alternative = ret[0]; ret[0] = stat.transform(compressor); continue loop; } if ((ret.length == 0 || ret[0] instanceof AST_Return) && stat.body.value && !stat.alternative && in_lambda) { CHANGED = true; stat = stat.clone(); stat.alternative = ret[0] || make_node(AST_Return, stat, { value: make_node(AST_Undefined, stat) }); ret[0] = stat.transform(compressor); continue loop; } if (!stat.body.value && in_lambda) { CHANGED = true; stat = stat.clone(); stat.condition = stat.condition.negate(compressor); stat.body = make_node(AST_BlockStatement, stat, { body: as_statement_array(stat.alternative).concat(ret) }); stat.alternative = null; ret = [ stat.transform(compressor) ]; continue loop; } if (ret.length == 1 && in_lambda && ret[0] instanceof AST_SimpleStatement && (!stat.alternative || stat.alternative instanceof AST_SimpleStatement)) { CHANGED = true; ret.push(make_node(AST_Return, ret[0], { value: make_node(AST_Undefined, ret[0]) }).transform(compressor)); ret = as_statement_array(stat.alternative).concat(ret); ret.unshift(stat); continue loop; } } var ab = aborts(stat.body); var lct = ab instanceof AST_LoopControl ? compressor.loopcontrol_target(ab.label) : null; if (ab && (ab instanceof AST_Return && !ab.value && in_lambda || ab instanceof AST_Continue && self === loop_body(lct) || ab instanceof AST_Break && lct instanceof AST_BlockStatement && self === lct)) { if (ab.label) { remove(ab.label.thedef.references, ab); } CHANGED = true; var body = as_statement_array(stat.body).slice(0, -1); stat = stat.clone(); stat.condition = stat.condition.negate(compressor); stat.body = make_node(AST_BlockStatement, stat, { body: as_statement_array(stat.alternative).concat(ret) }); stat.alternative = make_node(AST_BlockStatement, stat, { body: body }); ret = [ stat.transform(compressor) ]; continue loop; } var ab = aborts(stat.alternative); var lct = ab instanceof AST_LoopControl ? compressor.loopcontrol_target(ab.label) : null; if (ab && (ab instanceof AST_Return && !ab.value && in_lambda || ab instanceof AST_Continue && self === loop_body(lct) || ab instanceof AST_Break && lct instanceof AST_BlockStatement && self === lct)) { if (ab.label) { remove(ab.label.thedef.references, ab); } CHANGED = true; stat = stat.clone(); stat.body = make_node(AST_BlockStatement, stat.body, { body: as_statement_array(stat.body).concat(ret) }); stat.alternative = make_node(AST_BlockStatement, stat.alternative, { body: as_statement_array(stat.alternative).slice(0, -1) }); ret = [ stat.transform(compressor) ]; continue loop; } ret.unshift(stat); break; default: ret.unshift(stat); break; } } return ret; } function eliminate_dead_code(statements, compressor) { var has_quit = false; var orig = statements.length; var self = compressor.self(); statements = statements.reduce(function(a, stat) { if (has_quit) { extract_declarations_from_unreachable_code(compressor, stat, a); } else { if (stat instanceof AST_LoopControl) { var lct = compressor.loopcontrol_target(stat.label); if (stat instanceof AST_Break && lct instanceof AST_BlockStatement && loop_body(lct) === self || stat instanceof AST_Continue && loop_body(lct) === self) { if (stat.label) { remove(stat.label.thedef.references, stat); } } else { a.push(stat); } } else { a.push(stat); } if (aborts(stat)) has_quit = true; } return a; }, []); CHANGED = statements.length != orig; return statements; } function sequencesize(statements, compressor) { if (statements.length < 2) return statements; var seq = [], ret = []; function push_seq() { seq = AST_Seq.from_array(seq); if (seq) ret.push(make_node(AST_SimpleStatement, seq, { body: seq })); seq = []; } statements.forEach(function(stat) { if (stat instanceof AST_SimpleStatement) seq.push(stat.body); else push_seq(), ret.push(stat); }); push_seq(); ret = sequencesize_2(ret, compressor); CHANGED = ret.length != statements.length; return ret; } function sequencesize_2(statements, compressor) { function cons_seq(right) { ret.pop(); var left = prev.body; if (left instanceof AST_Seq) { left.add(right); } else { left = AST_Seq.cons(left, right); } return left.transform(compressor); } var ret = [], prev = null; statements.forEach(function(stat) { if (prev) { if (stat instanceof AST_For) { var opera = {}; try { prev.body.walk(new TreeWalker(function(node) { if (node instanceof AST_Binary && node.operator == "in") throw opera; })); if (stat.init && !(stat.init instanceof AST_Definitions)) { stat.init = cons_seq(stat.init); } else if (!stat.init) { stat.init = prev.body; ret.pop(); } } catch (ex) { if (ex !== opera) throw ex; } } else if (stat instanceof AST_If) { stat.condition = cons_seq(stat.condition); } else if (stat instanceof AST_With) { stat.expression = cons_seq(stat.expression); } else if (stat instanceof AST_Exit && stat.value) { stat.value = cons_seq(stat.value); } else if (stat instanceof AST_Exit) { stat.value = cons_seq(make_node(AST_Undefined, stat)); } else if (stat instanceof AST_Switch) { stat.expression = cons_seq(stat.expression); } } ret.push(stat); prev = stat instanceof AST_SimpleStatement ? stat : null; }); return ret; } function join_consecutive_vars(statements, compressor) { var prev = null; return statements.reduce(function(a, stat) { if (stat instanceof AST_Definitions && prev && prev.TYPE == stat.TYPE) { prev.definitions = prev.definitions.concat(stat.definitions); CHANGED = true; } else if (stat instanceof AST_For && prev instanceof AST_Definitions && (!stat.init || stat.init.TYPE == prev.TYPE)) { CHANGED = true; a.pop(); if (stat.init) { stat.init.definitions = prev.definitions.concat(stat.init.definitions); } else { stat.init = prev; } a.push(stat); prev = stat; } else { prev = stat; a.push(stat); } return a; }, []); } function negate_iifes(statements, compressor) { statements.forEach(function(stat) { if (stat instanceof AST_SimpleStatement) { stat.body = function transform(thing) { return thing.transform(new TreeTransformer(function(node) { if (node instanceof AST_Call && node.expression instanceof AST_Function) { return make_node(AST_UnaryPrefix, node, { operator: "!", expression: node }); } else if (node instanceof AST_Call) { node.expression = transform(node.expression); } else if (node instanceof AST_Seq) { node.car = transform(node.car); } else if (node instanceof AST_Conditional) { var expr = transform(node.condition); if (expr !== node.condition) { node.condition = expr; var tmp = node.consequent; node.consequent = node.alternative; node.alternative = tmp; } } return node; })); }(stat.body); } }); } } function extract_declarations_from_unreachable_code(compressor, stat, target) { compressor.warn("Dropping unreachable code [{file}:{line},{col}]", stat.start); stat.walk(new TreeWalker(function(node) { if (node instanceof AST_Definitions) { compressor.warn("Declarations in unreachable code! [{file}:{line},{col}]", node.start); node.remove_initializers(); target.push(node); return true; } if (node instanceof AST_Defun) { target.push(node); return true; } if (node instanceof AST_Scope) { return true; } })); } (function(def) { var unary_bool = [ "!", "delete" ]; var binary_bool = [ "in", "instanceof", "==", "!=", "===", "!==", "<", "<=", ">=", ">" ]; def(AST_Node, function() { return false; }); def(AST_UnaryPrefix, function() { return member(this.operator, unary_bool); }); def(AST_Binary, function() { return member(this.operator, binary_bool) || (this.operator == "&&" || this.operator == "||") && this.left.is_boolean() && this.right.is_boolean(); }); def(AST_Conditional, function() { return this.consequent.is_boolean() && this.alternative.is_boolean(); }); def(AST_Assign, function() { return this.operator == "=" && this.right.is_boolean(); }); def(AST_Seq, function() { return this.cdr.is_boolean(); }); def(AST_True, function() { return true; }); def(AST_False, function() { return true; }); })(function(node, func) { node.DEFMETHOD("is_boolean", func); }); (function(def) { def(AST_Node, function() { return false; }); def(AST_String, function() { return true; }); def(AST_UnaryPrefix, function() { return this.operator == "typeof"; }); def(AST_Binary, function(compressor) { return this.operator == "+" && (this.left.is_string(compressor) || this.right.is_string(compressor)); }); def(AST_Assign, function(compressor) { return (this.operator == "=" || this.operator == "+=") && this.right.is_string(compressor); }); def(AST_Seq, function(compressor) { return this.cdr.is_string(compressor); }); def(AST_Conditional, function(compressor) { return this.consequent.is_string(compressor) && this.alternative.is_string(compressor); }); def(AST_Call, function(compressor) { return compressor.option("unsafe") && this.expression instanceof AST_SymbolRef && this.expression.name == "String" && this.expression.undeclared(); }); })(function(node, func) { node.DEFMETHOD("is_string", func); }); function best_of(ast1, ast2) { return ast1.print_to_string().length > ast2.print_to_string().length ? ast2 : ast1; } (function(def) { AST_Node.DEFMETHOD("evaluate", function(compressor) { if (!compressor.option("evaluate")) return [ this ]; try { var val = this._eval(compressor); return [ best_of(make_node_from_constant(compressor, val, this), this), val ]; } catch (ex) { if (ex !== def) throw ex; return [ this ]; } }); def(AST_Statement, function() { throw new Error(string_template("Cannot evaluate a statement [{file}:{line},{col}]", this.start)); }); def(AST_Function, function() { throw def; }); function ev(node, compressor) { if (!compressor) throw new Error("Compressor must be passed"); return node._eval(compressor); } def(AST_Node, function() { throw def; }); def(AST_Constant, function() { return this.getValue(); }); def(AST_UnaryPrefix, function(compressor) { var e = this.expression; switch (this.operator) { case "!": return !ev(e, compressor); case "typeof": if (e instanceof AST_Function) return typeof function() {}; e = ev(e, compressor); if (e instanceof RegExp) throw def; return typeof e; case "void": return void ev(e, compressor); case "~": return ~ev(e, compressor); case "-": e = ev(e, compressor); if (e === 0) throw def; return -e; case "+": return +ev(e, compressor); } throw def; }); def(AST_Binary, function(c) { var left = this.left, right = this.right; switch (this.operator) { case "&&": return ev(left, c) && ev(right, c); case "||": return ev(left, c) || ev(right, c); case "|": return ev(left, c) | ev(right, c); case "&": return ev(left, c) & ev(right, c); case "^": return ev(left, c) ^ ev(right, c); case "+": return ev(left, c) + ev(right, c); case "*": return ev(left, c) * ev(right, c); case "/": return ev(left, c) / ev(right, c); case "%": return ev(left, c) % ev(right, c); case "-": return ev(left, c) - ev(right, c); case "<<": return ev(left, c) << ev(right, c); case ">>": return ev(left, c) >> ev(right, c); case ">>>": return ev(left, c) >>> ev(right, c); case "==": return ev(left, c) == ev(right, c); case "===": return ev(left, c) === ev(right, c); case "!=": return ev(left, c) != ev(right, c); case "!==": return ev(left, c) !== ev(right, c); case "<": return ev(left, c) < ev(right, c); case "<=": return ev(left, c) <= ev(right, c); case ">": return ev(left, c) > ev(right, c); case ">=": return ev(left, c) >= ev(right, c); case "in": return ev(left, c) in ev(right, c); case "instanceof": return ev(left, c) instanceof ev(right, c); } throw def; }); def(AST_Conditional, function(compressor) { return ev(this.condition, compressor) ? ev(this.consequent, compressor) : ev(this.alternative, compressor); }); def(AST_SymbolRef, function(compressor) { var d = this.definition(); if (d && d.constant && d.init) return ev(d.init, compressor); throw def; }); def(AST_Dot, function(compressor) { if (compressor.option("unsafe") && this.property == "length") { var str = ev(this.expression, compressor); if (typeof str == "string") return str.length; } throw def; }); })(function(node, func) { node.DEFMETHOD("_eval", func); }); (function(def) { function basic_negation(exp) { return make_node(AST_UnaryPrefix, exp, { operator: "!", expression: exp }); } def(AST_Node, function() { return basic_negation(this); }); def(AST_Statement, function() { throw new Error("Cannot negate a statement"); }); def(AST_Function, function() { return basic_negation(this); }); def(AST_UnaryPrefix, function() { if (this.operator == "!") return this.expression; return basic_negation(this); }); def(AST_Seq, function(compressor) { var self = this.clone(); self.cdr = self.cdr.negate(compressor); return self; }); def(AST_Conditional, function(compressor) { var self = this.clone(); self.consequent = self.consequent.negate(compressor); self.alternative = self.alternative.negate(compressor); return best_of(basic_negation(this), self); }); def(AST_Binary, function(compressor) { var self = this.clone(), op = this.operator; if (compressor.option("unsafe_comps")) { switch (op) { case "<=": self.operator = ">"; return self; case "<": self.operator = ">="; return self; case ">=": self.operator = "<"; return self; case ">": self.operator = "<="; return self; } } switch (op) { case "==": self.operator = "!="; return self; case "!=": self.operator = "=="; return self; case "===": self.operator = "!=="; return self; case "!==": self.operator = "==="; return self; case "&&": self.operator = "||"; self.left = self.left.negate(compressor); self.right = self.right.negate(compressor); return best_of(basic_negation(this), self); case "||": self.operator = "&&"; self.left = self.left.negate(compressor); self.right = self.right.negate(compressor); return best_of(basic_negation(this), self); } return basic_negation(this); }); })(function(node, func) { node.DEFMETHOD("negate", function(compressor) { return func.call(this, compressor); }); }); (function(def) { def(AST_Node, function(compressor) { return true; }); def(AST_EmptyStatement, function(compressor) { return false; }); def(AST_Constant, function(compressor) { return false; }); def(AST_This, function(compressor) { return false; }); def(AST_Call, function(compressor) { var pure = compressor.option("pure_funcs"); if (!pure) return true; return pure.indexOf(this.expression.print_to_string()) < 0; }); def(AST_Block, function(compressor) { for (var i = this.body.length; --i >= 0; ) { if (this.body[i].has_side_effects(compressor)) return true; } return false; }); def(AST_SimpleStatement, function(compressor) { return this.body.has_side_effects(compressor); }); def(AST_Defun, function(compressor) { return true; }); def(AST_Function, function(compressor) { return false; }); def(AST_Binary, function(compressor) { return this.left.has_side_effects(compressor) || this.right.has_side_effects(compressor); }); def(AST_Assign, function(compressor) { return true; }); def(AST_Conditional, function(compressor) { return this.condition.has_side_effects(compressor) || this.consequent.has_side_effects(compressor) || this.alternative.has_side_effects(compressor); }); def(AST_Unary, function(compressor) { return this.operator == "delete" || this.operator == "++" || this.operator == "--" || this.expression.has_side_effects(compressor); }); def(AST_SymbolRef, function(compressor) { return false; }); def(AST_Object, function(compressor) { for (var i = this.properties.length; --i >= 0; ) if (this.properties[i].has_side_effects(compressor)) return true; return false; }); def(AST_ObjectProperty, function(compressor) { return this.value.has_side_effects(compressor); }); def(AST_Array, function(compressor) { for (var i = this.elements.length; --i >= 0; ) if (this.elements[i].has_side_effects(compressor)) return true; return false; }); def(AST_Dot, function(compressor) { if (!compressor.option("pure_getters")) return true; return this.expression.has_side_effects(compressor); }); def(AST_Sub, function(compressor) { if (!compressor.option("pure_getters")) return true; return this.expression.has_side_effects(compressor) || this.property.has_side_effects(compressor); }); def(AST_PropAccess, function(compressor) { return !compressor.option("pure_getters"); }); def(AST_Seq, function(compressor) { return this.car.has_side_effects(compressor) || this.cdr.has_side_effects(compressor); }); })(function(node, func) { node.DEFMETHOD("has_side_effects", func); }); function aborts(thing) { return thing && thing.aborts(); } (function(def) { def(AST_Statement, function() { return null; }); def(AST_Jump, function() { return this; }); function block_aborts() { var n = this.body.length; return n > 0 && aborts(this.body[n - 1]); } def(AST_BlockStatement, block_aborts); def(AST_SwitchBranch, block_aborts); def(AST_If, function() { return this.alternative && aborts(this.body) && aborts(this.alternative); }); })(function(node, func) { node.DEFMETHOD("aborts", func); }); OPT(AST_Directive, function(self, compressor) { if (self.scope.has_directive(self.value) !== self.scope) { return make_node(AST_EmptyStatement, self); } return self; }); OPT(AST_Debugger, function(self, compressor) { if (compressor.option("drop_debugger")) return make_node(AST_EmptyStatement, self); return self; }); OPT(AST_LabeledStatement, function(self, compressor) { if (self.body instanceof AST_Break && compressor.loopcontrol_target(self.body.label) === self.body) { return make_node(AST_EmptyStatement, self); } return self.label.references.length == 0 ? self.body : self; }); OPT(AST_Block, function(self, compressor) { self.body = tighten_body(self.body, compressor); return self; }); OPT(AST_BlockStatement, function(self, compressor) { self.body = tighten_body(self.body, compressor); switch (self.body.length) { case 1: return self.body[0]; case 0: return make_node(AST_EmptyStatement, self); } return self; }); AST_Scope.DEFMETHOD("drop_unused", function(compressor) { var self = this; if (compressor.option("unused") && !(self instanceof AST_Toplevel) && !self.uses_eval) { var in_use = []; var initializations = new Dictionary(); var scope = this; var tw = new TreeWalker(function(node, descend) { if (node !== self) { if (node instanceof AST_Defun) { initializations.add(node.name.name, node); return true; } if (node instanceof AST_Definitions && scope === self) { node.definitions.forEach(function(def) { if (def.value) { initializations.add(def.name.name, def.value); if (def.value.has_side_effects(compressor)) { def.value.walk(tw); } } }); return true; } if (node instanceof AST_SymbolRef) { push_uniq(in_use, node.definition()); return true; } if (node instanceof AST_Scope) { var save_scope = scope; scope = node; descend(); scope = save_scope; return true; } } }); self.walk(tw); for (var i = 0; i < in_use.length; ++i) { in_use[i].orig.forEach(function(decl) { var init = initializations.get(decl.name); if (init) init.forEach(function(init) { var tw = new TreeWalker(function(node) { if (node instanceof AST_SymbolRef) { push_uniq(in_use, node.definition()); } }); init.walk(tw); }); }); } var tt = new TreeTransformer(function before(node, descend, in_list) { if (node instanceof AST_Lambda && !(node instanceof AST_Accessor)) { if (!compressor.option("keep_fargs")) { for (var a = node.argnames, i = a.length; --i >= 0; ) { var sym = a[i]; if (sym.unreferenced()) { a.pop(); compressor.warn("Dropping unused function argument {name} [{file}:{line},{col}]", { name: sym.name, file: sym.start.file, line: sym.start.line, col: sym.start.col }); } else break; } } } if (node instanceof AST_Defun && node !== self) { if (!member(node.name.definition(), in_use)) { compressor.warn("Dropping unused function {name} [{file}:{line},{col}]", { name: node.name.name, file: node.name.start.file, line: node.name.start.line, col: node.name.start.col }); return make_node(AST_EmptyStatement, node); } return node; } if (node instanceof AST_Definitions && !(tt.parent() instanceof AST_ForIn)) { var def = node.definitions.filter(function(def) { if (member(def.name.definition(), in_use)) return true; var w = { name: def.name.name, file: def.name.start.file, line: def.name.start.line, col: def.name.start.col }; if (def.value && def.value.has_side_effects(compressor)) { def._unused_side_effects = true; compressor.warn("Side effects in initialization of unused variable {name} [{file}:{line},{col}]", w); return true; } compressor.warn("Dropping unused variable {name} [{file}:{line},{col}]", w); return false; }); def = mergeSort(def, function(a, b) { if (!a.value && b.value) return -1; if (!b.value && a.value) return 1; return 0; }); var side_effects = []; for (var i = 0; i < def.length; ) { var x = def[i]; if (x._unused_side_effects) { side_effects.push(x.value); def.splice(i, 1); } else { if (side_effects.length > 0) { side_effects.push(x.value); x.value = AST_Seq.from_array(side_effects); side_effects = []; } ++i; } } if (side_effects.length > 0) { side_effects = make_node(AST_BlockStatement, node, { body: [ make_node(AST_SimpleStatement, node, { body: AST_Seq.from_array(side_effects) }) ] }); } else { side_effects = null; } if (def.length == 0 && !side_effects) { return make_node(AST_EmptyStatement, node); } if (def.length == 0) { return side_effects; } node.definitions = def; if (side_effects) { side_effects.body.unshift(node); node = side_effects; } return node; } if (node instanceof AST_For) { descend(node, this); if (node.init instanceof AST_BlockStatement) { var body = node.init.body.slice(0, -1); node.init = node.init.body.slice(-1)[0].body; body.push(node); return in_list ? MAP.splice(body) : make_node(AST_BlockStatement, node, { body: body }); } } if (node instanceof AST_Scope && node !== self) return node; }); self.transform(tt); } }); AST_Scope.DEFMETHOD("hoist_declarations", function(compressor) { var hoist_funs = compressor.option("hoist_funs"); var hoist_vars = compressor.option("hoist_vars"); var self = this; if (hoist_funs || hoist_vars) { var dirs = []; var hoisted = []; var vars = new Dictionary(), vars_found = 0, var_decl = 0; self.walk(new TreeWalker(function(node) { if (node instanceof AST_Scope && node !== self) return true; if (node instanceof AST_Var) { ++var_decl; return true; } })); hoist_vars = hoist_vars && var_decl > 1; var tt = new TreeTransformer(function before(node) { if (node !== self) { if (node instanceof AST_Directive) { dirs.push(node); return make_node(AST_EmptyStatement, node); } if (node instanceof AST_Defun && hoist_funs) { hoisted.push(node); return make_node(AST_EmptyStatement, node); } if (node instanceof AST_Var && hoist_vars) { node.definitions.forEach(function(def) { vars.set(def.name.name, def); ++vars_found; }); var seq = node.to_assignments(); var p = tt.parent(); if (p instanceof AST_ForIn && p.init === node) { if (seq == null) return node.definitions[0].name; return seq; } if (p instanceof AST_For && p.init === node) { return seq; } if (!seq) return make_node(AST_EmptyStatement, node); return make_node(AST_SimpleStatement, node, { body: seq }); } if (node instanceof AST_Scope) return node; } }); self = self.transform(tt); if (vars_found > 0) { var defs = []; vars.each(function(def, name) { if (self instanceof AST_Lambda && find_if(function(x) { return x.name == def.name.name; }, self.argnames)) { vars.del(name); } else { def = def.clone(); def.value = null; defs.push(def); vars.set(name, def); } }); if (defs.length > 0) { for (var i = 0; i < self.body.length; ) { if (self.body[i] instanceof AST_SimpleStatement) { var expr = self.body[i].body, sym, assign; if (expr instanceof AST_Assign && expr.operator == "=" && (sym = expr.left) instanceof AST_Symbol && vars.has(sym.name)) { var def = vars.get(sym.name); if (def.value) break; def.value = expr.right; remove(defs, def); defs.push(def); self.body.splice(i, 1); continue; } if (expr instanceof AST_Seq && (assign = expr.car) instanceof AST_Assign && assign.operator == "=" && (sym = assign.left) instanceof AST_Symbol && vars.has(sym.name)) { var def = vars.get(sym.name); if (def.value) break; def.value = assign.right; remove(defs, def); defs.push(def); self.body[i].body = expr.cdr; continue; } } if (self.body[i] instanceof AST_EmptyStatement) { self.body.splice(i, 1); continue; } if (self.body[i] instanceof AST_BlockStatement) { var tmp = [ i, 1 ].concat(self.body[i].body); self.body.splice.apply(self.body, tmp); continue; } break; } defs = make_node(AST_Var, self, { definitions: defs }); hoisted.push(defs); } } self.body = dirs.concat(hoisted, self.body); } return self; }); OPT(AST_SimpleStatement, function(self, compressor) { if (compressor.option("side_effects")) { if (!self.body.has_side_effects(compressor)) { compressor.warn("Dropping side-effect-free statement [{file}:{line},{col}]", self.start); return make_node(AST_EmptyStatement, self); } } return self; }); OPT(AST_DWLoop, function(self, compressor) { var cond = self.condition.evaluate(compressor); self.condition = cond[0]; if (!compressor.option("loops")) return self; if (cond.length > 1) { if (cond[1]) { return make_node(AST_For, self, { body: self.body }); } else if (self instanceof AST_While) { if (compressor.option("dead_code")) { var a = []; extract_declarations_from_unreachable_code(compressor, self.body, a); return make_node(AST_BlockStatement, self, { body: a }); } } } return self; }); function if_break_in_loop(self, compressor) { function drop_it(rest) { rest = as_statement_array(rest); if (self.body instanceof AST_BlockStatement) { self.body = self.body.clone(); self.body.body = rest.concat(self.body.body.slice(1)); self.body = self.body.transform(compressor); } else { self.body = make_node(AST_BlockStatement, self.body, { body: rest }).transform(compressor); } if_break_in_loop(self, compressor); } var first = self.body instanceof AST_BlockStatement ? self.body.body[0] : self.body; if (first instanceof AST_If) { if (first.body instanceof AST_Break && compressor.loopcontrol_target(first.body.label) === self) { if (self.condition) { self.condition = make_node(AST_Binary, self.condition, { left: self.condition, operator: "&&", right: first.condition.negate(compressor) }); } else { self.condition = first.condition.negate(compressor); } drop_it(first.alternative); } else if (first.alternative instanceof AST_Break && compressor.loopcontrol_target(first.alternative.label) === self) { if (self.condition) { self.condition = make_node(AST_Binary, self.condition, { left: self.condition, operator: "&&", right: first.condition }); } else { self.condition = first.condition; } drop_it(first.body); } } } OPT(AST_While, function(self, compressor) { if (!compressor.option("loops")) return self; self = AST_DWLoop.prototype.optimize.call(self, compressor); if (self instanceof AST_While) { if_break_in_loop(self, compressor); self = make_node(AST_For, self, self).transform(compressor); } return self; }); OPT(AST_For, function(self, compressor) { var cond = self.condition; if (cond) { cond = cond.evaluate(compressor); self.condition = cond[0]; } if (!compressor.option("loops")) return self; if (cond) { if (cond.length > 1 && !cond[1]) { if (compressor.option("dead_code")) { var a = []; if (self.init instanceof AST_Statement) { a.push(self.init); } else if (self.init) { a.push(make_node(AST_SimpleStatement, self.init, { body: self.init })); } extract_declarations_from_unreachable_code(compressor, self.body, a); return make_node(AST_BlockStatement, self, { body: a }); } } } if_break_in_loop(self, compressor); return self; }); OPT(AST_If, function(self, compressor) { if (!compressor.option("conditionals")) return self; var cond = self.condition.evaluate(compressor); self.condition = cond[0]; if (cond.length > 1) { if (cond[1]) { compressor.warn("Condition always true [{file}:{line},{col}]", self.condition.start); if (compressor.option("dead_code")) { var a = []; if (self.alternative) { extract_declarations_from_unreachable_code(compressor, self.alternative, a); } a.push(self.body); return make_node(AST_BlockStatement, self, { body: a }).transform(compressor); } } else { compressor.warn("Condition always false [{file}:{line},{col}]", self.condition.start); if (compressor.option("dead_code")) { var a = []; extract_declarations_from_unreachable_code(compressor, self.body, a); if (self.alternative) a.push(self.alternative); return make_node(AST_BlockStatement, self, { body: a }).transform(compressor); } } } if (is_empty(self.alternative)) self.alternative = null; var negated = self.condition.negate(compressor); var negated_is_best = best_of(self.condition, negated) === negated; if (self.alternative && negated_is_best) { negated_is_best = false; self.condition = negated; var tmp = self.body; self.body = self.alternative || make_node(AST_EmptyStatement); self.alternative = tmp; } if (is_empty(self.body) && is_empty(self.alternative)) { return make_node(AST_SimpleStatement, self.condition, { body: self.condition }).transform(compressor); } if (self.body instanceof AST_SimpleStatement && self.alternative instanceof AST_SimpleStatement) { return make_node(AST_SimpleStatement, self, { body: make_node(AST_Conditional, self, { condition: self.condition, consequent: self.body.body, alternative: self.alternative.body }) }).transform(compressor); } if (is_empty(self.alternative) && self.body instanceof AST_SimpleStatement) { if (negated_is_best) return make_node(AST_SimpleStatement, self, { body: make_node(AST_Binary, self, { operator: "||", left: negated, right: self.body.body }) }).transform(compressor); return make_node(AST_SimpleStatement, self, { body: make_node(AST_Binary, self, { operator: "&&", left: self.condition, right: self.body.body }) }).transform(compressor); } if (self.body instanceof AST_EmptyStatement && self.alternative && self.alternative instanceof AST_SimpleStatement) { return make_node(AST_SimpleStatement, self, { body: make_node(AST_Binary, self, { operator: "||", left: self.condition, right: self.alternative.body }) }).transform(compressor); } if (self.body instanceof AST_Exit && self.alternative instanceof AST_Exit && self.body.TYPE == self.alternative.TYPE) { return make_node(self.body.CTOR, self, { value: make_node(AST_Conditional, self, { condition: self.condition, consequent: self.body.value || make_node(AST_Undefined, self.body).optimize(compressor), alternative: self.alternative.value || make_node(AST_Undefined, self.alternative).optimize(compressor) }) }).transform(compressor); } if (self.body instanceof AST_If && !self.body.alternative && !self.alternative) { self.condition = make_node(AST_Binary, self.condition, { operator: "&&", left: self.condition, right: self.body.condition }).transform(compressor); self.body = self.body.body; } if (aborts(self.body)) { if (self.alternative) { var alt = self.alternative; self.alternative = null; return make_node(AST_BlockStatement, self, { body: [ self, alt ] }).transform(compressor); } } if (aborts(self.alternative)) { var body = self.body; self.body = self.alternative; self.condition = negated_is_best ? negated : self.condition.negate(compressor); self.alternative = null; return make_node(AST_BlockStatement, self, { body: [ self, body ] }).transform(compressor); } return self; }); OPT(AST_Switch, function(self, compressor) { if (self.body.length == 0 && compressor.option("conditionals")) { return make_node(AST_SimpleStatement, self, { body: self.expression }).transform(compressor); } for (;;) { var last_branch = self.body[self.body.length - 1]; if (last_branch) { var stat = last_branch.body[last_branch.body.length - 1]; if (stat instanceof AST_Break && loop_body(compressor.loopcontrol_target(stat.label)) === self) last_branch.body.pop(); if (last_branch instanceof AST_Default && last_branch.body.length == 0) { self.body.pop(); continue; } } break; } var exp = self.expression.evaluate(compressor); out: if (exp.length == 2) try { self.expression = exp[0]; if (!compressor.option("dead_code")) break out; var value = exp[1]; var in_if = false; var in_block = false; var started = false; var stopped = false; var ruined = false; var tt = new TreeTransformer(function(node, descend, in_list) { if (node instanceof AST_Lambda || node instanceof AST_SimpleStatement) { return node; } else if (node instanceof AST_Switch && node === self) { node = node.clone(); descend(node, this); return ruined ? node : make_node(AST_BlockStatement, node, { body: node.body.reduce(function(a, branch) { return a.concat(branch.body); }, []) }).transform(compressor); } else if (node instanceof AST_If || node instanceof AST_Try) { var save = in_if; in_if = !in_block; descend(node, this); in_if = save; return node; } else if (node instanceof AST_StatementWithBody || node instanceof AST_Switch) { var save = in_block; in_block = true; descend(node, this); in_block = save; return node; } else if (node instanceof AST_Break && this.loopcontrol_target(node.label) === self) { if (in_if) { ruined = true; return node; } if (in_block) return node; stopped = true; return in_list ? MAP.skip : make_node(AST_EmptyStatement, node); } else if (node instanceof AST_SwitchBranch && this.parent() === self) { if (stopped) return MAP.skip; if (node instanceof AST_Case) { var exp = node.expression.evaluate(compressor); if (exp.length < 2) { throw self; } if (exp[1] === value || started) { started = true; if (aborts(node)) stopped = true; descend(node, this); return node; } return MAP.skip; } descend(node, this); return node; } }); tt.stack = compressor.stack.slice(); self = self.transform(tt); } catch (ex) { if (ex !== self) throw ex; } return self; }); OPT(AST_Case, function(self, compressor) { self.body = tighten_body(self.body, compressor); return self; }); OPT(AST_Try, function(self, compressor) { self.body = tighten_body(self.body, compressor); return self; }); AST_Definitions.DEFMETHOD("remove_initializers", function() { this.definitions.forEach(function(def) { def.value = null; }); }); AST_Definitions.DEFMETHOD("to_assignments", function() { var assignments = this.definitions.reduce(function(a, def) { if (def.value) { var name = make_node(AST_SymbolRef, def.name, def.name); a.push(make_node(AST_Assign, def, { operator: "=", left: name, right: def.value })); } return a; }, []); if (assignments.length == 0) return null; return AST_Seq.from_array(assignments); }); OPT(AST_Definitions, function(self, compressor) { if (self.definitions.length == 0) return make_node(AST_EmptyStatement, self); return self; }); OPT(AST_Function, function(self, compressor) { self = AST_Lambda.prototype.optimize.call(self, compressor); if (compressor.option("unused")) { if (self.name && self.name.unreferenced()) { self.name = null; } } return self; }); OPT(AST_Call, function(self, compressor) { if (compressor.option("unsafe")) { var exp = self.expression; if (exp instanceof AST_SymbolRef && exp.undeclared()) { switch (exp.name) { case "Array": if (self.args.length != 1) { return make_node(AST_Array, self, { elements: self.args }).transform(compressor); } break; case "Object": if (self.args.length == 0) { return make_node(AST_Object, self, { properties: [] }); } break; case "String": if (self.args.length == 0) return make_node(AST_String, self, { value: "" }); if (self.args.length <= 1) return make_node(AST_Binary, self, { left: self.args[0], operator: "+", right: make_node(AST_String, self, { value: "" }) }).transform(compressor); break; case "Number": if (self.args.length == 0) return make_node(AST_Number, self, { value: 0 }); if (self.args.length == 1) return make_node(AST_UnaryPrefix, self, { expression: self.args[0], operator: "+" }).transform(compressor); case "Boolean": if (self.args.length == 0) return make_node(AST_False, self); if (self.args.length == 1) return make_node(AST_UnaryPrefix, self, { expression: make_node(AST_UnaryPrefix, null, { expression: self.args[0], operator: "!" }), operator: "!" }).transform(compressor); break; case "Function": if (all(self.args, function(x) { return x instanceof AST_String; })) { try { var code = "(function(" + self.args.slice(0, -1).map(function(arg) { return arg.value; }).join(",") + "){" + self.args[self.args.length - 1].value + "})()"; var ast = parse(code); ast.figure_out_scope({ screw_ie8: compressor.option("screw_ie8") }); var comp = new Compressor(compressor.options); ast = ast.transform(comp); ast.figure_out_scope({ screw_ie8: compressor.option("screw_ie8") }); ast.mangle_names(); var fun; try { ast.walk(new TreeWalker(function(node) { if (node instanceof AST_Lambda) { fun = node; throw ast; } })); } catch (ex) { if (ex !== ast) throw ex; } var args = fun.argnames.map(function(arg, i) { return make_node(AST_String, self.args[i], { value: arg.print_to_string() }); }); var code = OutputStream(); AST_BlockStatement.prototype._codegen.call(fun, fun, code); code = code.toString().replace(/^\{|\}$/g, ""); args.push(make_node(AST_String, self.args[self.args.length - 1], { value: code })); self.args = args; return self; } catch (ex) { if (ex instanceof JS_Parse_Error) { compressor.warn("Error parsing code passed to new Function [{file}:{line},{col}]", self.args[self.args.length - 1].start); compressor.warn(ex.toString()); } else { console.log(ex); throw ex; } } } break; } } else if (exp instanceof AST_Dot && exp.property == "toString" && self.args.length == 0) { return make_node(AST_Binary, self, { left: make_node(AST_String, self, { value: "" }), operator: "+", right: exp.expression }).transform(compressor); } else if (exp instanceof AST_Dot && exp.expression instanceof AST_Array && exp.property == "join") EXIT: { var separator = self.args.length == 0 ? "," : self.args[0].evaluate(compressor)[1]; if (separator == null) break EXIT; var elements = exp.expression.elements.reduce(function(a, el) { el = el.evaluate(compressor); if (a.length == 0 || el.length == 1) { a.push(el); } else { var last = a[a.length - 1]; if (last.length == 2) { var val = "" + last[1] + separator + el[1]; a[a.length - 1] = [ make_node_from_constant(compressor, val, last[0]), val ]; } else { a.push(el); } } return a; }, []); if (elements.length == 0) return make_node(AST_String, self, { value: "" }); if (elements.length == 1) return elements[0][0]; if (separator == "") { var first; if (elements[0][0] instanceof AST_String || elements[1][0] instanceof AST_String) { first = elements.shift()[0]; } else { first = make_node(AST_String, self, { value: "" }); } return elements.reduce(function(prev, el) { return make_node(AST_Binary, el[0], { operator: "+", left: prev, right: el[0] }); }, first).transform(compressor); } var node = self.clone(); node.expression = node.expression.clone(); node.expression.expression = node.expression.expression.clone(); node.expression.expression.elements = elements.map(function(el) { return el[0]; }); return best_of(self, node); } } if (compressor.option("side_effects")) { if (self.expression instanceof AST_Function && self.args.length == 0 && !AST_Block.prototype.has_side_effects.call(self.expression, compressor)) { return make_node(AST_Undefined, self).transform(compressor); } } if (compressor.option("drop_console")) { if (self.expression instanceof AST_PropAccess && self.expression.expression instanceof AST_SymbolRef && self.expression.expression.name == "console" && self.expression.expression.undeclared()) { return make_node(AST_Undefined, self).transform(compressor); } } return self.evaluate(compressor)[0]; }); OPT(AST_New, function(self, compressor) { if (compressor.option("unsafe")) { var exp = self.expression; if (exp instanceof AST_SymbolRef && exp.undeclared()) { switch (exp.name) { case "Object": case "RegExp": case "Function": case "Error": case "Array": return make_node(AST_Call, self, self).transform(compressor); } } } return self; }); OPT(AST_Seq, function(self, compressor) { if (!compressor.option("side_effects")) return self; if (!self.car.has_side_effects(compressor)) { var p; if (!(self.cdr instanceof AST_SymbolRef && self.cdr.name == "eval" && self.cdr.undeclared() && (p = compressor.parent()) instanceof AST_Call && p.expression === self)) { return self.cdr; } } if (compressor.option("cascade")) { if (self.car instanceof AST_Assign && !self.car.left.has_side_effects(compressor)) { if (self.car.left.equivalent_to(self.cdr)) { return self.car; } if (self.cdr instanceof AST_Call && self.cdr.expression.equivalent_to(self.car.left)) { self.cdr.expression = self.car; return self.cdr; } } if (!self.car.has_side_effects(compressor) && !self.cdr.has_side_effects(compressor) && self.car.equivalent_to(self.cdr)) { return self.car; } } if (self.cdr instanceof AST_UnaryPrefix && self.cdr.operator == "void" && !self.cdr.expression.has_side_effects(compressor)) { self.cdr.operator = self.car; return self.cdr; } if (self.cdr instanceof AST_Undefined) { return make_node(AST_UnaryPrefix, self, { operator: "void", expression: self.car }); } return self; }); AST_Unary.DEFMETHOD("lift_sequences", function(compressor) { if (compressor.option("sequences")) { if (this.expression instanceof AST_Seq) { var seq = this.expression; var x = seq.to_array(); this.expression = x.pop(); x.push(this); seq = AST_Seq.from_array(x).transform(compressor); return seq; } } return this; }); OPT(AST_UnaryPostfix, function(self, compressor) { return self.lift_sequences(compressor); }); OPT(AST_UnaryPrefix, function(self, compressor) { self = self.lift_sequences(compressor); var e = self.expression; if (compressor.option("booleans") && compressor.in_boolean_context()) { switch (self.operator) { case "!": if (e instanceof AST_UnaryPrefix && e.operator == "!") { return e.expression; } break; case "typeof": compressor.warn("Boolean expression always true [{file}:{line},{col}]", self.start); return make_node(AST_True, self); } if (e instanceof AST_Binary && self.operator == "!") { self = best_of(self, e.negate(compressor)); } } return self.evaluate(compressor)[0]; }); function has_side_effects_or_prop_access(node, compressor) { var save_pure_getters = compressor.option("pure_getters"); compressor.options.pure_getters = false; var ret = node.has_side_effects(compressor); compressor.options.pure_getters = save_pure_getters; return ret; } AST_Binary.DEFMETHOD("lift_sequences", function(compressor) { if (compressor.option("sequences")) { if (this.left instanceof AST_Seq) { var seq = this.left; var x = seq.to_array(); this.left = x.pop(); x.push(this); seq = AST_Seq.from_array(x).transform(compressor); return seq; } if (this.right instanceof AST_Seq && this instanceof AST_Assign && !has_side_effects_or_prop_access(this.left, compressor)) { var seq = this.right; var x = seq.to_array(); this.right = x.pop(); x.push(this); seq = AST_Seq.from_array(x).transform(compressor); return seq; } } return this; }); var commutativeOperators = makePredicate("== === != !== * & | ^"); OPT(AST_Binary, function(self, compressor) { var reverse = compressor.has_directive("use asm") ? noop : function(op, force) { if (force || !(self.left.has_side_effects(compressor) || self.right.has_side_effects(compressor))) { if (op) self.operator = op; var tmp = self.left; self.left = self.right; self.right = tmp; } }; if (commutativeOperators(self.operator)) { if (self.right instanceof AST_Constant && !(self.left instanceof AST_Constant)) { if (!(self.left instanceof AST_Binary && PRECEDENCE[self.left.operator] >= PRECEDENCE[self.operator])) { reverse(null, true); } } if (/^[!=]==?$/.test(self.operator)) { if (self.left instanceof AST_SymbolRef && self.right instanceof AST_Conditional) { if (self.right.consequent instanceof AST_SymbolRef && self.right.consequent.definition() === self.left.definition()) { if (/^==/.test(self.operator)) return self.right.condition; if (/^!=/.test(self.operator)) return self.right.condition.negate(compressor); } if (self.right.alternative instanceof AST_SymbolRef && self.right.alternative.definition() === self.left.definition()) { if (/^==/.test(self.operator)) return self.right.condition.negate(compressor); if (/^!=/.test(self.operator)) return self.right.condition; } } if (self.right instanceof AST_SymbolRef && self.left instanceof AST_Conditional) { if (self.left.consequent instanceof AST_SymbolRef && self.left.consequent.definition() === self.right.definition()) { if (/^==/.test(self.operator)) return self.left.condition; if (/^!=/.test(self.operator)) return self.left.condition.negate(compressor); } if (self.left.alternative instanceof AST_SymbolRef && self.left.alternative.definition() === self.right.definition()) { if (/^==/.test(self.operator)) return self.left.condition.negate(compressor); if (/^!=/.test(self.operator)) return self.left.condition; } } } } self = self.lift_sequences(compressor); if (compressor.option("comparisons")) switch (self.operator) { case "===": case "!==": if (self.left.is_string(compressor) && self.right.is_string(compressor) || self.left.is_boolean() && self.right.is_boolean()) { self.operator = self.operator.substr(0, 2); } case "==": case "!=": if (self.left instanceof AST_String && self.left.value == "undefined" && self.right instanceof AST_UnaryPrefix && self.right.operator == "typeof" && compressor.option("unsafe")) { if (!(self.right.expression instanceof AST_SymbolRef) || !self.right.expression.undeclared()) { self.right = self.right.expression; self.left = make_node(AST_Undefined, self.left).optimize(compressor); if (self.operator.length == 2) self.operator += "="; } } break; } if (compressor.option("booleans") && compressor.in_boolean_context()) switch (self.operator) { case "&&": var ll = self.left.evaluate(compressor); var rr = self.right.evaluate(compressor); if (ll.length > 1 && !ll[1] || rr.length > 1 && !rr[1]) { compressor.warn("Boolean && always false [{file}:{line},{col}]", self.start); return make_node(AST_False, self); } if (ll.length > 1 && ll[1]) { return rr[0]; } if (rr.length > 1 && rr[1]) { return ll[0]; } break; case "||": var ll = self.left.evaluate(compressor); var rr = self.right.evaluate(compressor); if (ll.length > 1 && ll[1] || rr.length > 1 && rr[1]) { compressor.warn("Boolean || always true [{file}:{line},{col}]", self.start); return make_node(AST_True, self); } if (ll.length > 1 && !ll[1]) { return rr[0]; } if (rr.length > 1 && !rr[1]) { return ll[0]; } break; case "+": var ll = self.left.evaluate(compressor); var rr = self.right.evaluate(compressor); if (ll.length > 1 && ll[0] instanceof AST_String && ll[1] || rr.length > 1 && rr[0] instanceof AST_String && rr[1]) { compressor.warn("+ in boolean context always true [{file}:{line},{col}]", self.start); return make_node(AST_True, self); } break; } if (compressor.option("comparisons")) { if (!(compressor.parent() instanceof AST_Binary) || compressor.parent() instanceof AST_Assign) { var negated = make_node(AST_UnaryPrefix, self, { operator: "!", expression: self.negate(compressor) }); self = best_of(self, negated); } switch (self.operator) { case "<": reverse(">"); break; case "<=": reverse(">="); break; } } if (self.operator == "+" && self.right instanceof AST_String && self.right.getValue() === "" && self.left instanceof AST_Binary && self.left.operator == "+" && self.left.is_string(compressor)) { return self.left; } if (compressor.option("evaluate")) { if (self.operator == "+") { if (self.left instanceof AST_Constant && self.right instanceof AST_Binary && self.right.operator == "+" && self.right.left instanceof AST_Constant && self.right.is_string(compressor)) { self = make_node(AST_Binary, self, { operator: "+", left: make_node(AST_String, null, { value: "" + self.left.getValue() + self.right.left.getValue(), start: self.left.start, end: self.right.left.end }), right: self.right.right }); } if (self.right instanceof AST_Constant && self.left instanceof AST_Binary && self.left.operator == "+" && self.left.right instanceof AST_Constant && self.left.is_string(compressor)) { self = make_node(AST_Binary, self, { operator: "+", left: self.left.left, right: make_node(AST_String, null, { value: "" + self.left.right.getValue() + self.right.getValue(), start: self.left.right.start, end: self.right.end }) }); } if (self.left instanceof AST_Binary && self.left.operator == "+" && self.left.is_string(compressor) && self.left.right instanceof AST_Constant && self.right instanceof AST_Binary && self.right.operator == "+" && self.right.left instanceof AST_Constant && self.right.is_string(compressor)) { self = make_node(AST_Binary, self, { operator: "+", left: make_node(AST_Binary, self.left, { operator: "+", left: self.left.left, right: make_node(AST_String, null, { value: "" + self.left.right.getValue() + self.right.left.getValue(), start: self.left.right.start, end: self.right.left.end }) }), right: self.right.right }); } } } if (self.right instanceof AST_Binary && self.right.operator == self.operator && (self.operator == "*" || self.operator == "&&" || self.operator == "||")) { self.left = make_node(AST_Binary, self.left, { operator: self.operator, left: self.left, right: self.right.left }); self.right = self.right.right; return self.transform(compressor); } return self.evaluate(compressor)[0]; }); OPT(AST_SymbolRef, function(self, compressor) { if (self.undeclared()) { var defines = compressor.option("global_defs"); if (defines && defines.hasOwnProperty(self.name)) { return make_node_from_constant(compressor, defines[self.name], self); } switch (self.name) { case "undefined": return make_node(AST_Undefined, self); case "NaN": return make_node(AST_NaN, self); case "Infinity": return make_node(AST_Infinity, self); } } return self; }); OPT(AST_Undefined, function(self, compressor) { if (compressor.option("unsafe")) { var scope = compressor.find_parent(AST_Scope); var undef = scope.find_variable("undefined"); if (undef) { var ref = make_node(AST_SymbolRef, self, { name: "undefined", scope: scope, thedef: undef }); ref.reference(); return ref; } } return self; }); var ASSIGN_OPS = [ "+", "-", "/", "*", "%", ">>", "<<", ">>>", "|", "^", "&" ]; OPT(AST_Assign, function(self, compressor) { self = self.lift_sequences(compressor); if (self.operator == "=" && self.left instanceof AST_SymbolRef && self.right instanceof AST_Binary && self.right.left instanceof AST_SymbolRef && self.right.left.name == self.left.name && member(self.right.operator, ASSIGN_OPS)) { self.operator = self.right.operator + "="; self.right = self.right.right; } return self; }); OPT(AST_Conditional, function(self, compressor) { if (!compressor.option("conditionals")) return self; if (self.condition instanceof AST_Seq) { var car = self.condition.car; self.condition = self.condition.cdr; return AST_Seq.cons(car, self); } var cond = self.condition.evaluate(compressor); if (cond.length > 1) { if (cond[1]) { compressor.warn("Condition always true [{file}:{line},{col}]", self.start); return self.consequent; } else { compressor.warn("Condition always false [{file}:{line},{col}]", self.start); return self.alternative; } } var negated = cond[0].negate(compressor); if (best_of(cond[0], negated) === negated) { self = make_node(AST_Conditional, self, { condition: negated, consequent: self.alternative, alternative: self.consequent }); } var consequent = self.consequent; var alternative = self.alternative; if (consequent instanceof AST_Assign && alternative instanceof AST_Assign && consequent.operator == alternative.operator && consequent.left.equivalent_to(alternative.left)) { return make_node(AST_Assign, self, { operator: consequent.operator, left: consequent.left, right: make_node(AST_Conditional, self, { condition: self.condition, consequent: consequent.right, alternative: alternative.right }) }); } if (consequent instanceof AST_Call && alternative.TYPE === consequent.TYPE && consequent.args.length == alternative.args.length && consequent.expression.equivalent_to(alternative.expression)) { if (consequent.args.length == 0) { return make_node(AST_Seq, self, { car: self.condition, cdr: consequent }); } if (consequent.args.length == 1) { consequent.args[0] = make_node(AST_Conditional, self, { condition: self.condition, consequent: consequent.args[0], alternative: alternative.args[0] }); return consequent; } } if (consequent instanceof AST_Conditional && consequent.alternative.equivalent_to(alternative)) { return make_node(AST_Conditional, self, { condition: make_node(AST_Binary, self, { left: self.condition, operator: "&&", right: consequent.condition }), consequent: consequent.consequent, alternative: alternative }); } return self; }); OPT(AST_Boolean, function(self, compressor) { if (compressor.option("booleans")) { var p = compressor.parent(); if (p instanceof AST_Binary && (p.operator == "==" || p.operator == "!=")) { compressor.warn("Non-strict equality against boolean: {operator} {value} [{file}:{line},{col}]", { operator: p.operator, value: self.value, file: p.start.file, line: p.start.line, col: p.start.col }); return make_node(AST_Number, self, { value: +self.value }); } return make_node(AST_UnaryPrefix, self, { operator: "!", expression: make_node(AST_Number, self, { value: 1 - self.value }) }); } return self; }); OPT(AST_Sub, function(self, compressor) { var prop = self.property; if (prop instanceof AST_String && compressor.option("properties")) { prop = prop.getValue(); if (RESERVED_WORDS(prop) ? compressor.option("screw_ie8") : is_identifier_string(prop)) { return make_node(AST_Dot, self, { expression: self.expression, property: prop }).optimize(compressor); } var v = parseFloat(prop); if (!isNaN(v) && v.toString() == prop) { self.property = make_node(AST_Number, self.property, { value: v }); } } return self; }); OPT(AST_Dot, function(self, compressor) { return self.evaluate(compressor)[0]; }); function literals_in_boolean_context(self, compressor) { if (compressor.option("booleans") && compressor.in_boolean_context()) { return make_node(AST_True, self); } return self; } OPT(AST_Array, literals_in_boolean_context); OPT(AST_Object, literals_in_boolean_context); OPT(AST_RegExp, literals_in_boolean_context); })(); "use strict"; function SourceMap(options) { options = defaults(options, { file: null, root: null, orig: null, orig_line_diff: 0, dest_line_diff: 0 }); var generator = new MOZ_SourceMap.SourceMapGenerator({ file: options.file, sourceRoot: options.root }); var orig_map = options.orig && new MOZ_SourceMap.SourceMapConsumer(options.orig); function add(source, gen_line, gen_col, orig_line, orig_col, name) { if (orig_map) { var info = orig_map.originalPositionFor({ line: orig_line, column: orig_col }); if (info.source === null) { return; } source = info.source; orig_line = info.line; orig_col = info.column; name = info.name; } generator.addMapping({ generated: { line: gen_line + options.dest_line_diff, column: gen_col }, original: { line: orig_line + options.orig_line_diff, column: orig_col }, source: source, name: name }); } return { add: add, get: function() { return generator; }, toString: function() { return generator.toString(); } }; } "use strict"; (function() { var MOZ_TO_ME = { ExpressionStatement: function(M) { var expr = M.expression; if (expr.type === "Literal" && typeof expr.value === "string") { return new AST_Directive({ start: my_start_token(M), end: my_end_token(M), value: expr.value }); } return new AST_SimpleStatement({ start: my_start_token(M), end: my_end_token(M), body: from_moz(expr) }); }, TryStatement: function(M) { var handlers = M.handlers || [ M.handler ]; if (handlers.length > 1 || M.guardedHandlers && M.guardedHandlers.length) { throw new Error("Multiple catch clauses are not supported."); } return new AST_Try({ start: my_start_token(M), end: my_end_token(M), body: from_moz(M.block).body, bcatch: from_moz(handlers[0]), bfinally: M.finalizer ? new AST_Finally(from_moz(M.finalizer)) : null }); }, Property: function(M) { var key = M.key; var name = key.type == "Identifier" ? key.name : key.value; var args = { start: my_start_token(key), end: my_end_token(M.value), key: name, value: from_moz(M.value) }; switch (M.kind) { case "init": return new AST_ObjectKeyVal(args); case "set": args.value.name = from_moz(key); return new AST_ObjectSetter(args); case "get": args.value.name = from_moz(key); return new AST_ObjectGetter(args); } }, ObjectExpression: function(M) { return new AST_Object({ start: my_start_token(M), end: my_end_token(M), properties: M.properties.map(function(prop) { prop.type = "Property"; return from_moz(prop); }) }); }, SequenceExpression: function(M) { return AST_Seq.from_array(M.expressions.map(from_moz)); }, MemberExpression: function(M) { return new (M.computed ? AST_Sub : AST_Dot)({ start: my_start_token(M), end: my_end_token(M), property: M.computed ? from_moz(M.property) : M.property.name, expression: from_moz(M.object) }); }, SwitchCase: function(M) { return new (M.test ? AST_Case : AST_Default)({ start: my_start_token(M), end: my_end_token(M), expression: from_moz(M.test), body: M.consequent.map(from_moz) }); }, VariableDeclaration: function(M) { return new (M.kind === "const" ? AST_Const : AST_Var)({ start: my_start_token(M), end: my_end_token(M), definitions: M.declarations.map(from_moz) }); }, Literal: function(M) { var val = M.value, args = { start: my_start_token(M), end: my_end_token(M) }; if (val === null) return new AST_Null(args); switch (typeof val) { case "string": args.value = val; return new AST_String(args); case "number": args.value = val; return new AST_Number(args); case "boolean": return new (val ? AST_True : AST_False)(args); default: args.value = val; return new AST_RegExp(args); } }, Identifier: function(M) { var p = FROM_MOZ_STACK[FROM_MOZ_STACK.length - 2]; return new (p.type == "LabeledStatement" ? AST_Label : p.type == "VariableDeclarator" && p.id === M ? p.kind == "const" ? AST_SymbolConst : AST_SymbolVar : p.type == "FunctionExpression" ? p.id === M ? AST_SymbolLambda : AST_SymbolFunarg : p.type == "FunctionDeclaration" ? p.id === M ? AST_SymbolDefun : AST_SymbolFunarg : p.type == "CatchClause" ? AST_SymbolCatch : p.type == "BreakStatement" || p.type == "ContinueStatement" ? AST_LabelRef : AST_SymbolRef)({ start: my_start_token(M), end: my_end_token(M), name: M.name }); } }; MOZ_TO_ME.UpdateExpression = MOZ_TO_ME.UnaryExpression = function To_Moz_Unary(M) { var prefix = "prefix" in M ? M.prefix : M.type == "UnaryExpression" ? true : false; return new (prefix ? AST_UnaryPrefix : AST_UnaryPostfix)({ start: my_start_token(M), end: my_end_token(M), operator: M.operator, expression: from_moz(M.argument) }); }; map("Program", AST_Toplevel, "body@body"); map("EmptyStatement", AST_EmptyStatement); map("BlockStatement", AST_BlockStatement, "body@body"); map("IfStatement", AST_If, "test>condition, consequent>body, alternate>alternative"); map("LabeledStatement", AST_LabeledStatement, "label>label, body>body"); map("BreakStatement", AST_Break, "label>label"); map("ContinueStatement", AST_Continue, "label>label"); map("WithStatement", AST_With, "object>expression, body>body"); map("SwitchStatement", AST_Switch, "discriminant>expression, cases@body"); map("ReturnStatement", AST_Return, "argument>value"); map("ThrowStatement", AST_Throw, "argument>value"); map("WhileStatement", AST_While, "test>condition, body>body"); map("DoWhileStatement", AST_Do, "test>condition, body>body"); map("ForStatement", AST_For, "init>init, test>condition, update>step, body>body"); map("ForInStatement", AST_ForIn, "left>init, right>object, body>body"); map("DebuggerStatement", AST_Debugger); map("FunctionDeclaration", AST_Defun, "id>name, params@argnames, body%body"); map("VariableDeclarator", AST_VarDef, "id>name, init>value"); map("CatchClause", AST_Catch, "param>argname, body%body"); map("ThisExpression", AST_This); map("ArrayExpression", AST_Array, "elements@elements"); map("FunctionExpression", AST_Function, "id>name, params@argnames, body%body"); map("BinaryExpression", AST_Binary, "operator=operator, left>left, right>right"); map("LogicalExpression", AST_Binary, "operator=operator, left>left, right>right"); map("AssignmentExpression", AST_Assign, "operator=operator, left>left, right>right"); map("ConditionalExpression", AST_Conditional, "test>condition, consequent>consequent, alternate>alternative"); map("NewExpression", AST_New, "callee>expression, arguments@args"); map("CallExpression", AST_Call, "callee>expression, arguments@args"); def_to_moz(AST_Directive, function To_Moz_Directive(M) { return { type: "ExpressionStatement", expression: { type: "Literal", value: M.value } }; }); def_to_moz(AST_SimpleStatement, function To_Moz_ExpressionStatement(M) { return { type: "ExpressionStatement", expression: to_moz(M.body) }; }); def_to_moz(AST_SwitchBranch, function To_Moz_SwitchCase(M) { return { type: "SwitchCase", test: to_moz(M.expression), consequent: M.body.map(to_moz) }; }); def_to_moz(AST_Try, function To_Moz_TryStatement(M) { return { type: "TryStatement", block: to_moz_block(M), handler: to_moz(M.bcatch), guardedHandlers: [], finalizer: to_moz(M.bfinally) }; }); def_to_moz(AST_Catch, function To_Moz_CatchClause(M) { return { type: "CatchClause", param: to_moz(M.argname), guard: null, body: to_moz_block(M) }; }); def_to_moz(AST_Definitions, function To_Moz_VariableDeclaration(M) { return { type: "VariableDeclaration", kind: M instanceof AST_Const ? "const" : "var", declarations: M.definitions.map(to_moz) }; }); def_to_moz(AST_Seq, function To_Moz_SequenceExpression(M) { return { type: "SequenceExpression", expressions: M.to_array().map(to_moz) }; }); def_to_moz(AST_PropAccess, function To_Moz_MemberExpression(M) { var isComputed = M instanceof AST_Sub; return { type: "MemberExpression", object: to_moz(M.expression), computed: isComputed, property: isComputed ? to_moz(M.property) : { type: "Identifier", name: M.property } }; }); def_to_moz(AST_Unary, function To_Moz_Unary(M) { return { type: M.operator == "++" || M.operator == "--" ? "UpdateExpression" : "UnaryExpression", operator: M.operator, prefix: M instanceof AST_UnaryPrefix, argument: to_moz(M.expression) }; }); def_to_moz(AST_Binary, function To_Moz_BinaryExpression(M) { return { type: M.operator == "&&" || M.operator == "||" ? "LogicalExpression" : "BinaryExpression", left: to_moz(M.left), operator: M.operator, right: to_moz(M.right) }; }); def_to_moz(AST_Object, function To_Moz_ObjectExpression(M) { return { type: "ObjectExpression", properties: M.properties.map(to_moz) }; }); def_to_moz(AST_ObjectProperty, function To_Moz_Property(M) { var key = is_identifier(M.key) ? { type: "Identifier", name: M.key } : { type: "Literal", value: M.key }; var kind; if (M instanceof AST_ObjectKeyVal) { kind = "init"; } else if (M instanceof AST_ObjectGetter) { kind = "get"; } else if (M instanceof AST_ObjectSetter) { kind = "set"; } return { type: "Property", kind: kind, key: key, value: to_moz(M.value) }; }); def_to_moz(AST_Symbol, function To_Moz_Identifier(M) { var def = M.definition(); return { type: "Identifier", name: def ? def.mangled_name || def.name : M.name }; }); def_to_moz(AST_Constant, function To_Moz_Literal(M) { var value = M.value; if (typeof value === "number" && (value < 0 || value === 0 && 1 / value < 0)) { return { type: "UnaryExpression", operator: "-", prefix: true, argument: { type: "Literal", value: -value } }; } return { type: "Literal", value: value }; }); def_to_moz(AST_Atom, function To_Moz_Atom(M) { return { type: "Identifier", name: String(M.value) }; }); AST_Boolean.DEFMETHOD("to_mozilla_ast", AST_Constant.prototype.to_mozilla_ast); AST_Null.DEFMETHOD("to_mozilla_ast", AST_Constant.prototype.to_mozilla_ast); AST_Hole.DEFMETHOD("to_mozilla_ast", function To_Moz_ArrayHole() { return null; }); AST_Block.DEFMETHOD("to_mozilla_ast", AST_BlockStatement.prototype.to_mozilla_ast); AST_Lambda.DEFMETHOD("to_mozilla_ast", AST_Function.prototype.to_mozilla_ast); function my_start_token(moznode) { var loc = moznode.loc; var range = moznode.range; return new AST_Token({ file: loc && loc.source, line: loc && loc.start.line, col: loc && loc.start.column, pos: range ? range[0] : moznode.start, endpos: range ? range[0] : moznode.start }); } function my_end_token(moznode) { var loc = moznode.loc; var range = moznode.range; return new AST_Token({ file: loc && loc.source, line: loc && loc.end.line, col: loc && loc.end.column, pos: range ? range[1] : moznode.end, endpos: range ? range[1] : moznode.end }); } function map(moztype, mytype, propmap) { if (typeof UglifyJS_NoUnsafeEval !== "undefined") { var prop_list = []; if (propmap) propmap.split(/\s*,\s*/).forEach(function(prop) { var m = /([a-z0-9$_]+)(=|@|>|%)([a-z0-9$_]+)/i.exec(prop); if (!m) throw new Error("Can't understand property map: " + prop); if ("=@>%".indexOf(m[2]) < 0) { throw new Error("Can't understand operator in propmap: " + prop); } prop_list.push(m); }); var moz_to_me = function(M) { var props = { start: my_start_token(M), end: my_end_token(M) }; for (var i = 0; i < prop_list.length; i++) { var m = prop_list[i]; var moz = m[1], how = m[2], my = m[3]; var mozProp = M[moz]; var myProp; switch (how) { case "@": myProp = mozProp.map(from_moz); break; case ">": myProp = from_moz(mozProp); break; case "=": myProp = mozProp; break; case "%": myProp = from_moz(mozProp).body; break; } props[my] = myProp; } return new mytype(props); }; var me_to_moz = function(M) { var props = { type: moztype }; for (var i = 0; i < prop_list.length; i++) { var m = prop_list[i]; var moz = m[1], how = m[2], my = m[3]; var myProp = M[my]; var mozProp; switch (how) { case "@": mozProp = myProp.map(to_moz); break; case ">": mozProp = to_moz(myProp); break; case "=": mozProp = myProp; break; case "%": mozProp = to_moz_block(M); break; } props[moz] = mozProp; } return props; }; MOZ_TO_ME[moztype] = moz_to_me; def_to_moz(mytype, me_to_moz); return; } var moz_to_me = "function From_Moz_" + moztype + "(M){\n"; moz_to_me += "return new " + mytype.name + "({\n" + "start: my_start_token(M),\n" + "end: my_end_token(M)"; var me_to_moz = "function To_Moz_" + moztype + "(M){\n"; me_to_moz += "return {\n" + "type: " + JSON.stringify(moztype); if (propmap) propmap.split(/\s*,\s*/).forEach(function(prop) { var m = /([a-z0-9$_]+)(=|@|>|%)([a-z0-9$_]+)/i.exec(prop); if (!m) throw new Error("Can't understand property map: " + prop); var moz = m[1], how = m[2], my = m[3]; moz_to_me += ",\n" + my + ": "; me_to_moz += ",\n" + moz + ": "; switch (how) { case "@": moz_to_me += "M." + moz + ".map(from_moz)"; me_to_moz += "M." + my + ".map(to_moz)"; break; case ">": moz_to_me += "from_moz(M." + moz + ")"; me_to_moz += "to_moz(M." + my + ")"; break; case "=": moz_to_me += "M." + moz; me_to_moz += "M." + my; break; case "%": moz_to_me += "from_moz(M." + moz + ").body"; me_to_moz += "to_moz_block(M)"; break; default: throw new Error("Can't understand operator in propmap: " + prop); } }); moz_to_me += "\n})\n}"; me_to_moz += "\n}\n}"; moz_to_me = new Function("my_start_token", "my_end_token", "from_moz", "return(" + moz_to_me + ")")(my_start_token, my_end_token, from_moz); me_to_moz = new Function("to_moz", "to_moz_block", "return(" + me_to_moz + ")")(to_moz, to_moz_block); MOZ_TO_ME[moztype] = moz_to_me; def_to_moz(mytype, me_to_moz); } var FROM_MOZ_STACK = null; function from_moz(node) { FROM_MOZ_STACK.push(node); var ret = node != null ? MOZ_TO_ME[node.type](node) : null; FROM_MOZ_STACK.pop(); return ret; } AST_Node.from_mozilla_ast = function(node) { var save_stack = FROM_MOZ_STACK; FROM_MOZ_STACK = []; var ast = from_moz(node); FROM_MOZ_STACK = save_stack; return ast; }; function moz_sub_loc(token) { return token.line ? { line: token.line, column: token.col } : null; } function set_moz_loc(mynode, moznode) { var start = mynode.start; var end = mynode.end; if (start.pos != null && end.pos != null) { moznode.range = [ start.pos, end.pos ]; } if (start.line) { moznode.loc = { start: moz_sub_loc(start), end: moz_sub_loc(end) }; if (start.file) { moznode.loc.source = start.file; } } return moznode; } function def_to_moz(mytype, handler) { mytype.DEFMETHOD("to_mozilla_ast", function() { return set_moz_loc(this, handler(this)); }); } function to_moz(node) { return node != null ? node.to_mozilla_ast() : null; } function to_moz_block(node) { return { type: "BlockStatement", body: node.body.map(to_moz) }; } })(); exports["array_to_hash"] = array_to_hash; exports["slice"] = slice; exports["characters"] = characters; exports["member"] = member; exports["find_if"] = find_if; exports["repeat_string"] = repeat_string; exports["DefaultsError"] = DefaultsError; exports["defaults"] = defaults; exports["merge"] = merge; exports["noop"] = noop; exports["MAP"] = MAP; exports["push_uniq"] = push_uniq; exports["string_template"] = string_template; exports["remove"] = remove; exports["mergeSort"] = mergeSort; exports["set_difference"] = set_difference; exports["set_intersection"] = set_intersection; exports["makePredicate"] = makePredicate; exports["all"] = all; exports["Dictionary"] = Dictionary; exports["DEFNODE"] = DEFNODE; exports["AST_Token"] = AST_Token; exports["AST_Node"] = AST_Node; exports["AST_Statement"] = AST_Statement; exports["AST_Debugger"] = AST_Debugger; exports["AST_Directive"] = AST_Directive; exports["AST_SimpleStatement"] = AST_SimpleStatement; exports["walk_body"] = walk_body; exports["AST_Block"] = AST_Block; exports["AST_BlockStatement"] = AST_BlockStatement; exports["AST_EmptyStatement"] = AST_EmptyStatement; exports["AST_StatementWithBody"] = AST_StatementWithBody; exports["AST_LabeledStatement"] = AST_LabeledStatement; exports["AST_IterationStatement"] = AST_IterationStatement; exports["AST_DWLoop"] = AST_DWLoop; exports["AST_Do"] = AST_Do; exports["AST_While"] = AST_While; exports["AST_For"] = AST_For; exports["AST_ForIn"] = AST_ForIn; exports["AST_With"] = AST_With; exports["AST_Scope"] = AST_Scope; exports["AST_Toplevel"] = AST_Toplevel; exports["AST_Lambda"] = AST_Lambda; exports["AST_Accessor"] = AST_Accessor; exports["AST_Function"] = AST_Function; exports["AST_Defun"] = AST_Defun; exports["AST_Jump"] = AST_Jump; exports["AST_Exit"] = AST_Exit; exports["AST_Return"] = AST_Return; exports["AST_Throw"] = AST_Throw; exports["AST_LoopControl"] = AST_LoopControl; exports["AST_Break"] = AST_Break; exports["AST_Continue"] = AST_Continue; exports["AST_If"] = AST_If; exports["AST_Switch"] = AST_Switch; exports["AST_SwitchBranch"] = AST_SwitchBranch; exports["AST_Default"] = AST_Default; exports["AST_Case"] = AST_Case; exports["AST_Try"] = AST_Try; exports["AST_Catch"] = AST_Catch; exports["AST_Finally"] = AST_Finally; exports["AST_Definitions"] = AST_Definitions; exports["AST_Var"] = AST_Var; exports["AST_Const"] = AST_Const; exports["AST_VarDef"] = AST_VarDef; exports["AST_Call"] = AST_Call; exports["AST_New"] = AST_New; exports["AST_Seq"] = AST_Seq; exports["AST_PropAccess"] = AST_PropAccess; exports["AST_Dot"] = AST_Dot; exports["AST_Sub"] = AST_Sub; exports["AST_Unary"] = AST_Unary; exports["AST_UnaryPrefix"] = AST_UnaryPrefix; exports["AST_UnaryPostfix"] = AST_UnaryPostfix; exports["AST_Binary"] = AST_Binary; exports["AST_Conditional"] = AST_Conditional; exports["AST_Assign"] = AST_Assign; exports["AST_Array"] = AST_Array; exports["AST_Object"] = AST_Object; exports["AST_ObjectProperty"] = AST_ObjectProperty; exports["AST_ObjectKeyVal"] = AST_ObjectKeyVal; exports["AST_ObjectSetter"] = AST_ObjectSetter; exports["AST_ObjectGetter"] = AST_ObjectGetter; exports["AST_Symbol"] = AST_Symbol; exports["AST_SymbolAccessor"] = AST_SymbolAccessor; exports["AST_SymbolDeclaration"] = AST_SymbolDeclaration; exports["AST_SymbolVar"] = AST_SymbolVar; exports["AST_SymbolConst"] = AST_SymbolConst; exports["AST_SymbolFunarg"] = AST_SymbolFunarg; exports["AST_SymbolDefun"] = AST_SymbolDefun; exports["AST_SymbolLambda"] = AST_SymbolLambda; exports["AST_SymbolCatch"] = AST_SymbolCatch; exports["AST_Label"] = AST_Label; exports["AST_SymbolRef"] = AST_SymbolRef; exports["AST_LabelRef"] = AST_LabelRef; exports["AST_This"] = AST_This; exports["AST_Constant"] = AST_Constant; exports["AST_String"] = AST_String; exports["AST_Number"] = AST_Number; exports["AST_RegExp"] = AST_RegExp; exports["AST_Atom"] = AST_Atom; exports["AST_Null"] = AST_Null; exports["AST_NaN"] = AST_NaN; exports["AST_Undefined"] = AST_Undefined; exports["AST_Hole"] = AST_Hole; exports["AST_Infinity"] = AST_Infinity; exports["AST_Boolean"] = AST_Boolean; exports["AST_False"] = AST_False; exports["AST_True"] = AST_True; exports["TreeWalker"] = TreeWalker; exports["KEYWORDS"] = KEYWORDS; exports["KEYWORDS_ATOM"] = KEYWORDS_ATOM; exports["RESERVED_WORDS"] = RESERVED_WORDS; exports["KEYWORDS_BEFORE_EXPRESSION"] = KEYWORDS_BEFORE_EXPRESSION; exports["OPERATOR_CHARS"] = OPERATOR_CHARS; exports["RE_HEX_NUMBER"] = RE_HEX_NUMBER; exports["RE_OCT_NUMBER"] = RE_OCT_NUMBER; exports["RE_DEC_NUMBER"] = RE_DEC_NUMBER; exports["OPERATORS"] = OPERATORS; exports["WHITESPACE_CHARS"] = WHITESPACE_CHARS; exports["PUNC_BEFORE_EXPRESSION"] = PUNC_BEFORE_EXPRESSION; exports["PUNC_CHARS"] = PUNC_CHARS; exports["REGEXP_MODIFIERS"] = REGEXP_MODIFIERS; exports["UNICODE"] = UNICODE; exports["is_letter"] = is_letter; exports["is_digit"] = is_digit; exports["is_alphanumeric_char"] = is_alphanumeric_char; exports["is_unicode_combining_mark"] = is_unicode_combining_mark; exports["is_unicode_connector_punctuation"] = is_unicode_connector_punctuation; exports["is_identifier"] = is_identifier; exports["is_identifier_start"] = is_identifier_start; exports["is_identifier_char"] = is_identifier_char; exports["is_identifier_string"] = is_identifier_string; exports["parse_js_number"] = parse_js_number; exports["JS_Parse_Error"] = JS_Parse_Error; exports["js_error"] = js_error; exports["is_token"] = is_token; exports["EX_EOF"] = EX_EOF; exports["tokenizer"] = tokenizer; exports["UNARY_PREFIX"] = UNARY_PREFIX; exports["UNARY_POSTFIX"] = UNARY_POSTFIX; exports["ASSIGNMENT"] = ASSIGNMENT; exports["PRECEDENCE"] = PRECEDENCE; exports["STATEMENTS_WITH_LABELS"] = STATEMENTS_WITH_LABELS; exports["ATOMIC_START_TOKEN"] = ATOMIC_START_TOKEN; exports["parse"] = parse; exports["TreeTransformer"] = TreeTransformer; exports["SymbolDef"] = SymbolDef; exports["base54"] = base54; exports["OutputStream"] = OutputStream; exports["Compressor"] = Compressor; exports["SourceMap"] = SourceMap; })({}, function() { return this; }()); ================================================ FILE: omega-target/.gitignore ================================================ /index.js /omega_target.min.js ================================================ FILE: omega-target/Gruntfile.coffee ================================================ module.exports = require('load-grunt-config') ================================================ FILE: omega-target/grunt/aliases.coffee ================================================ module.exports = default: [ 'coffeelint' 'browserify' ] test: ['mochaTest'] ================================================ FILE: omega-target/grunt/browserify.coffee ================================================ module.exports = index: files: 'index.js': 'index.coffee' options: transform: ['coffeeify'] exclude: ['bluebird', 'jsondiffpatch', 'omega-pac'] browserifyOptions: extensions: '.coffee' builtins: [] standalone: 'index.coffee' debug: true browser: files: 'omega_target.min.js': 'index.coffee' options: alias: [ './index.coffee:OmegaTarget' ] transform: ['coffeeify'] plugin: if process.env.BUILD == 'release' [['minifyify', {map: false}]] else [] browserifyOptions: extensions: '.coffee' standalone: 'OmegaTarget' ================================================ FILE: omega-target/grunt/coffeelint.coffee ================================================ module.exports = options: arrow_spacing: level: 'error' colon_assignment_spacing: level: 'error' spacing: left: 0 right: 1 missing_fat_arrows: level: 'warn' no_empty_functions: level: 'error' no_empty_param_list: level: 'error' no_interpolation_in_single_quotes: level: 'error' no_stand_alone_at: level: 'error' space_operators: level: 'error' # https://github.com/clutchski/coffeelint/issues/525 indentation: level: 'ignore' gruntfile: ['Gruntfile.coffee'] tasks: ['grunt/**/*.coffee'] src: ['src/**/*.coffee', 'test/**/*.coffee'] ================================================ FILE: omega-target/grunt/mochaTest.coffee ================================================ module.exports = test: options: reporter: 'spec' require: 'coffee-script/register' src: ['test/**/*.coffee'] ================================================ FILE: omega-target/grunt/watch.coffee ================================================ module.exports = grunt: options: reload: true files: 'grunt/*' tasks: ['coffeelint:tasks', 'default'] src: files: ['src/**/*.coffee', 'test/**/*.coffee'] tasks: ['default'] ================================================ FILE: omega-target/index.coffee ================================================ module.exports = Log: require('./src/log') Storage: require('./src/storage') BrowserStorage: require('./src/browser_storage') Options: require('./src/options') OptionsSync: require('./src/options_sync') OmegaPac: require('omega-pac') for name, value of require('./src/utils.coffee') module.exports[name] = value for name, value of require('./src/errors.coffee') module.exports[name] = value ================================================ FILE: omega-target/omega_pac_shim.js ================================================ module.exports = OmegaPac; ================================================ FILE: omega-target/package.json ================================================ { "name": "omega-target", "version": "0.0.1", "private": true, "main": "./index.js", "devDependencies": { "chai": "^1.10.0", "coffee-script": "^1.8.0", "coffeeify": "^0.7.0", "coffeelint": "^1.16.0", "grunt": "^0.4.5", "grunt-browserify": "^3.0.0", "grunt-coffeelint": "^0.0.13", "grunt-contrib-coffee": "^0.11.1", "grunt-contrib-watch": "^0.6.1", "grunt-mocha-test": "~0.11.0", "load-grunt-config": "^0.13.1", "minifyify": "^4.1.1", "sinon": "^1.12.2", "sinon-chai": "^2.6.0" }, "dependencies": { "bluebird": "^2.3.2", "jsondiffpatch": "^0.1.8", "limiter": "^1.0.5", "omega-pac": "../omega-pac" }, "browser": { "omega-pac": "./omega_pac_shim.js" }, "scripts": { "dev": "npm link omega-pac && npm link", "test": "grunt test" } } ================================================ FILE: omega-target/src/browser_storage.coffee ================================================ Storage = require('./storage') Promise = require('bluebird') class BrowserStorage extends Storage constructor: (@storage, @prefix = '') -> @proto = Object.getPrototypeOf(@storage) get: (keys) -> map = {} if typeof keys == 'string' map[keys] = undefined else if Array.isArray(keys) for key in keys map[key] = undefined else if typeof keys == 'object' map = keys for own key of map try value = JSON.parse(@proto.getItem.call(@storage, @prefix + key)) map[key] = value if value? if typeof map[key] == 'undefined' delete map[key] Promise.resolve map set: (items) -> for own key, value of items value = JSON.stringify(value) @proto.setItem.call(@storage, @prefix + key, value) Promise.resolve items remove: (keys) -> if not keys? if not @prefix @proto.clear.call(@storage) else index = 0 while true key = @proto.key.call(index) break if key == null if @key.substr(0, @prefix.length) == @prefix @proto.removeItem.call(@storage, @prefix + keys) else index++ if typeof keys == 'string' @proto.removeItem.call(@storage, @prefix + keys) for key in keys @proto.removeItem.call(@storage, @prefix + key) Promise.resolve() module.exports = BrowserStorage ================================================ FILE: omega-target/src/default_options.coffee ================================================ module.exports = -> schemaVersion: 2 "-enableQuickSwitch": false "-refreshOnProfileChange": true "-startupProfileName": "" "-quickSwitchProfiles": [] "-revertProxyChanges": true "-confirmDeletion": true "-showInspectMenu": true "-addConditionsToBottom": false "-showExternalProfile": true "-downloadInterval": 1440 "+proxy": bypassList: [ { pattern: "127.0.0.1" conditionType: "BypassCondition" } { pattern: "::1" conditionType: "BypassCondition" } { pattern: "localhost" conditionType: "BypassCondition" } ] profileType: "FixedProfile" name: "proxy" color: "#99ccee" fallbackProxy: port: 8080 scheme: "http" host: "proxy.example.com" "+auto switch": profileType: "SwitchProfile" rules: [ { condition: pattern: "internal.example.com" conditionType: "HostWildcardCondition" profileName: "direct" } { condition: pattern: "*.example.com" conditionType: "HostWildcardCondition" profileName: "proxy" } ] name: "auto switch" color: "#99dd99" defaultProfileName: "direct" ================================================ FILE: omega-target/src/errors.coffee ================================================ class NetworkError extends Error constructor: (err) -> super this.cause = err this.name = 'NetworkError' class HttpError extends NetworkError constructor: -> super this.statusCode = this.cause?.statusCode this.name = 'HttpError' class HttpNotFoundError extends HttpError constructor: -> super this.name = 'HttpNotFoundError' class HttpServerError extends HttpError constructor: -> super this.name = 'HttpServerError' class ContentTypeRejectedError extends Error constructor: -> super this.name = 'ContentTypeRejectedError' module.exports = NetworkError: NetworkError HttpError: HttpError HttpNotFoundError: HttpNotFoundError HttpServerError: HttpServerError ContentTypeRejectedError: ContentTypeRejectedError ================================================ FILE: omega-target/src/log.coffee ================================================ ### @module omega-target/log ### Log = require './log' replacer = (key, value) -> switch key # Hide values for a few keys with privacy concerns. when "username", "password", "host", "port" return "" else value # Log is used as singleton. # coffeelint: disable=missing_fat_arrows module.exports = Log = ###* # Pretty-print an object and return the result string. # @param {{}} obj The object to format # @returns {String} the formatted object in string ### str: (obj) -> # TODO(catus): This can be improved to print things more friendly. if typeof obj == 'object' and obj != null if obj.debugStr? if typeof obj.debugStr == 'function' obj.debugStr() else obj.debugStr else if obj instanceof Error obj.stack || obj.message else JSON.stringify(obj, replacer, 4) else if typeof obj == 'function' if obj.name "" else obj.toString() else '' + obj ###* # Print something to the log. # @param {...{}} args The objects to log ### log: console.log.bind(console) ###* # Print something to the error log. # @param {...{}} args The objects to log ### error: console.error.bind(console) ###* # Log a function call with target and arguments # @param {string} name The name of the method # @param {Array} args The arguments to the method call ### func: (name, args) -> this.log(name, '(', [].slice.call(args), ')') ###* # Log a method call with target and arguments # @param {string} name The name of the method # @param {{}} self The target of the method call # @param {Array} args The arguments to the method call ### method: (name, self, args) -> this.log(this.str(self), '<<', name, [].slice.call(args)) # coffeelint: enable=missing_fat_arrows ================================================ FILE: omega-target/src/options.coffee ================================================ ### @module omega-target/options ### Promise = require 'bluebird' Log = require './log' Storage = require './storage' OmegaPac = require 'omega-pac' jsondiffpatch = require 'jsondiffpatch' class Options ###* # The entire set of options including profiles and other settings. # @typedef OmegaOptions # @type {object} ### ###* # All the options, in a map from key to value. # @type OmegaOptions ### _options: null _storage: null _state: null _currentProfileName: null _revertToProfileName: null _watchingProfiles: {} _tempProfile: null _tempProfileActive: false fallbackProfileName: 'system' _isSystem: false debugStr: 'Options' ready: null @ProfileNotExistError: class ProfileNotExistError extends Error constructor: (@profileName) -> super.constructor("Profile #{@profileName} does not exist!") @NoOptionsError: class NoOptionsError extends Error constructor: -> super ###* # Transform options values (especially profiles) for syncing. # @param {{}} value The value to transform # @param {{}} key The key of the options # @returns {{}} The transformed value ### @transformValueForSync: (value, key) -> if key[0] == '+' if OmegaPac.Profiles.updateUrl(value) profile = {} for k, v of value continue if k == 'lastUpdate' || k == 'ruleList' || k == 'pacScript' profile[k] = v value = profile return value constructor: (options, @_storage, @_state, @log, @sync, @proxyImpl) -> @_options = {} @_tempProfileRules = {} @_tempProfileRulesByProfile = {} @_storage ?= Storage() @_state ?= Storage() @log ?= Log if not options? @init() else @ready = @_storage.remove().then(=> @_storage.set(options) ).then => @init() ###* # Attempt to load options from local and remote storage. # @param {?{}} args Extra arguments # @param {number=3} args.retry Number of retries before giving up. # @returns {Promise} The loaded options ### loadOptions: ({retry} = {}) -> retry ?= 3 @_syncWatchStop?() @_syncWatchStop = null @_watchStop?() @_watchStop = null loadRaw = if options? then Promise.resolve(options) else if not @sync?.enabled if not @sync? @_state.set({'syncOptions': 'unsupported'}) @_storage.get(null) else @_state.set({'syncOptions': 'sync'}) @_syncWatchStop = @sync.watchAndPull(@_storage) @sync.copyTo(@_storage).catch(Storage.StorageUnavailableError, => console.error('Warning: Sync storage is not available in this ' + 'browser! Disabling options sync.') @_syncWatchStop?() @_syncWatchStop = null @sync = null @_state.set({'syncOptions': 'unsupported'}) ).then => @_storage.get(null) @optionsLoaded = loadRaw.then((options) => @upgrade(options) ).then(([options, changes]) => @_storage.apply(changes: changes).return(options) ).tap((options) => @_options = options @_watchStop = @_watch() # Try to set syncOptions to some value if not initialized. @_state.get({'syncOptions': ''}).then ({syncOptions}) => return if syncOptions @_state.set({'syncOptions': 'conflict'}) @sync.storage.get('schemaVersion').then ({schemaVersion}) => @_state.set({'syncOptions': 'pristine'}) if not schemaVersion ).catch (e) => return Promise.reject(e) unless retry > 0 getFallbackOptions = Promise.resolve().then => if e instanceof NoOptionsError @_state.get({ 'firstRun': 'new' 'web.switchGuide': 'showOnFirstUse' }).then (items) => @_state.set(items) return null unless @sync? @_state.get({'syncOptions': ''}).then ({syncOptions}) => return if syncOptions == 'conflict' # Try to fetch options from sync storage. return @sync.storage.get(null).then((options) => if not options['schemaVersion'] @_state.set({'syncOptions': 'pristine'}) return null else @_state.set({'syncOptions': 'sync'}) @sync.enabled = true @log.log('Options#loadOptions::fromSync', options) options ).catch(-> null) else @log.error(e.stack) # Some serious error happened when loading options. Disable syncing # and use fallback options. @_state.remove(['syncOptions']) return null getFallbackOptions.then (options) => options ?= @parseOptions(@getDefaultOptions()) if @sync? prevEnabled = @sync.enabled @sync.enabled = false @_storage.remove().then(=> @_storage.set(options) ).then => @sync.enabled = prevEnabled if @sync? @loadOptions({retry: retry - 1}) ###* # Attempt to initialize (or reinitialize) options. # @returns {Promise} A promise that is fulfilled on ready. ### init: -> @ready = @loadOptions().then(=> if @_options['-startupProfileName'] @applyProfile(@_options['-startupProfileName']) else @_state.get({ 'currentProfileName': @fallbackProfileName 'isSystemProfile': false }).then (st) => if st['isSystemProfile'] @applyProfile('system') else @applyProfile(st['currentProfileName'] || @fallbackProfileName) ).catch((err) => if not err instanceof ProfileNotExistError @log.error(err) @applyProfile(@fallbackProfileName) ).catch((err) => @log.error(err) ).then => @getAll() @ready.then => @sync.requestPush(@_options) if @sync?.enabled @_state.get({'firstRun': ''}).then ({firstRun}) => @onFirstRun(firstRun) if firstRun if @_options['-downloadInterval'] > 0 @updateProfile() return @ready toString: -> "" ###* # Return a localized, human-readable description of the given profile. # In base class, this method is not implemented and will always return null. # @param {?{}} profile The profile to print # @returns {string} Description of the profile with details ### printProfile: (profile) -> null ###* # Upgrade options from previous versions. # For now, this method only supports schemaVersion 1 and 2. If so, it upgrades # the options to version 2 (the latest version). Otherwise it rejects. # It is recommended for the derived classes to call super() two times in the # beginning and in the end of the implementation to check the schemaVersion # and to apply future upgrades, respectively. # Example: super(options).catch -> super(doCustomUpgrades(options), changes) # @param {?OmegaOptions} options The legacy options to upgrade # @param {{}={}} changes Previous pending changes to be applied. Default to # an empty dictionary. Please provide this argument when calling super(). # @returns {Promise<[OmegaOptions, {}]>} The new options and the changes. ### upgrade: (options, changes) -> changes ?= {} version = options?['schemaVersion'] if version == 1 autoDetectUsed = false OmegaPac.Profiles.each options, (key, profile) -> if not autoDetectUsed refs = OmegaPac.Profiles.directReferenceSet(profile) if refs['+auto_detect'] autoDetectUsed = true if autoDetectUsed options['+auto_detect'] = OmegaPac.Profiles.create( name: 'auto_detect' profileType: 'PacProfile' pacUrl: 'http://wpad/wpad.dat' color: '#00cccc' ) version = changes['schemaVersion'] = options['schemaVersion'] = 2 if version == 2 # Current schemaVersion. Promise.resolve([options, changes]) else Promise.reject new Error("Invalid schemaVerion #{version}!") ###* # Parse options in various formats (including JSON & base64). # @param {OmegaOptions|string} options The options to parse # @returns {Promise} The parsed options. ### parseOptions: (options) -> if typeof options == 'string' if options[0] != '{' try Buffer = require('buffer').Buffer options = new Buffer(options, 'base64').toString('utf8') catch _ options = null options = try JSON.parse(options) if not options return throw new Error('Invalid options!') return options ###* # Reset the options to the given options or initial options. # @param {?OmegaOptions} options The options to set. Defaults to initial. # @returns {Promise} The options just applied ### reset: (options) -> @log.method('Options#reset', this, arguments) options ?= @getDefaultOptions() @upgrade(@parseOptions(options)).then ([opt]) => # Disable syncing when resetting to avoid affecting sync storage. @sync.enabled = false if @sync? @_state.remove(['syncOptions']) @_storage.remove().then(=> @_storage.set(opt) ).then => @init() ###* # Called on the first initialization of options. # @param {reason} reason The value of 'firstRun' in state. ### onFirstRun: (reason) -> null ###* # Return the default options used initially and on resets. # @returns {?OmegaOptions} The default options. ### getDefaultOptions: -> require('./default_options')() ###* # Return all options. # @returns {?OmegaOptions} The options. ### getAll: -> @_options ###* # Get profile by name. # @returns {?{}} The profile, or undefined if no such profile. ### profile: (name) -> OmegaPac.Profiles.byName(name, @_options) ###* # Apply the patch to the current options. # @param {jsondiffpatch} patch The patch to apply # @returns {Promise} The updated options ### patch: (patch) -> return unless patch @log.method('Options#patch', this, arguments) @_options = jsondiffpatch.patch(@_options, patch) # Only set the keys whose values have changed. changes = {} for own key, delta of patch if delta.length == 3 and delta[1] == 0 and delta[2] == 0 # [previousValue, 0, 0] indicates that the key was removed. changes[key] = undefined else changes[key] = @_options[key] @_setOptions(changes) _setOptions: (changes, args) => removed = [] checkRev = args?.checkRevision ? false profilesChanged = false currentProfileAffected = false for own key, value of changes if typeof value == 'undefined' delete @_options[key] removed.push(key) if key[0] == '+' profilesChanged = true if key == '+' + @_currentProfileName currentProfileAffected = 'removed' else if key[0] == '+' if checkRev and @_options[key] result = OmegaPac.Revision.compare(@_options[key].revision, value.revision) continue if result >= 0 profilesChanged = true @_options[key] = value if not currentProfileAffected and @_watchingProfiles[key] currentProfileAffected = 'changed' switch currentProfileAffected when 'removed' @applyProfile(@fallbackProfileName) when 'changed' @applyProfile(@_currentProfileName, update: false) else @_setAvailableProfiles() if profilesChanged if args?.persist ? true @sync?.requestPush(changes) if @sync?.enabled for key in removed delete changes[key] @_storage.set(changes).then => @_storage.remove(removed) return @_options _watch: -> handler = (changes) => if changes @_setOptions(changes, {checkRevision: true, persist: false}) else # Initial update. changes = @_options refresh = changes['-refreshOnProfileChange'] if refresh? @_state.set({'refreshOnProfileChange': refresh}) if Object::hasOwnProperty.call changes, '-showExternalProfile' showExternal = changes['-showExternalProfile'] if not showExternal? showExternal = true @_setOptions({'-showExternalProfile': true}, {persist: true}) @_state.set({'showExternalProfile': showExternal}) quickSwitchProfiles = changes['-quickSwitchProfiles'] quickSwitchProfiles = @_cleanUpQuickSwitchProfiles(quickSwitchProfiles) if changes['-enableQuickSwitch']? or quickSwitchProfiles? @reloadQuickSwitch() if changes['-downloadInterval']? @schedule 'updateProfile', @_options['-downloadInterval'], => @updateProfile() if changes['-showInspectMenu']? or changes == @_options showMenu = @_options['-showInspectMenu'] if not showMenu? showMenu = true @_setOptions({'-showInspectMenu': true}, {persist: true}) @setInspect(showMenu: showMenu) if changes['-monitorWebRequests']? or changes == @_options monitorWebRequests = @_options['-monitorWebRequests'] if not monitorWebRequests? monitorWebRequests = true @_setOptions({'-monitorWebRequests': true}, {persist: true}) @setMonitorWebRequests(monitorWebRequests) handler() @_storage.watch null, handler _cleanUpQuickSwitchProfiles: (quickSwitchProfiles) -> return unless quickSwitchProfiles? seenQuickSwitchProfile = {} validQuickSwitchProfiles = quickSwitchProfiles.filter (name) => return false if not name key = OmegaPac.Profiles.nameAsKey(name) return false if seenQuickSwitchProfile[key] return false if not OmegaPac.Profiles.byName(name, @_options) seenQuickSwitchProfile[key] = true return true if validQuickSwitchProfiles.length != quickSwitchProfiles.length @_setOptions( {'-quickSwitchProfiles': validQuickSwitchProfiles}, {persist: true}) return validQuickSwitchProfiles ###* # Reload the quick switch according to settings. # @returns {Promise} A promise which is fulfilled when the quick switch is set ### reloadQuickSwitch: -> profiles = @_options['-quickSwitchProfiles'] profiles = null if profiles.length < 2 if @_options['-enableQuickSwitch'] @setQuickSwitch(profiles, !!profiles) else @setQuickSwitch(null, !!profiles) ###* # Apply the settings related to element proxy inspection. # In base class, this method is not implemented and will not do anything. # @param {{}} settings # @param {boolean} settings.showMenu Whether to show the menu or not # @returns {Promise} A promise which is fulfilled when the settings apply ### setInspect: -> Promise.resolve() ###* # Apply the settings related to web request monitoring. # In base class, this method is not implemented and will not do anything. # @param {boolean} enabled Whether network shall be monitored or not # @returns {Promise} A promise which is fulfilled when the settings apply ### setMonitorWebRequests: -> Promise.resolve() ###* # @callback watchCallback # @param {Object.} changes A map from keys to values. ### ###* # Watch for any changes to the options # @param {watchCallback} callback Called everytime the value of a key changes # @returns {function} Calling the returned function will stop watching. ### watch: (callback) -> @_storage.watch null, callback _profileNotFound: (name) -> @log.error("Profile #{name} not found! Things may go very, very wrong.") return OmegaPac.Profiles.create({ name: name profileType: 'VirtualProfile' defaultProfileName: 'direct' }) ###* # Get PAC script for profile. # @param {?string|Object} profile The name of the profile, or the profile. # @param {bool=false} compress Compress the script if true. # @returns {string} The compiled ### pacForProfile: (profile, compress = false) -> ast = OmegaPac.PacGenerator.script(@_options, profile, profileNotFound: @_profileNotFound.bind(this)) if compress ast = OmegaPac.PacGenerator.compress(ast) Promise.resolve OmegaPac.PacGenerator.ascii(ast.print_to_string()) _setAvailableProfiles: -> profile = if @_currentProfileName then @currentProfile() else null profiles = {} currentIncludable = profile && OmegaPac.Profiles.isIncludable(profile) allReferenceSet = null if not profile or not OmegaPac.Profiles.isInclusive(profile) results = [] OmegaPac.Profiles.each @_options, (key, p) => profiles[key] = name: p.name profileType: p.profileType color: p.color desc: @printProfile(p) builtin: if p.builtin then true if p.profileType == 'VirtualProfile' profiles[key].defaultProfileName = p.defaultProfileName if not allReferenceSet? allReferenceSet = if profile OmegaPac.Profiles.allReferenceSet(profile, @_options, profileNotFound: @_profileNotFound.bind(this)) else {} if allReferenceSet[key] profiles[key].validResultProfiles = OmegaPac.Profiles.validResultProfilesFor(p, @_options) .map (result) -> result.name if currentIncludable and OmegaPac.Profiles.isIncludable(p) results?.push(p.name) if profile and OmegaPac.Profiles.isInclusive(profile) results = OmegaPac.Profiles.validResultProfilesFor(profile, @_options) results = results.map (profile) -> profile.name @_state.set({ 'availableProfiles': profiles 'validResultProfiles': results }) ###* # Apply the profile by name. # @param {?string} name The name of the profile, or null for default. # @param {?{}} options Some options # @param {bool=true} options.proxy Set proxy for the applied profile if true # @param {bool=true} options.update Try to update this profile and referenced # profiles after the proxy is set. # @param {bool=false} options.system Whether options is in system mode. # @param {{}=undefined} options.reason will be passed to currentProfileChanged # @returns {Promise} A promise which is fulfilled when the profile is applied. ### applyProfile: (name, options) -> @log.method('Options#applyProfile', this, arguments) profile = OmegaPac.Profiles.byName(name, @_options) if not profile return Promise.reject new ProfileNotExistError(name) @_currentProfileName = profile.name @_isSystem = options?.system || (profile.profileType == 'SystemProfile') @_watchingProfiles = OmegaPac.Profiles.allReferenceSet(profile, @_options, profileNotFound: @_profileNotFound.bind(this)) @_state.set({ 'currentProfileName': @_currentProfileName 'isSystemProfile': @_isSystem 'currentProfileCanAddRule': profile.rules? and profile.profileType != 'VirtualProfile' }) @_setAvailableProfiles() @currentProfileChanged(options?.reason) if options? and options.proxy == false return Promise.resolve() @_tempProfileActive = false if @_tempProfile? and OmegaPac.Profiles.isIncludable(profile) @_tempProfileActive = true if @_tempProfile.defaultProfileName != profile.name @_tempProfile.defaultProfileName = profile.name @_tempProfile.color = profile.color OmegaPac.Profiles.updateRevision(@_tempProfile) removedKeys = [] for own key, list of @_tempProfileRulesByProfile if not OmegaPac.Profiles.byKey(key, @_options) removedKeys.push(key) for rule in list rule.profileName = null @_tempProfile.rules.splice(@_tempProfile.rules.indexOf(rule), 1) if removedKeys.length > 0 for key in removedKeys delete @_tempProfileRulesByProfile[key] OmegaPac.Profiles.updateRevision(@_tempProfile) @_watchingProfiles = OmegaPac.Profiles.allReferenceSet(@_tempProfile, @_options, profileNotFound: @_profileNotFound.bind(this)) applyProxy = @proxyImpl.applyProfile(@_tempProfile, profile, @_options) else applyProxy = @proxyImpl.applyProfile(profile, profile, @_options) return applyProxy if options? and options.update == false applyProxy.then => return unless @_options['-downloadInterval'] > 0 return unless @_currentProfileName == profile.name updateProfiles = [] for key, name of @_watchingProfiles updateProfiles.push(name) if updateProfiles.length > 0 @updateProfile(updateProfiles) return applyProxy ###* # Get the current applied profile. # @returns {{}} The current profile ### currentProfile: -> if @_currentProfileName OmegaPac.Profiles.byName(@_currentProfileName, @_options) else @_externalProfile ###* # Return true if in system mode. # @returns {boolean} True if system mode is activated ### isSystem: -> @_isSystem ###* # Called when current profile has changed. # In base class, this method is not implemented and will not do anything. ### currentProfileChanged: -> null ###* # Set or disable the quick switch profiles. # In base class, this method is not implemented and will not do anything. # @param {string[]|null} quickSwitch The profile names, or null to disable # @param {boolean} canEnable Whether user can enable quick switch or not. # @returns {Promise} A promise which is fulfilled when the quick switch is set ### setQuickSwitch: (quickSwitch, canEnable) -> Promise.resolve() ###* # Schedule a task that runs every periodInMinutes. # In base class, this method is not implemented and will not do anything. # @param {string} name The name of the schedule. If there is a previous # schedule with the same name, it will be replaced by the new one. # @param {number} periodInMinutes The interval of the schedule # @param {function} callback The callback to call when the task runs # @returns {Promise} A promise which is fulfilled when the schedule is set ### schedule: (name, periodInMinutes, callback) -> Promise.resolve() ###* # Return true if the match result of current profile does not change with URLs # @returns {bool} Whether @match always return the same result for requests ### isCurrentProfileStatic: -> return true if not @_currentProfileName return false if @_tempProfileActive currentProfile = @currentProfile() return false if OmegaPac.Profiles.isInclusive(currentProfile) return true ###* # Update the profile by name. # @param {(string|string[]|null)} name The name of the profiles, # or null for all. # @param {?bool} opt_bypass_cache Do not read from the cache if true # @returns {Promise>} A map from keys to updated # profiles or errors. # A value is an error if `value instanceof Error`. Otherwise the value is an # updated profile. ### updateProfile: (name, opt_bypass_cache) -> @log.method('Options#updateProfile', this, arguments) results = {} OmegaPac.Profiles.each @_options, (key, profile) => if name? if Array.isArray(name) return unless name.indexOf(profile.name) >= 0 else return unless profile.name == name url = OmegaPac.Profiles.updateUrl(profile) if url type_hints = OmegaPac.Profiles.updateContentTypeHints(profile) fetchResult = @fetchUrl(url, opt_bypass_cache, type_hints) results[key] = fetchResult.then((data) => # Errors and unsuccessful response codes shoud have been already # rejected by fetchUrl and will not end up here. # So empty data indicates success without any update (e.g. 304). return profile unless data profile = OmegaPac.Profiles.byKey(key, @_options) profile.lastUpdate = new Date().toISOString() if OmegaPac.Profiles.update(profile, data) OmegaPac.Profiles.dropCache(profile) changes = {} changes[key] = profile @_setOptions(changes).return(profile) else return profile ).catch (reason) -> if reason instanceof Error then reason else new Error(reason) Promise.props(results) ###* # Make an HTTP GET request to fetch the content of the url. # In base class, this method is not implemented and will always reject. # @param {string} url The name of the profiles, # @param {?bool} opt_bypass_cache Do not read from the cache if true # @param {?string} opt_type_hints MIME type hints for downloaded content. # @returns {Promise} The text content fetched from the url ### fetchUrl: (url, opt_bypass_cache, opt_type_hints) -> Promise.reject new Error('not implemented') _replaceRefChanges: (fromName, toName, changes) -> changes ?= {} OmegaPac.Profiles.each @_options, (key, p) -> return if p.name == fromName or p.name == toName if OmegaPac.Profiles.replaceRef(p, fromName, toName) OmegaPac.Profiles.updateRevision(p) changes[OmegaPac.Profiles.nameAsKey(p)] = p if @_options['-startupProfileName'] == fromName changes['-startupProfileName'] = toName quickSwitch = @_options['-quickSwitchProfiles'] # Change fromName to toName in Quick Switch, but only if it does not contain # toName already. Otherwise it may cause duplicates. if quickSwitch.indexOf(toName) < 0 for i in [0...quickSwitch.length] if quickSwitch[i] == fromName quickSwitch[i] = toName changes['-quickSwitchProfiles'] = quickSwitch return changes ###* # Replace all references of profile fromName to toName. # @param {String} fromName The original profile name # @param {String} toname The target profile name # @returns {Promise} The updated options ### replaceRef: (fromName, toName) -> @log.method('Options#replaceRef', this, arguments) profile = OmegaPac.Profiles.byName(fromName, @_options) if not profile return Promise.reject new ProfileNotExistError(fromName) changes = @_replaceRefChanges(fromName, toName) for own key, value of changes @_options[key] = value fromKey = OmegaPac.Profiles.nameAsKey(fromName) if @_watchingProfiles[fromKey] if @_currentProfileName == fromName @_currentProfileName = toName @applyProfile(@_currentProfileName) @_setOptions(changes) ###* # Rename a profile and update references and options # @param {String} fromName The original profile name # @param {String} toname The target profile name # @returns {Promise} The updated options ### renameProfile: (fromName, toName) -> @log.method('Options#renameProfile', this, arguments) if OmegaPac.Profiles.byName(toName, @_options) return Promise.reject new Error("Target name #{name} already taken!") profile = OmegaPac.Profiles.byName(fromName, @_options) if not profile return Promise.reject new ProfileNotExistError(fromName) profile.name = toName changes = {} changes[OmegaPac.Profiles.nameAsKey(profile)] = profile @_replaceRefChanges(fromName, toName, changes) for own key, value of changes @_options[key] = value fromKey = OmegaPac.Profiles.nameAsKey(fromName) changes[fromKey] = undefined delete @_options[fromKey] if @_watchingProfiles[fromKey] if @_currentProfileName == fromName @_currentProfileName = toName @applyProfile(@_currentProfileName) @_setOptions(changes) ###* # Add a temp rule. # @param {String} domain The domain for the temp rule. # @param {String} profileName The profile to apply for the domain. # @returns {Promise} A promise which is fulfilled when the rule is applied. ### addTempRule: (domain, profileName) -> @log.method('Options#addTempRule', this, arguments) return Promise.resolve() if not @_currentProfileName profile = OmegaPac.Profiles.byName(profileName, @_options) if not profile return Promise.reject new ProfileNotExistError(profileName) if not @_tempProfile? @_tempProfile = OmegaPac.Profiles.create('', 'SwitchProfile') currentProfile = @currentProfile() @_tempProfile.color = currentProfile.color @_tempProfile.defaultProfileName = currentProfile.name changed = false rule = @_tempProfileRules[domain] if rule and rule.profileName if rule.profileName != profileName key = OmegaPac.Profiles.nameAsKey(rule.profileName) list = @_tempProfileRulesByProfile[key] list.splice(list.indexOf(rule), 1) rule.profileName = profileName changed = true else rule = condition: conditionType: 'HostWildcardCondition' pattern: '*.' + domain profileName: profileName isTempRule: true @_tempProfile.rules.push(rule) @_tempProfileRules[domain] = rule changed = true key = OmegaPac.Profiles.nameAsKey(profileName) rulesByProfile = @_tempProfileRulesByProfile[key] if not rulesByProfile? rulesByProfile = @_tempProfileRulesByProfile[key] = [] rulesByProfile.push(rule) if changed OmegaPac.Profiles.updateRevision(@_tempProfile) @applyProfile(@_currentProfileName) else Promise.resolve() ###* # Find a temp rule by domain. # @param {String} domain The domain of the temp rule. # @returns {Promise} The profile name for the domain, or null if such # rule does not exist. ### queryTempRule: (domain) -> rule = @_tempProfileRules[domain] if rule if rule.profileName return rule.profileName else delete @_tempProfileRules[domain] return null ###* # Add a condition to the current active switch profile. # @param {Object.} cond The condition to add # @param {string>} profileName The name of the result profile of the rule. # @returns {Promise} A promise which is fulfilled when the condition is saved. ### addCondition: (condition, profileName) -> @log.method('Options#addCondition', this, arguments) return Promise.resolve() if not @_currentProfileName profile = OmegaPac.Profiles.byName(@_currentProfileName, @_options) if not profile?.rules? return Promise.reject new Error( "Cannot add condition to Profile #{@profile.name} (#{profile.type})") target = OmegaPac.Profiles.byName(profileName, @_options) if not target? return Promise.reject new ProfileNotExistError(profileName) if not Array.isArray(condition) condition = [condition] for cond in condition # Try to remove rules with the same condition first. tag = OmegaPac.Conditions.tag(cond) for i in [0...profile.rules.length] if OmegaPac.Conditions.tag(profile.rules[i].condition) == tag profile.rules.splice(i, 1) break if @_options['-addConditionsToBottom'] profile.rules.push({ condition: cond profileName: profileName }) else profile.rules.unshift({ condition: cond profileName: profileName }) OmegaPac.Profiles.updateRevision(profile) changes = {} changes[OmegaPac.Profiles.nameAsKey(profile)] = profile @_setOptions(changes) ###* # Set the defaultProfileName of the profile. # @param {string>} profileName The name of the profile to modify. # @param {string>} defaultProfileName The defaultProfileName to set. # @returns {Promise} A promise which is fulfilled when the profile is saved. ### setDefaultProfile: (profileName, defaultProfileName) -> @log.method('Options#setDefaultProfile', this, arguments) profile = OmegaPac.Profiles.byName(profileName, @_options) if not profile? return Promise.reject new ProfileNotExistError(profileName) else if not profile.defaultProfileName? return Promise.reject new Error("Profile #{@profile.name} " + "(@{profile.type}) does not have defaultProfileName!") target = OmegaPac.Profiles.byName(defaultProfileName, @_options) if not target? return Promise.reject new ProfileNotExistError(defaultProfileName) profile.defaultProfileName = defaultProfileName OmegaPac.Profiles.updateRevision(profile) changes = {} changes[OmegaPac.Profiles.nameAsKey(profile)] = profile @_setOptions(changes) ###* # Add a profile to the options # @param {{}} profile The profile to create # @returns {Promise<{}>} The saved profile ### addProfile: (profile) -> @log.method('Options#addProfile', this, arguments) if OmegaPac.Profiles.byName(profile.name, @_options) return Promise.reject( new Error("Target name #{profile.name} already taken!")) else changes = {} changes[OmegaPac.Profiles.nameAsKey(profile)] = profile @_setOptions(changes) ###* # Get the matching results of a request # @param {{}} request The request to test # @returns {Promise<{profile: {}, results: {}[]}>} The last matched profile # and the matching details ### matchProfile: (request) -> if not @_currentProfileName return Promise.resolve({profile: @_externalProfile, results: []}) results = [] profile = if @_tempProfileActive @_tempProfile else OmegaPac.Profiles.byName(@_currentProfileName, @_options) while profile lastProfile = profile result = OmegaPac.Profiles.match(profile, request) break unless result? results.push(result) if Array.isArray(result) next = result[0] else if result.profileName next = OmegaPac.Profiles.nameAsKey(result.profileName) else break profile = OmegaPac.Profiles.byKey(next, @_options) Promise.resolve(profile: lastProfile, results: results) ###* # Notify Options that the proxy settings are set externally. # @param {{}} profile The external profile # @param {?{}} args Extra arguments # @param {boolean=false} args.noRevert If true, do not revert changes. # @param {boolean=false} args.internal If true, treat the profile change as # caused by the options itself instead of external reasons. # @returns {Promise} A promise which is fulfilled when the profile is set ### setExternalProfile: (profile, args) -> if @_options['-revertProxyChanges'] and not @_isSystem if profile.name != @_currentProfileName and @_currentProfileName if not args?.noRevert @applyProfile(@_revertToProfileName) @_revertToProfileName = null return else @_revertToProfileName ?= @_currentProfileName p = OmegaPac.Profiles.byName(profile.name, @_options) if p if args?.internal @applyProfile(p.name, {proxy: false}) else @applyProfile(p.name, {proxy: false, system: @_isSystem, reason: 'external'}) else @_currentProfileName = null @_externalProfile = profile profile.color ?= '#49afcd' @_state.set({ 'currentProfileName': '' 'externalProfile': profile 'validResultProfiles': [] 'currentProfileCanAddRule': false }) @currentProfileChanged('external') return ###* # Switch options syncing on and off. # @param {boolean} enabled Whether to enable syncing # @param {?{}} args Extra arguments # @param {boolean=false} args.force If true, overwrite options when conflict # @returns {Promise} A promise which is fulfilled when the syncing is switched ### setOptionsSync: (enabled, args) -> @log.method('Options#setOptionsSync', this, arguments) if not @sync? return Promise.reject(new Error('Options syncing is unsupported.')) @_state.get({'syncOptions': ''}).then ({syncOptions}) => if not enabled if syncOptions == 'sync' @_state.set({'syncOptions': 'conflict'}) @sync.enabled = false @_syncWatchStop?() @_syncWatchStop = null return if syncOptions == 'conflict' if not args?.force return Promise.reject(new Error( 'Syncing not enabled due to conflict. Retry with force to overwrite local options and enable syncing.')) return if syncOptions == 'sync' @_state.set({'syncOptions': 'sync'}).then => if syncOptions == 'conflict' # Try to re-init options from sync. @sync.enabled = false @_storage.remove().then => @sync.enabled = true @init() else @sync.enabled = true @_syncWatchStop?() @sync.requestPush(@_options) @_syncWatchStop = @sync.watchAndPull(@_storage) return ###* # Clear the sync storage, resetting syncing state to pristine. # @returns {Promise} A promise which is fulfilled when the syncing is reset. ### resetOptionsSync: -> @log.method('Options#resetOptionsSync', this, arguments) if not @sync? return Promise.reject(new Error('Options syncing is unsupported.')) @sync.enabled = false @_syncWatchStop?() @_syncWatchStop = null @_state.set({'syncOptions': 'conflict'}) return @sync.storage.remove().then => @_state.set({'syncOptions': 'pristine'}) module.exports = Options ================================================ FILE: omega-target/src/options_sync.coffee ================================================ ### @module omega-target/options_sync ### Promise = require 'bluebird' Storage = require './storage' Log = require './log' {Revision} = require 'omega-pac' jsondiffpatch = require 'jsondiffpatch' TokenBucket = require('limiter').TokenBucket class OptionsSync @TokenBucket: TokenBucket _timeout: null _bucket: null _waiting: false ###* # The debounce timeout (ms) for requestPush scheduling. See requestPush. # @type number ### debounce: 1000 ###* # The throttling timeout (ms) for watchAndPull. See watchAndPull. # @type number ### pullThrottle: 1000 ###* # The remote storage of syncing. # @type Storage ### storage: null constructor: (@storage, @_bucket) -> @_pending = {} @_bucket ?= new TokenBucket(10, 10, 'minute', null) @_bucket.clear ?= => @_bucket.tryRemoveTokens(@_bucket.content) ###* # Transform storage values for syncing. The default implementation applies no # transformation, but the behavior can be altered by assigning to this field. # Note: Transformation is applied before merging. # @param {{}} value The value to transform # @param {{}} key The key of the item # @returns {{}} The transformed value ### transformValue: (v) -> v ###* # Merge newVal and oldVal of a given key. The default implementation choose # between newVal and oldVal based on the following rules: # 1. Choose oldVal if syncOptions is 'disabled' in either oldVal or newVal. # 2. Choose oldVal if it has a revision newer than or equal to that of newVal. # 3. Choose oldVal if it deeply equals newVal. # 4. Otherwise, choose newVal. # # @param {string} key The key of the item # @param {} newVal The new value # @param {} oldVal The old value # @returns {} The merged result ### merge: do -> diff = jsondiffpatch.create( objectHash: (obj) -> JSON.stringify(obj) textDiff: minLength: 1 / 0 ) return (key, newVal, oldVal) -> return oldVal if newVal == oldVal if oldVal?.syncOptions == 'disabled' or newVal?.syncOptions == 'disabled' return oldVal if oldVal?.revision? and newVal?.revision? result = Revision.compare(oldVal.revision, newVal.revision) return oldVal if result >= 0 return oldVal unless diff.diff(oldVal, newVal)? return newVal ###* # Whether syncing is enabled or not. See requestPush for the effect. # @type boolean ### enabled: true ###* # Request pushing the changes to remote storage. The changes are cached first, # and then the actual write operations are scheduled if enabled is true. # The actual operation is delayed and debounced, combining continuous writes # in a short period into a single write operation. # @param {Object.} changes A map from keys to values. ### requestPush: (changes) -> clearTimeout(@_timeout) if @_timeout? for own key, value of changes if typeof value != 'undefined' value = @transformValue(value, key) continue if typeof value == 'undefined' @_pending[key] = value return unless @enabled @_timeout = setTimeout(@_doPush.bind(this), @debounce) ###* # Returning the pending changes not written to the remote storage. # @returns {Object.} The pending changes. ### pendingChanges: -> @_pending _doPush: -> @_timeout = null return if @_waiting @_waiting = true @_bucket.removeTokens 1, => @storage.get(null).then((base) => changes = @_pending @_pending = {} @_waiting = false Storage.operationsForChanges(changes, base: base, merge: @merge) ).then ({set, remove}) => doSet = if Object.keys(set).length == 0 Promise.resolve(0) else Log.log 'OptionsSync::set', set @storage.set(set).return(1) doSet.then((cost) => set = {} if remove.length > 0 if @_bucket.tryRemoveTokens(cost) Log.log 'OptionsSync::remove', remove return @storage.remove(remove) else return Promise.reject('bucket') ).catch (e) => # Re-submit the changes for syncing, but with lower priority. for own key, value of set if not (key of @_pending) @_pending[key] = value for key in remove if not (key of @_pending) @_pending[key] = undefined if e == 'bucket' @_doPush() else if e instanceof Storage.RateLimitExceededError Log.log 'OptionsSync::rateLimitExceeded' # Try to clear the @_bucket to wait more time before retrying. @_bucket.clear() @requestPush({}) return else if e instanceof Storage.QuotaExceededError # For now, we just disable syncing for all changed profiles. # TODO(catus): Remove the largest profile each time and retry. valuesAffected = 0 for own key, value of set if key[0] == '+' and value.syncOptions != 'disabled' value.syncOptions = 'disabled' value.syncError = {reason: 'quotaPerItem'} valuesAffected++ if valuesAffected > 0 @requestPush({}) else @_pending = {} return else Promise.reject(e) _logOperations: (text, operations) -> if Object.keys(operations.set).length Log.log(text + '::set', operations.set) if operations.remove.length Log.log(text + '::remove', operations.remove) ###* # Pull the remote storage for changes, and write them to local. # @param {Storage} local The local storage to be written to # @returns {function} Calling the returned function will stop watching. ### copyTo: (local) -> Promise.join local.get(null), @storage.get(null), (base, changes) => for own key of base when not (key of changes) if key[0] == '+' and not base[key]?.syncOptions == 'disabled' changes[key] = undefined local.apply( changes: changes base: base merge: @merge ).then (operations) => @_logOperations('OptionsSync::copyTo', operations) ###* # Watch the remote storage for changes, and write them to local. # The actual writing is throttled by pullThrottle with initial delay. # @param {Storage} local The local storage to be written to # @returns {function} Calling the returned function will stop watching. ### watchAndPull: (local) -> pullScheduled = null pull = {} doPull = => local.get(null).then((base) => changes = pull pull = {} pullScheduled = null Storage.operationsForChanges(changes, base: base, merge: @merge) ).then (operations) => @_logOperations('OptionsSync::pull', operations) local.apply(operations) @storage.watch null, (changes) => for own key, value of changes pull[key] = value return if pullScheduled? pullScheduled = setTimeout(doPull, @pullThrottle) module.exports = OptionsSync ================================================ FILE: omega-target/src/storage.coffee ================================================ ### @module omega-target/storage ### Promise = require 'bluebird' Log = require './log' class Storage ###* # Any operation that fails due to rate limiting should reject with an instance # of RateLimitExceededError, when implemented in derived classes of Storage. ### @RateLimitExceededError: class RateLimitExceededError extends Error constructor: -> super ###* # Any operation that fails due to storage quota should reject with an instance # of QuotaExceededError, when implemented in derived classes of Storage. ### @QuotaExceededError: class QuotaExceededError extends Error constructor: -> super ###* # If this storage is not available for some reason, all operations should # reject with an instance of StorageUnavailableError, when implemented in # derived classes of Storage. # This error is considered fatal and unrecoverable in the current environment. # Further access to this storage should be avoided until restart. ### @StorageUnavailableError: class StorageUnavailableError extends Error constructor: -> super ###* # A set of operations to be performed on a Storage. # @typedef WriteOperations # @type {object} # @property {Object.} set - A map from keys to new values of the # items to set # @property {{}[]} remove - An array of keys to remove ### ###* # Calculate the actual operations against storage that should be performed to # replay the changes on a storage. # @param {Object.} changes The changes to apply # @param {?{}} args Extra arguments # @param {Object.?} args.base The original items in the storage. # @param {function(key, newVal, oldVal)} args.merge A function that merges # the newVal and oldVal. oldVal is provided only if args.base is present. # Otherwise it will be equal to newVal (i.e. merge(key, newVal, newVal)). # @returns {WriteOperations} The operations that should be performed. ### @operationsForChanges: (changes, {base, merge} = {}) -> set = {} remove = [] for key, newVal of changes oldVal = if base? then base[key] else newVal if merge newVal = merge(key, newVal, oldVal) continue if base? and newVal == oldVal if typeof newVal == 'undefined' if typeof oldVal != 'undefined' or not base? remove.push(key) else set[key] = newVal return {set: set, remove: remove} ###* # Get the requested values by keys from the storage. # @param {(string|string[]|null|Object.)} keys The keys to retrive, # or null for all. # @returns {Promise<(Object.)>} A map from keys to values ### get: (keys) -> Log.method('Storage#get', this, arguments) return Promise.resolve({}) unless @_items if not keys? keys = @_items map = {} if typeof keys == 'string' map[keys] = @_items[keys] else if Array.isArray(keys) for key in keys map[key] = @_items[key] else if typeof keys == 'object' for key, value of keys map[key] = @_items[key] ? value Promise.resolve(map) ###* # Set multiple values by keys in the storage. # @param {(string|Object.)} items A map from key to value to set. # @returns {Promise<(Object.)>} A map of key-value pairs just set. ### set: (items) -> Log.method('Storage#set', this, arguments) @_items ?= {} for key, value of items @_items[key] = value Promise.resolve(items) ###* # Remove items by keys from the storage. # @param {(string|string[]|null)} keys The keys to remove, or null for all. # @returns {Promise} A promise that fulfills on successful removal. ### remove: (keys) -> Log.method('Storage#remove', this, arguments) if @_items? if not keys? @_items = {} else if Array.isArray(keys) for key in keys delete @_items[key] else delete @_items[keys] Promise.resolve() ###* # @callback watchCallback # @param {Object.} map A map of key-value pairs just changed. ### ###* # Watch for any changes to the storage. # @param {(string|string[]|null)} keys The keys to watch, or null for all. # @param {watchCallback} callback Called everytime something changes. # @returns {function} Calling the returned function will stop watching. ### watch: (keys, callback) -> Log.method('Storage#watch', this, arguments) return (-> null) ###* # Apply WriteOperations to the storage. # @param {WriteOperations|{changes: Object.}} operations The # operations to apply, or the changes to be applied. If changes is provided, # the operations are calculated by Storage.operationsForChanges, with extra # fields passed through as the second argument. # @returns {Promise} A promise that fulfills on operation success. ### apply: (operations) -> if 'changes' of operations operations = Storage.operationsForChanges(operations.changes, operations) @set(operations.set).then(=> @remove(operations.remove)).return(operations) module.exports = Storage ================================================ FILE: omega-target/src/utils.coffee ================================================ exports.Promise = require('bluebird') ================================================ FILE: omega-target/test/options_sync.coffee ================================================ chai = require 'chai' should = chai.should() sinon = require 'sinon' chai.use require('sinon-chai') describe 'OptionsSync', -> OptionsSync = require '../src/options_sync' Storage = require '../src/storage' Log = require '../src/log' Promise = require 'bluebird' before -> # Silence storage and sync logging. sinon.stub(Log, 'log') after -> Log.log.restore() # coffeelint: disable=missing_fat_arrows hookPostBasic = (func, hook) -> -> result = func.apply(this, arguments) hook.apply(this, arguments) return result # coffeelint: enable=missing_fat_arrows hookPost = (args...) -> if args.length == 2 [func, hook] = args hostPostBasic(func, hook) else [obj, method, hook] = args obj[method] = hookPostBasic(obj[method], hook) describe '#merge', -> sync = new OptionsSync() it 'should choose the one with newer revision', -> newVal = {revision: '2'} oldVal = {revision: '1'} sync.merge('example', newVal, oldVal).should.equal(newVal) it 'should use oldVal when sync is disabled in newVal', -> newVal = {revision: '2', is: 'newVal', syncOptions: 'disabled'} oldVal = {revision: '1', is: 'oldVal'} sync.merge('example', newVal, oldVal).should.equal(oldVal) it 'should use oldVal when sync is disabled in oldVal', -> newVal = {revision: '2', is: 'newVal'} oldVal = {revision: '1', is: 'oldVal', syncOptions: 'disabled'} sync.merge('example', newVal, oldVal).should.equal(oldVal) it 'should favor oldVal when revisions are equal', -> newVal = {revision: '1', is: 'newVal'} oldVal = {revision: '1', is: 'oldVal'} sync.merge('example', newVal, oldVal).should.equal(oldVal) it 'should favor oldVal when newVal deeply equals oldVal', -> newVal = {they: 'are', the: 'same'} oldVal = {they: 'are', the: 'same'} sync.merge('example', newVal, oldVal).should.equal(oldVal) it 'should choose newVal when newVal is different', -> newVal = {they: 'are', not: 'equal'} oldVal = {they: 'are', not: 'identical'} sync.merge('example', newVal, oldVal).should.equal(newVal) describe '#requestPush', -> unlimited = new OptionsSync.TokenBucket() it 'should store pendingChanges', -> sync = new OptionsSync() sync.enabled = false sync.requestPush({a: 1}) sync.pendingChanges().should.eql({a: 1}) it 'should schedule storage write', (done) -> check = -> return if storage.set.callCount == 0 or storage.remove.callCount == 0 storage.set.should.have.been.calledOnce.and.calledWith({b: 1}) storage.remove.should.have.been.calledOnce.and.calledWith(['a']) done() storage = new Storage() storage.set({a: 1}) hookPost storage, 'set', check hookPost storage, 'remove', check sinon.spy(storage, 'set') sinon.spy(storage, 'remove') sync = new OptionsSync(storage, unlimited) sync.debounce = 0 sync.requestPush({a: undefined, b: 1}) it 'should combine multiple write operations', (done) -> check = -> return if storage.set.callCount == 0 or storage.remove.callCount == 0 storage.set.should.have.been.calledOnce.and.calledWith({c: 1, d: 1}) storage.remove.should.have.been.calledOnce.and.calledWith(['a', 'b']) done() storage = new Storage() storage.set({a: 1, b: 1}) hookPost storage, 'set', check hookPost storage, 'remove', check sinon.spy(storage, 'set') sinon.spy(storage, 'remove') sync = new OptionsSync(storage, unlimited) sync.debounce = 0 sync.requestPush({a: undefined}) sync.requestPush({b: 2}) sync.requestPush({b: undefined}) sync.requestPush({c: 1}) sync.requestPush({d: 1}) sync.requestPush({e: 1}) sync.requestPush({e: undefined}) it 'should disable syncing for the profiles if quota is exceeded', (done) -> options = {'+a': {is: 'a', oversized: true}, b: {is: 'b'}} storage = new Storage() storage.set = (changes) -> for key, value of changes if value.oversized err = new Storage.QuotaExceededError() err.perItem = true return Promise.reject(err) storage.set.should.have.been.calledTwice storage.set.should.have.been.calledWith(options) storage.set.should.have.been.calledWith({b: {is: 'b'}}) options['+a'].syncOptions.should.equal('disabled') options['+a'].syncError.reason.should.equal('quotaPerItem') done() Promise.resolve() sinon.spy(storage, 'set') sync = new OptionsSync(storage, unlimited) sync.debounce = 0 sync.requestPush(options) describe '#copyTo', -> it 'should fetch all items from remote storage', (done) -> remote = new Storage() remote.set({a: 1, b: 2, c: 3}) storage = new Storage() hookPost storage, 'set', -> storage.set.should.have.been.calledOnce.and.calledWith( {a: 1, b: 2, c: 3} ) done() sinon.spy(storage, 'set') sync = new OptionsSync(remote) sync.copyTo(storage) it 'should merge with local as base', (done) -> check = -> return if storage.set.callCount == 0 or storage.remove.callCount == 0 storage.set.should.have.been.calledOnce.and.calledWith({b: 2, c: 3}) storage.remove.should.have.been.calledOnce.and.calledWith(['d']) done() remote = new Storage() remote.set({a: 1, b: 2, c: 3, d: undefined}) storage = new Storage() storage.set({a: 1, b: 0, d: 4}) hookPost storage, 'set', check hookPost storage, 'remove', check sinon.spy(storage, 'set') sinon.spy(storage, 'remove') sync = new OptionsSync(remote) sync.copyTo(storage) describe '#watchAndPull', -> it 'should pull changes into local when remote changes', (done) -> check = -> return if storage.set.callCount == 0 or storage.remove.callCount == 0 remote.watch.should.have.been.calledOnce storage.set.should.have.been.calledOnce.and.calledWith({b: 2, c: 3}) storage.remove.should.have.been.calledOnce.and.calledWith(['d']) done() remote = new Storage() hookPost remote, 'watch', (_, callback) -> setTimeout (-> callback({a: 1}) callback({b: 2}) callback({c: 3}) callback({d: undefined}) ), 10 sinon.spy(remote, 'watch') storage = new Storage() storage.set({a: 1, b: 0, d: 4}) hookPost storage, 'set', check hookPost storage, 'remove', check sinon.spy(storage, 'set') sinon.spy(storage, 'remove') sync = new OptionsSync(remote) sync.pullThrottle = 0 sync.watchAndPull(storage) ================================================ FILE: omega-target-chromium-extension/.gitignore ================================================ /index.js /omega_target_*.min.js /tmp /build /release.zip /web-ext-artifacts ================================================ FILE: omega-target-chromium-extension/Gruntfile.coffee ================================================ module.exports = (grunt) -> require('load-grunt-config')(grunt) require('./grunt-po2crx')(grunt) grunt.registerTask 'chromium-manifest', -> manifest = grunt.file.readJSON('overlay/manifest.json') manifest.permissions = manifest.permissions.filter (p) -> p != 'downloads' grunt.file.write('tmp/manifest.json', JSON.stringify(manifest)) ================================================ FILE: omega-target-chromium-extension/grunt/aliases.coffee ================================================ module.exports = default: [ 'coffeelint' 'browserify' 'coffee' 'copy' 'po2crx' ] test: ['mochaTest'] release: ['default', 'chromium-manifest', 'compress'] ================================================ FILE: omega-target-chromium-extension/grunt/browserify.coffee ================================================ path = require('path') module.exports = index: files: 'index.js': 'index.coffee' options: transform: ['coffeeify'] exclude: ['bluebird', 'omega-pac', 'omega-target'] browserifyOptions: extensions: '.coffee' builtins: [] standalone: 'index.coffee' debug: true browser: files: 'omega_target_chromium_extension.min.js': 'index.coffee' options: alias: [ './index.coffee:OmegaTargetChromium' ] transform: ['coffeeify'] plugin: if process.env.BUILD == 'release' [['minifyify', {map: false}]] else [] browserifyOptions: extensions: '.coffee' standalone: 'OmegaTargetChromium' omega_webext_proxy_script: files: 'build/js/omega_webext_proxy_script.min.js': 'src/js/omega_webext_proxy_script.js' options: alias: 'omega-pac': 'omega-pac/omega_pac.min.js' plugin: if process.env.BUILD == 'release' [['minifyify', {map: false}]] else [] browserifyOptions: noParse: [require.resolve('omega-pac/omega_pac.min.js')] ================================================ FILE: omega-target-chromium-extension/grunt/coffee.coffee ================================================ module.exports = coffee: expand: true cwd: 'src/coffee' src: ['**/*.coffee'] dest: 'build/js/' ext: '.js' ================================================ FILE: omega-target-chromium-extension/grunt/coffeelint.coffee ================================================ module.exports = options: arrow_spacing: level: 'error' colon_assignment_spacing: level: 'error' spacing: left: 0 right: 1 missing_fat_arrows: level: 'warn' no_empty_functions: level: 'error' no_empty_param_list: level: 'error' no_interpolation_in_single_quotes: level: 'error' no_stand_alone_at: level: 'error' space_operators: level: 'error' # https://github.com/clutchski/coffeelint/issues/525 indentation: level: 'ignore' gruntfile: ['Gruntfile.coffee'] tasks: ['grunt/**/*.coffee'] src: ['*.coffee', 'src/**/*.coffee', 'test/**/*.coffee'] ================================================ FILE: omega-target-chromium-extension/grunt/compress.coffee ================================================ module.exports = options: archive: './release.zip' mode: 'zip' build: files: [ { cwd: 'build' src: ['**', '!manifest.json'] expand: true filter: 'isFile' } { cwd: 'tmp/' src: 'manifest.json' expand: true } ] ================================================ FILE: omega-target-chromium-extension/grunt/copy.coffee ================================================ module.exports = web: expand: true cwd: '../omega-web/build' src: ['**/*'] dest: 'build/' target: files: 'build/js/omega_target.min.js': 'node_modules/omega-target/omega_target.min.js' target_self: src: 'omega_target_chromium_extension.min.js' dest: 'build/js/' target_popup: expand: true cwd: 'src/js' src: 'omega_target_popup.js' dest: 'build/js/' overlay: expand: true cwd: 'overlay' src: ['**/*'] dest: 'build/' docs: expand: true cwd: '..' src: ['COPYING', 'AUTHORS'] dest: 'build/' ================================================ FILE: omega-target-chromium-extension/grunt/mochaTest.coffee ================================================ module.exports = test: options: reporter: 'spec' require: 'coffee-script/register' src: ['test/**/*.coffee'] ================================================ FILE: omega-target-chromium-extension/grunt/po2crx.coffee ================================================ module.exports = locales: files: 'build/_locales/en/messages.json': '../omega-locales/en_US/LC_MESSAGES/omega-web.po' 'build/_locales/zh/messages.json': '../omega-locales/zh_CN/LC_MESSAGES/omega-web.po' 'build/_locales/cs/messages.json': '../omega-locales/cs/LC_MESSAGES/omega-web.po' 'build/_locales/fa/messages.json': '../omega-locales/fa/LC_MESSAGES/omega-web.po' 'build/_locales/zh_CN/messages.json': '../omega-locales/zh_CN/LC_MESSAGES/omega-web.po' 'build/_locales/zh_TW/messages.json': '../omega-locales/zh_TW/LC_MESSAGES/omega-web.po' ================================================ FILE: omega-target-chromium-extension/grunt/watch.coffee ================================================ module.exports = grunt: options: reload: true files: 'grunt/*' tasks: ['coffeelint:tasks', 'default'] po2crx_locales: files: ['../omega-locales/**/*'] tasks: ['po2crx:locales'] copy_web: files: ['node_modules/omega-web/build/**/*'] tasks: ['copy:web'] copy_target: files: ['node_modules/omega-target/omega_target.min.js'] tasks: ['copy:target'] copy_overlay: files: ['overlay/**/*'] tasks: ['copy:overlay'] copy_target_popup: files: ['src/js/omega_target_popup.js'] tasks: ['copy:target_popup'] coffee: files: ['src/**/*.coffee'] tasks: ['coffeelint:src', 'browserify', 'coffee', 'copy:target_self'] browserify_omega_webext_proxy_script: files: ['src/js/omega_webext_proxy_script.js'] tasks: ['browserify:omega_webext_proxy_script'] ================================================ FILE: omega-target-chromium-extension/grunt-po2crx.coffee ================================================ module.exports = (grunt) -> taskDesc = 'Convert gettext PO files to Chromium Extension messages format.' # coffeelint: disable=missing_fat_arrows grunt.registerMultiTask 'po2crx', taskDesc, -> for f in this.files result = {} for src in f.src json = require('po2json').parseFileSync(src) for own key, value of json when key message = value[1] refs = [] matchCount = 0 message = message.replace /\$(\d+:)?(\w+)\$/g, (_, order, ref) -> matchCount++ if order order = parseInt(order) else order = matchCount ### TODO(catus): Shall we enable this warning? if matchCount > 1 grunt.log.writeln("In this message: #{key}=#{message}") grunt.log.writeln( 'Order not specified for two or more refs in same message.') ### refs[order] = ref return '$' + ref + '$' if not matchCount placeholders = undefined else placeholders = {} for i in [0...refs.length] placeholder = refs[i] ? ('_unused_' + i) placeholders[placeholder] = {content: '$' + i} if message == ' ' message = '' result[key] = message: message placeholders: placeholders grunt.file.write(f.dest, JSON.stringify(result)) grunt.log.writeln("File \"#{f.dest}\" created.") # coffeelint: enable=missing_fat_arrows ================================================ FILE: omega-target-chromium-extension/index.coffee ================================================ module.exports = require('./src/module') ================================================ FILE: omega-target-chromium-extension/omega_target_shim.js ================================================ module.exports = OmegaTarget ================================================ FILE: omega-target-chromium-extension/overlay/background.html ================================================ SwitchyOmega Background ================================================ FILE: omega-target-chromium-extension/overlay/manifest.json ================================================ { "manifest_version": 2, "name": "__MSG_manifest_app_name__", "version": "2.5.21", "description": "__MSG_manifest_app_description__", "key": "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAkhwZJT76btQ04EEMOFtZPLESD1TmSVjbLjs0OyesD9Ht8YllFPfJ3qmtbSQGVuvmxH1GK/jUO2QcEWb8bHuOjoRlq20fi5j5Aq90O8FKET+y5D8PxCyi3WmnquiEwaE5cNmaCsw/G2JlO+bZOtdQ/QKOvMxBAegABYimEGfSvCMVUEvpymys0gBhLoch72zPAiJUBkf0z8BtjYTueMRcRXkrSeRPLygUDQnZ1TkQWMYYBp/zqpD5ggxytAklEMQzR9Hn0lqu5s7iuUAgihbysPn/8Wh00Zj5FySpK//KcpG3JS7UWxC28oSt8z5ZR3YimnX+HX3P36V0mC1pgM4o7wIDAQAB", "icons": { "16": "img/icons/omega-action-16.png", "24": "img/icons/omega-action-24.png", "32": "img/icons/omega-action-32.png", "48": "img/icons/omega-48.png", "64": "img/icons/omega-64.png", "128": "img/icons/omega-128.png" }, "default_locale": "en", "browser_action": { "browser_style": false, "default_icon": { "16": "img/icons/omega-action-16.png", "19": "img/icons/omega-action-19.png", "24": "img/icons/omega-action-24.png", "32": "img/icons/omega-action-32.png" }, "default_title": "__MSG_manifest_icon_default_title__", "default_popup": "popup/index.html" }, "background": { "page": "background.html" }, "minimum_chrome_version": "22.0.0", "options_page": "options.html", "options_ui": { "page": "options.html", "browser_style": false, "open_in_tab": true }, "permissions": [ "proxy", "tabs", "alarms", "storage", "webRequest", "downloads", "webRequestBlocking", "contextMenus", "http://*/*", "https://*/*", "" ], "commands": { "_execute_browser_action": { "suggested_key": { "default": "Alt+Shift+O" } } }, "applications": { "gecko": { "id": "switchyomega@feliscatus.addons.mozilla.org", "strict_min_version": "55.0a1" } } } ================================================ FILE: omega-target-chromium-extension/package.json ================================================ { "name": "omega-target-chromium-extension", "version": "0.0.1", "private": true, "main": "./index", "devDependencies": { "chai": "~1.9.1", "coffee-script": "^1.7.1", "coffeeify": "^0.7.0", "coffeelint": "^1.16.0", "grunt": "^0.4.5", "grunt-browserify": "^3.0.0", "grunt-coffeelint": "^0.0.13", "grunt-contrib-coffee": "^0.11.1", "grunt-contrib-compress": "^0.12.0", "grunt-contrib-copy": "^0.5.0", "grunt-contrib-watch": "^0.6.1", "grunt-mocha-test": "~0.11.0", "load-grunt-config": "^0.13.1", "minifyify": "^4.1.1", "po2json": "^0.3.2" }, "dependencies": { "heap": "^0.2.6", "omega-target": "../omega-target", "omega-web": "../omega-web", "omega-pac": "../omega-pac", "xhr": "^1.16.0" }, "browser": { "omega-target": "./omega_target_shim.js" }, "scripts": { "dev": "npm link omega-target && npm link omega-web && npm link omega-pac" } } ================================================ FILE: omega-target-chromium-extension/src/coffee/background.coffee ================================================ OmegaTargetCurrent = Object.create(OmegaTargetChromium) Promise = OmegaTargetCurrent.Promise Promise.longStackTraces() OmegaTargetCurrent.Log = Object.create(OmegaTargetCurrent.Log) Log = OmegaTargetCurrent.Log _writeLogToLocalStorage = (content) -> try localStorage['log'] += content catch _ # Maybe we have reached our limit here. See #1288. Try trimming it. localStorage['log'] = content Log.log = (args...) -> console.log(args...) content = args.map(Log.str.bind(Log)).join(' ') + '\n' _writeLogToLocalStorage(content) Log.error = (args...) -> console.error(args...) content = args.map(Log.str.bind(Log)).join(' ') localStorage['logLastError'] = content _writeLogToLocalStorage('ERROR: ' + content + '\n') unhandledPromises = [] unhandledPromisesId = [] unhandledPromisesNextId = 1 Promise.onPossiblyUnhandledRejection (reason, promise) -> Log.error("[#{unhandledPromisesNextId}] Unhandled rejection:\n", reason) unhandledPromises.push(promise) unhandledPromisesId.push(unhandledPromisesNextId) unhandledPromisesNextId++ Promise.onUnhandledRejectionHandled (promise) -> index = unhandledPromises.indexOf(promise) Log.log("[#{unhandledPromisesId[index]}] Rejection handled!", promise) unhandledPromises.splice(index, 1) unhandledPromisesId.splice(index, 1) iconCache = {} drawContext = null drawError = null drawIcon = (resultColor, profileColor) -> cacheKey = "omega+#{resultColor ? ''}+#{profileColor}" icon = iconCache[cacheKey] return icon if icon try if not drawContext? drawContext = document.getElementById('canvas-icon').getContext('2d') icon = {} for size in [16, 19, 24, 32, 38] drawContext.scale(size, size) drawContext.clearRect(0, 0, 1, 1) if resultColor? drawOmega drawContext, resultColor, profileColor else drawOmega drawContext, profileColor drawContext.setTransform(1, 0, 0, 1, 0, 0) icon[size] = drawContext.getImageData(0, 0, size, size) if icon[size].data[3] == 255 # Some browsers may replace the image data with a opaque white image to # resist fingerprinting. In that case the icon cannot be drawn. throw new Error('Icon drawing blocked by privacy.resistFingerprinting.') catch e if not drawError? drawError = e Log.error(e) Log.error('Profile-colored icon disabled. Falling back to static icon.') icon = null return iconCache[cacheKey] = icon charCodeUnderscore = '_'.charCodeAt(0) isHidden = (name) -> (name.charCodeAt(0) == charCodeUnderscore and name.charCodeAt(1) == charCodeUnderscore) dispName = (name) -> chrome.i18n.getMessage('profile_' + name) || name actionForUrl = (url) -> options.ready.then(-> request = OmegaPac.Conditions.requestFromUrl(url) options.matchProfile(request) ).then(({profile, results}) -> current = options.currentProfile() currentName = dispName(current.name) if current.profileType == 'VirtualProfile' realCurrentName = current.defaultProfileName currentName += " [#{dispName(realCurrentName)}]" current = options.profile(realCurrentName) details = '' direct = false attached = false condition2Str = (condition) -> condition.pattern || OmegaPac.Conditions.str(condition) for result in results if Array.isArray(result) if not result[1]? attached = false name = result[0] if name[0] == '+' name = name.substr(1) if isHidden(name) attached = true else if name != realCurrentName details += chrome.i18n.getMessage 'browserAction_defaultRuleDetails' details += " => #{dispName(name)}\n" else if result[1].length == 0 if result[0] == 'DIRECT' details += chrome.i18n.getMessage('browserAction_directResult') details += '\n' direct = true else details += "#{result[0]}\n" else if typeof result[1] == 'string' details += "#{result[1]} => #{result[0]}\n" else condition = condition2Str(result[1].condition ? result[1]) details += "#{condition} => " if result[0] == 'DIRECT' details += chrome.i18n.getMessage('browserAction_directResult') details += '\n' direct = true else details += "#{result[0]}\n" else if result.profileName if result.isTempRule details += chrome.i18n.getMessage('browserAction_tempRulePrefix') else if attached details += chrome.i18n.getMessage('browserAction_attachedPrefix') attached = false condition = result.source ? condition2Str(result.condition) details += "#{condition} => #{dispName(result.profileName)}\n" if not details details = options.printProfile(current) resultColor = profile.color profileColor = current.color icon = null if direct resultColor = options.profile('direct').color profileColor = profile.color else if profile.name == current.name and options.isCurrentProfileStatic() resultColor = profileColor = profile.color icon = drawIcon(profile.color) else resultColor = profile.color profileColor = current.color icon ?= drawIcon(resultColor, profileColor) shortTitle = 'Omega: ' + currentName # TODO: I18n. if profile.name != currentName shortTitle += ' => ' + profile.name # TODO: I18n. return { title: chrome.i18n.getMessage('browserAction_titleWithResult', [ currentName dispName(profile.name) details ]) shortTitle: shortTitle icon: icon resultColor: resultColor profileColor: profileColor } ).catch -> return null storage = new OmegaTargetCurrent.Storage('local') state = new OmegaTargetCurrent.BrowserStorage(localStorage, 'omega.local.') if chrome?.storage?.sync or browser?.storage?.sync syncStorage = new OmegaTargetCurrent.Storage('sync') sync = new OmegaTargetCurrent.OptionsSync(syncStorage) if localStorage['omega.local.syncOptions'] != '"sync"' sync.enabled = false sync.transformValue = OmegaTargetCurrent.Options.transformValueForSync proxyImpl = OmegaTargetCurrent.proxy.getProxyImpl(Log) state.set({proxyImplFeatures: proxyImpl.features}) options = new OmegaTargetCurrent.Options(null, storage, state, Log, sync, proxyImpl) options.externalApi = new OmegaTargetCurrent.ExternalApi(options) options.externalApi.listen() if chrome.runtime.id != OmegaTargetCurrent.SwitchySharp.extId options.switchySharp = new OmegaTargetCurrent.SwitchySharp() options.switchySharp.monitor() tabs = new OmegaTargetCurrent.ChromeTabs(actionForUrl) tabs.watch() options._inspect = new OmegaTargetCurrent.Inspect (url, tab) -> if url == tab.url options.clearBadge() tabs.processTab(tab) state.remove('inspectUrl') return state.set({inspectUrl: url}) actionForUrl(url).then (action) -> return if not action parsedUrl = OmegaTargetCurrent.Url.parse(url) if parsedUrl.hostname == OmegaTargetCurrent.Url.parse(tab.url).hostname urlDisp = parsedUrl.path else urlDisp = parsedUrl.hostname title = chrome.i18n.getMessage('browserAction_titleInspect', urlDisp) + '\n' title += action.title chrome.browserAction.setTitle(title: title, tabId: tab.id) tabs.setTabBadge(tab, { text: '#' color: action.resultColor }) options.setProxyNotControllable(null) timeout = null proxyImpl.watchProxyChange (details) -> return if options.externalApi.disabled return unless details notControllableBefore = options.proxyNotControllable() internal = false noRevert = false switch details['levelOfControl'] when "controlled_by_other_extensions", "not_controllable" reason = if details['levelOfControl'] == 'not_controllable' 'policy' else 'app' options.setProxyNotControllable(reason) noRevert = true else options.setProxyNotControllable(null) if details['levelOfControl'] == 'controlled_by_this_extension' internal = true return if not notControllableBefore Log.log('external proxy: ', details) # Chromium will send chrome.proxy.settings.onChange on extension unload, # just after the current extension has lost control of the proxy settings. # This is just annoying, and may change the currentProfileName state # suprisingly. # To workaround this issue, wait for some time before setting the proxy. # However this will cause some delay before the settings are processed. clearTimeout(timeout) if timeout? parsed = null timeout = setTimeout (-> if parsed options.setExternalProfile(parsed, {noRevert: noRevert, internal: internal}) ), 500 parsed = proxyImpl.parseExternalProfile(details, options._options) return external = false options.currentProfileChanged = (reason) -> iconCache = {} if reason == 'external' external = true else if reason != 'clearBadge' external = false current = options.currentProfile() currentName = '' if current currentName = dispName(current.name) if current.profileType == 'VirtualProfile' realCurrentName = current.defaultProfileName currentName += " [#{dispName(realCurrentName)}]" current = options.profile(realCurrentName) details = options.printProfile(current) if currentName title = chrome.i18n.getMessage('browserAction_titleWithResult', [ currentName, '', details]) shortTitle = 'Omega: ' + currentName # TODO: I18n. else title = details shortTitle = 'Omega: ' + details # TODO: I18n. if external and current.profileType != 'SystemProfile' message = chrome.i18n.getMessage('browserAction_titleExternalProxy') title = message + '\n' + title shortTitle = 'Omega-Extern: ' + details # TODO: I18n. options.setBadge() if not current.name or not OmegaPac.Profiles.isInclusive(current) icon = drawIcon(current.color) else icon = drawIcon(options.profile('direct').color, current.color) tabs.resetAll( icon: icon title: title shortTitle: shortTitle ) encodeError = (obj) -> if obj instanceof Error { _error: 'error' name: obj.name message: obj.message stack: obj.stack original: obj } else obj refreshActivePageIfEnabled = -> return if localStorage['omega.local.refreshOnProfileChange'] == 'false' chrome.tabs.query {active: true, lastFocusedWindow: true}, (tabs) -> url = tabs[0].url return if not url return if url.substr(0, 6) == 'chrome' return if url.substr(0, 6) == 'about:' return if url.substr(0, 4) == 'moz-' chrome.tabs.reload(tabs[0].id, {bypassCache: true}) chrome.runtime.onMessage.addListener (request, sender, respond) -> return unless request and request.method options.ready.then -> if request.method == 'getState' target = state method = state.get else target = options method = target[request.method] if typeof method != 'function' Log.error("No such method #{request.method}!") respond( error: reason: 'noSuchMethod' ) return promise = Promise.resolve().then -> method.apply(target, request.args) if request.refreshActivePage promise.then refreshActivePageIfEnabled return if request.noReply promise.then (result) -> if request.method == 'updateProfile' for own key, value of result result[key] = encodeError(value) respond(result: result) promise.catch (error) -> Log.error(request.method + ' ==>', error) respond(error: encodeError(error)) # Wait for my response! return true unless request.noReply ================================================ FILE: omega-target-chromium-extension/src/coffee/background_preload.coffee ================================================ window.UglifyJS_NoUnsafeEval = true localStorage['log'] = '' localStorage['logLastError'] = '' window.OmegaContextMenuQuickSwitchHandler = -> null if chrome.contextMenus? # We don't need this API. However its presence indicates that Chrome >= 35 # which provides info.checked we need in contextMenu callback. # https://developer.chrome.com/extensions/contextMenus if chrome.i18n.getUILanguage? # We must create the menu item here before others to make it first in menu. chrome.contextMenus.create({ id: 'enableQuickSwitch' title: chrome.i18n.getMessage('contextMenu_enableQuickSwitch') type: 'checkbox' checked: false contexts: ["browser_action"] onclick: (info) -> window.OmegaContextMenuQuickSwitchHandler(info) }) chrome.contextMenus.create({ title: chrome.i18n.getMessage('popup_reportIssues') contexts: ["browser_action"] onclick: OmegaDebug.reportIssue }) chrome.contextMenus.create({ title: chrome.i18n.getMessage('popup_errorLog') contexts: ["browser_action"] onclick: OmegaDebug.downloadLog }) ================================================ FILE: omega-target-chromium-extension/src/coffee/omega_debug.coffee ================================================ window.OmegaDebug = getProjectVersion: -> chrome.runtime.getManifest().version getExtensionVersion: -> chrome.runtime.getManifest().version downloadLog: -> blob = new Blob [localStorage['log']], {type: "text/plain;charset=utf-8"} filename = "OmegaLog_#{Date.now()}.txt" if browser?.downloads?.download? url = URL.createObjectURL(blob) browser.downloads.download({url: url, filename: filename}) else saveAs(blob, filename) resetOptions: -> localStorage.clear() # Prevent options loading from sync storage after reload. localStorage['omega.local.syncOptions'] = '"conflict"' chrome.storage.local.clear() chrome.runtime.reload() reportIssue: -> url = 'https://github.com/FelisCatus/SwitchyOmega/issues/new?title=&body=' finalUrl = url try projectVersion = OmegaDebug.getProjectVersion() extensionVersion = OmegaDebug.getExtensionVersion() env = extensionVersion: extensionVersion projectVersion: extensionVersion userAgent: navigator.userAgent body = chrome.i18n.getMessage('popup_issueTemplate', [ env.projectVersion, env.userAgent ]) body ||= """ \n\n SwitchyOmega #{env.projectVersion} #{env.userAgent} """ finalUrl = url + encodeURIComponent(body) err = localStorage['logLastError'] if err body += "\n```\n#{err}\n```" finalUrl = (url + encodeURIComponent(body)).substr(0, 2000) chrome.tabs.create(url: finalUrl) ================================================ FILE: omega-target-chromium-extension/src/coffee/omega_target_web.coffee ================================================ angular.module('omegaTarget', []).factory 'omegaTarget', ($q) -> decodeError = (obj) -> if obj._error == 'error' err = new Error(obj.message) err.name = obj.name err.stack = obj.stack err.original = obj.original err else obj callBackgroundNoReply = (method, args...) -> chrome.runtime.sendMessage({ method: method args: args noReply: true }) callBackground = (method, args...) -> d = $q['defer']() chrome.runtime.sendMessage({ method: method args: args }, (response) -> if chrome.runtime.lastError? d.reject(chrome.runtime.lastError) return if response.error d.reject(decodeError(response.error)) else d.resolve(response.result) ) return d.promise connectBackground = (name, message, callback) -> port = chrome.runtime.connect({name: name}) onDisconnect = -> port.onDisconnect.removeListener(onDisconnect) port.onMessage.removeListener(callback) port.onDisconnect.addListener(onDisconnect) port.postMessage(message) port.onMessage.addListener(callback) return isChromeUrl = (url) -> url.substr(0, 6) == 'chrome' or url.substr(0, 4) == 'moz-' or url.substr(0, 6) == 'about:' optionsChangeCallback = [] requestInfoCallback = null prefix = 'omega.local.' urlParser = document.createElement('a') omegaTarget = options: null state: (name, value) -> if arguments.length == 1 getValue = (key) -> try JSON.parse(localStorage[prefix + key]) if Array.isArray(name) return $q.when(name.map(getValue)) else value = getValue(name) else localStorage[prefix + name] = JSON.stringify(value) return $q.when(value) lastUrl: (url) -> name = 'web.last_url' if url omegaTarget.state(name, url) url else try JSON.parse(localStorage[prefix + name]) addOptionsChangeCallback: (callback) -> optionsChangeCallback.push(callback) refresh: (args) -> return callBackground('getAll').then (opt) -> omegaTarget.options = opt for callback in optionsChangeCallback callback(omegaTarget.options) return args renameProfile: (fromName, toName) -> callBackground('renameProfile', fromName, toName).then omegaTarget.refresh replaceRef: (fromName, toName) -> callBackground('replaceRef', fromName, toName).then omegaTarget.refresh optionsPatch: (patch) -> callBackground('patch', patch).then omegaTarget.refresh resetOptions: (opt) -> callBackground('reset', opt).then omegaTarget.refresh updateProfile: (name, opt_bypass_cache) -> callBackground('updateProfile', name, opt_bypass_cache).then((results) -> for own key, value of results results[key] = decodeError(value) results ).then omegaTarget.refresh getMessage: chrome.i18n.getMessage.bind(chrome.i18n) openOptions: (hash) -> d = $q['defer']() options_url = chrome.extension.getURL('options.html') chrome.tabs.query url: options_url, (tabs) -> url = if hash urlParser.href = tabs[0]?.url || options_url urlParser.hash = hash urlParser.href else options_url if tabs.length > 0 props = {active: true} if hash props.url = url chrome.tabs.update(tabs[0].id, props) else chrome.tabs.create({url: url}) d.resolve() return d.promise applyProfile: (name) -> callBackground('applyProfile', name) applyProfileNoReply: (name) -> callBackgroundNoReply('applyProfile', name) addTempRule: (domain, profileName) -> callBackground('addTempRule', domain, profileName) addCondition: (condition, profileName) -> callBackground('addCondition', condition, profileName) addProfile: (profile) -> callBackground('addProfile', profile).then omegaTarget.refresh setDefaultProfile: (profileName, defaultProfileName) -> callBackground('setDefaultProfile', profileName, defaultProfileName) getActivePageInfo: -> clearBadge = true d = $q['defer']() chrome.tabs.query {active: true, lastFocusedWindow: true}, (tabs) -> if not tabs[0]?.url d.resolve(null) return args = {tabId: tabs[0].id, url: tabs[0].url} if tabs[0].id and requestInfoCallback connectBackground('tabRequestInfo', args, requestInfoCallback) d.resolve(callBackground('getPageInfo', args)) return d.promise.then (info) -> if info?.url then info else null refreshActivePage: -> d = $q['defer']() chrome.tabs.query {active: true, lastFocusedWindow: true}, (tabs) -> if tabs[0].url and not isChromeUrl(tabs[0].url) chrome.tabs.reload(tabs[0].id, {bypassCache: true}) d.resolve() return d.promise openManage: -> chrome.tabs.create url: 'chrome://extensions/?id=' + chrome.runtime.id openShortcutConfig: -> chrome.tabs.create url: 'chrome://extensions/configureCommands' setOptionsSync: (enabled, args) -> callBackground('setOptionsSync', enabled, args) resetOptionsSync: (enabled, args) -> callBackground('resetOptionsSync') setRequestInfoCallback: (callback) -> requestInfoCallback = callback return omegaTarget ================================================ FILE: omega-target-chromium-extension/src/js/omega_target_popup.js ================================================ function callBackgroundNoReply(method, args, cb) { chrome.runtime.sendMessage({ method: method, args: args, noReply: true, refreshActivePage: true, }); if (cb) return cb(); } function callBackground(method, args, cb) { chrome.runtime.sendMessage({ method: method, args: args, }, function(response) { if (chrome.runtime.lastError != null) return cb && cb(chrome.runtime.lastError) if (response.error) return cb && cb(response.error) return cb && cb(null, response.result) }); } var requestInfoCallback = null; OmegaTargetPopup = { getState: function (keys, cb) { if (typeof localStorage === 'undefined' || !localStorage.length) { callBackground('getState', [keys], cb); return; } var results = {}; keys.forEach(function(key) { try { results[key] = JSON.parse(localStorage['omega.local.' + key]); } catch (_) { return null; } }); if (cb) cb(null, results); }, applyProfile: function (name, cb) { callBackgroundNoReply('applyProfile', [name], cb); }, openOptions: function (hash, cb) { var options_url = chrome.extension.getURL('options.html'); chrome.tabs.query({ url: options_url }, function(tabs) { if (!chrome.runtime.lastError && tabs && tabs.length > 0) { var props = { active: true }; if (hash) { var url = options_url + hash; props.url = url; } chrome.tabs.update(tabs[0].id, props); } else { chrome.tabs.create({ url: options_url }); } if (cb) return cb(); }); }, getActivePageInfo: function(cb) { chrome.tabs.query({active: true, lastFocusedWindow: true}, function (tabs) { if (tabs.length === 0 || !tabs[0].url) return cb(); var args = {tabId: tabs[0].id, url: tabs[0].url}; callBackground('getPageInfo', [args], cb) }); }, setDefaultProfile: function(profileName, defaultProfileName, cb) { callBackgroundNoReply('setDefaultProfile', [profileName, defaultProfileName], cb); }, addTempRule: function(domain, profileName, cb) { callBackgroundNoReply('addTempRule', [domain, profileName], cb); }, openManage: function(domain, profileName, cb) { chrome.tabs.create({ url: 'chrome://extensions/?id=' + chrome.runtime.id, }, cb); }, getMessage: chrome.i18n.getMessage.bind(chrome.i18n), }; ================================================ FILE: omega-target-chromium-extension/src/js/omega_webext_proxy_script.js ================================================ FindProxyForURL = (function () { var OmegaPac = require('omega-pac'); var options = {}; var state = {}; var activeProfile = null; var fallbackResult = 'DIRECT'; var pacCache = {}; init(); return FindProxyForURL; function FindProxyForURL(url, host, details) { if (!activeProfile) { warn('Warning: Proxy script not initialized on handling: ' + url); return fallbackResult; } // Moz: Neither path or query is included url regardless of scheme for now. // This is even more strict than Chromium restricting HTTPS URLs. // Therefore, it leads to different behavior than the icon and badge. // https://bugzilla.mozilla.org/show_bug.cgi?id=1337001 var request = OmegaPac.Conditions.requestFromUrl(url); var profile = activeProfile; var matchResult, next; while (profile) { matchResult = OmegaPac.Profiles.match(profile, request) if (!matchResult) { if (profile.profileType === 'DirectProfile') { return 'DIRECT'; } else { warn('Warning: Unsupported profile: ' + profile.profileType); return fallbackResult; } } if (Array.isArray(matchResult)) { next = matchResult[0]; var proxy = matchResult[2]; var auth = matchResult[3]; if (proxy && !state.useLegacyStringReturn) { var proxyInfo = { type: proxy.scheme, host: proxy.host, port: proxy.port, }; if (proxyInfo.type === 'socks5') { // MOZ: SOCKS5 proxies are identified by "type": "socks". // https://dxr.mozilla.org/mozilla-central/rev/ffe6cc09ccf38cca6f0e727837bbc6cb722d1e71/toolkit/components/extensions/ProxyScriptContext.jsm#51 proxyInfo.type = 'socks'; // Enable SOCKS5 remote DNS. // TODO(catus): Maybe allow the users to configure this? proxyInfo.proxyDNS = true; } if (auth) { proxyInfo.username = auth.username; proxyInfo.password = auth.password; } return [proxyInfo]; } else if (next.charCodeAt(0) !== 43) { // MOZ: Legacy proxy support expects PAC-like string return type. // TODO(catus): Remove support for string return type. // MOZ: SOCKS5 proxies are supported under the prefix SOCKS. // https://dxr.mozilla.org/mozilla-central/rev/ffe6cc09ccf38cca6f0e727837bbc6cb722d1e71/toolkit/components/extensions/ProxyScriptContext.jsm#51 // Note: We have to replace this because MOZ won't process the rest of // the list if the syntax of the first item is not recognized. return next.replace(/SOCKS5 /g, 'SOCKS '); } } else if (matchResult.profileName) { next = OmegaPac.Profiles.nameAsKey(matchResult.profileName) } else { return fallbackResult; } profile = OmegaPac.Profiles.byKey(next, options) } warn('Warning: Cannot find profile: ' + next); return fallbackResult; } function warn(message, error) { // We don't have console here and alert is not implemented. // Throwing and messaging seems to be the only ways to communicate. // MOZ: alert(): https://bugzilla.mozilla.org/show_bug.cgi?id=1353510 browser.runtime.sendMessage({ event: 'proxyScriptLog', message: message, error: error, level: 'warn', }); } function init() { browser.runtime.onMessage.addListener(function(message) { if (message.event === 'proxyScriptStateChanged') { state = message.state; options = message.options; if (!state.currentProfileName) { activeProfile = state.tempProfile; } else { activeProfile = OmegaPac.Profiles.byName(state.currentProfileName, options); } } }); browser.runtime.sendMessage({event: 'proxyScriptLoaded'}); } })(); ================================================ FILE: omega-target-chromium-extension/src/module/chrome_api.coffee ================================================ OmegaTarget = require('omega-target') Promise = OmegaTarget.Promise exports.chromeApiPromisify = (target, method) -> return (args...) -> new Promise (resolve, reject) -> callback = (callbackArgs...) -> if chrome.runtime.lastError? error = new Error(chrome.runtime.lastError.message) error.original = chrome.runtime.lastError return reject(error) if callbackArgs.length <= 1 resolve(callbackArgs[0]) else resolve(callbackArgs) args.push(callback) target[method].apply(target, args) ================================================ FILE: omega-target-chromium-extension/src/module/chrome_port.coffee ================================================ # A wrapper around type Port in Chromium Extension API. # https://developer.chrome.com/extensions/runtime#type-Port # # Please wrap any Port object in this class BEFORE adding listeners. Adding # listeners to events of raw Port objects should be avoided to minimize the risk # of memory leaks. See the comments of the TrackedEvent class for more details. module.exports = class ChromePort constructor: (@port) -> @name = @port.name @sender = @port.sender @disconnect = @port.disconnect.bind(@port) @postMessage = (args...) => try @port.postMessage(args...) catch _ return @onMessage = new TrackedEvent(@port.onMessage) @onDisconnect = new TrackedEvent(@port.onDisconnect) @onDisconnect.addListener @dispose.bind(this) dispose: -> @onMessage.dispose() @onDisconnect.dispose() # A wrapper around chrome.Event. # https://developer.chrome.com/extensions/events#type-Event # # ALL event listeners MUST be manually removed before disposing any Event or # object containing Event, such as Port. Otherwise, a memory leak will happen. # https://code.google.com/p/chromium/issues/detail?id=320723 # # TrackedEvent helps to solve this problem by keeping track of all listeners # installed and removes them when the #dispose method is called. # Don't forget to call #dispose when this TrackedEvent is not needed any more. class TrackedEvent constructor: (@event) -> @callbacks = [] mes = ['hasListener', 'hasListeners', 'addRules', 'getRules', 'removeRules'] for methodName in mes method = @event[methodName] if method? this[methodName] = method.bind(@event) addListener: (callback) -> @event.addListener(callback) @callbacks.push(callback) return this removeListener: (callback) -> @event.removeListener(callback) i = @callbacks.indexOf(callback) @callbacks.splice(i, 1) if i >= 0 return this ###* # Removes all listeners added via this TrackedEvent instance. # Note: Won't remove listeners added via other TrackedEvent or raw Event. ### removeAllListeners: -> for callback in @callbacks @event.removeListener(callback) @callbacks = [] return this ###* # Removes all listeners added via this TrackedEvent instance and prevent any # further listeners from being added. It is considered safe to nullify any # references to this instance and the underlying Event without causing leaks. # This should be the last method called in the lifetime of TrackedEvent. # # Throws if the underlying raw Event object still has listeners. This can # happen when listeners have been added via other TrackedEvents or raw Event. ### dispose: -> @removeAllListeners() if @event.hasListeners?() throw new Error("Underlying Event still has listeners!") @event = null @callbacks = null ================================================ FILE: omega-target-chromium-extension/src/module/external_api.coffee ================================================ OmegaTarget = require('omega-target') OmegaPac = OmegaTarget.OmegaPac Promise = OmegaTarget.Promise ChromePort = require('./chrome_port') module.exports = class ExternalApi constructor: (options) -> @options = options knownExts: 'padekgcemlokbadohgkifijomclgjgif': 32 disabled: false listen: -> return unless chrome.runtime.onConnectExternal chrome.runtime.onConnectExternal.addListener (rawPort) => port = new ChromePort(rawPort) port.onMessage.addListener (msg) => @onMessage(msg, port) port.onDisconnect.addListener @reenable.bind(this) _previousProfileName: null reenable: -> return unless @disabled @options.setProxyNotControllable(null) chrome.browserAction.setPopup?({popup: 'popup/index.html'}) @options.reloadQuickSwitch() @disabled = false @options.clearBadge() @options.applyProfile(@_previousProfileName) checkPerm: (port, level) -> perm = @knownExts[port.sender.id] || 0 if perm < level port.postMessage({action: 'error', error: 'permission'}) false else true onMessage: (msg, port) -> @options.log.log("#{port.sender.id} -> #{msg.action}", msg) switch msg.action when 'disable' return unless @checkPerm(port, 16) return if @disabled @disabled = true @_previousProfileName = @options.currentProfile()?.name || 'system' @options.applyProfile('system').then => reason = 'disabled' if @knownExts[port.sender.id] >= 32 reason = 'upgrade' @options.setProxyNotControllable reason, {text: 'X', color: '#5ab432'} chrome.browserAction.setPopup?({popup: 'popup/index.html'}) port.postMessage({action: 'state', state: 'disabled'}) when 'enable' @reenable() port.postMessage({action: 'state', state: 'enabled'}) when 'getOptions' return unless @checkPerm(port, 8) port.postMessage({action: 'options', options: @options.getAll()}) else port.postMessage( action: 'error' error: 'noSuchAction' action_name: msg.action ) ================================================ FILE: omega-target-chromium-extension/src/module/fetch_url.coffee ================================================ Promise = OmegaTarget.Promise xhr = Promise.promisify(require('xhr')) Url = require('url') ContentTypeRejectedError = OmegaTarget.ContentTypeRejectedError xhrWrapper = (args...) -> xhr(args...).catch (err) -> throw err unless err.isOperational if not err.statusCode throw new OmegaTarget.NetworkError(err) if err.statusCode == 404 throw new OmegaTarget.HttpNotFoundError(err) if err.statusCode >= 500 and err.statusCode < 600 throw new OmegaTarget.HttpServerError(err) throw new OmegaTarget.HttpError(err) fetchUrl = (dest_url, opt_bypass_cache, opt_type_hints) -> getResBody = ([response, body]) -> return body unless opt_type_hints contentType = response.headers['content-type']?.toLowerCase() for hint in opt_type_hints handler = hintHandlers[hint] ? defaultHintHandler result = handler(response, body, {contentType, hint}) return result if result? throw new ContentTypeRejectedError( 'Unrecognized Content-Type: ' + contentType) return body if opt_bypass_cache and dest_url.indexOf('?') < 0 parsed = Url.parse(dest_url, true) parsed.search = undefined parsed.query['_'] = Date.now() dest_url_nocache = Url.format(parsed) # Try first with the dumb parameter to bypass cache. xhrWrapper(dest_url_nocache).then(getResBody).catch -> # If failed, try again with the original URL. xhrWrapper(dest_url).then(getResBody) else xhrWrapper(dest_url).then(getResBody) defaultHintHandler = (response, body, {contentType, hint}) -> if '!' + contentType == hint throw new ContentTypeRejectedError( 'Response Content-Type blacklisted: ' + contentType) if contentType == hint return body hintHandlers = '*': (response, body) -> # Allow all contents. return body '!text/html': (response, body, {contentType, hint}) -> if contentType == hint # Sometimes other content can also be served with the text/html # Content-Type header. So we check if the body actually looks like HTML. looksLikeHtml = false if body.indexOf('= 0 || body.indexOf('= 0 looksLikeHtml = true else if body.indexOf('') >= 0 looksLikeHtml = true else if body.indexOf('') >= 0 looksLikeHtml = true if looksLikeHtml throw new ContentTypeRejectedError('Response must not be HTML.') '!application/xhtml+xml': (args...) -> hintHandlers['!text/html'](args...) 'application/x-ns-proxy-autoconfig': (response, body, {contentType, hint}) -> if contentType == hint return body # Sometimes PAC scripts can also be served using with wrong Content-Type. if body.indexOf('FindProxyForURL') >= 0 return body else # The content is not a PAC script if it does not contain FindProxyForURL. return undefined module.exports = fetchUrl ================================================ FILE: omega-target-chromium-extension/src/module/index.coffee ================================================ module.exports = Storage: require('./storage') Options: require('./options') ChromeTabs: require('./tabs') SwitchySharp: require('./switchysharp') ExternalApi: require('./external_api') WebRequestMonitor: require('./web_request_monitor') Inspect: require('./inspect') Url: require('url') proxy: require('./proxy') for name, value of require('omega-target') module.exports[name] ?= value ================================================ FILE: omega-target-chromium-extension/src/module/inspect.coffee ================================================ OmegaTarget = require('omega-target') OmegaPac = OmegaTarget.OmegaPac Promise = OmegaTarget.Promise module.exports = class Inspect _enabled: false constructor: (onInspect) -> @onInspect = onInspect enable: -> return unless chrome.contextMenus? # We don't need this API. However its presence indicates that Chrome >= 35, # which provides the menuItemId we need in contextMenu callback. # https://developer.chrome.com/extensions/contextMenus return unless chrome.i18n.getUILanguage? return if @_enabled webResource = [ "http://*/*" "https://*/*" "ftp://*/*" ] ### Not so useful... chrome.contextMenus.create({ id: 'inspectPage' title: chrome.i18n.getMessage('contextMenu_inspectPage') contexts: ['page'] onclick: @inspect.bind(this) documentUrlPatterns: webResource }) ### chrome.contextMenus.create({ id: 'inspectFrame' title: chrome.i18n.getMessage('contextMenu_inspectFrame') contexts: ['frame'] onclick: @inspect.bind(this) documentUrlPatterns: webResource }) chrome.contextMenus.create({ id: 'inspectLink' title: chrome.i18n.getMessage('contextMenu_inspectLink') contexts: ['link'] onclick: @inspect.bind(this) targetUrlPatterns: webResource }) chrome.contextMenus.create({ id: 'inspectElement' title: chrome.i18n.getMessage('contextMenu_inspectElement') contexts: [ 'image' 'video' 'audio' ] onclick: @inspect.bind(this) targetUrlPatterns: webResource }) @_enabled = true disable: -> return unless @_enabled for own menuId of @propForMenuItem try chrome.contextMenus.remove(menuId) @_enabled = false propForMenuItem: 'inspectPage': 'pageUrl' 'inspectFrame': 'frameUrl' 'inspectLink': 'linkUrl' 'inspectElement': 'srcUrl' inspect: (info, tab) -> return unless info.menuItemId url = info[@propForMenuItem[info.menuItemId]] if not url and info.menuItemId == 'inspectPage' url = tab.url return unless url @onInspect(url, tab) ================================================ FILE: omega-target-chromium-extension/src/module/options.coffee ================================================ OmegaTarget = require('omega-target') OmegaPac = OmegaTarget.OmegaPac Promise = OmegaTarget.Promise querystring = require('querystring') WebRequestMonitor = require('./web_request_monitor') ChromePort = require('./chrome_port') fetchUrl = require('./fetch_url') Url = require('url') class ChromeOptions extends OmegaTarget.Options _inspect: null fetchUrl: fetchUrl updateProfile: (args...) -> super(args...).then (results) -> error = false for own profileName, result of results if result instanceof Error error = true break if error # TODO(catus): Find a better way to notify the user. ### @setBadge( text: '!' color: '#faa732' title: chrome.i18n.getMessage('browserAction_titleDownloadFail') ) ### return results _proxyNotControllable: null proxyNotControllable: -> @_proxyNotControllable setProxyNotControllable: (reason, badge) -> @_proxyNotControllable = reason if reason @_state.set({'proxyNotControllable': reason}) @setBadge(badge) else @_state.remove(['proxyNotControllable']) @clearBadge() _badgeTitle: null setBadge: (options) -> if not options options = if @_proxyNotControllable text: '=' color: '#da4f49' else text: '?' color: '#49afcd' chrome.browserAction.setBadgeText(text: options.text) chrome.browserAction.setBadgeBackgroundColor(color: options.color) if options.title @_badgeTitle = options.title chrome.browserAction.setTitle(title: options.title) else @_badgeTitle = null clearBadge: -> return if @externalApi.disabled if @_badgeTitle @currentProfileChanged('clearBadge') if @_proxyNotControllable @setBadge() else chrome.browserAction.setBadgeText?(text: '') return _quickSwitchInit: false _quickSwitchHandlerReady: false _quickSwitchCanEnable: false setQuickSwitch: (quickSwitch, canEnable) -> @_quickSwitchCanEnable = canEnable if not @_quickSwitchHandlerReady @_quickSwitchHandlerReady = true window.OmegaContextMenuQuickSwitchHandler = (info) => changes = {} changes['-enableQuickSwitch'] = info.checked setOptions = @_setOptions(changes) if info.checked and not @_quickSwitchCanEnable setOptions.then -> chrome.tabs.create( url: chrome.extension.getURL('options.html#/ui') ) if quickSwitch or not chrome.browserAction.setPopup? chrome.browserAction.setPopup?({popup: ''}) if not @_quickSwitchInit @_quickSwitchInit = true chrome.browserAction.onClicked.addListener (tab) => @clearBadge() if not @_options['-enableQuickSwitch'] # If we reach here, then the browser does not support popup. # Let's open the popup page in a tab. chrome.tabs.create(url: 'popup/index.html') return profiles = @_options['-quickSwitchProfiles'] index = profiles.indexOf(@_currentProfileName) index = (index + 1) % profiles.length @applyProfile(profiles[index]).then => if @_options['-refreshOnProfileChange'] url = tab.url return if not url return if url.substr(0, 6) == 'chrome' return if url.substr(0, 6) == 'about:' return if url.substr(0, 4) == 'moz-' chrome.tabs.reload(tab.id) else chrome.browserAction.setPopup({popup: 'popup/index.html'}) chrome.contextMenus?.update('enableQuickSwitch', {checked: !!quickSwitch}) Promise.resolve() setInspect: (settings) -> if @_inspect if settings.showMenu @_inspect.enable() else @_inspect.disable() return Promise.resolve() _requestMonitor: null _monitorWebRequests: false _tabRequestInfoPorts: null setMonitorWebRequests: (enabled) -> @_monitorWebRequests = enabled if enabled and not @_requestMonitor? @_tabRequestInfoPorts = {} wildcardForReq = (req) -> OmegaPac.wildcardForUrl(req.url) @_requestMonitor = new WebRequestMonitor(wildcardForReq) @_requestMonitor.watchTabs (tabId, info) => return unless @_monitorWebRequests if info.errorCount > 0 info.badgeSet = true badge = {text: info.errorCount.toString(), color: '#f0ad4e'} chrome.browserAction.setBadgeText(text: badge.text, tabId: tabId) chrome.browserAction.setBadgeBackgroundColor( color: badge.color tabId: tabId ) else if info.badgeSet info.badgeSet = false chrome.browserAction.setBadgeText(text: '', tabId: tabId) @_tabRequestInfoPorts[tabId]?.postMessage({ errorCount: info.errorCount summary: info.summary }) chrome.runtime.onConnect.addListener (rawPort) => return unless rawPort.name == 'tabRequestInfo' return unless @_monitorWebRequests tabId = null port = new ChromePort(rawPort) port.onMessage.addListener (msg) => tabId = msg.tabId @_tabRequestInfoPorts[tabId] = port info = @_requestMonitor.tabInfo[tabId] if info port.postMessage({ errorCount: info.errorCount summary: info.summary }) port.onDisconnect.addListener => delete @_tabRequestInfoPorts[tabId] if tabId? _alarms: null schedule: (name, periodInMinutes, callback) -> name = 'omega.' + name if not _alarms? @_alarms = {} chrome.alarms.onAlarm.addListener (alarm) => @_alarms[alarm.name]?() if periodInMinutes < 0 delete @_alarms[name] chrome.alarms.clear(name) else @_alarms[name] = callback chrome.alarms.create(name, { periodInMinutes: periodInMinutes }) Promise.resolve() printFixedProfile: (profile) -> return unless profile.profileType == 'FixedProfile' result = '' for scheme in OmegaPac.Profiles.schemes when profile[scheme.prop] pacResult = OmegaPac.Profiles.pacResult(profile[scheme.prop]) if scheme.scheme result += "#{scheme.scheme}: #{pacResult}\n" else result += "#{pacResult}\n" result ||= chrome.i18n.getMessage( 'browserAction_profileDetails_DirectProfile') return result printProfile: (profile) -> type = profile.profileType if type.indexOf('RuleListProfile') >= 0 type = 'RuleListProfile' if type == 'FixedProfile' @printFixedProfile(profile) else if type == 'PacProfile' and profile.pacUrl profile.pacUrl else chrome.i18n.getMessage('browserAction_profileDetails_' + type) || null upgrade: (options, changes) -> super(options).catch (err) => return Promise.reject err if options?['schemaVersion'] getOldOptions = if @switchySharp @switchySharp.getOptions().timeout(1000) else Promise.reject() getOldOptions = getOldOptions.catch -> if options?['config'] Promise.resolve options else if localStorage['config'] Promise.resolve localStorage else Promise.reject new OmegaTarget.Options.NoOptionsError() getOldOptions.then (oldOptions) => i18n = { upgrade_profile_auto: chrome.i18n.getMessage('upgrade_profile_auto') } try # Upgrade from SwitchySharp. upgraded = require('./upgrade')(oldOptions, i18n) catch ex @log.error(ex) return Promise.reject ex if localStorage['config'] Object.getPrototypeOf(localStorage).clear.call(localStorage) @_state.set({'firstRun': 'upgrade'}) return this && super(upgraded, upgraded) onFirstRun: (reason) -> chrome.tabs.create url: chrome.extension.getURL('options.html') getPageInfo: ({tabId, url}) -> errorCount = @_requestMonitor?.tabInfo[tabId]?.errorCount result = if errorCount then {errorCount: errorCount} else null getBadge = new Promise (resolve, reject) -> if not chrome.browserAction.getBadgeText? resolve('') return chrome.browserAction.getBadgeText {tabId: tabId}, (result) -> resolve(result) getInspectUrl = @_state.get({inspectUrl: ''}) Promise.join getBadge, getInspectUrl, (badge, {inspectUrl}) => if badge == '#' and inspectUrl url = inspectUrl else @clearBadge() return result if not url if url.substr(0, 6) == 'chrome' errorPagePrefix = 'chrome://errorpage/' if url.substr(0, errorPagePrefix.length) == errorPagePrefix url = querystring.parse(url.substr(url.indexOf('?') + 1)).lasturl return result if not url else return result return result if url.substr(0, 6) == 'about:' return result if url.substr(0, 4) == 'moz-' domain = OmegaPac.getBaseDomain(Url.parse(url).hostname) return { url: url domain: domain tempRuleProfileName: @queryTempRule(domain) errorCount: errorCount } module.exports = ChromeOptions ================================================ FILE: omega-target-chromium-extension/src/module/proxy/index.coffee ================================================ ListenerProxyImpl = require('./proxy_impl_listener') SettingsProxyImpl = require('./proxy_impl_settings') ScriptProxyImpl = require('./proxy_impl_script') exports.proxyImpls = [ListenerProxyImpl, ScriptProxyImpl, SettingsProxyImpl] exports.getProxyImpl = (log) -> for Impl in exports.proxyImpls if Impl.isSupported() return new Impl(log) throw new Error('Your browser does not support proxy settings!') ================================================ FILE: omega-target-chromium-extension/src/module/proxy/proxy_auth.coffee ================================================ OmegaTarget = require('omega-target') OmegaPac = OmegaTarget.OmegaPac Promise = OmegaTarget.Promise module.exports = class ProxyAuth constructor: (log) -> @_requests = {} @log = log listening: false listen: -> return if @listening if not chrome.webRequest @log.error('Proxy auth disabled! No webRequest permission.') return if not chrome.webRequest.onAuthRequired @log.error('Proxy auth disabled! onAuthRequired not available.') return chrome.webRequest.onAuthRequired.addListener( @authHandler.bind(this) {urls: ['']} ['blocking'] ) chrome.webRequest.onCompleted.addListener( @_requestDone.bind(this) {urls: ['']} ) chrome.webRequest.onErrorOccurred.addListener( @_requestDone.bind(this) {urls: ['']} ) @listening = true _keyForProxy: (proxy) -> "#{proxy.host.toLowerCase()}:#{proxy.port}" setProxies: (profiles) -> @_proxies = {} @_fallbacks = [] for profile in profiles when profile.auth for scheme in OmegaPac.Profiles.schemes when profile[scheme.prop] auth = profile.auth?[scheme.prop] continue unless auth proxy = profile[scheme.prop] key = @_keyForProxy(proxy) list = @_proxies[key] if not list? @_proxies[key] = list = [] list.push({ config: proxy auth: auth name: profile.name + '.' + scheme.prop }) fallback = profile.auth?['all'] if fallback? @_fallbacks.push({ auth: fallback name: profile.name + '.' + 'all' }) _proxies: {} _fallbacks: [] _requests: null authHandler: (details) -> return {} unless details.isProxy req = @_requests[details.requestId] if not req? @_requests[details.requestId] = req = {authTries: 0} key = @_keyForProxy( host: details.challenger.host port: details.challenger.port ) list = @_proxies[key] listLen = if list? then list.length else 0 if req.authTries < listLen proxy = list[req.authTries] else proxy = @_fallbacks[req.authTries - listLen] @log.log('ProxyAuth', key, req.authTries, proxy?.name) return {} unless proxy? req.authTries++ return authCredentials: proxy.auth _requestDone: (details) -> delete @_requests[details.requestId] ================================================ FILE: omega-target-chromium-extension/src/module/proxy/proxy_impl.coffee ================================================ OmegaTarget = require('omega-target') Promise = OmegaTarget.Promise ProxyAuth = require('./proxy_auth') class ProxyImpl constructor: (log) -> @log = log @isSupported: -> false applyProfile: (profile, meta) -> Promise.reject() watchProxyChange: (callback) -> null parseExternalProfile: (details, options) -> null _profileNotFound: (name) -> @log.error("Profile #{name} not found! Things may go very, very wrong.") return OmegaPac.Profiles.create({ name: name profileType: 'VirtualProfile' defaultProfileName: 'direct' }) setProxyAuth: (profile, options) -> return Promise.try(=> @_proxyAuth ?= new ProxyAuth(@log) @_proxyAuth.listen() referenced_profiles = [] ref_set = OmegaPac.Profiles.allReferenceSet(profile, options, profileNotFound: @_profileNotFound.bind(this)) for own _, name of ref_set profile = OmegaPac.Profiles.byName(name, options) if profile referenced_profiles.push(profile) @_proxyAuth.setProxies(referenced_profiles) ) getProfilePacScript: (profile, meta, options) -> meta ?= profile ast = OmegaPac.PacGenerator.script(options, profile, profileNotFound: @_profileNotFound.bind(this)) ast = OmegaPac.PacGenerator.compress(ast) script = OmegaPac.PacGenerator.ascii(ast.print_to_string()) profileName = OmegaPac.PacGenerator.ascii(JSON.stringify(meta.name)) profileName = profileName.replace(/\*/g, '\\u002a') profileName = profileName.replace(/\\/g, '\\u002f') prefix = "/*OmegaProfile*#{profileName}*#{meta.revision}*/" return prefix + script module.exports = ProxyImpl ================================================ FILE: omega-target-chromium-extension/src/module/proxy/proxy_impl_listener.coffee ================================================ OmegaTarget = require('omega-target') # The browser only accepts native promises as onRequest return values. # DO NOT USE Bluebird Promises here! NativePromise = Promise ? null ProxyImpl = require('./proxy_impl') class ListenerProxyImpl extends ProxyImpl @isSupported: -> Promise? and browser?.proxy?.onRequest? features: ['fullUrl', 'socks5Auth'] constructor: -> super(arguments...) @_optionsReady = new NativePromise (resolve) => @_optionsReadyCallback = resolve # We want to register listeners early so that it can start blocking requests # when starting the browser & extension, returning correct results later. @_initRequestListeners() _initRequestListeners: -> browser.proxy.onRequest.addListener(@onRequest.bind(this), {urls: [""]}) browser.proxy.onError.addListener(@onError.bind(this)) watchProxyChange: (callback) -> null applyProfile: (profile, state, options) -> @_options = options @_profile = profile @_optionsReadyCallback?() @_optionsReadyCallback = null return @setProxyAuth(profile, options) onRequest: (requestDetails) -> # The browser only recognizes native promises return values, not Bluebird. return NativePromise.resolve(@_optionsReady.then(=> request = OmegaPac.Conditions.requestFromUrl(requestDetails.url) profile = @_profile while profile result = OmegaPac.Profiles.match(profile, request) if not result switch profile.profileType when 'DirectProfile' return {type: 'direct'} when 'SystemProfile' # Returning undefined means using the default proxy from previous. # https://hg.mozilla.org/mozilla-central/rev/9f0ee2f582a2#l1.337 return undefined else throw new Error('Unsupported profile: ' + profile.profileType) if Array.isArray(result) proxy = result[2] auth = result[3] return @proxyInfo(proxy, auth) if proxy next = result[0] else if result.profileName next = OmegaPac.Profiles.nameAsKey(result.profileName) else break profile = OmegaPac.Profiles.byKey(next, @_options) throw new Error('Profile not found: ' + next) )) onError: (error) -> @log.error(error) proxyInfo: (proxy, auth) -> proxyInfo = type: proxy.scheme host: proxy.host port: proxy.port if proxyInfo.type == 'socks5' # MOZ: SOCKS5 proxies should be specified as "type": "socks". # https://developer.mozilla.org/en-US/Add-ons/WebExtensions/API/proxy/ProxyInfo proxyInfo.type = 'socks' if auth # Username & password here are only available for SOCKS5. # https://developer.mozilla.org/en-US/Add-ons/WebExtensions/API/proxy/ProxyInfo # HTTP proxy auth must be handled via webRequest.onAuthRequired. proxyInfo.username = auth.username proxyInfo.password = auth.password if proxyInfo.type == 'socks' # Enable SOCKS remote DNS. # TODO(catus): Maybe allow the users to configure this? proxyInfo.proxyDNS = true # TODO(catus): Maybe allow proxyDNS for socks4? Server may support SOCKS4a. # It cannot default to true though, since SOCKS4 servers that does not have # the SOCKS4a extension may simply refuse to work. return [proxyInfo] module.exports = ListenerProxyImpl ================================================ FILE: omega-target-chromium-extension/src/module/proxy/proxy_impl_script.coffee ================================================ OmegaTarget = require('omega-target') Promise = OmegaTarget.Promise ProxyImpl = require('./proxy_impl') class ScriptProxyImpl extends ProxyImpl @isSupported: -> return browser?.proxy?.register? or browser?.proxy?.registerProxyScript? features: ['socks5Auth'] _proxyScriptUrl: 'js/omega_webext_proxy_script.min.js' _proxyScriptDisabled: false _proxyScriptInitialized: false _proxyScriptState: {} watchProxyChange: (callback) -> null applyProfile: (profile, state, options) -> @log.error( 'Your browser is outdated! Full-URL based matching, etc. unsupported! ' + "Please update your browser ASAP!") state = state ? {} @_options = options state.currentProfileName = profile.name if profile.name == '' state.tempProfile = profile if profile.profileType == 'SystemProfile' # MOZ: SystemProfile cannot be done now due to lack of "PASS" support. # https://bugzilla.mozilla.org/show_bug.cgi?id=1319634 # In the mean time, let's just unregister the script. if browser.proxy.unregister? browser.proxy.unregister() else # Some older browers may not ship with .unregister API. # In that case, let's just set an invalid script to unregister it. browser.proxy.registerProxyScript('js/omega_invalid_proxy_script.js') @_proxyScriptDisabled = true else @_proxyScriptState = state Promise.all([ browser.runtime.getBrowserInfo(), @_initWebextProxyScript(), ]).then ([info]) => if info.vendor == 'Mozilla' and info.buildID < '20170918220054' # MOZ: Legacy proxy support expects PAC-like string return type. # TODO(catus): Remove support for string return type. @log.error( 'Your browser is outdated! SOCKS5 DNS/Auth unsupported! ' + "Please update your browser ASAP! (Current Build #{info.buildID})") @_proxyScriptState.useLegacyStringReturn = true @_proxyScriptStateChanged() return @setProxyAuth(profile, options) _initWebextProxyScript: -> if not @_proxyScriptInitialized browser.proxy.onProxyError.addListener (err) => if err?.message? if err.message.indexOf('Invalid Proxy Rule: DIRECT') >= 0 # DIRECT cannot be parsed in Mozilla earlier due to a bug. Even # though it throws, it actually falls back to direct connection # so it works. # https://bugzilla.mozilla.org/show_bug.cgi?id=1355198 return if err.message.indexOf('Return type must be a string') >= 0 # MOZ: Legacy proxy support expects PAC-like string return type. # TODO(catus): Remove support for string return type. # @log.error( 'Your browser is outdated! SOCKS5 DNS/Auth unsupported! ' + 'Please update your browser ASAP!') @_proxyScriptState.useLegacyStringReturn = true @_proxyScriptStateChanged() return @log.error(err) browser.runtime.onMessage.addListener (message) => return unless message.event == 'proxyScriptLog' if message.level == 'error' @log.error(message) else if message.level == 'warn' @log.error(message) else @log.log(message) if not @_proxyScriptInitialized or @_proxyScriptDisabled promise = new Promise (resolve) -> onMessage = (message) -> return unless message.event == 'proxyScriptLoaded' resolve() browser.runtime.onMessage.removeListener onMessage return browser.runtime.onMessage.addListener onMessage # The API has been renamed to .register but for some old browsers' sake: if browser.proxy.register? browser.proxy.register(@_proxyScriptUrl) else browser.proxy.registerProxyScript(@_proxyScriptUrl) @_proxyScriptDisabled = false else promise = Promise.resolve() @_proxyScriptInitialized = true return promise _proxyScriptStateChanged: -> browser.runtime.sendMessage({ event: 'proxyScriptStateChanged' state: @_proxyScriptState options: @_options }, { toProxyScript: true }) module.exports = ScriptProxyImpl ================================================ FILE: omega-target-chromium-extension/src/module/proxy/proxy_impl_settings.coffee ================================================ OmegaTarget = require('omega-target') OmegaPac = OmegaTarget.OmegaPac Promise = OmegaTarget.Promise chromeApiPromisify = require('../chrome_api').chromeApiPromisify ProxyImpl = require('./proxy_impl') class SettingsProxyImpl extends ProxyImpl @isSupported: -> chrome?.proxy?.settings? features: ['fullUrlHttp', 'pacScript', 'watchProxyChange'] applyProfile: (profile, meta, options) -> meta ?= profile if profile.profileType == 'SystemProfile' # Clear proxy settings, returning proxy control to Chromium. return chromeApiPromisify(chrome.proxy.settings, 'clear')({}).then => chrome.proxy.settings.get {}, @_proxyChangeListener return config = {} if profile.profileType == 'DirectProfile' config['mode'] = 'direct' else if profile.profileType == 'PacProfile' config['mode'] = 'pac_script' config['pacScript'] = if !profile.pacScript || OmegaPac.Profiles.isFileUrl(profile.pacUrl) url: profile.pacUrl mandatory: true else data: OmegaPac.PacGenerator.ascii(profile.pacScript) mandatory: true else if profile.profileType == 'FixedProfile' config = @_fixedProfileConfig(profile) else config['mode'] = 'pac_script' config['pacScript'] = mandatory: true data: @getProfilePacScript(profile, meta, options) return @setProxyAuth(profile, options).then(-> return chromeApiPromisify(chrome.proxy.settings, 'set')({value: config}) ).then(=> chrome.proxy.settings.get {}, @_proxyChangeListener return ) _fixedProfileConfig: (profile) -> config = {} config['mode'] = 'fixed_servers' rules = {} protocols = ['proxyForHttp', 'proxyForHttps', 'proxyForFtp'] protocolProxySet = false for protocol in protocols when profile[protocol]? rules[protocol] = profile[protocol] protocolProxySet = true if profile.fallbackProxy if profile.fallbackProxy.scheme == 'http' # Chromium does not allow HTTP proxies in 'fallbackProxy'. if not protocolProxySet # Use 'singleProxy' if no proxy is configured for other protocols. rules['singleProxy'] = profile.fallbackProxy else # Try to set the proxies of all possible protocols. for protocol in protocols rules[protocol] ?= JSON.parse(JSON.stringify(profile.fallbackProxy)) else rules['fallbackProxy'] = profile.fallbackProxy else if not protocolProxySet config['mode'] = 'direct' if config['mode'] != 'direct' rules['bypassList'] = bypassList = [] for condition in profile.bypassList bypassList.push(@_formatBypassItem(condition)) config['rules'] = rules return config _formatBypassItem: (condition) -> str = OmegaPac.Conditions.str(condition) i = str.indexOf(' ') return str.substr(i + 1) _proxyChangeWatchers: null _proxyChangeListener: (details) -> for watcher in (@_proxyChangeWatchers ? []) watcher(details) watchProxyChange: (callback) -> if not @_proxyChangeWatchers? @_proxyChangeWatchers = [] if chrome?.proxy?.settings?.onChange? chrome.proxy.settings.onChange.addListener( @_proxyChangeListener.bind(this)) @_proxyChangeWatchers.push(callback) return parseExternalProfile: (details, options) -> if details.name return details switch details.value.mode when 'system' OmegaPac.Profiles.byName('system') when 'direct' OmegaPac.Profiles.byName('direct') when 'auto_detect' OmegaPac.Profiles.create({ profileType: 'PacProfile' name: '' pacUrl: 'http://wpad/wpad.dat' }) when 'pac_script' url = details.value.pacScript.url if url profile = null OmegaPac.Profiles.each options, (key, p) -> if p.profileType == 'PacProfile' and p.pacUrl == url profile = p profile ? OmegaPac.Profiles.create({ profileType: 'PacProfile' name: '' pacUrl: url }) else do -> profile = null script = details.value.pacScript.data OmegaPac.Profiles.each options, (key, p) -> if p.profileType == 'PacProfile' and p.pacScript == script profile = p return profile if profile # Try to parse the prefix used by this class. script = script.trim() magic = '/*OmegaProfile*' if script.substr(0, magic.length) == magic end = script.indexOf('*/') if end > 0 i = magic.length tokens = script.substring(magic.length, end).split('*') [profileName, revision] = tokens try profileName = JSON.parse(profileName) catch _ profileName = null if profileName and revision profile = OmegaPac.Profiles.byName(profileName, options) if OmegaPac.Revision.compare(profile.revision, revision) == 0 return profile return OmegaPac.Profiles.create({ profileType: 'PacProfile' name: '' pacScript: script }) when 'fixed_servers' props = ['proxyForHttp', 'proxyForHttps', 'proxyForFtp', 'fallbackProxy', 'singleProxy'] proxies = {} for prop in props result = OmegaPac.Profiles.pacResult(details.value.rules[prop]) if prop == 'singleProxy' and details.value.rules[prop]? proxies['fallbackProxy'] = result else proxies[prop] = result bypassSet = {} bypassCount = 0 if details.value.rules.bypassList for pattern in details.value.rules.bypassList bypassSet[pattern] = true bypassCount++ if bypassSet[''] for host in OmegaPac.Conditions.localHosts when bypassSet[host] delete bypassSet[host] bypassCount-- profile = null OmegaPac.Profiles.each options, (key, p) => return if p.profileType != 'FixedProfile' return if p.bypassList.length != bypassCount for condition in p.bypassList return unless bypassSet[condition.pattern] rules = @_fixedProfileConfig(p).rules if rules['singleProxy'] rules['fallbackProxy'] = rules['singleProxy'] delete rules['singleProxy'] return unless rules? for prop in props when rules[prop] or proxies[prop] if OmegaPac.Profiles.pacResult(rules[prop]) != proxies[prop] return profile = p if profile profile else profile = OmegaPac.Profiles.create({ profileType: 'FixedProfile' name: '' }) for prop in props when details.value.rules[prop] if prop == 'singleProxy' profile['fallbackProxy'] = details.value.rules[prop] else profile[prop] = details.value.rules[prop] profile.bypassList = for own pattern of bypassSet {conditionType: 'BypassCondition', pattern: pattern} profile module.exports = SettingsProxyImpl ================================================ FILE: omega-target-chromium-extension/src/module/storage.coffee ================================================ chromeApiPromisify = require('./chrome_api').chromeApiPromisify OmegaTarget = require('omega-target') Promise = OmegaTarget.Promise class ChromeStorage extends OmegaTarget.Storage @parseStorageErrors: (err) -> if err?.message sustainedPerMinute = 'MAX_SUSTAINED_WRITE_OPERATIONS_PER_MINUTE' if err.message.indexOf('QUOTA_BYTES_PER_ITEM') >= 0 err = new OmegaTarget.Storage.QuotaExceededError() err.perItem = true else if err.message.indexOf('QUOTA_BYTES') >= 0 err = new OmegaTarget.Storage.QuotaExceededError() else if err.message.indexOf('MAX_ITEMS') >= 0 err = new OmegaTarget.Storage.QuotaExceededError() err.maxItems = true else if err.message.indexOf('MAX_WRITE_OPERATIONS_') >= 0 err = new OmegaTarget.Storage.RateLimitExceededError() if err.message.indexOf('MAX_WRITE_OPERATIONS_PER_HOUR') >= 0 err.perHour = true else if err.message.indexOf('MAX_WRITE_OPERATIONS_PER_MINUTE') >= 0 err.perMinute = true else if err.message.indexOf(sustainedPerMinute) >= 0 err = new OmegaTarget.Storage.RateLimitExceededError() err.perMinute = true err.sustained = 10 else if err.message.indexOf('is not available') >= 0 # This could happen if the storage area is not available. For example, # some Chromium-based browsers disable access to the sync storage. err = new OmegaTarget.Storage.StorageUnavailableError() else if err.message.indexOf( 'Please set webextensions.storage.sync.enabled to true') >= 0 # This happens when sync storage is disabled in flags. err = new OmegaTarget.Storage.StorageUnavailableError() return Promise.reject(err) constructor: (@areaName) -> if browser?.storage?[@areaName] @storage = browser.storage[@areaName] else @storage = get: chromeApiPromisify(chrome.storage[@areaName], 'get') set: chromeApiPromisify(chrome.storage[@areaName], 'set') remove: chromeApiPromisify(chrome.storage[@areaName], 'remove') clear: chromeApiPromisify(chrome.storage[@areaName], 'clear') get: (keys) -> keys ?= null Promise.resolve(@storage.get(keys)).catch(ChromeStorage.parseStorageErrors) set: (items) -> if Object.keys(items).length == 0 return Promise.resolve({}) Promise.resolve(@storage.set(items)).catch(ChromeStorage.parseStorageErrors) remove: (keys) -> if not keys? return Promise.resolve(@storage.clear()) if Array.isArray(keys) and keys.length == 0 return Promise.resolve({}) Promise.resolve(@storage.remove(keys)) .catch(ChromeStorage.parseStorageErrors) watch: (keys, callback) -> ChromeStorage.watchers[@areaName] ?= {} area = ChromeStorage.watchers[@areaName] watcher = {keys: keys, callback: callback} id = Date.now().toString() while area[id] id = Date.now().toString() if Array.isArray(keys) keyMap = {} for key in keys keyMap[key] = true keys = keyMap area[id] = {keys: keys, callback: callback} if not ChromeStorage.onChangedListenerInstalled chrome.storage.onChanged.addListener(ChromeStorage.onChangedListener) ChromeStorage.onChangedListenerInstalled = true return -> delete area[id] @onChangedListener: (changes, areaName) -> map = null for _, watcher of ChromeStorage.watchers[areaName] match = watcher.keys == null if not match for own key of changes if watcher.keys[key] match = true break if match if not map? map = {} for own key, change of changes map[key] = change.newValue watcher.callback(map) @onChangedListenerInstalled: false @watchers: {} module.exports = ChromeStorage ================================================ FILE: omega-target-chromium-extension/src/module/switchysharp.coffee ================================================ OmegaTarget = require('omega-target') OmegaPac = OmegaTarget.OmegaPac Promise = OmegaTarget.Promise ChromePort = require('./chrome_port') module.exports = class SwitchySharp @extId: 'dpplabbmogkhghncfbfdeeokoefdjegm' port: null monitor: (action) -> return if location.href.substr(0, 4) == 'moz-' if not port? and not @_monitorTimerId? @_monitorTimerId = setInterval @_connect.bind(this), 5000 if action != 'reconnect' @_connect() getOptions: -> if not @_getOptions @_getOptions = new Promise (resolve) => @_getOptionsResolver = resolve @monitor() @_getOptions _getOptions: null _getOptionsResolver: null _monitorTimerId: null _onMessage: (msg) -> if @_monitorTimerId clearInterval @_monitorTimerId @_monitorTimerId = null switch msg?.action when 'state' # State changed. OmegaTarget.Log.log(msg) if @_getOptionsResolver @port.postMessage({action: 'getOptions'}) when 'options' @_getOptionsResolver?(msg.options) @_getOptionsResolver = null _onDisconnect: (msg) -> @port = null @_getOptions = null @_getOptionsResolver = null @monitor('reconnect') _connect: -> if not @port @port = new ChromePort(chrome.runtime.connect(SwitchySharp.extId)) @port.onDisconnect.addListener(@_onDisconnect.bind(this)) @port?.onMessage.addListener(@_onMessage.bind(this)) try @port.postMessage({action: 'disable'}) catch _ @port = null return @port? ================================================ FILE: omega-target-chromium-extension/src/module/tabs.coffee ================================================ class ChromeTabs _defaultAction: null _badgeTab: null constructor: (@actionForUrl) -> @_dirtyTabs = {} return ignoreError: -> chrome.runtime.lastError return watch: -> chrome.tabs.onUpdated.addListener @onUpdated.bind(this) chrome.tabs.onActivated.addListener (info) => chrome.tabs.get info.tabId, (tab) => return if chrome.runtime.lastError if @_dirtyTabs.hasOwnProperty(info.tabId) @onUpdated tab.id, {}, tab resetAll: (action) -> @_defaultAction = action chrome.tabs.query {}, (tabs) => @_dirtyTabs = {} tabs.forEach (tab) => @_dirtyTabs[tab.id] = tab.id @onUpdated tab.id, {}, tab if tab.active if chrome.browserAction.setPopup? chrome.browserAction.setTitle({title: action.title}) else chrome.browserAction.setTitle({title: action.shortTitle}) @setIcon(action.icon) onUpdated: (tabId, changeInfo, tab) -> if @_dirtyTabs.hasOwnProperty(tab.id) delete @_dirtyTabs[tab.id] else if not changeInfo.url? if changeInfo.status? and changeInfo.status != 'loading' return @processTab(tab, changeInfo) processTab: (tab, changeInfo) -> if @_badgeTab for own id of @_badgeTab try chrome.browserAction.setBadgeText?(text: '', tabId: id) @_badgeTab = null if not tab.url? or tab.url.indexOf("chrome") == 0 if @_defaultAction chrome.browserAction.setTitle({ title: @_defaultAction.title tabId: tab.id }) @clearIcon tab.id return @actionForUrl(tab.url).then (action) => if not action @clearIcon tab.id return @setIcon(action.icon, tab.id) if chrome.browserAction.setPopup? chrome.browserAction.setTitle({title: action.title, tabId: tab.id}) else chrome.browserAction.setTitle({title: action.shortTitle, tabId: tab.id}) setTabBadge: (tab, badge) -> @_badgeTab ?= {} @_badgeTab[tab.id] = true chrome.browserAction.setBadgeText?(text: badge.text, tabId: tab.id) chrome.browserAction.setBadgeBackgroundColor?( color: badge.color tabId: tab.id ) setIcon: (icon, tabId) -> return unless icon? if tabId? params = { imageData: icon tabId: tabId } else params = { imageData: icon } @_chromeSetIcon(params) _chromeSetIcon: (params) -> try chrome.browserAction.setIcon?(params, @ignoreError) catch _ # Some legacy Chrome versions will panic if there are other icon sizes. params.imageData = {19: params.imageData[19], 38: params.imageData[38]} chrome.browserAction.setIcon?(params, @ignoreError) clearIcon: (tabId) -> return unless @_defaultAction?.icon? @_chromeSetIcon({ imageData: @_defaultAction.icon tabId: tabId }, @ignoreError) module.exports = ChromeTabs ================================================ FILE: omega-target-chromium-extension/src/module/upgrade.coffee ================================================ OmegaTarget = require('omega-target') OmegaPac = OmegaTarget.OmegaPac module.exports = (oldOptions, i18n) -> config = try JSON.parse(oldOptions['config']) if config options = changes ? {} options['schemaVersion'] = 2 boolItems = '-confirmDeletion': 'confirmDeletion' '-refreshOnProfileChange': 'refreshTab' '-enableQuickSwitch': 'quickSwitch' '-revertProxyChanges': 'preventProxyChanges' for own key, oldKey of boolItems options[key] = !!config[oldKey] options['-downloadInterval'] = parseInt(config['ruleListReload']) || 15 auto = OmegaPac.Profiles.create( profileType: 'SwitchProfile' name: i18n.upgrade_profile_auto color: '#55bb55' defaultProfileName: 'direct' # We will set this to rulelist.name soon. ) OmegaPac.Profiles.updateRevision(auto) options[OmegaPac.Profiles.nameAsKey(auto.name)] = auto rulelist = OmegaPac.Profiles.create( profileType: 'RuleListProfile' name: '__ruleListOf_' + auto.name color: '#dd6633' format: if config['ruleListAutoProxy'] then 'AutoProxy' else 'Switchy' defaultProfileName: 'direct' sourceUrl: config['ruleListUrl'] || '' ) options[OmegaPac.Profiles.nameAsKey(rulelist.name)] = rulelist auto.defaultProfileName = rulelist.name nameMap = {'auto': auto.name, 'direct': 'direct'} oldProfiles = (try JSON.parse(oldOptions['profiles'])) || {} colorTranslations = 'blue': '#99ccee' 'green': '#99dd99' 'red': '#ffaa88' 'yellow': '#ffee99' 'purple': '#d497ee' '': '#99ccee' seenFixedProfile = false for own _, oldProfile of oldProfiles profile = null switch oldProfile['proxyMode'] when 'auto' profile = OmegaPac.Profiles.create( profileType: 'PacProfile' ) url = oldProfile['proxyConfigUrl'] if url.substr(0, 5) == 'data:' text = url.substr(url.indexOf(',') + 1) Buffer = require('buffer').Buffer text = new Buffer(text, 'base64').toString('utf8') profile.pacScript = text else profile.pacUrl = url when 'manual' seenFixedProfile = true profile = OmegaPac.Profiles.create( profileType: 'FixedProfile' ) if !!oldProfile['useSameProxy'] profile.fallbackProxy = OmegaPac.Profiles.parseHostPort( oldProfile['proxyHttp'], 'http') else if oldProfile['proxySocks'] protocol = if oldProfile['socksVersion'] == 5 'socks5' else 'socks4' profile.fallbackProxy = OmegaPac.Profiles.parseHostPort( oldProfile['proxySocks'], protocol ) else profile.proxyForHttp = OmegaPac.Profiles.parseHostPort( oldProfile['proxyHttp'], 'http') profile.proxyForHttps = OmegaPac.Profiles.parseHostPort( oldProfile['proxyHttps'], 'http') profile.proxyForFtp = OmegaPac.Profiles.parseHostPort( oldProfile['proxyFtp'], 'http') if oldProfile['proxyExceptions']? haslocalPattern = false profile.bypassList = [] oldProfile['proxyExceptions'].split(';').forEach (line) -> line = line.trim() return unless line haslocalPattern = true if line == '' profile.bypassList.push( conditionType: 'BypassCondition' pattern: line ) if haslocalPattern profile.bypassList = profile.bypassList.filter (cond) -> OmegaPac.Conditions.localHosts.indexOf(cond.pattern) < 0 if profile color = oldProfile['color'] profile.color = colorTranslations[color] ? colorTranslations[''] name = oldProfile['name'] ? oldProfile['id'] name = name.trim() if name[0] == '_' name = 'p' + name profile.name = name num = 1 while OmegaPac.Profiles.byName(profile.name, options) profile.name = name + num num++ nameMap[oldProfile['id']] = profile.name OmegaPac.Profiles.updateRevision(profile) options[OmegaPac.Profiles.nameAsKey(profile.name)] = profile if not seenFixedProfile exampleFixedProfileName = 'Example Profile' options[OmegaPac.Profiles.nameAsKey(exampleFixedProfileName)] = bypassList: [ { pattern: "127.0.0.1" conditionType: "BypassCondition" } { pattern: "::1" conditionType: "BypassCondition" } { pattern: "localhost" conditionType: "BypassCondition" } ] profileType: "FixedProfile" name: exampleFixedProfileName color: "#99ccee" fallbackProxy: port: 8080 scheme: "http" host: "proxy.example.com" startupId = config['startupProfileId'] options['-startupProfileName'] = nameMap[startupId] || '' quickSwitch = try JSON.parse(oldOptions['quickSwitchProfiles']) options['-quickSwitchProfiles'] = if not quickSwitch? then [] else quickSwitch.map (p) -> nameMap[p] if config['ruleListProfileId'] rulelist.matchProfileName = nameMap[config['ruleListProfileId']] || 'direct' defaultRule = try JSON.parse(oldOptions['defaultRule']) if defaultRule rulelist.defaultProfileName = nameMap[defaultRule.profileId] || 'direct' if not config.ruleListEnabled auto.defaultProfileName = rulelist.defaultProfileName OmegaPac.Profiles.updateRevision(rulelist) rules = try JSON.parse(oldOptions['rules']) if rules conditionFromRule = (rule) -> switch rule['patternType'] when 'wildcard' pattern = rule['urlPattern'] OmegaPac.RuleList['Switchy'].conditionFromLegacyWildcard(pattern) else conditionType: 'UrlRegexCondition' pattern: rule['urlPattern'] auto.rules = for own _, rule of rules profileName: nameMap[rule['profileId']] || 'direct' condition: conditionFromRule(rule) note: rule.name return options return ================================================ FILE: omega-target-chromium-extension/src/module/web_request_monitor.coffee ================================================ Heap = require('heap') Url = require('url') module.exports = class WebRequestMonitor constructor: (@getSummaryId) -> @_requests = {} @_recentRequests = new Heap((a, b) -> a._startTime - b._startTime) @_callbacks = [] @_tabCallbacks = [] @tabInfo = {} _callbacks: null watching: false timer: null watch: (callback) -> @_callbacks.push(callback) return if @watching if not chrome.webRequest console.log('Request monitor disabled! No webRequest permission.') return chrome.webRequest.onBeforeRequest.addListener( @_requestStart.bind(this) {urls: ['']} ) chrome.webRequest.onHeadersReceived.addListener( @_requestHeadersReceived.bind(this) {urls: ['']} ) chrome.webRequest.onBeforeRedirect.addListener( @_requestRedirected.bind(this) {urls: ['']} ) chrome.webRequest.onCompleted.addListener( @_requestDone.bind(this) {urls: ['']} ) chrome.webRequest.onErrorOccurred.addListener( @_requestError.bind(this) {urls: ['']} ) @watching = true _requests: null _recentRequests: null _requestStart: (req) -> return if req.tabId < 0 req._startTime = Date.now() @_requests[req.requestId] = req @_recentRequests.push(req) @timer ?= setInterval(@_tick.bind(this), 1000) for callback in @_callbacks callback('start', req) _tick: -> now = Date.now() while (req = @_recentRequests.peek()) reqInfo = @_requests[req.requestId] if reqInfo and not reqInfo.noTimeout if now - req._startTime < 5000 break else reqInfo.timeoutCalled = true for callback in @_callbacks callback('timeout', reqInfo) @_recentRequests.pop() _requestHeadersReceived: (req) -> reqInfo = @_requests[req.requestId] return unless reqInfo reqInfo.noTimeout = true if reqInfo.timeoutCalled for callback in @_callbacks callback('ongoing', req) _requestRedirected: (req) -> url = req.redirectUrl return unless url if url.indexOf('data:') == 0 || url.indexOf('about:') == 0 @_requestDone(req) _requestError: (req) -> reqInfo = @_requests[req.requestId] delete @_requests[req.requestId] return if req.tabId < 0 return if req.error == 'net::ERR_INCOMPLETE_CHUNKED_ENCODING' return if req.error.indexOf('BLOCKED') >= 0 return if req.error.indexOf('net::ERR_FILE_') == 0 # Blocked by other extensions in Firefox. return if req.error.indexOf('NS_ERROR_ABORT') == 0 return if req.url.indexOf('file:') == 0 return if req.url.indexOf('chrome') == 0 return if req.url.indexOf('about:') == 0 return if req.url.indexOf('moz-') == 0 # Some ad-blocking extensions may redirect requests to 127.0.0.1. return if req.url.indexOf('://127.0.0.1') > 0 return unless reqInfo if req.error == 'net::ERR_ABORTED' if reqInfo.timeoutCalled and not reqInfo.noTimeout for callback in @_callbacks callback('timeoutAbort', req) return for callback in @_callbacks callback('error', req) _requestDone: (req) -> for callback in @_callbacks callback('done', req) delete @_requests[req.requestId] eventCategory: start: 'ongoing' ongoing: 'ongoing' timeout: 'error' error: 'error' timeoutAbort: 'error' done: 'done' tabsWatching: false _tabCallbacks: null watchTabs: (callback) -> @_tabCallbacks.push(callback) return if @tabsWatching @watch(@setTabRequestInfo.bind(this)) @tabsWatching = true chrome.tabs.onCreated.addListener (tab) => return unless tab.id @tabInfo[tab.id] = @_newTabInfo() chrome.tabs.onRemoved.addListener (tab) => delete @tabInfo[tab.id] chrome.tabs.onReplaced?.addListener (added, removed) => @tabInfo[added] ?= @_newTabInfo() delete @tabInfo[removed] chrome.tabs.onUpdated.addListener (tabId, changeInfo, tab) => info = @tabInfo[tab.id] ?= @_newTabInfo() return unless info for callback in @_tabCallbacks callback(tab.id, info, null, 'updated') chrome.tabs.query {}, (tabs) => for tab in tabs @tabInfo[tab.id] ?= @_newTabInfo() _newTabInfo: -> { requests: {} requestCount: 0 requestStatus: {} ongoingCount: 0 errorCount: 0 doneCount: 0 summary: {} } setTabRequestInfo: (status, req) -> info = @tabInfo[req.tabId] if info if status == 'start' and req.type == 'main_frame' if req.url.indexOf('chrome://errorpage/') != 0 for own key, value of @_newTabInfo() info[key] = value return if info.requestCount > 1000 info.requests[req.requestId] = req if (oldStatus = info.requestStatus[req.requestId]) info[@eventCategory[oldStatus] + 'Count']-- else return if status == 'timeoutAbort' info.requestCount++ info.requestStatus[req.requestId] = status info[@eventCategory[status] + 'Count']++ id = @getSummaryId?(req) if id? if @eventCategory[status] == 'error' if @eventCategory[oldStatus] != 'error' summaryItem = info.summary[id] if not summaryItem? summaryItem = info.summary[id] = {errorCount: 0} summaryItem.errorCount++ else if @eventCategory[oldStatus] == 'error' summaryItem = info.summary[id] summaryItem.errorCount-- if summaryItem? for callback in @_tabCallbacks callback(req.tabId, info, req, status) ================================================ FILE: omega-web/.gitattributes ================================================ lib/* linguist-vendored ================================================ FILE: omega-web/.gitignore ================================================ /build /tmp ================================================ FILE: omega-web/Gruntfile.coffee ================================================ module.exports = require('load-grunt-config') ================================================ FILE: omega-web/bower.json ================================================ { "name": "switchyomega", "version": "0.0.1", "authors": [ "FelisCatus " ], "description": "The ultimate proxy switcher.", "keywords": [ "proxy", "pac", "extension" ], "license": "GPL", "homepage": "https://github.com/FelisCatus/SwitchyOmega", "private": true, "ignore": [ "**/.*", "node_modules", "bower_components", "test", "tests" ], "dependencies": { "angular": "~1.7.2", "angular-animate": "~1.7.2", "angular-loader": "~1.7.2", "angular-i18n": "~1.7.2", "angular-sanitize": "~1.7.2", "angular-bootstrap": "~0.12.0", "angular-ui-router": "~0.2.18", "bootstrap": "~3.3.2", "script.js": "~2.5.3", "ngprogress": "~1.0.4", "angular-ui-sortable": "~0.13.3", "jsondiffpatch": "~0.1.7", "angular-spectrum-colorpicker": "~1.3.5", "blob": "*", "FileSaver": "=1.3.3", "angular-ui-utils": "bower-validate", "angular-ladda": "~0.2.1", "shepherd.js": "~0.5.1", "jqueryui-touch-punch": "*" }, "exportsOverride": { "script.js": { "": "dist/*.min.js" }, "jquery": { "": "dist/jquery.min.js" }, "jquery-ui": { "": [] }, "jqueryui-touch-punch": { "": "jquery.ui.touch-punch.min.js" }, "angular": { "": "angular.min.js" }, "angular-animate": { "": "*.min.js" }, "angular-bootstrap": { "": "ui-bootstrap-tpls.min.js" }, "angular-i18n": { "": [ "angular-locale_en-us.js", "angular-locale_zh-cn.js", "angular-locale_zh-hk.js", "angular-locale_zh-tw.js" ] }, "angular-loader": { "": "*.min.js" }, "angular-sanitize": { "": "*.min.js" }, "angular-spectrum-colorpicker": { "": "dist/*.min.js" }, "angular-ui-router": { "": "release/*.min.js" }, "angular-ui-sortable": { "": "*.min.js" }, "angular-ui-utils": { "": "*.min.js" }, "bootstrap": { "css": "dist/css/bootstrap.min.css", "fonts": "dist/fonts/*", "js": "js/dropdown.*" }, "ngprogress": { "": "build/*.min.js" }, "jsondiffpatch": { "": "public/build/jsondiffpatch.min.js" }, "shepherd.js": { "": [ "*.min.js", "css/shepherd-theme-arrows.css" ] }, "spectrum": { "": [ "*.js", "*.css" ] }, "FileSaver": { "": "*.min.js" }, "blob": { "": "*.js" }, "ladda": { "": [ "dist/ladda-themeless.min.css", "dist/ladda.min.js" ] } }, "resolutions": { "angular": "~1.7.2" } } ================================================ FILE: omega-web/grunt/aliases.coffee ================================================ module.exports = default: [ 'copy' 'jade' 'less' 'autoprefixer' 'coffeelint' 'coffee' 'bower' ] test: ['mochaTest'] ================================================ FILE: omega-web/grunt/autoprefixer.coffee ================================================ module.exports = options: map: false unprefixed: expand: true cwd: 'tmp/css' src: '**/*.css' dest: 'build/css/' ================================================ FILE: omega-web/grunt/bower.coffee ================================================ module.exports = install: options: copy: true targetDir: 'build/lib/' layout: 'byComponent' ================================================ FILE: omega-web/grunt/coffee.coffee ================================================ module.exports = web: expand: true cwd: 'src/coffee' src: ['**/*.coffee'] dest: 'build/js/' ext: '.js' web_omega: files: 'build/js/omega.js': 'src/omega/**/*.coffee' ================================================ FILE: omega-web/grunt/coffeelint.coffee ================================================ module.exports = options: arrow_spacing: level: 'error' colon_assignment_spacing: level: 'error' spacing: left: 0 right: 1 missing_fat_arrows: level: 'warn' no_empty_functions: level: 'error' no_empty_param_list: level: 'error' no_interpolation_in_single_quotes: level: 'error' no_stand_alone_at: level: 'error' space_operators: level: 'error' # https://github.com/clutchski/coffeelint/issues/525 indentation: level: 'ignore' gruntfile: ['Gruntfile.coffee'] tasks: ['grunt/**/*.coffee'] src: ['src/**/*.coffee'] ================================================ FILE: omega-web/grunt/copy.coffee ================================================ module.exports = pac: files: 'build/js/omega_pac.min.js': 'node_modules/omega-pac/omega_pac.min.js' lib: expand: true cwd: 'lib' src: ['**/*'] dest: 'build/lib/' img: expand: true cwd: 'img' src: ['**/*'] dest: 'build/img/' popup: expand: true cwd: 'src/popup' src: ['**/*'] dest: 'build/popup/' ================================================ FILE: omega-web/grunt/jade.coffee ================================================ module.exports = options: pretty: true web: files: [ { expand: true dest: 'build/' cwd: 'src/' ext: '.html' src: '*.jade' } { expand: true dest: 'build/partials/' cwd: 'src/partials' ext: '.html' src: ['*.jade'] } ] ================================================ FILE: omega-web/grunt/less.coffee ================================================ module.exports = web_options: files: 'tmp/css/options.css': 'src/less/options.less' web_popup: files: 'tmp/css/popup.css': 'src/less/popup.less' ================================================ FILE: omega-web/grunt/mochaTest.coffee ================================================ module.exports = test: options: reporter: 'spec' require: 'coffee-script/register' src: ['test/**/*.coffee'] ================================================ FILE: omega-web/grunt/ngAnnotate.coffee ================================================ module.exports = options: singleQuotes: true app: files: 'build/js/omega.ngmin.js': 'build/js/omega.js' ================================================ FILE: omega-web/grunt/watch.coffee ================================================ module.exports = grunt: options: reload: true files: 'grunt/*' tasks: ['coffeelint:tasks', 'default'] copy_pac: files: 'node_modules/omega-pac/omega_pac.min.js' tasks: 'copy:pac' copy_lib: files: 'lib/**/*' tasks: 'copy:lib' copy_img: files: 'img/**/*' tasks: 'copy:img' copy_popup: files: 'src/popup/**/*' tasks: 'copy:popup' jade: files: ['src/**/*.jade'] tasks: 'jade' less: files: 'src/less/**/*.less' tasks: ['less', 'autoprefixer'] coffeelint: files: 'src/**/*.coffee' tasks: ['coffeelint'] coffee: files: [ 'src/coffee/**/*.coffee' 'src/omega/**/*.coffee' ] tasks: ['coffee'] ================================================ FILE: omega-web/img/icons/draw_omega.js ================================================ var drawOmega = function (ctx, outerCircleColor, innerCircleColor) { ctx.globalCompositeOperation = "source-over"; ctx.fillStyle = outerCircleColor; ctx.beginPath(); ctx.arc(0.5, 0.5, 0.5, 0, Math.PI * 2, true); ctx.closePath(); ctx.fill(); if (innerCircleColor != null) { ctx.fillStyle = innerCircleColor; } else { ctx.globalCompositeOperation = "destination-out"; } ctx.beginPath(); ctx.arc(0.5, 0.5, 0.25, 0, Math.PI * 2, true); ctx.closePath(); ctx.fill(); }; ================================================ FILE: omega-web/package.json ================================================ { "name": "omega-web", "version": "0.0.1", "private": true, "devDependencies": { "chai": "~1.9.1", "coffeelint": "^1.16.0", "grunt": "^0.4.5", "grunt-autoprefixer": "^1.0.1", "grunt-bower-task": "^0.5.0", "grunt-coffeelint": "^0.0.13", "grunt-contrib-coffee": "^0.11.1", "grunt-contrib-concat": "^0.5.0", "grunt-contrib-copy": "^0.5.0", "grunt-contrib-jade": "^0.12.0", "grunt-contrib-less": "^0.11.4", "grunt-contrib-watch": "^0.6.1", "grunt-mocha-test": "~0.11.0", "grunt-ng-annotate": "^0.3.2", "load-grunt-config": "^0.13.1", "omega-pac": "../omega-pac" }, "scripts": { "dev": "npm link omega-pac && npm link" } } ================================================ FILE: omega-web/src/coffee/log_error.coffee ================================================ window.onerror = (message, url, line, col, err) -> log = localStorage['log'] || '' if err?.stack log += err.stack + '\n\n' else log += "#{url}:#{line}:#{col}:\t#{message}\n\n" localStorage['log'] = log return ================================================ FILE: omega-web/src/coffee/omega_decoration.coffee ================================================ orderForType = 'FixedProfile': -2000 'PacProfile': -1000 'VirtualProfile': 1000 'SwitchProfile': 2000 'RuleListProfile': 3000 angular.module('omegaDecoration', []).value('profileIcons', { 'DirectProfile': 'glyphicon-transfer' 'SystemProfile': 'glyphicon-off' 'AutoDetectProfile': 'glyphicon-file' 'FixedProfile': 'glyphicon-globe' 'PacProfile': 'glyphicon-file' 'VirtualProfile': 'glyphicon-question-sign' 'RuleListProfile': 'glyphicon-list' 'SwitchProfile': 'glyphicon-retweet' }).constant('profileOrder', (a, b) -> diff = (orderForType[a.profileType] | 0) - (orderForType[b.profileType] | 0) return diff if diff != 0 if a.name == b.name 0 else if a.name < b.name -1 else 1 ).constant('getVirtualTarget', (profile, options) -> if profile?.profileType == 'VirtualProfile' options?['+' + profile.defaultProfileName] ).directive('omegaProfileIcon', (profileIcons, getVirtualTarget) -> restrict: 'A' template: ''' ''' scope: 'profile': '=?omegaProfileIcon' 'icon': '=?icon' 'color': '=?color' 'options': '=options' link: (scope, element, attrs, ngModel) -> scope.profileIcons = profileIcons scope.isVirtual = (profile) -> profile?.profileType == 'VirtualProfile' scope.getIcon = (profile) -> type = profile?.profileType type = getVirtualTarget(profile, scope.options)?.profileType ? type profileIcons[type] scope.getColor = (profile) -> color = undefined while profile color = profile.color profile = getVirtualTarget(profile, scope.options) color ).directive('omegaProfileInline', -> restrict: 'A' template: ''' {{dispName ? dispName(profile) : profile.name}} ''' scope: 'profile': '=omegaProfileInline' 'dispName': '=?dispName' 'options': '=options' ).directive('omegaHtml', ($compile) -> restrict: 'A' link: (scope, element, attrs, ngModel) -> locals = $profile: (profile = 'profile', dispName = 'dispNameFilter', options = 'options') -> """ """ getHtml = -> scope.$eval(attrs.omegaHtml, locals) scope.$watch getHtml, (html) -> element.html(html) $compile(element.contents())(scope) ).directive('omegaProfileSelect', ($timeout, profileIcons) -> restrict: 'A' templateUrl: 'partials/omega_profile_select.html' require: '?ngModel' scope: 'profiles': '&omegaProfileSelect' 'defaultText': '@?defaultText' 'dispName': '=?dispName' 'options': '=options' link: (scope, element, attrs, ngModel) -> scope.profileIcons = profileIcons scope.currentProfiles = [] scope.dispProfiles = undefined updateView = -> scope.profileIcon = '' for profile in scope.currentProfiles if profile.name == scope.profileName scope.selectedProfile = profile scope.profileIcon = profileIcons[profile.profileType] break scope.$watch(scope.profiles, ((profiles) -> scope.currentProfiles = profiles || [] if scope.dispProfiles? scope.dispProfiles = currentProfiles updateView() ), true) scope.toggled = (open) -> if open and not scope.dispProfiles? scope.dispProfiles = scope.currentProfiles scope.toggled = undefined if ngModel ngModel.$render = -> scope.profileName = ngModel.$viewValue updateView() scope.setProfileName = (name) -> if ngModel ngModel.$setViewValue(name) ngModel.$render() scope.getName = (profile) -> if profile scope.dispName(profile) || profile.name ) ================================================ FILE: omega-web/src/coffee/options.coffee ================================================ this.UglifyJS_NoUnsafeEval = true $script 'lib/angular-loader/angular-loader.min.js', 'angular-loader' $script 'lib/jquery/jquery.min.js', 'jquery' $script 'js/omega_pac.min.js', 'omega-pac' $script 'lib/FileSaver/FileSaver.min.js', 'filesaver' $script 'lib/blob/Blob.js', 'blob' $script 'lib/spin.js/spin.js', -> $script 'lib/ladda/ladda.min.js', -> $script.ready ['angular-loader'], -> $script 'lib/angular-ladda/angular-ladda.min.js', 'angular-ladda' $script.ready ['angular-loader'], -> angular.module 'omega', ['ngLocale', 'ngAnimate', 'ngSanitize', 'ui.bootstrap', 'ui.router', 'ngProgress', 'ui.sortable', 'angularSpectrumColorpicker', 'ui.validate', 'angular-ladda', 'omegaTarget', 'omegaDecoration'] $script.ready ['omega-pac'], -> $script 'js/omega.js', 'omega' $script([ 'js/omega_target_web.js' 'js/omega_decoration.js' 'lib/angular-animate/angular-animate.min.js' 'lib/angular-bootstrap/ui-bootstrap-tpls.min.js' 'lib/ngprogress/ngProgress.min.js' 'lib/angular-ui-sortable/sortable.min.js' 'lib/angular-ui-utils/validate.min.js' 'lib/jsondiffpatch/jsondiffpatch.min.js' 'lib/angular-spectrum-colorpicker/angular-spectrum-colorpicker.min.js' ], 'omega-deps') $script.ready ['jquery'], -> $script 'lib/jquery-ui-1.10.4.custom.min.js', 'jquery-ui-base' $script 'lib/spectrum/spectrum.js', 'spectrum' $script.ready ['jquery-ui-base'], -> $script 'lib/jqueryui-touch-punch/jquery.ui.touch-punch.min.js', 'jquery-ui' $script.ready ['angular-loader', 'jquery'], -> $script 'lib/angular/angular.min.js', 'angular' $script.ready ['angular'], -> $script 'lib/angular-ui-router/angular-ui-router.min.js', 'angular-ui-router' $script 'lib/angular-sanitize/angular-sanitize.min.js', 'angular-sanitize' locales = '': 'en-us' 'en': 'en-us' 'zh': 'zh-cn' 'zh-hans': 'zh-cn' 'zh-hant': 'zh-tw' 'zh-cn': 'zh-cn' 'zh-hk': 'zh-hk' 'zh-tw': 'zh-tw' lang = navigator.language lang1 = navigator.language?.split('-')[0] || '' locale = locales[lang] || locales[lang1] || locales[''] $script 'lib/angular-i18n/angular-locale_' + locale + '.js', 'angular-i18n' $script.ready ['angular', 'omega', 'omega-deps', 'angular-ui-router', 'jquery-ui', 'spectrum', 'filesaver', 'blob', 'angular-ladda', 'angular-sanitize', 'angular-i18n'], -> angular.bootstrap document, ['omega'] ================================================ FILE: omega-web/src/coffee/options_guide.coffee ================================================ $script 'lib/tether/tether.js', -> $script 'lib/shepherd.js/shepherd.min.js', -> tr = chrome.i18n.getMessage.bind(chrome.i18n) tour = new Shepherd.Tour defaults: classes: 'shepherd-theme-arrows' scrollTo: true targetAnchorClick = selector: '.shepherd-target a' event: 'click' tour.addStep('fixed-profile-step', text: tr('options_guide_fixedProfileStep') attachTo: '.nav-profile[data-profile-type="FixedProfile"] right' scrollTo: false advanceOn: targetAnchorClick buttons: [ text: tr('options_guideNext') action: tour.next ] ) tour.addStep 'fixed-servers-step', text: tr('options_guide_fixedServersStep') attachTo: '.fixed-servers top' scrollTo: false buttons: [ text: tr('options_guideNext') action: tour.next ] tour.addStep 'auto-switch-profile-step', text: tr('options_guide_autoSwitchProfileStep') attachTo: '.nav-profile[data-profile-type="SwitchProfile"] right' scrollTo: false advanceOn: targetAnchorClick buttons: [ text: tr('options_guideNext') action: tour.next ] tour.addStep 'add-more-profiles-step', text: tr('options_guide_addMoreProfilesStep') attachTo: '.nav-new-profile right' scrollTo: false advanceOn: targetAnchorClick buttons: [ text: tr('options_guideDone') action: tour.next ] tour.start() ================================================ FILE: omega-web/src/coffee/popup.coffee ================================================ module = angular.module('omegaPopup', ['omegaTarget', 'omegaDecoration', 'ui.bootstrap', 'ui.validate']) module.filter 'tr', (omegaTarget) -> omegaTarget.getMessage module.filter 'dispName', (omegaTarget) -> (name) -> if typeof name == 'object' name = name.name omegaTarget.getMessage('profile_' + name) || name moveUp = (activeIndex, items) -> i = activeIndex - 1 if i >= 0 items.eq(i)[0]?.focus() moveDown = (activeIndex, items) -> items.eq(activeIndex + 1)[0]?.focus() shortcutKeys = 38: moveUp # Up 40: moveDown # Down 74: moveDown # j 75: moveUp # k 48: '+direct' # 0 83: '+system' # s 191: 'help' # / 63: 'help' # ? 69: 'external' # e 65: 'addRule' # a 43: 'addRule' # + 61: 'addRule' # = 84: 'tempRule' # t 79: 'option' # o 82: 'requestInfo' # r for i in [1..9] shortcutKeys[48 + i] = i customProfiles = do -> _customProfiles = null return -> _customProfiles ?= jQuery('.custom-profile:not(.ng-hide) > a') jQuery(document).on 'keydown', (e) -> handler = shortcutKeys[e.keyCode] return unless handler return if e.target.tagName == 'INPUT' or e.target.tagName == 'TEXTAREA' switch typeof handler when 'string' switch handler when 'help' showHelp = (element, key) -> if typeof element == 'string' element = jQuery("a[data-shortcut='#{element}']") span = jQuery('.shortcut-help', element) if span.length == 0 span = jQuery('').addClass('shortcut-help') span.text(key) element.find('.glyphicon').after(span) keys = '+direct': '0' '+system': 'S' 'external': 'E' 'addRule': 'A' 'tempRule': 'T' 'option': 'O' 'requestInfo': 'R' for shortcut, key of keys showHelp(shortcut, key) customProfiles().each (i, el) -> if i <= 8 showHelp(jQuery(el), i + 1) else jQuery("a[data-shortcut='#{handler}']")[0]?.click() when 'number' customProfiles().eq(handler - 1)?.click() when 'function' items = jQuery('.popup-menu-nav > li:not(.ng-hide) > a') i = items.index(jQuery(e.target).closest('a')) if i == -1 i = items.index(jQuery('.popup-menu-nav > li.active > a')) handler(i, items) return false module.controller 'PopupCtrl', ($scope, $window, $q, omegaTarget, profileIcons, profileOrder, dispNameFilter, getVirtualTarget) -> $scope.closePopup = -> $window.close() $scope.openManage = -> omegaTarget.openManage() $window.close() refreshOnProfileChange = false refresh = -> if refreshOnProfileChange omegaTarget.refreshActivePage().then -> $window.close() else $window.close() $scope.profileIcons = profileIcons $scope.dispNameFilter = dispNameFilter $scope.isActive = (profileName) -> if $scope.isSystemProfile profileName == 'system' else $scope.currentProfileName == profileName $scope.isEffective = (profileName) -> $scope.isSystemProfile and $scope.currentProfileName == profileName $scope.getIcon = (profile, normal) -> return unless profile if not normal and $scope.isEffective(profile.name) 'glyphicon-ok' else undefined $scope.getProfileTitle = (profile, normal) -> desc = '' while profile desc = profile.desc profile = getVirtualTarget(profile, $scope.availableProfiles) desc || profile?.name || '' $scope.openOptions = (hash) -> omegaTarget.openOptions(hash).then -> $window.close() $scope.openConditionHelp = -> pname = encodeURIComponent($scope.currentProfileName) $scope.openOptions("#/profile/#{pname}?help=condition") $scope.applyProfile = (profile) -> next = -> if profile.profileType == 'SwitchProfile' return omegaTarget.state('web.switchGuide').then (switchGuide) -> if switchGuide == 'showOnFirstUse' return $scope.openOptions("#/profile/#{profile.name}") if not refreshOnProfileChange omegaTarget.applyProfileNoReply(profile.name) apply = next() else apply = omegaTarget.applyProfile(profile.name).then(-> return omegaTarget.refreshActivePage() ).then(next) if apply apply.then -> $window.close() else $window.close() $scope.tempRuleMenu = {open: false} $scope.nameExternal = {open: false} $scope.addTempRule = (domain, profileName) -> $scope.tempRuleMenu.open = false omegaTarget.addTempRule(domain, profileName).then -> omegaTarget.state('lastProfileNameForCondition', profileName) refresh() $scope.setDefaultProfile = (profileName, defaultProfileName) -> omegaTarget.setDefaultProfile(profileName, defaultProfileName).then -> refresh() $scope.addCondition = (condition, profileName) -> omegaTarget.addCondition(condition, profileName).then -> omegaTarget.state('lastProfileNameForCondition', profileName) refresh() $scope.addConditionForDomains = (domains, profileName) -> conditions = [] for own domain, enabled of domains when enabled conditions.push({ conditionType: 'HostWildcardCondition' pattern: domain }) omegaTarget.addCondition(conditions, profileName).then -> omegaTarget.state('lastProfileNameForCondition', profileName) refresh() $scope.validateProfileName = conflict: '!$value || !availableProfiles["+" + $value]' hidden: '!$value || $value[0] != "_"' $scope.saveExternal = -> $scope.nameExternal.open = false name = $scope.externalProfile.name if name omegaTarget.addProfile($scope.externalProfile).then -> omegaTarget.applyProfile(name).then -> refresh() $scope.returnToMenu = -> if location.hash.indexOf('!') >= 0 location.href = 'popup/index.html' return $scope.showConditionForm = false $scope.showRequestInfo = false preselectedProfileNameForCondition = 'direct' if $window.location.hash == '#!requestInfo' $scope.showRequestInfo = true else if $window.location.hash == '#!external' $scope.nameExternal = {open: true} omegaTarget.state([ 'availableProfiles', 'currentProfileName', 'isSystemProfile', 'validResultProfiles', 'refreshOnProfileChange', 'externalProfile', 'proxyNotControllable', 'lastProfileNameForCondition' ]).then ([availableProfiles, currentProfileName, isSystemProfile, validResultProfiles, refresh, externalProfile, proxyNotControllable, lastProfileNameForCondition]) -> $scope.proxyNotControllable = proxyNotControllable return if proxyNotControllable $scope.availableProfiles = availableProfiles $scope.currentProfile = availableProfiles['+' + currentProfileName] $scope.currentProfileName = currentProfileName $scope.isSystemProfile = isSystemProfile $scope.externalProfile = externalProfile refreshOnProfileChange = refresh charCodeUnderscore = '_'.charCodeAt(0) profilesByNames = (names) -> profiles = [] for name in names shown = (name.charCodeAt(0) != charCodeUnderscore or name.charCodeAt(1) != charCodeUnderscore) if shown profiles.push(availableProfiles['+' + name]) profiles $scope.validResultProfiles = profilesByNames(validResultProfiles) if lastProfileNameForCondition for profile in $scope.validResultProfiles if profile.name == lastProfileNameForCondition preselectedProfileNameForCondition = lastProfileNameForCondition $scope.builtinProfiles = [] $scope.customProfiles = [] for own key, profile of availableProfiles if profile.builtin $scope.builtinProfiles.push(profile) else if profile.name.charCodeAt(0) != charCodeUnderscore $scope.customProfiles.push(profile) if profile.validResultProfiles profile.validResultProfiles = profilesByNames(profile.validResultProfiles) $scope.customProfiles.sort(profileOrder) $scope.domainsForCondition = {} $scope.requestInfoProvided = null omegaTarget.setRequestInfoCallback (info) -> info.domains = [] for own domain, domainInfo of info.summary domainInfo.domain = domain info.domains.push(domainInfo) info.domains.sort (a, b) -> b.errorCount - a.errorCount $scope.$apply -> $scope.requestInfo = info $scope.requestInfoProvided ?= (info?.domains.length > 0) for domain in info.domains $scope.domainsForCondition[domain.domain] ?= true $scope.profileForDomains ?= preselectedProfileNameForCondition $q.all([ omegaTarget.state('currentProfileCanAddRule') omegaTarget.getActivePageInfo(), ]).then ([canAddRule, info]) -> $scope.currentProfileCanAddRule = canAddRule if info $scope.currentTempRuleProfile = info.tempRuleProfileName if $scope.currentTempRuleProfile preselectedProfileNameForCondition = $scope.currentTempRuleProfile $scope.currentDomain = info.domain if $window.location.hash == '#!addRule' $scope.prepareConditionForm() $scope.prepareConditionForm = -> currentDomain = $scope.currentDomain currentDomainEscaped = currentDomain.replace(/\./g, '\\.') domainLooksLikeIp = false if currentDomain.indexOf(':') >= 0 domainLooksLikeIp = true if currentDomain[0] != '[' currentDomain = '[' + currentDomain + ']' currentDomainEscaped = currentDomain.replace(/\./g, '\\.') .replace(/\[/g, '\\[').replace(/\]/g, '\\]') else if currentDomain[currentDomain.length - 1] >= 0 domainLooksLikeIp = true if domainLooksLikeIp conditionSuggestion = 'HostWildcardCondition': currentDomain 'HostRegexCondition': '^' + currentDomainEscaped + '$' 'UrlWildcardCondition': '*://' + currentDomain + '/*' 'UrlRegexCondition': '://' + currentDomainEscaped + '(:\\d+)?/' 'KeywordCondition': currentDomain else conditionSuggestion = 'HostWildcardCondition': '*.' + currentDomain 'HostRegexCondition': '(^|\\.)' + currentDomainEscaped + '$' 'UrlWildcardCondition': '*://*.' + currentDomain + '/*' 'UrlRegexCondition': '://([^/.]+\\.)*' + currentDomainEscaped + '(:\\d+)?/' 'KeywordCondition': currentDomain $scope.rule = condition: conditionType: 'HostWildcardCondition' pattern: conditionSuggestion['HostWildcardCondition'] profileName: preselectedProfileNameForCondition $scope.$watch 'rule.condition.conditionType', (type) -> $scope.rule.condition.pattern = conditionSuggestion[type] $scope.showConditionForm = true ================================================ FILE: omega-web/src/coffee/switch_profile_guide.coffee ================================================ $script 'lib/tether/tether.js', -> $script 'lib/shepherd.js/shepherd.min.js', -> return if jQuery('.switch-rule-row').length == 0 jQuery('html, body').scrollTop(0) tr = chrome.i18n.getMessage.bind(chrome.i18n) tour = new Shepherd.Tour defaults: classes: 'shepherd-theme-arrows' tour.addStep 'condition-step', text: tr('options_guide_conditionStep') attachTo: '.switch-rule-row bottom' buttons: [ { text: tr('options_guideSkip') action: tour.cancel classes: 'shepherd-button-secondary' } { text: tr('options_guideNext') action: tour.next } ] conditionTypeStep = tour.addStep('condition-type-step', text: tr('options_guide_conditionTypeStep') attachTo: '.condition-type-th bottom' advanceOn: selector: '.close-condition-help' event: 'click' buttons: [ text: tr('options_guideNext') action: tour.next ] ) conditionTypeStep.on 'show', -> jQuery('.toggle-condition-help').one 'click', -> return unless conditionTypeStep.isOpen() jQuery('.shepherd-step.shepherd-enabled').hide() jQuery('.toggle-condition-help, .close-condition-help').one 'click', -> tour.next() tour.addStep 'condition-profile-step', text: tr('options_guide_conditionProfileStep') attachTo: '.switch-rule-row-target bottom' buttons: [ text: tr('options_guideNext') action: tour.next ] defaultStep = tour.addStep 'switch-default-step', text: tr('options_guide_switchDefaultStep') attachTo: '.switch-default-row top' buttons: [ text: tr('options_guideNext') action: tour.next ] defaultStep.on 'show', -> row = jQuery('.switch-default-row') scrollTop = row.offset().top + row.height() - $(window).height() scrollTop = 0 if scrollTop < 0 jQuery('html, body').animate({scrollTop: scrollTop}) tour.addStep 'apply-switch-profile-step', text: tr('options_guide_applySwitchProfileStep') attachTo: 'body top' scrollTo: false classes: 'shepherd-theme-arrows fixed-top-right' buttons: [ text: tr('options_guideDone') action: tour.next ] Shepherd.activeTour?.cancel() tour.start() ================================================ FILE: omega-web/src/less/common.less ================================================ /* angular */ .ng-hide { display: none !important; } /* helpers */ .clear-padding { padding: 0 !important; } /* basic */ a[role="button"] { cursor: pointer; } .form-control.ng-invalid { border-color: #a94442; box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); &:hover { border-color: #843534; box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075),0 0 6px #CE8483; } } .disabled .btn { background-color: #ddd !important; border-color: #ccc !important; cursor: not-allowed !important; pointer-events: none !important; opacity: .65 !important; box-shadow: none !important; } /* profile */ .virtual-profile-icon { border: dotted 1px; margin: -1px; } .profile-inline { background-color: #eee; color: #333; padding: 0 5px; } /* omega-profile-select */ .omega-profile-select { width: 100%; .dropdown-menu>li>a { max-width: none !important; } .btn { width: 100%; display: block; text-align: left; text-align: initial; position: relative; padding-right: 25px; .caret { position: absolute; top: 50%; right: 12px; margin-top: -2px; vertical-align: middle; } } .dropdown-menu { width: 100%; cursor: pointer; } } .monospace { font-family: Menlo,Monaco,Consolas,"Courier New",monospace !important; } ================================================ FILE: omega-web/src/less/options.less ================================================ @import 'common.less'; .width-initial { width: auto !important; width: initial !important; } .width-limit { max-width: 600px; } textarea.width-limit { max-width: 80%; } .width-limit-lg { max-width: 800px; } .width-limit-xl { max-width: 1000px; } .inline-form-control { display: inline-block; margin-right: 20px; margin-left: 20px; min-width: 50%; width: 50% !important; width: initial !important; } .no-min-width { min-width: 0 !important; } .align-initial { text-align: left; text-align: initial; } .opacity-half { opacity: .5 !important; } .opacity-0 { opacity: 0 !important; } ul.list-style-none, li.list-style-none { list-style: none; padding-left: 0; } .help-inline { margin-left: 10px; color: #595959; } .settings-group { > * { margin-left: 30px; } > h3 { margin-left: 0; } } /* shepherd.js */ .shepherd-element { z-index: 20; } .shepherd-active { &:before { content: " "; position: fixed; top: 0; bottom: 0; left: 0; right: 0; background-color: rgba(0, 0, 0, .5); z-index: 10; } .switch-rules { position: relative; background-color: #7f7f7f; z-index: 11; &, th, td, tbody { border-color: #6e6e6e !important; } .btn { opacity: .5; } .form-control, .btn-default { background-color: #7f7f7f; border-color: #6e6e6e; opacity: 1; } .shepherd-enabled { background-color: #fff; border-color: #ddd !important; &, td, tbody { border-color: #ddd !important; } .btn { opacity: 1; } .form-control, .btn-default { background-color: #fff; border-color: #ddd; } } } .condition-help-section { position: relative; z-index: 11; background-color: #fff; } &:not([data-shepherd-step="fixed-servers-step"]) { .side-nav { position: absolute; overflow: visible; bottom: 0; } .shepherd-enabled > a { color: #428bca; background-color: #fff; } } &[data-shepherd-step="switch-default-step"] { .sort-bar { position: relative; z-index: 11; background-color: #ffc; } } } .shepherd-enabled { position: relative; z-index: 11; &.fixed-servers { background-color: #fff; } } .fixed-top-right { position: fixed !important; top: 0 !important; right: 0 !important; left: auto !important; bottom: auto !important; transform: none !important; } /* alert */ .alert-top-wrapper { z-index: 100; position: fixed; top: 0; left: 0; right: 0; width: 100%; display: inline-block !important; transition: transform .5s, opacity .5s; transition: transform cubic-bezier(0.19, 1, 0.22, 1) .5s, opacity cubic-bezier(0.19, 1, 0.22, 1) .5s; &.ng-hide { transform: translateY(-100%); opacity: 0; } pointer-events: none; text-align: center; * { pointer-events: auto; pointer-events: initial; .align-initial(); } .alert { display: inline-block; min-width: 400px; margin-bottom: 0; @media (max-width: 767px) { min-width: 80%; } } } /* body */ html { height: 100%; } body { min-height: 100%; } .modal-backdrop { position: fixed; bottom: 0; } h1 { color: #5c6166; font-size: 1.7em; font-weight: bold; margin-bottom: 1.5em; } .side-nav { position: fixed; height: 100%; overflow: auto; @media (max-width: 767px) { position: static; height: auto; height: initial; } .nav-pills { > li > a { padding: 8px 15px; @media (max-height: 767px) { padding: 5px 15px; } &.btn-success:hover { // Fix hover style of [Apply changes] when highlighted. color: #fff; background-color: #449d44; border-color: #398439; } } } } main { padding-top: 85px; padding-bottom: 20px; .page-header { margin: 0; padding: 20px 60px 20px 0; position: fixed; top: 0; width: inherit; background-color: rgba(255, 255, 255, 0.6); background-image: linear-gradient(to bottom, rgba(255, 255, 255, 1), rgba(255, 255, 255, 0.6)); max-height: 85px; z-index: 3; h2 { margin: 0; } } @media (max-width: 767px) { padding-top: 0; .page-header { position: static; max-height: none; } } .ng-enter { opacity: 0; transition: opacity .5s; } .ng-enter-active { opacity: 1; } } #ngProgress-container { position: fixed; top: 0; width: 100%; } .divider { height: 1px; margin: 9px 1px; overflow: hidden; background-color: #e5e5e5; } .nav-header { margin-right: -15px !important; margin-left: -15px !important; text-shadow: 0 1px 0 rgba(255,255,255,0.5); 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; } #restore-local-file { position: absolute; visibility: hidden; } .virtual-profile-icon { border: dotted 1px; margin: -1px; } .profile-actions { float: right; } .profile-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .profile-color-editor { display: inline-block; float: left; margin-right: 10px; input[type="color"] { height: 30px; width: 30px; padding: 0; border: none; background: none; &::-webkit-color-swatch-wrapper { padding: 0; } } .sp-replacer { padding: 0; border: none; } .sp-preview, .profile-color-editor-fake { margin-right: 0; height: 30px; width: 30px; border: solid 1px #222; } .sp-dd { display: none; } } @media (min-width: 768px) { // Try to workaround the issue where dropdown menus in the table are clipped. // .table-responsive sets overflow-x, which causes the issue. Just setting // overflow-y: visible will NOT work. Scrolling must be disabled for X & Y. // See: http://stackoverflow.com/a/6433475 .table-responsive { overflow: visible; } } @media (max-width: 767px) { // Try to make sure that the dropdown fits in the table-responsive scroll box. // It effectively inlines the whole dropdown menu. Ugly, but at least working. .table-responsive .dropdown-menu { position: static !important; } } .fixed-servers, .switch-rules { td { vertical-align: middle !important; } } .condition-help { dl { margin-left: 5px; padding-left: 10px; border-left: solid 1px #ccc; } dt { font-size: 1.2em; } dd { padding-left: 20px; } } .close-condition-help { float: none !important; margin-left: 15px !important; opacity: 1 !important; &:hover, &:active { color: #444 !important; } } .switch-attached { > tr > td { background-color: #f9f9f9; .shepherd-active & { background-color: transparent; } &:first-child { text-align: center; } } } .fixed-show-advanced { td { background-color: transparent !important; } .btn-link { padding: 0; } } .proxy-actions { text-align: center; padding: 0 !important; } .proxy-auth-toggle { padding: 5px 7px !important; } .host-levels-details { input { .width-initial(); display: inline-block; } } .sort-bar { width: 1em; text-align: center; cursor: move; } .switch-rule-row td.has-icon { > .form-control { display: inline-block; width: ~"calc(100% - 1.5em)"; } > .icon-wrapper { display: block; float: right; line-height: 34px; } } .cycle-profile-container { list-style-type: none; min-height: 20px; display: inline-block; min-width: 40%; padding: 0; border: solid 1px #abc; li { display: block; margin: 10px; padding: 5px; cursor: move; background-color: #ddd; } &.cycle-enabled li { background-color: #e4ffcd; } } .modal-body .well:last-child { margin-bottom: 0; } ================================================ FILE: omega-web/src/less/popup.less ================================================ @import 'common.less'; /* popup */ body { margin: 0; padding: 0; min-width: 180px; } body.with-condition-form { } .condition-form { min-width: 360px; } .nav { margin-bottom: 0; } li > a { text-overflow: ellipsis; overflow: hidden; max-width: 20em; } .shortcut-help { .monospace(); border: solid 1px #000; border-radius: 2px; display: inline-block; color: #000; box-shadow: 1px 1px; width: 1em; height: 1em; line-height: 1em; text-align: center; margin-top: -3px; } .nav-pills.nav-stacked { > li > a { padding: 5px 25px 5px 8px; white-space: nowrap; cursor: pointer; .glyphicon { margin-right: 6px; } &.profile-with-default-edit { padding-right: 32px; position: relative; .dropdown-toggle { margin: -5px 0; color: inherit; padding: 5px 8px 3px; min-width: 20px; position: absolute; right: 0; .glyphicon { margin-right: 0; } } } } > li.active .dropdown-toggle { border-color: transparent !important; border-left: solid 1px !important; background: none !important; border-radius: 0 !important; } } .divider { height: 1px; overflow: hidden; background-color: #E5E5E5; } .temp-rule a { padding-left: 8px !important; box-shadow: none !important; } li .dropdown-menu { position: static; top: initial; top: -moz-initial; margin: 0 5px !important; float: none; a { cursor: pointer; } } .current-domain { color: #08C; } select, textarea, input { margin-bottom: 0px !important; } form { margin: 10px; } legend, .well { margin-bottom: 10px; } .well { padding: 10px; } .condition-controls, .proxy-not-controllable-controls { .btn-primary { float: right; } } .external-profile { a { padding-right: 10px !important; } form { margin: 0; padding: 0; display: inline-block; } .form-control { display: inline-block; padding: 0; height: 2em; width: ~"calc(100% - 1em - 8px)"; } } .proxy-not-controllable { min-width: 400px; padding: 10px 10px; .proxy-not-controllable-controls { margin-bottom: 0; } } .request-info-details { min-width: 360px; } ================================================ FILE: omega-web/src/omega/app.coffee ================================================ angular.module('omega').constant('builtinProfiles', OmegaPac.Profiles.builtinProfiles) profileColors = [ '#9ce', '#9d9', '#fa8', '#fe9', '#d497ee', '#47b', '#5b5', '#d63', '#ca0' ] colors = [].concat(profileColors) profileColorPalette = (colors.splice(0, 3) while colors.length) angular.module('omega').constant('profileColors', profileColors) angular.module('omega').constant('profileColorPalette', profileColorPalette) attachedPrefix = '__ruleListOf_' angular.module('omega').constant 'getAttachedName', (name) -> attachedPrefix + name angular.module('omega').constant 'getParentName', (name) -> if name.indexOf(attachedPrefix) == 0 name.substr(attachedPrefix.length) else undefined charCodeUnderscore = '_'.charCodeAt(0) angular.module('omega').constant 'charCodeUnderscore', charCodeUnderscore angular.module('omega').constant 'isProfileNameHidden', (name) -> # Hide profiles beginning with underscore. name.charCodeAt(0) == charCodeUnderscore angular.module('omega').constant 'isProfileNameReserved', (name) -> # Reserve profile names beginning with double-underscore. (name.charCodeAt(0) == charCodeUnderscore and name.charCodeAt(1) == charCodeUnderscore) angular.module('omega').config ($stateProvider, $urlRouterProvider, $httpProvider, $animateProvider, $compileProvider) -> $compileProvider.aHrefSanitizationWhitelist( /^\s*(https?|ftp|mailto|chrome-extension|moz-extension):/) $compileProvider.imgSrcSanitizationWhitelist( /^\s*(https?|local|data|chrome-extension|moz-extension):/) $animateProvider.classNameFilter(/angular-animate/) $urlRouterProvider.otherwise '/about' $urlRouterProvider.otherwise ($injector, $location) -> if $location.path() == '' $injector.get('omegaTarget').lastUrl() || '/about' else '/about' $stateProvider .state('ui', url: '/ui' templateUrl: 'partials/ui.html' #controller: 'UiCtrl' ).state('general', url: '/general' templateUrl: 'partials/general.html' #controller: 'GeneralCtrl' ).state('io', url: '/io' templateUrl: 'partials/io.html' controller: 'IoCtrl' ).state('profile', url: '/profile/*name' templateUrl: 'partials/profile.html' controller: 'ProfileCtrl' ).state('about', url: '/about' templateUrl: 'partials/about.html' controller: 'AboutCtrl' ) angular.module('omega').factory '$exceptionHandler', ($log) -> return (exception, cause) -> return if exception.message == 'transition aborted' return if exception.message == 'transition superseded' return if exception.message == 'transition prevented' return if exception.message == 'transition failed' $log.error(exception, cause) angular.module('omega').factory 'omegaDebug', ($window, $rootScope, $injector) -> omegaDebug = $window.OmegaDebug ? {} omegaDebug.downloadLog ?= -> downloadFile = $injector.get('downloadFile') ? saveAs blob = new Blob [localStorage['log']], {type: "text/plain;charset=utf-8"} downloadFile(blob, "OmegaLog_#{Date.now()}.txt") omegaDebug.reportIssue ?= -> $window.open( 'https://github.com/FelisCatus/SwitchyOmega/issues/new?title=&body=') return omegaDebug.resetOptions ?= -> $rootScope.resetOptions() omegaDebug angular.module('omega').factory 'downloadFile', -> if browser?.downloads?.download? return (blob, filename) -> url = URL.createObjectURL(blob) if filename browser.downloads.download({url: url, filename: filename}) else browser.downloads.download({url: url}) else return (blob, filename) -> noAutoBom = true saveAs(blob, filename, noAutoBom) ================================================ FILE: omega-web/src/omega/controllers/about.coffee ================================================ angular.module('omega').controller 'AboutCtrl', ($scope, $rootScope, $modal, omegaDebug) -> $scope.downloadLog = omegaDebug.downloadLog $scope.reportIssue = omegaDebug.reportIssue $scope.showResetOptionsModal = -> $modal.open(templateUrl: 'partials/reset_options_confirm.html').result .then -> omegaDebug.resetOptions() try $scope.version = omegaDebug.getProjectVersion() catch _ $scope.version = '?.?.?' ================================================ FILE: omega-web/src/omega/controllers/fixed_profile.coffee ================================================ angular.module('omega').controller 'FixedProfileCtrl', ($scope, $modal, trFilter) -> $scope.urlSchemes = ['', 'http', 'https', 'ftp'] $scope.urlSchemeDefault = 'fallbackProxy' proxyProperties = '': 'fallbackProxy' 'http': 'proxyForHttp' 'https': 'proxyForHttps' 'ftp': 'proxyForFtp' $scope.schemeDisp = '': null 'http': 'http://' 'https': 'https://' 'ftp': 'ftp://' defaultPort = 'http': 80 'https': 443 'socks4': 1080 'socks5': 1080 $scope.showAdvanced = false $scope.optionsForScheme = {} for scheme in $scope.urlSchemes defaultLabel = if scheme trFilter('options_protocol_useDefault') else trFilter('options_protocol_direct') $scope.optionsForScheme[scheme] = [ {label: defaultLabel, value: undefined}, {label: 'HTTP', value: 'http'}, {label: 'HTTPS', value: 'https'}, {label: 'SOCKS4', value: 'socks4'}, {label: 'SOCKS5', value: 'socks5'}, ] $scope.proxyEditors = {} socks5AuthSupported = (browser?.proxy?.register?) $scope.authSupported = { "http": true, "https": true, "socks5": socks5AuthSupported, } $scope.isProxyAuthActive = (scheme) -> return $scope.profile.auth?[proxyProperties[scheme]]? $scope.editProxyAuth = (scheme) -> prop = proxyProperties[scheme] proxy = $scope.profile[prop] scope = $scope.$new('isolate') scope.proxy = proxy auth = $scope.profile.auth?[prop] scope.auth = auth && angular.copy(auth) scope.authSupported = $scope.authSupported[proxy.scheme] scope.protocolDisp = proxy.scheme $modal.open( templateUrl: 'partials/fixed_auth_edit.html' scope: scope size: if scope.authSupported then 'sm' else 'lg' ).result.then (auth) -> if not auth?.username if $scope.profile.auth $scope.profile.auth[prop] = undefined else $scope.profile.auth ?= {} $scope.profile.auth[prop] = auth onProxyChange = (proxyEditors, oldProxyEditors) -> return unless proxyEditors for scheme in $scope.urlSchemes proxy = proxyEditors[scheme] if $scope.profile.auth and not $scope.authSupported[proxy.scheme] delete $scope.profile.auth[proxyProperties[scheme]] if not proxy.scheme if not scheme proxyEditors[scheme] = {} delete $scope.profile[proxyProperties[scheme]] continue else if not oldProxyEditors[scheme].scheme if proxy.scheme == proxyEditors[''].scheme proxy.port ?= proxyEditors[''].port proxy.port ?= defaultPort[proxy.scheme] proxy.host ?= proxyEditors[''].host ? 'example.com' $scope.profile[proxyProperties[scheme]] ?= proxy for scheme in $scope.urlSchemes do (scheme) -> $scope.$watch (-> $scope.profile[proxyProperties[scheme]]), (proxy) -> if scheme and proxy $scope.showAdvanced = true $scope.proxyEditors[scheme] = proxy ? {} $scope.$watch 'proxyEditors', onProxyChange, true onBypassListChange = (list) -> $scope.bypassList = (item.pattern for item in list).join('\n') $scope.$watch 'profile.bypassList', onBypassListChange, true $scope.$watch 'bypassList', (bypassList, oldList) -> return if not bypassList? or bypassList == oldList $scope.profile.bypassList = for entry in bypassList.split(/\r?\n/) when entry conditionType: "BypassCondition" pattern: entry ================================================ FILE: omega-web/src/omega/controllers/io.coffee ================================================ angular.module('omega').controller 'IoCtrl', ($scope, $rootScope, $window, $http, omegaTarget, downloadFile) -> omegaTarget.state('web.restoreOnlineUrl').then (url) -> if url $scope.restoreOnlineUrl = url $scope.exportOptions = -> $rootScope.applyOptionsConfirm().then -> plainOptions = angular.fromJson(angular.toJson($rootScope.options)) content = JSON.stringify(plainOptions) blob = new Blob [content], {type: "text/plain;charset=utf-8"} downloadFile(blob, "OmegaOptions.bak") $scope.importSuccess = -> $rootScope.showAlert( type: 'success' i18n: 'options_importSuccess' message: 'Options imported.' ) $scope.restoreLocal = (content) -> $scope.restoringLocal = true $rootScope.resetOptions(content).then(( -> $scope.importSuccess() ), -> $scope.restoreLocalError()).finally -> $scope.restoringLocal = false $scope.restoreLocalError = -> $rootScope.showAlert( type: 'error' i18n: 'options_importFormatError' message: 'Invalid backup file!' ) $scope.downloadError = -> $rootScope.showAlert( type: 'error' i18n: 'options_importDownloadError' message: 'Error downloading backup file!' ) $scope.triggerFileInput = -> angular.element('#restore-local-file').click() return $scope.restoreOnline = -> omegaTarget.state('web.restoreOnlineUrl', $scope.restoreOnlineUrl) $scope.restoringOnline = true $http( method: 'GET' url: $scope.restoreOnlineUrl cache: false timeout: 10000 responseType: "text" ).then(((result) -> $rootScope.resetOptions(result.data).then (-> $scope.importSuccess() ), -> $scope.restoreLocalError() ), $scope.downloadError).finally -> $scope.restoringOnline = false $scope.enableOptionsSync = (args) -> enable = -> omegaTarget.setOptionsSync(true, args).finally -> $window.location.reload() if args?.force enable() else $rootScope.applyOptionsConfirm().then enable $scope.disableOptionsSync = -> omegaTarget.setOptionsSync(false).then -> $rootScope.applyOptionsConfirm().then -> $window.location.reload() $scope.resetOptionsSync = -> omegaTarget.resetOptionsSync().then -> $rootScope.applyOptionsConfirm().then -> $window.location.reload() ================================================ FILE: omega-web/src/omega/controllers/master.coffee ================================================ angular.module('omega').controller 'MasterCtrl', ($scope, $rootScope, $window, $q, $modal, $state, profileColors, profileIcons, omegaTarget, $timeout, $location, $filter, getAttachedName, isProfileNameReserved, isProfileNameHidden, dispNameFilter, downloadFile) -> if browser?.proxy?.register? or browser?.proxy?.registerProxyScript? $scope.isExperimental = true $scope.pacProfilesUnsupported = true tr = $filter('tr') $rootScope.options = null omegaTarget.addOptionsChangeCallback (newOptions) -> $rootScope.options = angular.copy(newOptions) $rootScope.optionsOld = angular.copy(newOptions) omegaTarget.state('syncOptions').then (syncOptions) -> $scope.syncOptions = syncOptions $timeout -> $rootScope.optionsDirty = false showFirstRun() $rootScope.revertOptions = -> $window.location.reload() $rootScope.exportScript = (name) -> getProfileName = if name $q.when(name) else omegaTarget.state('currentProfileName') getProfileName.then (profileName) -> return unless profileName profile = $rootScope.profileByName(profileName) return if profile.profileType in ['DirectProfile', 'SystemProfile'] missingProfile = null profileNotFound = (name) -> missingProfile = name return 'dumb' ast = OmegaPac.PacGenerator.script($rootScope.options, profileName, profileNotFound: profileNotFound) pac = ast.print_to_string(beautify: true, comments: true) pac = OmegaPac.PacGenerator.ascii(pac) blob = new Blob [pac], {type: "text/plain;charset=utf-8"} fileName = profileName.replace(/\W+/g, '_') downloadFile(blob, "OmegaProfile_#{fileName}.pac") if missingProfile $timeout -> $rootScope.showAlert( type: 'error' message: tr('options_profileNotFound', [missingProfile]) ) diff = jsondiffpatch.create( objectHash: (obj) -> JSON.stringify(obj) textDiff: minLength: 1 / 0 ) $rootScope.showAlert = (alert) -> $timeout -> $scope.alert = alert $scope.alertShown = true $scope.alertShownAt = Date.now() $timeout $rootScope.hideAlert, 3000 return $rootScope.hideAlert = -> $timeout -> if Date.now() - $scope.alertShownAt >= 1000 $scope.alertShown = false checkFormValid = -> fields = angular.element('.ng-invalid') if fields.length > 0 fields[0].focus() $rootScope.showAlert( type: 'error' i18n: 'options_formInvalid' ) return false return true $rootScope.applyOptions = -> return unless checkFormValid() return if $rootScope.$broadcast('omegaApplyOptions').defaultPrevented plainOptions = angular.fromJson(angular.toJson($rootScope.options)) patch = diff.diff($rootScope.optionsOld, plainOptions) omegaTarget.optionsPatch(patch).then -> $rootScope.showAlert( type: 'success' i18n: 'options_saveSuccess' ) $rootScope.resetOptions = (options) -> omegaTarget.resetOptions(options).then(-> $rootScope.showAlert( type: 'success' i18n: 'options_resetSuccess' ) ).catch (err) -> $rootScope.showAlert( type: 'error' message: err ) $q.reject err $rootScope.profileByName = (name) -> OmegaPac.Profiles.byName(name, $rootScope.options) $rootScope.systemProfile = $rootScope.profileByName('system') $rootScope.externalProfile = color: '#49afcd' name: tr('popup_externalProfile') profileType: 'FixedProfile' fallbackProxy: {host: "127.0.0.1", port: 42, scheme: "http"} $rootScope.applyOptionsConfirm = -> return $q.reject 'form_invalid' unless checkFormValid() return $q.when(true) unless $rootScope.optionsDirty $modal.open(templateUrl: 'partials/apply_options_confirm.html').result .then -> $rootScope.applyOptions() $rootScope.newProfile = -> scope = $rootScope.$new('isolate') scope.options = $rootScope.options scope.isProfileNameReserved = isProfileNameReserved scope.isProfileNameHidden = isProfileNameHidden scope.profileByName = $rootScope.profileByName scope.validateProfileName = conflict: '!$value || !profileByName($value)' reserved: '!$value || !isProfileNameReserved($value)' scope.profileIcons = profileIcons scope.dispNameFilter = dispNameFilter scope.options = $scope.options scope.pacProfilesUnsupported = $scope.pacProfilesUnsupported $modal.open( templateUrl: 'partials/new_profile.html' scope: scope ).result.then (profile) -> profile = OmegaPac.Profiles.create(profile) choice = Math.floor(Math.random() * profileColors.length) profile.color ?= profileColors[choice] OmegaPac.Profiles.updateRevision(profile) $rootScope.options[OmegaPac.Profiles.nameAsKey(profile)] = profile $state.go('profile', {name: profile.name}) $rootScope.replaceProfile = (fromName, toName) -> $rootScope.applyOptionsConfirm().then -> scope = $rootScope.$new('isolate') scope.options = $rootScope.options scope.fromName = fromName scope.toName = toName scope.profileByName = $rootScope.profileByName scope.dispNameFilter = dispNameFilter scope.options = $scope.options scope.profileSelect = (model) -> """
""" $modal.open( templateUrl: 'partials/replace_profile.html' scope: scope ).result.then ({fromName, toName}) -> omegaTarget.replaceRef(fromName, toName).then(-> $rootScope.showAlert( type: 'success' i18n: 'options_replaceProfileSuccess' ) ).catch (err) -> $rootScope.showAlert( type: 'error' message: err ) $rootScope.renameProfile = (fromName) -> $rootScope.applyOptionsConfirm().then -> profile = $rootScope.profileByName(fromName) scope = $rootScope.$new('isolate') scope.options = $rootScope.options scope.fromName = fromName scope.isProfileNameReserved = isProfileNameReserved scope.isProfileNameHidden = isProfileNameHidden scope.profileByName = $rootScope.profileByName scope.validateProfileName = conflict: '!$value || $value == fromName || !profileByName($value)' reserved: '!$value || !isProfileNameReserved($value)' scope.dispNameFilter = $scope.dispNameFilter scope.options = $scope.options $modal.open( templateUrl: 'partials/rename_profile.html' scope: scope ).result.then (toName) -> if toName != fromName rename = omegaTarget.renameProfile(fromName, toName) attachedName = getAttachedName(fromName) if $rootScope.profileByName(attachedName) toAttachedName = getAttachedName(toName) defaultProfileName = undefined if $rootScope.profileByName(toAttachedName) defaultProfileName = profile.defaultProfileName rename = rename.then -> toAttachedKey = OmegaPac.Profiles.nameAsKey(toAttachedName) profile = $rootScope.profileByName(toName) profile.defaultProfileName = 'direct' OmegaPac.Profiles.updateRevision(profile) delete $rootScope.options[toAttachedKey] $rootScope.applyOptions() rename = rename.then -> omegaTarget.renameProfile(attachedName, toAttachedName) if defaultProfileName rename = rename.then -> profile = $rootScope.profileByName(toName) profile.defaultProfileName = defaultProfileName $rootScope.applyOptions() rename.then(-> $state.go('profile', {name: toName}) ).catch (err) -> $rootScope.showAlert( type: 'error' message: err ) $scope.updatingProfile = {} $rootScope.updateProfile = (name) -> $rootScope.applyOptionsConfirm().then(-> if name? $scope.updatingProfile[name] = true else OmegaPac.Profiles.each $scope.options, (key, profile) -> if not profile.builtin $scope.updatingProfile[profile.name] = true omegaTarget.updateProfile(name, 'bypass_cache').then((results) -> success = 0 error = 0 for own profileName, result of results if result instanceof Error error++ else success++ if error == 0 $rootScope.showAlert( type: 'success' i18n: 'options_profileDownloadSuccess' ) else if error == 1 singleErr = results[OmegaPac.Profiles.nameAsKey(name)] if singleErr return $q.reject(singleErr) return $q.reject(results) ).catch((err) -> message = tr('options_profileDownloadError_' + err.name, [err.statusCode ? err.original?.statusCode ? '']) if message $rootScope.showAlert( type: 'error' message: message ) else $rootScope.showAlert( type: 'error' i18n: 'options_profileDownloadError' ) ).finally -> if name? $scope.updatingProfile[name] = false else $scope.updatingProfile = {} ) onOptionChange = (options, oldOptions) -> return if options == oldOptions or not oldOptions? $rootScope.optionsDirty = true $rootScope.$watch 'options', onOptionChange, true $rootScope.$on '$stateChangeStart', (event, _, __, fromState) -> if not checkFormValid() event.preventDefault() $rootScope.$on '$stateChangeSuccess', -> omegaTarget.lastUrl($location.url()) $window.onbeforeunload = -> if $rootScope.optionsDirty return tr('options_optionsNotSaved') else null document.addEventListener 'click', (-> $rootScope.hideAlert() ), false $scope.profileIcons = profileIcons $scope.dispNameFilter = dispNameFilter for own type of OmegaPac.Profiles.formatByType $scope.profileIcons[type] = $scope.profileIcons['RuleListProfile'] $scope.alertIcons = 'success': 'glyphicon-ok', 'warning': 'glyphicon-warning-sign', 'error': 'glyphicon-remove', 'danger': 'glyphicon-danger', $scope.alertClassForType = (type) -> return '' if not type if type == 'error' type = 'danger' return 'alert-' + type $scope.downloadIntervals = [15, 60, 180, 360, 720, 1440, -1] $scope.downloadIntervalI18n = (interval) -> "options_downloadInterval_" + (if interval < 0 then "never" else interval) $scope.openShortcutConfig = omegaTarget.openShortcutConfig.bind(omegaTarget) showFirstRunOnce = true showFirstRun = -> return unless showFirstRunOnce showFirstRunOnce = false omegaTarget.state('firstRun').then (firstRun) -> return unless firstRun omegaTarget.state('firstRun', '') profileName = null OmegaPac.Profiles.each $rootScope.options, (key, profile) -> if not profileName and profile.profileType == 'FixedProfile' profileName = profile.name return unless profileName scope = $rootScope.$new('isolate') scope.upgrade = (firstRun == 'upgrade') $modal.open( templateUrl: 'partials/options_welcome.html' keyboard: false scope: scope backdrop: 'static' backdropClass: 'opacity-half' ).result.then (r) -> switch r when 'later' return when 'show' $state.go('profile', {name: profileName}).then -> $script 'js/options_guide.js' omegaTarget.refresh() ================================================ FILE: omega-web/src/omega/controllers/pac_profile.coffee ================================================ angular.module('omega').controller 'PacProfileCtrl', ($scope, $modal) -> # coffeelint: disable=max_line_length # https://github.com/angular/angular.js/blob/master/src/ng/directive/input.js#L13 $scope.urlRegex = /^(ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?$/ # With the file: scheme added to the pattern: $scope.urlWithFile = /^(ftp|http|https|file):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?$/ # coffeelint: enable=max_line_length $scope.isFileUrl = OmegaPac.Profiles.isFileUrl $scope.pacUrlCtrl = {ctrl: null} set = OmegaPac.Profiles.referencedBySet($scope.profile, $scope.options) $scope.referenced = Object.keys(set).length > 0 oldPacUrl = null oldLastUpdate = null oldPacScript = null onProfileChange = (profile, oldProfile) -> return unless profile and oldProfile if profile.pacUrl != oldProfile.pacUrl if profile.lastUpdate oldPacUrl = oldProfile.pacUrl oldLastUpdate = profile.lastUpdate oldPacScript = oldProfile.pacScript profile.lastUpdate = null else if oldPacUrl and profile.pacUrl == oldPacUrl profile.lastUpdate = oldLastUpdate profile.pacScript = oldPacScript $scope.pacUrlIsFile = $scope.isFileUrl(profile.pacUrl) $scope.$watch 'profile', onProfileChange, true $scope.editProxyAuth = (scheme) -> prop = 'all' auth = $scope.profile.auth?[prop] scope = $scope.$new('isolate') scope.auth = auth && angular.copy(auth) $modal.open( templateUrl: 'partials/fixed_auth_edit.html' scope: scope size: 'sm' ).result.then (auth) -> if not auth?.username if $scope.profile.auth $scope.profile.auth[prop] = undefined else $scope.profile.auth ?= {} $scope.profile.auth[prop] = auth ================================================ FILE: omega-web/src/omega/controllers/profile.coffee ================================================ angular.module('omega').controller 'ProfileCtrl', ($scope, $stateParams, $location, $rootScope, $timeout, $state, $modal, profileColorPalette, getAttachedName, getParentName, getVirtualTarget) -> name = $stateParams.name profileTemplates = 'FixedProfile': 'profile_fixed.html' 'PacProfile': 'profile_pac.html' 'VirtualProfile': 'profile_virtual.html' 'SwitchProfile': 'profile_switch.html' 'RuleListProfile': 'profile_rule_list.html' $scope.spectrumOptions = localStorageKey: 'spectrum.profileColor' palette: profileColorPalette preferredFormat: 'hex' showButtons: false showInitial: true showInput: true showPalette: true showSelectionPalette: true maxSelectionSize: 5 $scope.getProfileColor = -> color = undefined profile = $scope.profile while profile color = profile.color profile = getVirtualTarget(profile, $scope.options) color $scope.deleteProfile = -> profileName = $scope.profile.name refs = OmegaPac.Profiles.referencedBySet(profileName, $rootScope.options) scope = $rootScope.$new('isolate') scope.profile = $scope.profile scope.dispNameFilter = $scope.dispNameFilter scope.options = $scope.options if Object.keys(refs).length > 0 refSet = {} for own key, pname of refs parent = getParentName(pname) if parent key = OmegaPac.Profiles.nameAsKey(parent) pname = parent refSet[key] = pname refProfiles = [] for own key of refSet refProfiles.push(OmegaPac.Profiles.byKey(key, $rootScope.options)) scope.refs = refProfiles $modal.open( templateUrl: 'partials/cannot_delete_profile.html' scope: scope ) return else $modal.open( templateUrl: 'partials/delete_profile.html' scope: scope ).result.then -> attachedName = getAttachedName(profileName) delete $rootScope.options[OmegaPac.Profiles.nameAsKey(attachedName)] delete $rootScope.options[OmegaPac.Profiles.nameAsKey(profileName)] if $rootScope.options['-startupProfileName'] == profileName $rootScope.options['-startupProfileName'] = "" quickSwitch = $rootScope.options['-quickSwitchProfiles'] for i in [0...quickSwitch.length] if profileName == quickSwitch[i] quickSwitch.splice i, 1 break $state.go('ui') # The watcher should be applied on the calling scope. # coffeelint: disable=missing_fat_arrows $scope.watchAndUpdateRevision = (expression) -> revisionChanged = false onChange = (profile, oldProfile) -> return profile if profile == oldProfile or not profile or not oldProfile if revisionChanged and profile.revision != oldProfile.revision revisionChanged = false else OmegaPac.Profiles.updateRevision(profile) revisionChanged = true this.$watch expression, onChange, true $scope.exportRuleList = null $scope.exportRuleListOptions = null $scope.setExportRuleListHandler = (exportRuleList, options) -> $scope.exportRuleList = exportRuleList $scope.exportRuleListOptions = options unwatch = $scope.$watch (-> $scope.options?['+' + name]), (profile) -> if not profile if $scope.options unwatch() $location.path '/' else unwatch2 = $scope.$watch 'options', -> if $scope.options unwatch2() if not $scope.options['+' + name] unwatch() $location.path '/' return if OmegaPac.Profiles.formatByType[profile.profileType] profile.format = OmegaPac.Profiles.formatByType[profile.profileType] profile.profileType = 'RuleListProfile' $scope.profile = profile type = $scope.profile.profileType templ = profileTemplates[type] ? 'profile_unsupported.html' $scope.profileTemplate = 'partials/' + templ $scope.scriptable = true $scope.watchAndUpdateRevision 'profile' ================================================ FILE: omega-web/src/omega/controllers/quick_switch.coffee ================================================ angular.module('omega').controller 'QuickSwitchCtrl', ($scope, $filter) -> $scope.sortableOptions = tolerance: 'pointer' axis: 'y' forceHelperSize: true forcePlaceholderSize: true connectWith: '.cycle-profile-container' containment: '#quick-switch-settings' $scope.$watchCollection 'options', (options) -> return unless options? $scope.notCycledProfiles = for profile in $filter('profiles')(options, 'all') when ( options["-quickSwitchProfiles"].indexOf(profile.name) < 0) profile.name ================================================ FILE: omega-web/src/omega/controllers/rule_list_profile.coffee ================================================ angular.module('omega').controller 'RuleListProfileCtrl', ($scope) -> $scope.ruleListFormats = OmegaPac.Profiles.ruleListFormats ================================================ FILE: omega-web/src/omega/controllers/switch_profile.coffee ================================================ angular.module('omega').controller 'SwitchProfileCtrl', ($scope, $rootScope, $location, $timeout, $q, $modal, profileIcons, getAttachedName, omegaTarget, trFilter, downloadFile) -> # == Rule list == $scope.ruleListFormats = OmegaPac.Profiles.ruleListFormats exportRuleList = -> text = OmegaPac.RuleList.Switchy.compose( rules: $scope.profile.rules defaultProfileName: $scope.attachedOptions.defaultProfileName ) eol = '\r\n' info = '\n' info += '; Require: SwitchyOmega >= 2.3.2' + eol info += "; Date: #{new Date().toLocaleDateString()}" + eol info += "; Usage: #{trFilter('ruleList_usageUrl')}" + eol text = text.replace('\n', info) blob = new Blob [text], {type: "text/plain;charset=utf-8"} fileName = $scope.profile.name.replace(/\W+/g, '_') downloadFile(blob, "OmegaRules_#{fileName}.sorl") exportLegacyRuleList = -> wildcardRules = '' regexpRules = '' for rule in $scope.profile.rules i = '' if rule.profileName == $scope.attachedOptions.defaultProfileName i = '!' switch rule.condition.conditionType when 'HostWildcardCondition' wildcardRules += i + '@*://' + rule.condition.pattern + '/*' + '\r\n' when 'UrlWildcardCondition' wildcardRules += i + '@' + rule.condition.pattern + '\r\n' when 'UrlRegexCondition' regexpRules += i + rule.condition.pattern + '\r\n' text = """ ; Summary: Proxy Switchy! Exported Rule List ; Date: #{new Date().toLocaleDateString()} ; Website: #{trFilter('ruleList_usageUrl')} #BEGIN [wildcard] #{wildcardRules} [regexp] #{regexpRules} #END """ blob = new Blob [text], {type: "text/plain;charset=utf-8"} fileName = $scope.profile.name.replace(/\W+/g, '_') downloadFile(blob, "SwitchyRules_#{fileName}.ssrl") # == Condition types == $scope.conditionHelp = show: ($location.search().help == 'condition') $scope.basicConditionTypes = [ { group: 'default' types: [ 'HostWildcardCondition' 'UrlWildcardCondition' 'UrlRegexCondition' 'FalseCondition' ] } ] $scope.advancedConditionTypes = [ { group: 'host' types: [ 'HostWildcardCondition' 'HostRegexCondition' 'HostLevelsCondition' 'IpCondition' ] } { group: 'url' types: [ 'UrlWildcardCondition' 'UrlRegexCondition' 'KeywordCondition' ] } { group: 'special' types: [ 'WeekdayCondition' 'TimeCondition' 'FalseCondition' ] } ] expandGroups = (groups) -> result = [] for group in groups for type in group.types result.push({type: type, group: 'condition_group_' + group.group}) result basicConditionTypesExpanded = expandGroups($scope.basicConditionTypes) advancedConditionTypesExpanded = expandGroups($scope.advancedConditionTypes) basicConditionTypeSet = {} for type in basicConditionTypesExpanded basicConditionTypeSet[type.type] = type.type $scope.conditionTypes = basicConditionTypesExpanded $scope.showConditionTypes = 0 $scope.hasConditionTypes = 0 $scope.hasUrlConditions = false $scope.isUrlConditionType = 'UrlWildcardCondition': true 'UrlRegexCondition': true updateHasConditionTypes = -> return unless $scope.profile?.rules? $scope.hasUrlConditions = false for rule in $scope.profile.rules if $scope.isUrlConditionType[rule.condition.conditionType] $scope.hasUrlConditions = true break return unless $scope.hasConditionTypes == 0 for rule in $scope.profile.rules # Convert TrueCondition to a HostWildcardCondition with pattern '*'. if rule.condition.conditionType == 'TrueCondition' rule.condition = { conditionType: 'HostWildcardCondition' pattern: '*' } if not basicConditionTypeSet[rule.condition.conditionType] $scope.hasConditionTypes = 1 $scope.showConditionTypes = 1 break $scope.$watch 'options["-showConditionTypes"]', (show) -> show ||= 0 if show > 0 $scope.showConditionTypes = show else updateHasConditionTypes() $scope.showConditionTypes = $scope.hasConditionTypes if $scope.options['-exportLegacyRuleList'] if $scope.showConditionTypes > 0 $scope.setExportRuleListHandler(exportRuleList, {warning: true}) else $scope.setExportRuleListHandler(exportLegacyRuleList) else $scope.setExportRuleListHandler(exportRuleList) if $scope.showConditionTypes == 0 $scope.conditionTypes = basicConditionTypesExpanded if $scope.options['-exportLegacyRuleList'] $scope.setExportRuleListHandler exportLegacyRuleList else $scope.conditionTypes = advancedConditionTypesExpanded if not $scope.options["-showConditionTypes"]? $scope.options["-showConditionTypes"] = $scope.showConditionTypes unwatchRules?() if $scope.hasConditionTypes == 0 unwatchRules = $scope.$watch 'profile.rules', updateHasConditionTypes, true # == Rules == rulesReadyDefer = $q.defer() rulesReady = rulesReadyDefer.promise stopWatchingForRules = $scope.$watch 'profile.rules', (rules) -> return unless rules stopWatchingForRules() rulesReadyDefer.resolve(rules) $scope.addRule = -> rule = if $scope.profile.rules.length > 0 [..., templ] = $scope.profile.rules angular.copy(templ) else condition: {conditionType: 'HostWildcardCondition', pattern: ''} profileName: $scope.attachedOptions.defaultProfileName if rule.condition.pattern rule.condition.pattern = '' $scope.profile.rules.push rule $scope.validateCondition = (condition, pattern) -> if condition.conditionType.indexOf('Regex') >= 0 try new RegExp(pattern) catch _ return false return true $scope.conditionHasWarning = (condition) -> if condition.conditionType == 'HostWildcardCondition' pattern = condition.pattern return pattern.indexOf(':') >= 0 || pattern.indexOf('/') >= 0 return false $scope.validateIpCondition = (condition, input) -> return false unless input ip = OmegaPac.Conditions.parseIp(input) return ip? $scope.getWeekdayList = OmegaPac.Conditions.getWeekdayList $scope.updateDay = (condition, i, selected) -> condition.days ||= '-------' char = if selected then 'SMTWtFs'[i] else '-' condition.days = condition.days.substr(0, i) + char + condition.days.substr(i + 1) delete condition.startDay delete condition.endDay $scope.removeRule = (index) -> removeForReal = -> $scope.profile.rules.splice index, 1 if $scope.options['-confirmDeletion'] scope = $scope.$new('isolate') scope.rule = $scope.profile.rules[index] scope.ruleProfile = $scope.profileByName(scope.rule.profileName) scope.dispNameFilter = $scope.dispNameFilter scope.options = $scope.options $modal.open( templateUrl: 'partials/rule_remove_confirm.html' scope: scope ).result.then removeForReal else removeForReal() $scope.cloneRule = (index) -> rule = angular.copy($scope.profile.rules[index]) $scope.profile.rules.splice(index + 1, 0, rule) $timeout -> input = angular.element(".switch-rule-row:nth-child(#{index + 2}) input") input[0]?.focus() input[0]?.select() $scope.showNotes = false $scope.addNote = (index) -> $scope.showNotes = true unwatchRulesShowNote() unwatchRulesShowNote = $scope.$watch 'profile.rules', ((rules) -> if rules and rules.some((rule) -> !!rule.note) $scope.showNotes = true unwatchRulesShowNote() ), true $scope.resetRules = -> scope = $scope.$new('isolate') scope.ruleProfile = $scope.profileByName($scope.attachedOptions.defaultProfileName) scope.dispNameFilter = $scope.dispNameFilter scope.options = $scope.options $modal.open( templateUrl: 'partials/rule_reset_confirm.html' scope: scope ).result.then -> for rule in $scope.profile.rules rule.profileName = $scope.attachedOptions.defaultProfileName $scope.sortableOptions = handle: '.sort-bar' tolerance: 'pointer' axis: 'y' forceHelperSize: true forcePlaceholderSize: true containment: 'parent' # == Attached == attachedReadyDefer = $q.defer() attachedReady = attachedReadyDefer.promise $scope.$watch 'profile.name', (name) -> $scope.attachedName = getAttachedName(name) $scope.attachedKey = OmegaPac.Profiles.nameAsKey($scope.attachedName) $scope.$watch 'options[attachedKey]', (attached) -> $scope.attached = attached $scope.watchAndUpdateRevision 'options[attachedKey]' oldSourceUrl = null oldLastUpdate = null oldRuleList = null onAttachedChange = (attached, oldAttached) -> return unless attached and oldAttached if attached.sourceUrl != oldAttached.sourceUrl if attached.lastUpdate oldSourceUrl = oldAttached.sourceUrl oldLastUpdate = attached.lastUpdate oldRuleList = oldAttached.ruleList attached.lastUpdate = null else if oldSourceUrl and attached.sourceUrl == oldSourceUrl attached.lastUpdate = oldLastUpdate attached.ruleList = oldRuleList $scope.$watch 'options[attachedKey]', onAttachedChange, true $scope.attachedOptions = {enabled: false} $scope.$watch 'profile.defaultProfileName', (name) -> $scope.attachedOptions.enabled = (name == $scope.attachedName) if not $scope.attached or not $scope.attachedOptions.enabled $scope.attachedOptions.defaultProfileName = name $scope.$watch 'attachedOptions.enabled', (enabled, oldValue) -> return if enabled == oldValue if enabled if $scope.profile.defaultProfileName != $scope.attachedName $scope.profile.defaultProfileName = $scope.attachedName else if $scope.profile.defaultProfileName == $scope.attachedName if $scope.attached $scope.profile.defaultProfileName = $scope.attached.defaultProfileName $scope.attachedOptions.defaultProfileName = $scope.attached.defaultProfileName else $scope.profile.defaultProfileName = 'direct' $scope.attachedOptions.defaultProfileName = 'direct' $scope.$watch 'attached.defaultProfileName', (name) -> if name and $scope.attachedOptions.enabled $scope.attachedOptions.defaultProfileName = name $scope.$watch 'attachedOptions.defaultProfileName', (name) -> attachedReadyDefer.resolve() if $scope.attached and $scope.attachedOptions.enabled $scope.attached.defaultProfileName = name else $scope.profile.defaultProfileName = name $scope.attachNew = -> $scope.attached = OmegaPac.Profiles.create( name: $scope.attachedName defaultProfileName: $scope.profile.defaultProfileName profileType: 'RuleListProfile' color: $scope.profile.color ) OmegaPac.Profiles.updateRevision($scope.attached) $scope.options[$scope.attachedKey] = $scope.attached $scope.attachedOptions.enabled = true $scope.profile.defaultProfileName = $scope.attachedName $scope.removeAttached = -> return unless $scope.attached scope = $scope.$new('isolate') scope.attached = $scope.attached scope.dispNameFilter = $scope.dispNameFilter scope.options = $scope.options $modal.open( templateUrl: 'partials/delete_attached.html' scope: scope ).result.then -> $scope.profile.defaultProfileName = $scope.attached.defaultProfileName delete $scope.options[$scope.attachedKey] # == Edit source == stateEditorKey = 'web._profileEditor.' + $scope.profile.name $scope.loadRules = false $scope.editSource = false parseOmegaRules = (code, {detect, requireResult} = {}) -> setError = (error) -> if error.reason args = error.args ? [ error.sourceLineNo error.source ] message = trFilter('ruleList_error_' + error.reason, args) error.message = message if message return {error: error} if detect and not OmegaPac.RuleList.Switchy.detect(code) return {error: {reason: 'notSwitchy'}} refs = OmegaPac.RuleList.Switchy.directReferenceSet({ ruleList: code }) if requireResult and not refs return setError({reason: 'resultNotEnabled'}) for own key, name of refs if not OmegaPac.Profiles.byKey(key, $scope.options) return setError({reason: 'unknownProfile', args: [name]}) try return rules: OmegaPac.RuleList.Switchy.parseOmega(code, null, null, {strict: true, source: false}) catch err return setError(err) parseSource = -> return true unless $scope.source {rules, error} = parseOmegaRules($scope.source.code.trim(), requireResult: true) if error $scope.source.error = error $scope.editSource = true return false else $scope.source.error = undefined $scope.attachedOptions.defaultProfileName = rules.pop().profileName # Try to merge with existing rules if possible. diff = jsondiffpatch.create( objectHash: (obj) -> JSON.stringify(obj) textDiff: minLength: 1 / 0 ) oldRules = angular.fromJson(angular.toJson($scope.profile.rules)) patch = diff.diff(oldRules, rules) jsondiffpatch.patch($scope.profile.rules, patch) return true $scope.toggleSource = -> $q.all([attachedReady, rulesReady]).then -> $scope.editSource = not $scope.editSource if $scope.editSource args = rules: $scope.profile.rules defaultProfileName: $scope.attachedOptions.defaultProfileName code = OmegaPac.RuleList.Switchy.compose(args, withResult: true) $scope.source = {code: code} else return unless parseSource() $scope.source = null $scope.loadRules = true omegaTarget.state(stateEditorKey, {editSource: $scope.editSource}) $rootScope.$on '$stateChangeStart', (event, _, __, fromState) -> if $scope.editSource and $scope.source.touched sourceValid = parseSource() event.preventDefault() unless sourceValid $scope.$on 'omegaApplyOptions', (event) -> if $scope.attached?.ruleList and not $scope.attached.sourceUrl $scope.attachedRuleListError = undefined {error} = parseOmegaRules($scope.attached.ruleList.trim(), detect: true) if error if error.reason != 'resultNotEnabled' and error.reason != 'notSwitchy' $scope.attachedRuleListError = error event.preventDefault() angular.element('#attached-rulelist')[0].focus() else $scope.attached.format = 'Switchy' if $scope.editSource and $scope.source.touched event.preventDefault() if parseSource() $scope.source.touched = false $timeout -> $rootScope.applyOptions() omegaTarget.state(stateEditorKey).then (opts) -> if opts?.editSource $scope.toggleSource() else $scope.loadRules = true getState = omegaTarget.state(['web.switchGuide', 'firstRun']) $q.all([rulesReady, getState]).then ([_, [switchGuide, firstRun]]) -> return if firstRun or switchGuide == 'shown' omegaTarget.state('web.switchGuide', 'shown') return if $scope.profile.rules.length == 0 $script 'js/switch_profile_guide.js' ================================================ FILE: omega-web/src/omega/directives.coffee ================================================ angular.module('omega').directive 'inputGroupClear', ($timeout) -> restrict: 'A' templateUrl: 'partials/input_group_clear.html' scope: 'model': '=model' 'type': '@type' 'ngPattern': '=?ngPattern' 'placeholder': '@placeholder' 'controller': '=?controller' link: (scope, element, attrs) -> scope.catchAll = new RegExp('') $timeout -> scope.controller = element.find('input').controller('ngModel') scope.oldModel = '' scope.controller = scope.input scope.modelChange = -> if scope.model scope.oldModel = '' scope.toggleClear = -> [scope.model, scope.oldModel] = [scope.oldModel, scope.model] angular.module('omega').directive 'omegaUpload', -> restrict: 'A' scope: success: '&omegaUpload' error: '&omegaError' link: (scope, element, attrs) -> input = element[0] element.on 'change', -> if input.files.length > 0 and input.files[0].name.length > 0 reader = new FileReader() reader.addEventListener 'load', (e) -> scope.$apply -> scope.success({'$content': e.target.result}) reader.addEventListener 'error', (e) -> scope.$apply -> scope.error({'$error': e.target.error}) reader.readAsText(input.files[0]) input.value = '' angular.module('omega').directive 'omegaIp2str', -> restrict: 'A' priority: 2 # Run post-link after input directive (0) and ngModel (1). require: 'ngModel' link: (scope, element, attr, ngModel) -> ngModel.$parsers.push (value) -> if value OmegaPac.Conditions.fromStr('Ip: ' + value) else ({conditionType: 'IpCondition', ip: '0.0.0.0', prefixLength: 0}) ngModel.$formatters.push (value) -> if value?.ip OmegaPac.Conditions.str(value).split(' ', 2)[1] else '' ================================================ FILE: omega-web/src/omega/filters.coffee ================================================ angular.module('omega').filter 'profiles', (builtinProfiles, profileOrder, isProfileNameHidden, isProfileNameReserved) -> charCodePlus = '+'.charCodeAt(0) builtinProfileList = (profile for _, profile of builtinProfiles) (options, filter) -> result = [] for name, value of options when name.charCodeAt(0) == charCodePlus result.push value if (typeof filter == 'object' or ( typeof filter == 'string' and filter.charCodeAt(0) == charCodePlus)) if typeof filter == 'string' filter = filter.substr(1) result = OmegaPac.Profiles.validResultProfilesFor(filter, options) if filter == 'all' result = result.filter (profile) -> !isProfileNameHidden(profile.name) result = result.concat builtinProfileList else result = result.filter (profile) -> !isProfileNameReserved(profile.name) if filter == 'sorted' result.sort profileOrder result angular.module('omega').filter 'tr', (omegaTarget) -> omegaTarget.getMessage angular.module('omega').filter 'dispName', (omegaTarget) -> (name) -> if typeof name == 'object' name = name.name omegaTarget.getMessage('profile_' + name) || name ================================================ FILE: omega-web/src/options.jade ================================================ doctype html html(lang='en' ng-controller='MasterCtrl' ng-csp) head meta(charset='utf-8') title(ng-bind="'options_title' | tr") SwitchyOmega Options meta(name='viewport' content='width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no') link(rel='stylesheet' href='lib/bootstrap/css/bootstrap.min.css') link(rel='stylesheet' href='lib/spectrum/spectrum.css') link(rel='stylesheet' href='lib/ladda/ladda-themeless.min.css') link(rel='stylesheet' href='lib/shepherd.js/shepherd-theme-arrows.css') link(rel='stylesheet' href='css/options.css') body(style='display: none;' ng-style='{display: options ? "block" : "none"}') .container-fluid header.col-lg-2.col-sm-3.side-nav h1 a(ui-sref='about' title='{{"about_title" | tr}}') {{'appNameShort' | tr}} sup.om-experimental.text-danger(ng-show='isExperimental') | {{'options_experimental_badge' | tr}} nav.nav.nav-pills.nav-stacked li.nav-header {{'options_navHeader_setting' | tr}} li(ui-sref-active='active'): a(ui-sref='ui') span.glyphicon.glyphicon-wrench = ' ' | {{'options_tab_ui' | tr}} li(ui-sref-active='active'): a(ui-sref='general') span.glyphicon.glyphicon-cog = ' ' | {{'options_tab_general' | tr}} li(ui-sref-active='active'): a(ui-sref='io') span.glyphicon.glyphicon-floppy-save = ' ' | {{'options_tab_importExport' | tr}} li.divider li.nav-header {{'options_navHeader_profiles' | tr}} li.nav-profile(ng-repeat='profile in options | profiles:"sorted"' ui-sref-active='active' data-profile-type="{{profile.profileType}}") a(ui-sref='profile({name: profile.name})') span(omega-profile-inline='profile' options='options') li.nav-new-profile a(role='button' ng-click='newProfile()') span.glyphicon.glyphicon-plus = ' ' span {{'options_newProfile' | tr}} li.divider li.nav-header Actions li a.btn-default.btn.align-initial(role='button' ng-click='applyOptions()' ng-class='{"btn-success": optionsDirty}') span.glyphicon.glyphicon-ok-circle = ' ' | {{'options_apply' | tr}} li(ng-class='{disabled: !optionsDirty}') a.text-danger(role='button' ng-click='revertOptions()') span.glyphicon.glyphicon-remove-circle = ' ' | {{'options_discard' | tr}} main.col-lg-10.col-sm-9.col-lg-offset-2.col-sm-offset-3.angular-animate(ui-view) //- Note: Alert type classes cannot be changed in angular-bootstrap. This is already fixed but they don't have time for a new release: https://github.com/angular-ui/bootstrap/issues/2641 .alert-top-wrapper(ng-show='alertShown') div(alert type='workaround' close='hideAlert()' class='{{alertClassForType(alert.type)}}') span.glyphicon(class="{{alertIcons[alert.type]}}") = ' ' | {{alert.i18n ? (alert.i18n | tr) : alert.message}} script(src='js/omega_debug.js') script(src='js/log_error.js') script(src='lib/script.js/script.min.js') script(src='js/options.js') ================================================ FILE: omega-web/src/partials/about.jade ================================================ .page-header h2 {{'about_title' | tr}} section.omega-experimental(ng-show='isExperimental') p.alert.alert-warning span.glyphicon.glyphicon-warning-sign = ' ' span {{'about_experimental_warning_moz' | tr}} section .media(style='margin: 1em 0') .media-left img.media-object(src='img/icons/omega-action-32.png') .media-body h4.media-heading {{'appNameShort' | tr}} p {{'about_app_description' | tr}} section p button.btn.btn-info(ng-click='reportIssue()') span.glyphicon.glyphicon-comment = ' ' | {{'popup_reportIssues' | tr}} = ' ' button.btn.btn-default(ng-click='downloadLog()') span.glyphicon.glyphicon-download = ' ' | {{'popup_errorLog' | tr}} = ' ' button.btn.btn-danger(ng-click='showResetOptionsModal()') span.glyphicon.glyphicon-alert = ' ' | {{'options_reset' | tr}} section p | {{'about_version' | tr:[version]}} p.text-warning span.glyphicon.glyphicon-info-sign = ' ' span(ng-bind-html='"about_disclaimer_networkService" | tr') p.text-success span.glyphicon.glyphicon-eye-close = ' ' span(ng-bind-html='"about_disclaimer_privacy" | tr') p.text-info span.glyphicon.glyphicon-question-sign = ' ' span(ng-bind-html='"about_help" | tr') section(style='margin-top: 7em') p | {{'appNameShort' | tr}} br span(ng-bind-html='"about_copyright" | tr') br span(ng-bind-html='"about_license" | tr') br span(ng-bind-html='"about_credits" | tr') ================================================ FILE: omega-web/src/partials/apply_options_confirm.jade ================================================ .modal-header button.close(type='button' ng-click='$dismiss()') span(aria-hidden='true') × span.sr-only {{'dialog_close' | tr}} h4.modal-title {{'options_modalHeader_applyOptions' | tr}} .modal-body p {{'options_applyOptionsRequired' | tr}} p {{'options_applyOptionsConfirm' | tr}} .modal-footer button.btn.btn-default(ng-click='$dismiss()') {{'dialog_cancel' | tr}} button.btn.btn-primary(type='button' ng-click='$close("ok")') {{'options_apply' | tr}} ================================================ FILE: omega-web/src/partials/cannot_delete_profile.jade ================================================ .modal-header button.close(type='button' ng-click='$dismiss()') span(aria-hidden='true') × span.sr-only {{'dialog_close' | tr}} h4.modal-title {{'options_modalHeader_cannotDeleteProfile' | tr}} .modal-body p {{'options_profileReferredBy' | tr}} .well ul.list-style-none li(ng-repeat='p in refs') span(omega-profile-inline='p' options='options' disp-name='dispNameFilter') p {{'options_modifyReferringProfiles' | tr}} .modal-footer button.btn.btn-default(ng-click='$dismiss()') {{'dialog_cancel' | tr}} ================================================ FILE: omega-web/src/partials/delete_attached.jade ================================================ .modal-header button.close(type='button' ng-click='$dismiss()') span(aria-hidden='true') × span.sr-only {{'dialog_close' | tr}} h4.modal-title {{'options_modalHeader_deleteAttached' | tr}} .modal-body p {{'options_deleteAttachedConfirm' | tr}} .well span(omega-profile-icon='attached' options='options') = ' ' | {{attached.sourceUrl || ('options_ruleListLineCount' | tr:[attached.ruleList.split('\n').length])}} .modal-footer button.btn.btn-default(ng-click='$dismiss()') {{'dialog_cancel' | tr}} button.btn.btn-danger(type='button' ng-click='$close("ok")') {{'options_deleteAttached' | tr}} ================================================ FILE: omega-web/src/partials/delete_profile.jade ================================================ .modal-header button.close(type='button' ng-click='$dismiss()') span(aria-hidden='true') × span.sr-only {{'dialog_close' | tr}} h4.modal-title {{'options_modalHeader_deleteProfile' | tr}} .modal-body p {{'options_deleteProfileConfirm' | tr}} .well span(omega-profile-inline='profile' options='options' disp-name='dispNameFilter') .modal-footer button.btn.btn-default(ng-click='$dismiss()') {{'dialog_cancel' | tr}} button.btn.btn-danger(type='button' ng-click='$close("ok")') {{'options_deleteProfile' | tr}} ================================================ FILE: omega-web/src/partials/fixed_auth_edit.jade ================================================ form(ng-submit='authForm.$valid && $close(auth)' name='authForm') .modal-header button.close(type='button' ng-click='$dismiss()') span(aria-hidden='true') × span.sr-only Close h4.modal-title {{'options_modalHeader_proxyAuth' | tr}} .modal-body(style='padding-bottom: 0;') .form-group(ng-show='!authSupported') .alert.alert-danger span.glyphicon.glyphicon-warning-sign = ' ' | {{"options_proxy_authNotSupported" | tr:[protocolDisp]}} .form-group label.sr-only {{'options_proxyAuthUsername' | tr}} div(input-group-clear type='text' model='auth.username' autofocus placeholder='{{"options_proxyAuthUsername" | tr}}') .form-group(ng-class='{"has-error": !authForm.password.$valid}') label.sr-only {{'options_proxyAuthPassword' | tr}} .input-group input.form-control(type='text' name='password' ng-model='auth.password' ng-attr-type='{{showPassword ? "text" : "password"}}' placeholder='{{"options_proxyAuthPassword" | tr}}' ng-show='!!auth.username') input.form-control(type='text' value='' placeholder='{{"options_proxyAuthNone" | tr}}' disabled ng-show='!auth.username') span.input-group-btn button.btn.btn-default(type='button' ng-click='showPassword = !showPassword' title="{{(showPassword ? 'options_proxyAuthHidePassword' : 'options_proxyAuthShowPassword') | tr}}" ng-disabled='!auth.username') span.glyphicon(ng-class='{"glyphicon-eye-close": !showPassword, "glyphicon-eye-open": !!showPassword}') .modal-footer button.btn.btn-default(type='button' ng-click='$dismiss()') {{'dialog_cancel' | tr}} button.btn.btn-primary(type='submit' ng-disabled='!authForm.$valid') {{'dialog_save' | tr}} ================================================ FILE: omega-web/src/partials/general.jade ================================================ .page-header h2 {{'options_tab_general' | tr}} section.settings-group h3 {{'options_group_networkRequests' | tr}} div.checkbox label input#revert-proxy-changes(type='checkbox' ng-model='options["-monitorWebRequests"]') span {{'options_monitorWebRequests' | tr}} p.help-block(omega-html="'options_monitorWebRequestsHelp' | tr") section.settings-group.width-limit h3 {{'options_downloadOptions' | tr}} p.help-block {{'options_downloadOptionsHelp' | tr}} .form-group label(for='download-interval') {{'options_downloadInterval' | tr}} select#download-interval.form-control.inline-form-control(ng-model='options["-downloadInterval"]' ng-options='interval as (downloadIntervalI18n(interval) | tr) for interval in downloadIntervals') section.settings-group.width-limit h3 {{'options_group_conflicts' | tr}} p {{'options_conflicts_introduction' | tr}} p.help-text.text-danger span(style='padding: 1px 4px; background: #da4f49; color: #fff; box-shadow: #ccc 1px 1px 1px 1px;') = = ' ' | {{'options_conflicts_lowerPriority' | tr}} p.help-text.text-info span.glyphicon.glyphicon-info-sign = ' ' span(omega-html="'options_conflicts_higherPriority' | tr:[$profile('systemProfile')]") div.checkbox label input#revert-proxy-changes(type='checkbox' ng-model='options["-showExternalProfile"]') span {{'options_showExternalProfile' | tr}} p.help-block(omega-html="'options_showExternalProfileHelp' | tr:[$profile('systemProfile'), $profile('externalProfile')]") ================================================ FILE: omega-web/src/partials/input_group_clear.jade ================================================ .input-group input.form-control(ng-model='model' ng-attr-type='{{type}}' ng-pattern='ngPattern || catchAll' placeholder='{{placeholder}}' ng-change='modelChange()') span.input-group-btn button.btn.btn-default.input-group-clear-btn(type='button' ng-click='toggleClear()' ng-disabled='!model && !oldModel' title="{{'inputClear_' + (oldModel ? 'restore' : 'clear') | tr}}") span.glyphicon(ng-class='{"glyphicon-remove": !oldModel, "glyphicon-repeat": !!oldModel}') ================================================ FILE: omega-web/src/partials/io.jade ================================================ .page-header h2 {{'options_tab_importExport' | tr}} section.settings-group h3 {{'options_group_importExportProfile' | tr}} .help-block .text-info span.glyphicon.glyphicon-info-sign = ' ' | {{'options_exportProfileHelp' | tr}} div.checkbox(ng-show='!(options["-showConditionTypes"] > 0)') label input(type='checkbox' ng-model='options["-exportLegacyRuleList"]') span {{'options_exportLegacyRuleList' | tr}} p.help-block(omega-html="'options_exportLegacyRuleListHelp' | tr") section.settings-group h3 {{'options_group_importExportSettings' | tr}} p button.btn.btn-default(ng-click='exportOptions()') span.glyphicon.glyphicon-floppy-save = ' ' | {{'options_makeBackup' | tr}} span.help-inline {{'options_makeBackupHelp' | tr}} p input#restore-local-file(type='file' omega-upload='restoreLocal($content)' omega-error='restoreLocalError($error)') button.btn.btn-default(ng-click='triggerFileInput()' ladda='restoringLocal' data-spinner-color="#000000") span.glyphicon.glyphicon-folder-open = ' ' | {{'options_restoreLocal' | tr}} span.help-inline {{'options_restoreLocalHelp' | tr}} div label {{'options_restoreOnline' | tr}} .input-group.width-limit input.form-control(type='url' ng-model='restoreOnlineUrl' placeholder="{{'options_restoreOnlinePlaceholder' | tr}}") span.input-group-btn button.btn.btn-default(ng-click='restoreOnline()' ladda='restoringOnline' data-spinner-color="#000000") | {{'options_restoreOnlineSubmit' | tr}} section.settings-group h3 {{'options_group_syncing' | tr}} div(ng-show='syncOptions == "pristine" || syncOptions == "disabled"') p.help-block(omega-html='"options_syncPristineHelp" | tr') p button.btn.btn-default(ng-click='enableOptionsSync()') span.glyphicon.glyphicon-cloud-upload = ' ' | {{'options_syncEnable' | tr}} div(ng-show='syncOptions == "sync"') p.alert.alert-success.width-limit span.glyphicon.glyphicon-ok = ' ' | {{"options_syncSyncAlert" | tr}} p.help-block(omega-html='"options_syncSyncHelp" | tr') p button.btn.btn-warning(ng-click='disableOptionsSync()') span.glyphicon.glyphicon-remove-sign = ' ' | {{'options_syncDisable' | tr}} div(ng-show='syncOptions == "conflict"') p.alert.alert-info.width-limit span.glyphicon.glyphicon-info-sign = ' ' | {{"options_syncConflictAlert" | tr}} p.help-block(omega-html='"options_syncConflictHelp" | tr') p button.btn.btn-danger(ng-click='enableOptionsSync({force: true})') span.glyphicon.glyphicon-cloud-download = ' ' | {{'options_syncEnableForce' | tr}} = ' ' button.btn.btn-link(ng-click='resetOptionsSync()') span.glyphicon.glyphicon-erase = ' ' | {{'options_syncReset' | tr}} div(ng-show='syncOptions == "unsupported"') p.help-block(omega-html='"options_syncUnsupportedHelp" | tr') ================================================ FILE: omega-web/src/partials/new_profile.jade ================================================ form(ng-submit='newProfile.$valid && $close(profile)' name='newProfile') .modal-header button.close(type='button' ng-click='$dismiss()') span(aria-hidden='true') × span.sr-only Close h4.modal-title {{'options_modalHeader_newProfile' | tr}} .modal-body .form-group(ng-class='{"has-error": !newProfile.profileNewName.$valid}') label(for='profile-new-name') {{'options_newProfileName' | tr}} input#profile-new-name.form-control(type='text' name='profileNewName' required ng-model='profile.name' ui-validate='validateProfileName' autofocus) .help-block(ng-show='newProfile.profileNewName.$error.required') {{'options_profileNameEmpty' | tr}} .help-block(ng-show='newProfile.profileNewName.$error.reserved') {{'options_profileNameReserved' | tr}} .help-block(ng-show='!newProfile.profileNewName.$error.reserved && newProfile.profileNewName.$error.conflict') | {{'options_profileNameConflict' | tr}} .help-block(ng-show='newProfile.profileNewName.$valid && profile.name && isProfileNameHidden(profile.name)') .text-info span.glyphicon.glyphicon-info-sign = ' ' | {{'options_profileNameHidden' | tr}} label {{'options_profileType' | tr}} .radio label input(type='radio' name='profile-new-type' value='FixedProfile' ng-model='profile.profileType' ng-init='profile.profileType = "FixedProfile"') span.profile-type span.glyphicon(ng-class='profileIcons["FixedProfile"]') = ' ' span {{'options_profileTypeFixedProfile' | tr}} .help-block {{'options_profileDescFixedProfile' | tr}} .radio label input(type='radio', name='profile-new-type', value='SwitchProfile' ng-model='profile.profileType') span.profile-type span.glyphicon(ng-class='profileIcons["SwitchProfile"]') = ' ' span {{'options_profileTypeSwitchProfile' | tr}} .help-block {{'options_profileDescSwitchProfile' | tr}} .radio label input(type='radio', name='profile-new-type', value='PacProfile' ng-model='profile.profileType' ng-disabled='pacProfilesUnsupported') span.profile-type span.glyphicon(ng-class='profileIcons["PacProfile"]') = ' ' span {{'options_profileTypePacProfile' | tr}} .help-block {{'options_profileDescPacProfile' | tr}} .help-block(ng-show='!pacProfilesUnsupported') {{'options_profileDescMorePacProfile' | tr}} .has-error(ng-show='pacProfilesUnsupported') .help-block span.glyphicon.glyphicon-warning-sign = ' ' | {{'options_pac_profile_unsupported_moz' | tr}} .radio label input(type='radio', name='profile-new-type', value='VirtualProfile' ng-model='profile.profileType') span.profile-type span.glyphicon.virtual-profile-icon(ng-class='profileIcons["VirtualProfile"]') = ' ' span {{'options_profileTypeVirtualProfile' | tr}} .help-block {{'options_profileDescVirtualProfile' | tr}} .modal-footer button.btn.btn-default(type='button' ng-click='$dismiss()') {{'dialog_cancel' | tr}} button.btn.btn-primary(type='submit' ng-disabled='!newProfile.$valid') {{'options_createProfile' | tr}} ================================================ FILE: omega-web/src/partials/omega_profile_select.jade ================================================ .btn-group.omega-profile-select(dropdown on-toggle="toggled(open)") button.btn.btn-default.dropdown-toggle(dropdown-toggle type='button' aria-expanded='false' role='listbox' aria-haspopup='true') span(omega-profile-icon='selectedProfile' options='options' icon='selectedProfile ? undefined : "glyphicon-time"') = ' ' span(ng-show='!!profileName') {{getName(selectedProfile)}} span(ng-show='!profileName') {{defaultText}} = ' ' span.caret ul.dropdown-menu(role='listbox') li(role='option' ng-if='!!defaultText' ng-class='{active: profileName == ""}') a(ng-click='setProfileName("")') span.glyphicon.glyphicon-time = ' {{defaultText}}' li(role='option' ng-repeat='profile in dispProfiles' ng-class='{active: profileName == profile.name}') a(ng-click='setProfileName(profile.name)') span(omega-profile-icon='profile' options='options') = ' {{getName(profile)}}' ================================================ FILE: omega-web/src/partials/options_welcome.jade ================================================ .modal-header button.close(type='button' ng-click='$dismiss()') span(aria-hidden='true') × span.sr-only {{'dialog_close' | tr}} h4.modal-title {{'options_modalHeader_welcome' | tr}} .modal-body p(ng-show="upgrade") {{'options_welcomeUpgrade' | tr}} p(ng-show="upgrade") {{'options_welcomeUpgradeGuide' | tr}} p(ng-show="!upgrade") {{'options_welcomeNormal' | tr}} p(ng-show="!upgrade") {{'options_welcomeNormalGuide' | tr}} .modal-footer button.btn.btn-default(ng-click='$close("skip")') {{'options_guideSkip' | tr}} button.btn.btn-primary(type='button' ng-click='$close("show")') {{'options_guideNext' | tr}} ================================================ FILE: omega-web/src/partials/profile.jade ================================================ .page-header .profile-actions button.btn(ng-show='exportRuleList' ng-click='exportRuleList(profile.name)' title="{{'options_profileExportRuleListHelp' | tr}}" ng-class="exportRuleListOptions.warning ? 'btn-warning' : 'btn-default'") span.glyphicon.glyphicon-list = ' ' | {{'options_profileExportRuleList' | tr}} = ' ' button.btn.btn-default(ng-show='scriptable' ng-click='exportScript(profile.name)' title="{{'options_exportPacFileHelp' | tr}}") span.glyphicon.glyphicon-download = ' ' | {{'options_profileExportPac' | tr}} = ' ' button.btn.btn-default(ng-click='renameProfile(profile.name)') span.glyphicon.glyphicon-edit = ' ' | {{'options_renameProfile' | tr}} = ' ' button.btn.btn-danger(ng-click='deleteProfile(profile.name)') span.glyphicon.glyphicon-trash = ' ' | {{'options_deleteProfile' | tr}} span.profile-color-editor .profile-color-editor-fake(ng-if='profile.profileType == "VirtualProfile"' ng-style="{'background-color': getProfileColor()}") x-spectrum-colorpicker(ng-model='profile.color' options='spectrumOptions' ng-if='profile.profileType != "VirtualProfile"') h2.profile-name {{'options_profileTabPrefix' | tr}}{{profile.name}} section.settings-group(ng-show='profile.syncOptions == "disabled"') p.alert.alert-info.width-limit(ng-show='!profile.syncError') span.glyphicon.glyphicon-info-sign = ' ' | {{'Syncing is disabled for this profile.'}} p.alert.alert-danger.width-limit(ng-show='!!profile.syncError') span.glyphicon.glyphicon-remove = ' ' | {{('options_profileSyncDisabled_' + profile.syncError.reason) | tr}} div(ng-include='profileTemplate') ================================================ FILE: omega-web/src/partials/profile_fixed.jade ================================================ div(ng-controller='FixedProfileCtrl') section.settings-group.settings-group-fixed-servers h3 {{'options_group_proxyServers' | tr}} .table-responsive table.fixed-servers.table.table-bordered.table-striped.width-limit-lg thead tr th {{'options_proxy_scheme' | tr}} th {{'options_proxy_protocol' | tr}} th {{'options_proxy_server' | tr}} th {{'options_proxy_port' | tr}} th tbody tr(ng-repeat='scheme in urlSchemes' ng-show='scheme == "" || showAdvanced') td {{schemeDisp[scheme] || ('options_scheme_default' | tr)}} td select.form-control(ng-model='proxyEditors[scheme].scheme' ng-options='opt.value as opt.label for opt in optionsForScheme[scheme]') td(ng-if='proxyEditors[scheme].scheme') input.form-control(type='text' ng-model='proxyEditors[scheme].host' required) td(ng-if='!proxyEditors[scheme].scheme') input.form-control(type='text' value='' placeholder='{{proxyEditors[""].host}}' disabled) td(ng-if='proxyEditors[scheme].scheme') input.form-control(type='number' min='1' ng-model='proxyEditors[scheme].port' required) td(ng-if='!proxyEditors[scheme].scheme') input.form-control(type='number' value='' placeholder='{{proxyEditors[""].port}}' disabled) td.proxy-actions button.btn.btn-xs.proxy-auth-toggle( ng-class='isProxyAuthActive(scheme) ? "btn-success" : "btn-default"' type='button' role='button' ng-click='editProxyAuth(scheme)' title='{{"options_proxy_auth" | tr}}') span.glyphicon.glyphicon-lock tbody(ng-show='!showAdvanced') tr.fixed-show-advanced td(colspan='7') button.btn.btn-link(ng-click='showAdvanced = true') | #[span.glyphicon.glyphicon-chevron-down] {{'options_proxy_expand' | tr}} section.settings-group h3 {{'options_group_bypassList' | tr}} p.help-block {{'options_bypassListHelp' | tr}} p.help-block a(href='https://developer.chrome.com/extensions/proxy#bypass_list' target='_blank') | {{'options_bypassListHelpLinkText' | tr}} textarea.monospace.form-control.width-limit(rows='10' ng-model='bypassList' ng-model-options="{updateOn:'blur'}") ================================================ FILE: omega-web/src/partials/profile_pac.jade ================================================ div(ng-controller='PacProfileCtrl') p.alert.alert-danger.width-limit(ng-show='pacProfilesUnsupported') span.glyphicon.glyphicon-remove = ' ' | {{'options_pac_profile_unsupported_moz' | tr}} section.settings-group h3 {{'options_group_pacUrl' | tr}} .width-limit(input-group-clear type='text' model='profile.pacUrl' ng-pattern='referenced ? urlRegex : urlWithFile' controller='pacUrlCtrl.ctrl') p.help-block {{'options_pacUrlHelp' | tr}} .has-warning(ng-show='pacUrlIsFile && !referenced') p.help-block #[span.glyphicon.glyphicon-warning-sign] {{'options_pacUrlFile' | tr}} .has-error(ng-show='isFileUrl(pacUrlCtrl.ctrl.$viewValue) && referenced') p.help-block #[span.glyphicon.glyphicon-remove-sign] {{'options_pacUrlFile' | tr}} p.help-block {{'options_pacUrlFileDisabled' | tr}} p(ng-show='profile.pacUrl && !pacUrlIsFile') button.btn(ng-click='updateProfile(profile.name)' ladda='updatingProfile[profile.name]' data-spinner-color="#000000" ng-class='profile.pacUrl && !profile.lastUpdate ? "btn-primary" : "btn-default"') | #[span.glyphicon.glyphicon-download-alt] {{'options_downloadProfileNow' | tr}} section.settings-group h3 | {{'options_group_pacScript' | tr}} = ' ' button.btn.btn-xs.proxy-auth-toggle(ng-class='profile.auth["all"] ? "btn-success" : "btn-default"' type='button' role='button' ng-click='editProxyAuth()' title='{{"options_proxy_auth" | tr}}') span.glyphicon.glyphicon-lock div.alert.alert-warning.width-limit(ng-show='profile.auth["all"]') p {{'options_proxy_authAllWarningPac' | tr}} p(ng-show='!!profile.pacUrl') {{'options_proxy_authAllWarningPacUrl' | tr}} p(ng-show='!profile.pacUrl') {{'options_proxy_authAllWarningPacScript' | tr}} p(ng-show='!!referenced') | #[span.glyphicon.glyphicon-warning-sign] {{'options_proxy_authReferencedWarning' | tr}} div(ng-hide='pacUrlIsFile') p.alert.alert-success.width-limit(ng-show='profile.pacUrl && profile.lastUpdate') | {{'options_pacScriptLastUpdate' | tr:[(profile.lastUpdate | date:'medium')]}} p.alert.alert-danger.width-limit(ng-show='profile.pacUrl && !profile.lastUpdate') | {{'options_pacScriptObsolete' | tr}} textarea.monospace.form-control.width-limit(ng-model='profile.pacScript' rows=20 ng-disabled='pacUrlCtrl.ctrl.$invalid || !!profile.pacUrl') ================================================ FILE: omega-web/src/partials/profile_rule_list.jade ================================================ div(ng-controller='RuleListProfileCtrl') section.settings-group h3 {{'options_group_ruleListConfig' | tr}} .form-group label {{'options_ruleListMatchProfile' | tr}} = ' ' div(omega-profile-select='options | profiles:profile' ng-model='profile.matchProfileName' disp-name='dispNameFilter' options='options' style='display: inline-block;') .form-group label {{'options_ruleListDefaultProfile' | tr}} = ' ' div(omega-profile-select='options | profiles:profile' ng-model='profile.defaultProfileName' disp-name='dispNameFilter' options='options' style='display: inline-block;') form.form-group label {{'options_ruleListFormat' | tr}} .radio.inline-form-control.no-min-width(ng-repeat='format in ruleListFormats') label input(type='radio' name='formatInput' value='{{format}}' ng-model='profile.format') | {{'ruleListFormat_' + format | tr}} section.settings-group h3 {{'options_group_ruleListUrl' | tr}} .width-limit(input-group-clear type='url' model='profile.sourceUrl' ng-if='profile') p.help-block {{'options_ruleListUrlHelp' | tr}} section.settings-group h3 {{'options_group_ruleListText' | tr}} p button.btn.btn-default(ng-disabled='!profile.sourceUrl' ng-click='updateProfile(profile.name)' ladda='updatingProfile[profile.name]' data-spinner-color="#000000") | #[span.glyphicon.glyphicon-download-alt] {{'options_downloadProfileNow' | tr}} textarea.monospace.form-control.width-limit(ng-model='profile.ruleList' rows=20 ng-disabled='!!profile.sourceUrl') ================================================ FILE: omega-web/src/partials/profile_switch.jade ================================================ div(ng-controller='SwitchProfileCtrl') section.condition-help-section.settings-group(ng-show='conditionHelp.show' ng-init='expandedSection = {id: 0}') h3 | {{'options_group_conditionHelp' | tr}} button.close.close-condition-help(type='button' ng-click='conditionHelp.show = false') span(aria-hidden='true') × span.sr-only {{'dialog_close' | tr}} div.condition-help(ng-repeat='group in (showConditionTypes == 0 ? basicConditionTypes : advancedConditionTypes)') h4(ng-show="!!('condition_group_' + group.group | tr)") a(ng-click='expandedSection.id = $index' role='button') span.glyphicon(ng-class="{'glyphicon-chevron-down': expandedSection.id == $index, 'glyphicon-chevron-right': expandedSection.id != $index}") = ' ' | {{'condition_group_' + group.group | tr}} dl(ng-show='expandedSection.id == $index') dt(ng-repeat-start='type in group.types') {{'condition_' + type | tr}} dd(ng-repeat-end) div(ng-bind-html='"condition_help_" + type | tr') .text-danger(ng-if='isUrlConditionType[type]') span.glyphicon.glyphicon-alert = ' ' span(ng-bind-html='"condition_alert_fullUrlLimitation" | tr') section.settings-group h3 | {{'options_group_switchRules' | tr}} = ' ' button.btn(ng-click='toggleSource()' ng-class='editSource ? "btn-primary active" : "btn-default"') span.glyphicon.glyphicon-edit = ' ' | {{'options_profileEditSource' | tr}} = ' ' a.btn.btn-link.btn-sm.clear-padding.toggle-condition-help( ng-show='editSource' target='_blank' title='{{"options_profileEditSourceHelp" | tr}}' href='{{"options_profileEditSourceHelpUrl" | tr}}') span.glyphicon.glyphicon-question-sign .alert.alert-danger.width-limit(ng-show='source.error') span.glyphicon.glyphicon-remove = ' ' | {{source.error.message}} .alert.alert-danger(ng-show='!!hasUrlConditions') span.glyphicon.glyphicon-alert = ' ' span(ng-bind-html='"condition_alert_fullUrlLimitation" | tr') .rules-source(ng-show='editSource') textarea.monospace.form-control.width-limit(ng-model='source.code' rows=20 ng-change='source.touched = true; $root.optionsDirty = true') .table-responsive.switch-rules-wrapper(ng-if='loadRules' ng-show='!editSource') table.switch-rules.table.table-bordered.table-condensed.width-limit-xl thead tr th(style='white-space: nowrap') {{'options_sort' | tr}} th.condition-type-th | {{'options_conditionType' | tr}} = ' ' button.btn.btn-link.btn-sm.clear-padding.toggle-condition-help( title='{{"options_showConditionTypeHelp" | tr}}' ng-click='conditionHelp.show = !conditionHelp.show') span.glyphicon.glyphicon-question-sign th {{'options_conditionDetails' | tr}} th {{'options_resultProfile' | tr}} th {{'options_conditionActions' | tr}} th(ng-if='showNotes') {{'options_ruleNote' | tr}} tbody(ui-sortable='sortableOptions' ng-model='profile.rules') tr.switch-rule-row(ng-repeat='rule in profile.rules') td.sort-bar span.glyphicon.glyphicon-sort td(ng-class='{"has-icon": isUrlConditionType[rule.condition.conditionType]}') select.form-control(ng-model='rule.condition.conditionType' ng-options='type.type as ("condition_" + type.type | tr) group by (type.group | tr) for type in conditionTypes') a.icon-wrapper(ng-href='{{"condition_alert_fullUrlLimitationLink" | tr}}' target='_blank' ng-if='isUrlConditionType[rule.condition.conditionType]') span.glyphicon.glyphicon-alert.text-danger td(ng-switch='rule.condition.conditionType' ng-class='{"has-warning": conditionHasWarning(rule.condition)}') span(ng-switch-when='FalseCondition') span(ng-show='!!rule.condition.pattern') input.form-control(ng-model='rule.condition.pattern' disabled title="{{'condition_details_FalseCondition' | tr}}") span(ng-show='!rule.condition.pattern') {{'condition_details_FalseCondition' | tr}} span.host-levels-details(ng-switch-when='HostLevelsCondition') input.form-control(type='number' min='1' max='99' ng-model='rule.condition.minValue' required) = ' ' span {{'options_hostLevelsBetween' | tr}} = ' ' input.form-control(type='number' max='99' min='1' ng-model='rule.condition.maxValue' required) span(ng-switch-when='IpCondition') input.form-control(type='text' ng-model='rule.condition' required omega-ip2str placeholder='127.0.0.1/8' ui-validate='{pattern: "validateIpCondition(rule.condition, $value)"}') span.host-levels-details(ng-switch-when='TimeCondition') input.form-control(type='number' min='0' max='23' ng-model='rule.condition.startHour' required) = ' ' span {{'options_hourBetween' | tr}} = ' ' input.form-control(type='number' min='0' max='23' ng-model='rule.condition.endHour' required) span.host-levels-details(ng-switch-when='WeekdayCondition') label.checkbox-inline(ng-repeat='selected in getWeekdayList(rule.condition) track by $index') input(type='checkbox' ng-model='selected' ng-change='updateDay(rule.condition, $index, selected)') = '{{"options_weekDayShort_" + $index | tr}} ' input.form-control(ng-model='rule.condition.pattern' ng-switch-default required ui-validate='{pattern: "validateCondition(rule.condition, $value)"}') td.switch-rule-row-target div(omega-profile-select='options | profiles:profile' ng-model='rule.profileName' disp-name='dispNameFilter' options='options' ng-class='{disabled: rule.condition.conditionType == "NeverCondition"}') td button.btn.btn-danger.btn-sm(title="{{'options_deleteRule' | tr}}" ng-click='removeRule($index)') span.glyphicon.glyphicon-trash = ' ' button.btn.btn-default.btn-sm(title="{{'options_cloneRule' | tr}}" ng-click='cloneRule($index)') span.glyphicon.glyphicon-duplicate button.btn.btn-default.btn-sm(title="{{'options_ruleNote' | tr}}" ng-if='!showNotes' ng-click='addNote($index)') span.glyphicon.glyphicon-comment td(ng-if='showNotes') input.form-control(ng-model='rule.note') tbody tr td(style='border-right: none;') td(style='border-left: none;' colspan='4' ng-attr-colspan='{{showNotes ? 5 : 4}}') button.btn.btn-default.btn-sm(ng-click='addRule()') span.glyphicon.glyphicon-plus = ' ' span {{'options_addCondition' | tr}} tbody.switch-attached(ng-if='attached') tr td(style='border-right: none;') span.glyphicon(class='{{profileIcons["RuleListProfile"]}}') td(style='border-left: none;') span.checkbox label input(type='checkbox' ng-model='attachedOptions.enabled') | {{'options_switchAttachedProfileInCondition' | tr}} td span(ng-show='!!attachedOptions.enabled') | {{'options_switchAttachedProfileInConditionDetails' | tr}} span(ng-show='!attachedOptions.enabled') | {{'options_switchAttachedProfileInConditionDisabled' | tr}} td div(omega-profile-select='options | profiles:profile' ng-model='attached.matchProfileName' disp-name='dispNameFilter' options='options' ng-class='{disabled: !attachedOptions.enabled}') td button.btn.btn-danger.btn-sm(title="{{'options_deleteAttached' | tr}}" ng-click='removeAttached()') span.glyphicon.glyphicon-trash td(ng-if='showNotes') tbody tr.switch-default-row td td(colspan='2') {{'options_switchDefaultProfile' | tr}} td div(omega-profile-select='options | profiles:profile' ng-model='attachedOptions.defaultProfileName' disp-name='dispNameFilter' options='options') td button.btn.btn-info.btn-sm(title="{{'options_resetRules_help' | tr}}" ng-click='resetRules()') span.glyphicon.glyphicon-chevron-up td(ng-if='showNotes') section.settings-group(ng-if='!attached') h3 {{'options_group_attachProfile' | tr}} p.help-block {{'options_attachProfileHelp' | tr}} button.btn.btn-default(ng-click='attachNew()') span.glyphicon.glyphicon-plus = ' ' | {{'options_attachProfile' | tr}} section.settings-group(ng-if='attached') h3 {{'options_group_ruleListConfig' | tr}} form .form-group label {{'options_ruleListFormat' | tr}} .radio.inline-form-control.no-min-width(ng-repeat='format in ruleListFormats') label input(type='radio' name='formatInput' value='{{format}}' ng-model='attached.format') | {{'ruleListFormat_' + format | tr}} .form-group label {{'options_group_ruleListUrl' | tr}} .width-limit.inline-form-control(input-group-clear type='url' model='attached.sourceUrl' style='vertical-align: middle') p.help-block {{'options_ruleListUrlHelp' | tr}} p button.btn.btn-default(ng-disabled='!attached.sourceUrl' ng-click='updateProfile(attached.name)' ladda='updatingProfile[attached.name]' data-spinner-color="#000000" ng-class='attached.sourceUrl && !attached.lastUpdate ? "btn-primary" : "btn-default"') | #[span.glyphicon.glyphicon-download-alt] {{'options_downloadProfileNow' | tr}} section.settings-group(ng-if='attached') h3 {{'options_group_ruleListText' | tr}} p.alert.alert-success.width-limit(ng-show='attached.sourceUrl && attached.lastUpdate') | {{'options_ruleListLastUpdate' | tr:[(attached.lastUpdate | date:'medium')]}} p.alert.alert-danger.width-limit(ng-show='attached.sourceUrl && !attached.lastUpdate') | {{'options_ruleListObsolete' | tr}} p.alert.alert-danger.width-limit(ng-show='attachedRuleListError') span.glyphicon.glyphicon-remove = ' ' | {{attachedRuleListError.message}} textarea#attached-rulelist.monospace.form-control.width-limit(rows=20 ng-model='attached.ruleList' ng-disabled='!!attached.sourceUrl') ================================================ FILE: omega-web/src/partials/profile_unsupported.jade ================================================ .lead | {{'options_profileUnsupported' | tr:profile.profileType}} p {{'options_profileUnsupportedHelp' | tr}} ================================================ FILE: omega-web/src/partials/profile_virtual.jade ================================================ div section.settings-group h3 {{'options_group_virtualProfile' | tr}} p.help-block | {{'options_virtualProfileTargetHelp' | tr}} .form-group label {{'options_virtualProfileTarget' | tr}} = ' ' div(omega-profile-select='options | profiles:profile' ng-model='profile.defaultProfileName' disp-name='dispNameFilter' style='display: inline-block;' options='options') section.settings-group h3 {{'options_group_virtualProfileReplace' | tr}} p.help-block(omega-html='"options_virtualProfileReplaceHelp" | tr:[$profile("profileByName(profile.defaultProfileName)")]') .form-group button.btn.btn-default(ng-click='replaceProfile(profile.defaultProfileName, profile.name)') span.glyphicon.glyphicon-search = ' ' | {{'options_virtualProfileReplace' | tr}} ================================================ FILE: omega-web/src/partials/rename_profile.jade ================================================ form(ng-submit='renameProfile.$valid && $close(newName)' name='renameProfile') .modal-header button.close(type='button' ng-click='$dismiss()') span(aria-hidden='true') × span.sr-only {{'dialog_close' | tr}} h4.modal-title {{'options_modalHeader_renameProfile' | tr}} .modal-body .form-group(ng-class='{"has-error": !renameProfile.profileNewName.$valid}') label(for='profile-new-name') {{'options_renameProfileName' | tr}} input#profile-new-name.form-control(type='text' name='profileNewName' required ng-model='newName' ui-validate='validateProfileName' ng-init='newName = fromName') .help-block(ng-show='renameProfile.profileNewName.$error.required') {{'options_profileNameEmpty' | tr}} .help-block(ng-show='renameProfile.profileNewName.$error.reserved') {{'options_profileNameReserved' | tr}} .help-block(ng-show='!renameProfile.profileNewName.$error.reserved && renameProfile.profileNewName.$error.conflict') | {{'options_profileNameConflict' | tr}} .help-block(ng-show='renameProfile.profileNewName.$valid && newName && isProfileNameHidden(newName)') .text-info span.glyphicon.glyphicon-info-sign = ' ' | {{'options_profileNameHidden' | tr}} .modal-footer button.btn.btn-default(type='button' ng-click='$dismiss()') {{'dialog_cancel' | tr}} button.btn.btn-primary(type='submit' ng-disabled='!renameProfile.$valid') {{'options_renameProfile' | tr}} ================================================ FILE: omega-web/src/partials/replace_profile.jade ================================================ .modal-header button.close(type='button' ng-click='$dismiss()') span(aria-hidden='true') × span.sr-only {{'dialog_close' | tr}} h4.modal-title {{'options_modalHeader_replaceProfile' | tr}} .modal-body p(omega-html='"options_replaceProfileConfirm" | tr:[profileSelect("fromName"), profileSelect("toName")]') .well span(omega-profile-inline='profileByName(fromName)' options='options' disp-name='dispNameFilter') = ' ' span.glyphicon.glyphicon-chevron-right = ' ' span(omega-profile-inline='profileByName(toName)' options='options' disp-name='dispNameFilter') .help-block(omega-html="'options_replaceProfileHelp' | tr:[$profile('profileByName(fromName)'), $profile('profileByName(toName)')]") .modal-footer button.btn.btn-default(ng-click='$dismiss()') {{'dialog_cancel' | tr}} button.btn.btn-warning(type='button' ng-click='$close({fromName: fromName, toName: toName})') {{'options_replaceProfile' | tr}} ================================================ FILE: omega-web/src/partials/reset_options_confirm.jade ================================================ .modal-header button.close(type='button' ng-click='$dismiss()') span(aria-hidden='true') × span.sr-only {{'dialog_close' | tr}} h4.modal-title {{'options_modalHeader_resetOptions' | tr}} .modal-body p.text-danger {{'options_resetOptionsConfirm' | tr}} .modal-footer button.btn.btn-default(ng-click='$dismiss()') {{'dialog_cancel' | tr}} button.btn.btn-danger(type='button' ng-click='$close("ok")') {{'options_reset' | tr}} ================================================ FILE: omega-web/src/partials/rule_remove_confirm.jade ================================================ .modal-header button.close(type='button' ng-click='$dismiss()') span(aria-hidden='true') × span.sr-only {{'dialog_close' | tr}} h4.modal-title {{'options_modalHeader_deleteRule' | tr}} .modal-body p {{'options_deleteRuleConfirm' | tr}} div.well span.label.label-info {{'condition_' + rule.condition.conditionType | tr}} = ' ' | {{rule.condition.pattern}} span.pull-right span(omega-profile-inline='ruleProfile' disp-name='dispNameFilter' options='options') .modal-footer button.btn.btn-default(ng-click='$dismiss()') {{'dialog_cancel' | tr}} button.btn.btn-danger(type='button' ng-click='$close("ok")') {{'options_deleteRule' | tr}} ================================================ FILE: omega-web/src/partials/rule_reset_confirm.jade ================================================ .modal-header button.close(type='button' ng-click='$dismiss()') span(aria-hidden='true') × span.sr-only {{'dialog_close' | tr}} h4.modal-title {{'options_modalHeader_resetRules' | tr}} .modal-body p {{'options_resetRulesConfirm' | tr}} .well span(omega-profile-inline='ruleProfile' disp-name='dispNameFilter' options='options') .modal-footer button.btn.btn-default(ng-click='$dismiss()') {{'dialog_cancel' | tr}} button.btn.btn-warning(type='button' ng-click='$close("ok")') {{'options_resetRules' | tr}} ================================================ FILE: omega-web/src/partials/ui.jade ================================================ .page-header h2 {{'options_tab_ui' | tr}} section.settings-group h3 {{'options_group_miscOptions' | tr}} div.checkbox label input(type='checkbox' ng-model='options["-confirmDeletion"]') span {{'options_confirmDeletion' | tr}} div.checkbox label input#refresh-on-profile-change(type='checkbox' ng-model='options["-refreshOnProfileChange"]') span {{'options_refreshOnProfileChange' | tr}} div.checkbox label input(type='checkbox' ng-model='options["-showInspectMenu"]') span {{'options_showInspectMenu' | tr}} div.checkbox label input(type='checkbox' ng-model='options["-addConditionsToBottom"]') span {{'options_addConditionsToBottom' | tr}} section.settings-group h3 {{'options_group_keyboardShortcut' | tr}} p button.btn.btn-default(type='button' role='button' ng-click='openShortcutConfig()') span.glyphicon.glyphicon-share-alt = ' ' | {{'options_menuShortcutConfigure' | tr}} = ' ' | {{'options_menuShortcutHelp' | tr}} p.help-block | {{'options_menuShortcutMore' | tr}} section.settings-group h3 {{'options_group_switchOptions' | tr}} div.form-group label {{'options_startupProfile' | tr}} = ' ' div(omega-profile-select='options | profiles:"all"' ng-model='options["-startupProfileName"]' default-text="{{'options_startupProfile_none' | tr}}" disp-name='dispNameFilter' style='display: inline-block;' options='options') div.checkbox label input(type='checkbox' ng-model='options["-showConditionTypes"]' ng-true-value='1' ng-false-value='0') span {{'options_showConditionTypesAdvanced' | tr}} p.help-block | {{'options_showConditionTypesAdvancedHelp' | tr}} div.checkbox label input(type='checkbox' ng-model='options["-enableQuickSwitch"]') span {{'options_quickSwitch' | tr}} #quick-switch-settings.settings-group(ng-show='options["-enableQuickSwitch"]' ng-controller='QuickSwitchCtrl') h4 {{'options_cycledProfiles' | tr}} p.help-block {{'options_cycledProfilesHelp' | tr}} div.has-error(ng-show='options["-quickSwitchProfiles"].length < 2') p.help-block {{'options_cycledProfilesTooFew' | tr}} ul.cycle-profile-container.cycle-enabled(ui-sortable="sortableOptions" ng-model='options["-quickSwitchProfiles"]') li(ng-repeat='name in options["-quickSwitchProfiles"]') span(omega-profile-inline='profileByName(name)' options='options' disp-name='dispNameFilter') h4 {{'options_notCycledProfiles' | tr}} ul.cycle-profile-container(ui-sortable="sortableOptions" ng-model='notCycledProfiles') li.bg-success(ng-repeat='name in notCycledProfiles') span(omega-profile-inline='profileByName(name)' options='options' disp-name='dispNameFilter') ================================================ FILE: omega-web/src/popup/css/dialog.css ================================================ /*! * Copyright 2017 The SwitchyOmega Authors. Please see the AUTHORS file * for details. * Based on Bootstrap v3.3.2 (http://getbootstrap.com) * Copyright 2011-2015 Twitter, Inc. * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) */ /* Dialog */ body, html { margin: 0; padding: 0; } p { margin: 0 0 1em 0; } .om-dialog { min-width: 400px; padding: 10px 10px; font-size: 14px; } .om-text-danger { color: #a94442; } .om-dialog-help { display: block; margin-top: 5px; margin-bottom: 10px; color: #737373; } .om-dialog-controls { margin-bottom: 0; } .om-dialog-controls .om-btn-primary { float: right; } /* Button */ .om-btn { display: inline-block; padding: 6px 12px; margin-bottom: 0; font-size: 14px; font-weight: 400; line-height: 1.42857143; text-align: center; white-space: nowrap; vertical-align: middle; -ms-touch-action: manipulation; touch-action: manipulation; cursor: pointer; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; background-image: none; border: 1px solid transparent; border-radius: 4px } .om-btn.active, .om-btn:active { background-image: none; outline: 0; -webkit-box-shadow: inset 0 3px 5px rgba(0,0,0,.125); box-shadow: inset 0 3px 5px rgba(0,0,0,.125); } .om-btn-default { color: #333; background-color: #fff; border-color: #ccc; } .om-btn-default:hover { background-color: #e6e6e6; border-color: #adadad; } .om-btn-link { font-weight: 400; color: #337ab7; border-radius: 0; background-color: rgba(0, 0, 0, 0); -webkit-box-shadow: none; box-shadow: none; border-color: rgba(0, 0, 0, 0); } .om-btn-link:hover { color: #23527c; text-decoration: underline; background-color: rgba(0, 0, 0, 0); } .om-btn-link:active { background-color: rgba(0, 0, 0, 0); -webkit-box-shadow: none; box-shadow: none; } .om-btn-primary { color: #fff; background-color: #337ab7; border-color: #2e6da4; } .om-btn-primary:hover { color: #fff; background-color: #286090; border-color: #204d74; } ================================================ FILE: omega-web/src/popup/css/index.css ================================================ /*! * Copyright 2017 The SwitchyOmega Authors. Please see the AUTHORS file * for details. * Based on Bootstrap v3.3.2 (http://getbootstrap.com) * Copyright 2011-2015 Twitter, Inc. * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) */ /* Layout */ html, body { font-family: "Helvetica Neue",Helvetica,Arial,sans-serif; font-size: 14px; padding: 0; margin: 0; } body { min-width: 12em; } .om-hidden { display: none !important; } /* Menu */ .om-nav { list-style: none; padding: 0; margin: 0; } .om-nav-item { display: block; margin: 2px 0; } .om-nav-item > a > .glyphicon { margin-right: 8px; } .om-nav-item > a { display: block; padding: 5px 25px 5px 8px; border-radius: 4px; line-height: 1.5em; font-size: 1em; color: #337ab7; text-decoration: none; white-space: nowrap; cursor: pointer; } .om-nav-item > a:hover { text-decoration: none; background-color: #eee; } .om-nav-item > a:hover { color: #23527c; } .om-nav-item.om-effective > a { background-color: #d9edf7; } .om-nav-item.om-active > a { color: #fff; background-color: #337ab7; } .om-divider { height: 1px; overflow: hidden; background-color: #E5E5E5; } .om-reqinfo { background-color: #fcf8e3; } .glyphicon-warning-sign { color: #8a6d3b; } /* Dropdown */ .om-dropdown { display: none; list-style: none; padding: 5px 0; margin: 0 5px !important; border: 1px solid rgba(0,0,0,.15); border-radius: 4px; box-shadow: 0 6px 12px rgba(0,0,0,.175); } .om-open .om-dropdown { display: block; } .om-dropdown .om-nav-item { margin: 0; } .om-dropdown .om-nav-item > a { padding: 3px 20px; line-height: 1.3em; margin: 0; } .om-caret { display: inline-block; width: 0; height: 0; margin-left: 2px; vertical-align: middle; border-top: 4px solid; border-right: 4px solid transparent; border-left: 4px solid transparent; } .om-virtual-profile-icon { border: dotted 1px; margin: -1px; } /* Default Edit */ .om-has-edit { padding-right: 32px; position: relative; } .om-edit-toggle { background-color: #fff; border: 1px solid #ccc; color: #337ab7; display: inline-block; margin: -5px 0; text-align: center; padding: 5px 8px 3px; position: absolute; right: 0; } .om-edit-toggle:hover { background-color: #e6e6e6; border-color: #adadad; } /* Keyboard */ .om-keyboard-help { font-family: Menlo, Monaco, Consolas, "Courier New", monospace; border: solid 1px #000; border-radius: 2px; display: inline-block; color: #000; box-shadow: 1px 1px; width: 1em; height: 1em; line-height: 1em; text-align: center; margin-top: -3px; } /* Glyphicons */ @font-face { font-family: 'Glyphicons Halflings'; src: url(../../../lib/bootstrap/fonts/glyphicons-halflings-regular.eot); src: url(../../../lib/bootstrap/fonts/glyphicons-halflings-regular.eot?#iefix) format('embedded-opentype'),url(../../../lib/bootstrap/fonts/glyphicons-halflings-regular.woff2) format('woff2'),url(../../../lib/bootstrap/fonts/glyphicons-halflings-regular.woff) format('woff'),url(../../../lib/bootstrap/fonts/glyphicons-halflings-regular.ttf) format('truetype'),url(../../../lib/bootstrap/fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular) format('svg') } .glyphicon { position: relative; top: 1px; display: inline-block; font-family: 'Glyphicons Halflings'; font-style: normal; font-weight: 400; line-height: 1; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; } .glyphicon-transfer:before { content: "\e178"; } .glyphicon-off:before { content: "\e017"; } .glyphicon-warning-sign:before { content: "\e107"; } .glyphicon-file:before { content: "\e022" } .glyphicon-globe:before { content: "\e135" } .glyphicon-question-sign:before { content: "\e085" } .glyphicon-list:before { content: "\e056" } .glyphicon-retweet:before { content: "\e115" } .glyphicon-plus:before { content: "\2b" } .glyphicon-filter:before { content: "\e138" } .glyphicon-wrench:before { content: "\e136" } .glyphicon-chevron-down:before { content: "\e114"; } ================================================ FILE: omega-web/src/popup/index.html ================================================ SwitchyOmega Popup ================================================ FILE: omega-web/src/popup/js/i18n.js ================================================ $script.ready('om-page-info', function() { document.querySelector('#js-direct .om-profile-name').textContent = OmegaTargetPopup.getMessage('profile_direct'); document.querySelector('#js-system .om-profile-name').textContent = OmegaTargetPopup.getMessage('profile_system'); document.querySelector('#js-addrule-label').textContent = OmegaTargetPopup.getMessage('popup_addCondition'); document.querySelector('#js-option-label').textContent = OmegaTargetPopup.getMessage('popup_showOptions'); }); ================================================ FILE: omega-web/src/popup/js/index.js ================================================ (function() { handleClick('js-option', showOptions); handleClick('js-temprule', showTempRuleDropdown); handleClick('js-direct', applyProfile.bind(this, 'direct')); handleClick('js-system', applyProfile.bind(this, 'system')); OmegaPopup.addTempRule = addTempRule; OmegaPopup.setDefaultProfile = setDefaultProfile; OmegaPopup.applyProfile = applyProfile; return; function handleClick(id, handler) { document.getElementById(id).addEventListener('click', handler, false); } function closePopup() { window.close(); // If the popup is opened as a tab, the above won't work. Let's reload then. document.body.style.opacity = 0; setTimeout(function() { history.go(0); }, 300); } function showOptions(e) { if (typeof OmegaTargetPopup !== 'undefined') { try { OmegaTargetPopup.openOptions(null, closePopup); e.preventDefault(); } catch (_) { } } } function applyProfile(profileName) { $script.ready('om-target', function() { OmegaTargetPopup.applyProfile(profileName, closePopup); }); } function setDefaultProfile(profileName, defaultProfileName) { $script.ready('om-target', function() { OmegaTargetPopup.setDefaultProfile(profileName, defaultProfileName, closePopup); }); } function addTempRule(domain, profileName) { $script.ready('om-target', function() { OmegaTargetPopup.addTempRule(domain, profileName, closePopup); }); } function showTempRuleDropdown() { $script.ready('om-dropdowns', function() { OmegaPopup.showTempRuleDropdown(); }); } })(); ================================================ FILE: omega-web/src/popup/js/keyboard.js ================================================ (function() { var keyHandler = { 38: moveUp, // Up 40: moveDown, // Down 37: closeDropdown, // Left 39: openDropdown, // Right 72: closeDropdown, // h 74: moveDown, // j 75: moveUp, // k 76: openDropdown, // l 191: showKeyboardHelp, // / 63: showKeyboardHelp, // ? 48: 'js-direct', // 0 83: 'js-system', // s 69: 'js-external', // e 65: 'js-addrule', // a 187: 'js-addrule', // +, = 84: 'js-temprule', // t 79: 'js-option', // o 82: 'js-reqinfo', // r }; for (i = 1; i <= 9; i++) { keyHandler[48 + i] = 'js-profile-' + i; } var walker; return init(); function init() { walker = document.createTreeWalker( document.querySelector('.om-nav'), NodeFilter.SHOW_ELEMENT, {acceptNode: tabbableElementsOnly} ); window.addEventListener('keydown', function(e) { var handler = keyHandler[e.keyCode]; if (!handler) console.log(e.keyCode); if (handler == null) return; if (e.target.tagName === 'INPUT' || e.target.tagName === 'TEXTAREA') return; if (typeof handler === 'string') { clickById(handler); } else { handler(); } }); $script.ready('om-profile-items', function() { var activeNavLink = document.querySelector('.om-nav-item.om-active > a'); if (activeNavLink) activeNavLink.focus(); }); } function tabbableElementsOnly(node) { if (node.classList.contains('om-hidden')) { return NodeFilter.FILTER_REJECT; } else if (node.classList.contains('om-dropdown') && !node.parentElement.classList.contains('om-open')) { return NodeFilter.FILTER_REJECT; } else if (node.tabIndex >= 0) { return NodeFilter.FILTER_ACCEPT; } else { return NodeFilter.FILTER_SKIP; } } function moveUp() { walker.currentNode = document.activeElement; var result = null; if (walker.currentNode) { result = walker.previousNode(); } if (!result) { walker.currentNode = walker.root.lastElementChild; walker.previousNode(); walker.nextNode(); } walker.currentNode.focus(); } function moveDown() { walker.currentNode = document.activeElement; var result = null; if (walker.currentNode) { result = walker.nextNode(); } if (!result) { walker.currentNode = walker.root; walker.nextNode(); } walker.currentNode.focus(); } function openDropdown() { var container = document.querySelector('.om-open'); if (container) { // Existing dropdown. Just move to it. container.querySelector('a').focus(); return; } var selectedItem = document.activeElement; if (!selectedItem || !selectedItem.parentElement) return; if (selectedItem.parentElement.classList.contains('om-has-dropdown')) { var toggle = selectedItem.querySelector('.om-edit-toggle'); if (toggle) { toggle.click(); } else { selectedItem.click(); } } } function closeDropdown() { var container = document.querySelector('.om-open'); if (container) { container.classList.remove('om-open'); container.querySelector('a').focus(); } } function showKeyboardHelp() { $script('js/keyboard_help.js'); } function clickById(id) { var element = document.getElementById(id); if (element) element.click(); } })(); ================================================ FILE: omega-web/src/popup/js/keyboard_help.js ================================================ (function() { var keyForId = { 'js-direct': '0', 'js-system': 'S', 'js-external': 'E', 'js-addrule': 'A', 'js-temprule': 'T', 'js-option': 'O', 'js-reqinfo': 'R' } Object.keys(keyForId).forEach(function (id) { showHelp(id, keyForId[id]); }); for (var i = 1; i <= 9; i++) { showHelp('js-profile-' + i, '' + i); } return; function showHelp(id, key) { var element = document.getElementById(id); if (!element) return; if (!element.querySelector('.om-keyboard-help')) { var span = document.createElement('span'); span.classList.add('om-keyboard-help'); span.textContent = key; var reference = element.querySelector('.glyphicon'); reference.parentNode.insertBefore(span, reference.nextSibling); } } })(); ================================================ FILE: omega-web/src/popup/js/loader.js ================================================ window.OmegaPopup = {}; $script(['js/index.js', 'js/profiles.js', 'js/keyboard.js'], 'om-main'); $script(['js/i18n.js']); $script('../js/omega_target_popup.js', 'om-target', function() { OmegaTargetPopup.getActivePageInfo(function(err, info) { window.OmegaPopup.pageInfo = info; $script.done('om-page-info'); }); OmegaTargetPopup.getState([ 'availableProfiles', 'currentProfileName', 'validResultProfiles', 'isSystemProfile', 'currentProfileCanAddRule', 'proxyNotControllable', 'externalProfile', 'showExternalProfile', ], function(err, state) { window.OmegaPopup.state = state; $script.done('om-state'); }); }); ================================================ FILE: omega-web/src/popup/js/profiles.js ================================================ (function() { $script.ready('om-state', updateMenuByState); $script.ready('om-page-info', updateMenuByPageInfo); $script.ready(['om-state', 'om-page-info'], updateMenuByStateAndPageInfo); var profileTemplate = document.getElementById('js-profile-tpl') .cloneNode(true); profileTemplate.removeAttribute('id'); var iconForProfileType = { 'DirectProfile': 'glyphicon-transfer', 'SystemProfile': 'glyphicon-off', 'AutoDetectProfile': 'glyphicon-file', 'FixedProfile': 'glyphicon-globe', 'PacProfile': 'glyphicon-file', 'VirtualProfile': 'glyphicon-question-sign', 'RuleListProfile': 'glyphicon-list', 'SwitchProfile': 'glyphicon-retweet', }; var orderForType = { 'FixedProfile': -2000, 'PacProfile': -1000, 'VirtualProfile': 1000, 'SwitchProfile': 2000, 'RuleListProfile': 3000, }; return; function updateMenuByState() { var state = OmegaPopup.state; if (state.proxyNotControllable) { location.href = 'proxy_not_controllable.html'; return; } addProfilesItems(state); $script.done('om-profile-items'); updateOtherItems(state); } function compareProfile(a, b) { var diff; diff = (orderForType[a.profileType] | 0) - (orderForType[b.profileType] | 0); if (diff !== 0) { return diff; } if (a.name === b.name) { return 0; } else if (a.name < b.name) { return -1; } else { return 1; } } function updateMenuByPageInfo() { var info = OmegaPopup.pageInfo; if (info && info.errorCount > 0) { document.querySelector('.om-reqinfo').classList.remove('om-hidden'); var text = OmegaTargetPopup.getMessage('popup_requestErrorCount', [info.errorCount]); document.querySelector('.om-reqinfo-text').textContent = text; } } function updateMenuByStateAndPageInfo() { var state = OmegaPopup.state; var info = OmegaPopup.pageInfo; if (state.showExternalProfile && state.externalProfile && (!info || !info.errorCount)) { showMenuForExternalProfile(state); } if (!info || !info.url) return updateOtherItems(null); document.querySelector('.om-page-domain').textContent = info.domain; OmegaPopup.showTempRuleDropdown = showTempRuleDropdown; $script.done('om-dropdowns'); } function showMenuForExternalProfile(state) { var profile = state.externalProfile; profile.name = OmegaTargetPopup.getMessage('popup_externalProfile') var profileDisp = createMenuItemForProfile(profile); var link = profileDisp.querySelector('a'); link.id = 'js-external'; link.addEventListener('click', function() { location.href = '../popup.html#!external'; }); if (state.currentProfileName === '') { profileDisp.classList.add('om-effective'); } var reqInfo = document.querySelector('.om-reqinfo'); reqInfo.parentElement.insertBefore(profileDisp, reqInfo); } function showTempRuleDropdown() { var tempRuleItem = document.querySelector('.om-nav-temprule'); toggleDropdown(tempRuleItem, createTempRuleDropdown); document.getElementById('js-temprule').focus(); } function updateOtherItems(state) { var hasValidResults = state && state.validResultProfiles && state.validResultProfiles.length; if (!hasValidResults || !state.currentProfileCanAddRule) { document.querySelector('.om-nav-addrule').classList.add('om-hidden'); document.getElementById('js-addrule').href = '#'; } if (!hasValidResults) { document.querySelector('.om-nav-temprule').classList.add('om-hidden'); document.getElementById('js-temprule').href = '#'; } } var isValidResultProfile = {}; validResultProfiles.forEach(function(name) { isValidResultProfile['+' + name] = true; }); function addProfilesItems(state) { var systemProfileDisp = document.getElementById('js-system'); var directProfileDisp = document.getElementById('js-direct'); var currentProfileClass = 'om-active'; if (state.isSystemProfile) { systemProfileDisp.parentElement.classList.add('om-active'); currentProfileClass = 'om-effective'; } if (state.currentProfileName === 'direct') { directProfileDisp.parentElement.classList.add(currentProfileClass); } systemProfileDisp.setAttribute('title', state.availableProfiles['+system'].desc); directProfileDisp.setAttribute('title', state.availableProfiles['+direct'].desc); var profilesEnd = document.getElementById('js-profiles-end'); var profilesContainer = profilesEnd.parentElement; var profileCount = 0; var charCodeUnderscore = '_'.charCodeAt(0) var profiles = Object.keys(state.availableProfiles).map(function(key) { return state.availableProfiles[key]; }).sort(compareProfile); profiles.forEach(function(profile) { if (profile.builtin) return; if (profile.name.charCodeAt(0) === charCodeUnderscore) return; profileCount++; var profileDisp = createMenuItemForProfile(profile, state.availableProfiles); var link = profileDisp.querySelector('a'); link.id = 'js-profile-' + profileCount; link.addEventListener('click', function() { $script.ready('om-main', function() { OmegaPopup.applyProfile(profile.name); }); }); if (profile.name === state.currentProfileName) { profileDisp.classList.add(currentProfileClass); } if (profile.validResultProfiles) { profileDisp.classList.add('om-has-dropdown'); link.classList.add('om-has-edit'); var toggle = document.createElement('div'); toggle.classList.add('om-edit-toggle'); var icon = document.createElement('span'); icon.setAttribute('class', 'glyphicon glyphicon-chevron-down'); toggle.appendChild(icon); toggle.addEventListener('click', function(e) { e.stopPropagation(); e.preventDefault(); toggleDropdown(profileDisp, createDefaultProfileDropdown.bind(profileDisp, profile)); }); link.appendChild(toggle); } profilesContainer.insertBefore(profileDisp, profilesEnd); }); } function createMenuItemForProfile(profile, profiles) { var profileDisp = profileTemplate.cloneNode(true); var text = OmegaTargetPopup.getMessage('profile_' + profile.name) || profile.name; if (profile.defaultProfileName) { text += ' [' + profile.defaultProfileName + ']'; } profileDisp.querySelector('.om-profile-name').textContent = text; var targetProfile = profile; if (profile.profileType === 'VirtualProfile') { targetProfile = profiles['+' + profile.defaultProfileName]; } profileDisp.setAttribute('title', targetProfile.desc || targetProfile.name || ''); var iconClass = iconForProfileType[targetProfile.profileType]; var icon = profileDisp.querySelector('.glyphicon'); icon.setAttribute('class', 'glyphicon ' + iconClass) icon.style.color = targetProfile.color; if (targetProfile !== profile) { icon.classList.add('om-virtual-profile-icon'); } return profileDisp; } function toggleDropdown(container, createDropdown) { if (!container.classList.contains('om-dropdown-loaded')) { var dropdown = createDropdown(); dropdown.classList.add('om-dropdown'); container.appendChild(dropdown); container.classList.add('om-dropdown-loaded'); } if (container.classList.contains('om-open')) { container.classList.remove('om-open'); } else { container.classList.add('om-open'); } } function createTempRuleDropdown() { var ul = document.createElement('ul'); var state = OmegaPopup.state; var pageInfo = OmegaPopup.pageInfo; var profiles = state.validResultProfiles.map(function(name) { return state.availableProfiles['+' + name]; }).sort(compareProfile); profiles.forEach(function(profile) { if (profile.name.indexOf('__') === 0) return; if ((profile.name === OmegaPopup.state.currentProfileName) && (!pageInfo.tempRuleProfileName) && (state.validResultProfiles.length > 1) ) return; var li = createMenuItemForProfile(profile, state.availableProfiles); var link = li.querySelector('a'); link.addEventListener('click', function() { $script.ready('om-main', function() { OmegaPopup.addTempRule(pageInfo.domain, profile.name); }); }); if (profile.name === pageInfo.tempRuleProfileName) { li.classList.add('om-active'); } ul.appendChild(li); }); return ul; } function createDefaultProfileDropdown(profile) { var ul = document.createElement('ul'); var state = OmegaPopup.state; var profiles = profile.validResultProfiles.map(function(name) { return state.availableProfiles['+' + name]; }).sort(compareProfile); profiles.forEach(function(resultProfile) { if (resultProfile.name.indexOf('__') === 0) return; if ((resultProfile === profile.currentProfileName) && (profile.validResultProfiles.length > 1) ) return; var li = createMenuItemForProfile(resultProfile, state.availableProfiles); var link = li.querySelector('a'); link.addEventListener('click', function() { $script.ready('om-main', function() { OmegaPopup.setDefaultProfile(profile.name, resultProfile.name); }); }); if (resultProfile.name === profile.currentProfileName) { li.classList.add('om-active'); } ul.appendChild(li); }); return ul; } })(); ================================================ FILE: omega-web/src/popup/js/proxy_not_controllable.js ================================================ (function() { function closePopup() { window.close(); // If the popup is opened as a tab, the above won't work. Let's reload then. document.body.style.opacity = 0; setTimeout(function() { history.go(0); }, 300); } var closeButton = document.getElementById('js-close'); closeButton.addEventListener('click', closePopup, false); var manageButton = document.getElementById('js-manage-ext'); manageButton.addEventListener('click', function () { OmegaTargetPopup.openManage(closePopup); }, false); var learnMoreButton = document.getElementById('js-nc-learn-more'); learnMoreButton.addEventListener('click', function () { OmegaTargetPopup.openOptions('#!/general', closePopup); }, false); closeButton.textContent = OmegaTargetPopup.getMessage('dialog_cancel'); learnMoreButton.textContent = 'Learn More' //OmegaTargetPopup.getMessage('popup_proxyNotControllableLearnMore'); manageButton.textContent = OmegaTargetPopup.getMessage( 'popup_proxyNotControllableManage'); OmegaTargetPopup.getState([ 'proxyNotControllable', ], function(err, state) { var reason = state.proxyNotControllable; var messageElement = document.getElementById('js-nc-text'); var detailsElement = document.getElementById('js-nc-details'); messageElement.textContent = OmegaTargetPopup.getMessage( 'popup_proxyNotControllable_' + reason); var detailsMessage = OmegaTargetPopup.getMessage( 'popup_proxyNotControllableDetails_' + reason); if (!detailsMessage) detailsMessage = OmegaTargetPopup.getMessage( 'popup_proxyNotControllableDetails'); detailsElement.textContent = detailsMessage; }); })(); ================================================ FILE: omega-web/src/popup/proxy_not_controllable.html ================================================ SwitchyOmega Popup

================================================ FILE: omega-web/src/popup.jade ================================================ doctype html // Copyright 2017 The SwitchyOmega Authors. Please see the AUTHORS file for details. This file is part of SwitchyOmega. SwitchyOmega is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. SwitchyOmega is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with SwitchyOmega. If not, see . html(lang='en' ng-app='omegaPopup' ng-controller='PopupCtrl' ng-csp) head meta(charset='utf-8') title {{'popup_title' | tr}} meta(name='viewport' content='width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no') link(rel='stylesheet' href='lib/bootstrap/css/bootstrap.min.css') link(rel='stylesheet' href='css/popup.css') body(ng-class='{"with-condition-form": showConditionForm}') ul.popup-menu-nav.nav.nav-pills.nav-stacked(ng-hide='showConditionForm || proxyNotControllable || showRequestInfo') li.profile(ng-repeat='profile in builtinProfiles' ng-class='{active: isActive(profile.name), "bg-info": isEffective(profile.name)}') a(href='#' role='button' ng-attr-tabindex='{{100 + $index}}' ng-click='applyProfile(profile)' title='{{getProfileTitle(profile)}}' data-shortcut='+{{profile.name}}') span(omega-profile-inline='profile' icon='getIcon(profile)' options='availableProfiles' disp-name='dispNameFilter') li.profile.external-profile(ng-show='!requestInfoProvided && !!externalProfile' ng-class='{active: isActive(""), "bg-info": isEffective("")}') a(href='#' role='button' ng-click='nameExternal.open = true' title='{{getProfileTitle(externalProfile)}}' data-shortcut='external') form(name='nameExternalForm' ng-submit='nameExternalForm.$valid && saveExternal()') span(omega-profile-icon='externalProfile' icon='getIcon(externalProfile, "normal")' options='availableProfiles' disp-name='dispNameFilter') = ' ' span(ng-show='!nameExternal.open') {{'popup_externalProfile' | tr}} input.form-control(ng-show='!!nameExternal.open' ng-model='externalProfile.name' ng-blur='nameExternalForm.$valid && saveExternal()' placeholder='{{"popup_externalProfileName" | tr}}' ui-validate='validateProfileName' autofocus) li.request-info(ng-show='!!requestInfoProvided' class='bg-warning') a(href='#' role='button' ng-click='showRequestInfo = true' data-shortcut='requestInfo') span.glyphicon.glyphicon-warning-sign.text-warning = ' ' | {{'popup_requestErrorCount' | tr:[requestInfo.errorCount]}} li.divider li.profile.custom-profile(ng-repeat='profile in customProfiles' ng-class='{active: isActive(profile.name), "bg-info": isEffective(profile.name)}' dropdown) a(href='#' role='button' ng-click='applyProfile(profile)' ng-if='!profile.validResultProfiles' title='{{getProfileTitle(profile)}}') span(omega-profile-inline='profile' icon='getIcon(profile)' options='availableProfiles' disp-name='dispNameFilter') a.profile-with-default-edit(href='#' role='button' ng-click='applyProfile(profile)' ng-if='!!profile.validResultProfiles' title='{{getProfileTitle(profile)}}') span(omega-profile-inline='profile' icon='getIcon(profile)' options='availableProfiles' disp-name='dispNameFilter') = ' ' | [{{profile.defaultProfileName}}] button.dropdown-toggle.btn.btn-default(role='button' dropdown-toggle href='#' ng-click='$event.stopPropagation()') span.glyphicon.glyphicon-chevron-down ul.dropdown-menu(ng-if='!!profile.validResultProfiles') li(ng-repeat='p in profile.validResultProfiles' ng-class='{active: p.name == profile.defaultProfileName}') a(href='#' role='button' ng-click='setDefaultProfile(profile.name, p.name)' title='{{getProfileTitle(profile)}}') span(omega-profile-inline='p' options='availableProfiles' disp-name='dispNameFilter') li.divider(ng-show='!!currentDomain && validResultProfiles.length') li(ng-show='!!currentProfileCanAddRule && !!currentDomain') a(href='#' role='button' ng-click='prepareConditionForm()' data-shortcut='addRule') span.glyphicon.glyphicon-plus = ' ' span {{'popup_addCondition' | tr}} li(ng-show='!!currentDomain && validResultProfiles.length' dropdown is-open="tempRuleMenu.open") a.dropdown-toggle(href='#' role='button' dropdown-toggle data-shortcut='tempRule') span.glyphicon.glyphicon-filter = ' ' span.current-domain {{currentDomain}} span.caret ul.dropdown-menu li(ng-repeat='profile in validResultProfiles' ng-class='{active: profile.name == currentTempRuleProfile}' ng-show='!!currentTempRuleProfile || validResultProfiles.length == 1 || profile.name != currentProfileName') a(href='#' role='button' ng-click='addTempRule(currentDomain, profile.name)' title='{{getProfileTitle(profile)}}') span(omega-profile-inline='profile' options='availableProfiles' disp-name='dispNameFilter') li.divider li a(href='#' role='button' ng-click='openOptions()' data-shortcut='option') span.glyphicon.glyphicon-wrench = ' ' span {{'popup_showOptions' | tr}} form.condition-form(name='conditionForm' style='display: none;' ng-style='{display: showConditionForm ? "block" : "none"}' ng-submit='addCondition(rule.condition, rule.profileName)') fieldset legend | {{'popup_addConditionTo' | tr}} = ' ' span.profile-inline span(omega-profile-inline='currentProfile' options='availableProfiles' disp-name='dispNameFilter') div.form-group label | {{'options_conditionType' | tr}} = ' ' button.btn.btn-link.btn-sm.clear-padding(type='button' ng-click='openConditionHelp()') | {{"options_showConditionTypeHelp" | tr}} = ' ' span.glyphicon.glyphicon-new-window select.form-control(ng-model='rule.condition.conditionType') option(value='HostWildcardCondition') {{'condition_HostWildcardCondition' | tr}} option(value='HostRegexCondition') {{'condition_HostRegexCondition' | tr}} option(value='UrlWildcardCondition') {{'condition_UrlWildcardCondition' | tr}} option(value='UrlRegexCondition') {{'condition_UrlRegexCondition' | tr}} option(value='KeywordCondition') {{'condition_KeywordCondition' | tr}} div.form-group label {{'options_conditionDetails' | tr}} input.form-control.condition-details(type='text' required ng-model='rule.condition.pattern' autofocus) div.form-group label {{'options_resultProfile' | tr}} div(omega-profile-select='validResultProfiles' ng-model='rule.profileName' disp-name='dispNameFilter' options='availableProfiles') div.condition-controls button.btn.btn-default(type='button' ng-click='returnToMenu()') | {{'dialog_cancel' | tr}} button.btn.btn-primary(type='submit' ng-disabled='conditionForm.$invalid') {{'popup_addCondition' | tr}} div.proxy-not-controllable(ng-show='proxyNotControllable') p.text-danger {{'popup_proxyNotControllable_' + proxyNotControllable | tr}} p.help-block {{('popup_proxyNotControllableDetails_' + proxyNotControllable | tr) || ('popup_proxyNotControllableDetails' | tr)}} p.proxy-not-controllable-controls button.btn.btn-default(ng-click='closePopup()') {{'dialog_cancel' | tr}} button.btn.btn-primary(ng-click='openManage()') {{'popup_proxyNotControllableManage' | tr}} div.request-info-details(ng-show='showRequestInfo') form.request-info-details(style='display: none;' ng-style='{display: showRequestInfo ? "block" : "none"}' ng-submit='addConditionForDomains(domainsForCondition, profileForDomains)') fieldset legend(ng-show='!!currentProfileCanAddRule') | {{'popup_addConditionTo' | tr}} = ' ' span.profile-inline span(omega-profile-inline='currentProfile' options='availableProfiles' disp-name='dispNameFilter') legend(ng-show='!currentProfileCanAddRule') | {{'popup_requestErrorHeading' | tr}} .text-warning {{'popup_requestErrorWarning' | tr}} p.help-block {{'popup_requestErrorWarningHelp' | tr}} p.help-block(ng-show='!!currentProfileCanAddRule') {{'popup_requestErrorAddCondition' | tr}} .checkbox(ng-repeat='domain in requestInfo.domains track by domain.domain') label input(type='checkbox' ng-model='domainsForCondition[domain.domain]' autofocus ng-if='$index === 0') input(type='checkbox' ng-model='domainsForCondition[domain.domain]' ng-if='$index > 0') span.label.label-warning {{domain.errorCount}} =' {{domain.domain}}' div.form-group(ng-show='!!currentProfileCanAddRule') label {{'options_resultProfileForSelectedDomains' | tr}} div(omega-profile-select='validResultProfiles' ng-model='profileForDomains' disp-name='dispNameFilter' options='availableProfiles') p.help-block(ng-show='!currentProfileCanAddRule') | {{'popup_requestErrorCannotAddCondition' | tr}} div.condition-controls button.btn.btn-default(type='button' ng-click='returnToMenu()') | {{'dialog_cancel' | tr}} button.btn.btn-primary(type='submit' ng-show='!!currentProfileCanAddRule') {{'popup_addCondition' | tr}} button.btn.btn-default.pull-right(type='button' ng-show='!currentProfileCanAddRule' ng-click='openOptions("#/general")') {{'popup_configureMonitorWebRequests' | tr}} script(src='js/log_error.js') script(src='lib/jquery/jquery.min.js') script(src='lib/angular/angular.min.js') script(src='lib/angular-bootstrap/ui-bootstrap-tpls.min.js') script(src='lib/angular-ui-utils/validate.min.js') script(src='js/omega_target_web.js') script(src='js/omega_decoration.js') script(src='js/popup.js')