Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWalter Bender <walter.bender@gmail.com>2012-04-03 23:01:48 (GMT)
committer Walter Bender <walter.bender@gmail.com>2012-04-03 23:01:48 (GMT)
commitf8a66c1d8fde0d0a59f3217bd7589eff22f40f47 (patch)
treee4ed55087edb402c27421b729c66deab1b7477e4
parent85c80742d44d3175e327bdb4852027c2ecd33e31 (diff)
Python rebase
-rw-r--r--COPYING675
-rw-r--r--NEWS11
-rw-r--r--XOEditorActivity.py153
-rw-r--r--activity/activity.info16
-rw-r--r--game.py293
-rw-r--r--html/.svn/all-wcprops17
-rw-r--r--html/.svn/entries52
-rw-r--r--html/.svn/format1
-rw-r--r--html/.svn/text-base/prototype.js.svn-base3277
-rw-r--r--html/.svn/text-base/xo-color.xml.svn-base964
-rw-r--r--html/prototype.js3277
-rw-r--r--html/xo-color.xml970
-rw-r--r--logic.py48
-rw-r--r--logic.pycbin1380 -> 0 bytes
-rw-r--r--result.py25
-rw-r--r--result.pycbin539 -> 0 bytes
-rw-r--r--server.py59
-rw-r--r--server.pycbin2158 -> 0 bytes
-rw-r--r--sprites.py459
-rw-r--r--toolbar_utils.py164
-rw-r--r--webviewer.py147
-rw-r--r--webviewer.pycbin5822 -> 0 bytes
-rw-r--r--xoEditorActivity.py74
-rw-r--r--xoEditorActivity.pycbin2200 -> 0 bytes
24 files changed, 1761 insertions, 8921 deletions
diff --git a/COPYING b/COPYING
new file mode 100644
index 0000000..10926e8
--- /dev/null
+++ b/COPYING
@@ -0,0 +1,675 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+ The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works. By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users. We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors. You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+ To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights. Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received. You must make sure that they, too, receive
+or can get the source code. And you must show them these terms so they
+know their rights.
+
+ Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+ For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software. For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+ Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so. This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software. The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable. Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products. If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+ Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary. To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ TERMS AND CONDITIONS
+
+ 0. Definitions.
+
+ "This License" refers to version 3 of the GNU General Public License.
+
+ "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+ "The Program" refers to any copyrightable work licensed under this
+License. Each licensee is addressed as "you". "Licensees" and
+"recipients" may be individuals or organizations.
+
+ To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy. The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+ A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+ To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy. Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+ To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies. Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+ An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License. If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+ 1. Source Code.
+
+ The "source code" for a work means the preferred form of the work
+for making modifications to it. "Object code" means any non-source
+form of a work.
+
+ A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+ The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form. A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+ The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities. However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work. For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+ The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+ The Corresponding Source for a work in source code form is that
+same work.
+
+ 2. Basic Permissions.
+
+ All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met. This License explicitly affirms your unlimited
+permission to run the unmodified Program. The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work. This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+ You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force. You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright. Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+ Conveying under any other circumstances is permitted solely under
+the conditions stated below. Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+ 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+ No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+ When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+ 4. Conveying Verbatim Copies.
+
+ You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+ You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+ 5. Conveying Modified Source Versions.
+
+ You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+ a) The work must carry prominent notices stating that you modified
+ it, and giving a relevant date.
+
+ b) The work must carry prominent notices stating that it is
+ released under this License and any conditions added under section
+ 7. This requirement modifies the requirement in section 4 to
+ "keep intact all notices".
+
+ c) You must license the entire work, as a whole, under this
+ License to anyone who comes into possession of a copy. This
+ License will therefore apply, along with any applicable section 7
+ additional terms, to the whole of the work, and all its parts,
+ regardless of how they are packaged. This License gives no
+ permission to license the work in any other way, but it does not
+ invalidate such permission if you have separately received it.
+
+ d) If the work has interactive user interfaces, each must display
+ Appropriate Legal Notices; however, if the Program has interactive
+ interfaces that do not display Appropriate Legal Notices, your
+ work need not make them do so.
+
+ A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit. Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+ 6. Conveying Non-Source Forms.
+
+ You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+ a) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by the
+ Corresponding Source fixed on a durable physical medium
+ customarily used for software interchange.
+
+ b) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by a
+ written offer, valid for at least three years and valid for as
+ long as you offer spare parts or customer support for that product
+ model, to give anyone who possesses the object code either (1) a
+ copy of the Corresponding Source for all the software in the
+ product that is covered by this License, on a durable physical
+ medium customarily used for software interchange, for a price no
+ more than your reasonable cost of physically performing this
+ conveying of source, or (2) access to copy the
+ Corresponding Source from a network server at no charge.
+
+ c) Convey individual copies of the object code with a copy of the
+ written offer to provide the Corresponding Source. This
+ alternative is allowed only occasionally and noncommercially, and
+ only if you received the object code with such an offer, in accord
+ with subsection 6b.
+
+ d) Convey the object code by offering access from a designated
+ place (gratis or for a charge), and offer equivalent access to the
+ Corresponding Source in the same way through the same place at no
+ further charge. You need not require recipients to copy the
+ Corresponding Source along with the object code. If the place to
+ copy the object code is a network server, the Corresponding Source
+ may be on a different server (operated by you or a third party)
+ that supports equivalent copying facilities, provided you maintain
+ clear directions next to the object code saying where to find the
+ Corresponding Source. Regardless of what server hosts the
+ Corresponding Source, you remain obligated to ensure that it is
+ available for as long as needed to satisfy these requirements.
+
+ e) Convey the object code using peer-to-peer transmission, provided
+ you inform other peers where the object code and Corresponding
+ Source of the work are being offered to the general public at no
+ charge under subsection 6d.
+
+ A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+ A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling. In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage. For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product. A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+ "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source. The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+ If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information. But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+ The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed. Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+ Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+ 7. Additional Terms.
+
+ "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law. If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+ When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it. (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.) You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+ Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+ a) Disclaiming warranty or limiting liability differently from the
+ terms of sections 15 and 16 of this License; or
+
+ b) Requiring preservation of specified reasonable legal notices or
+ author attributions in that material or in the Appropriate Legal
+ Notices displayed by works containing it; or
+
+ c) Prohibiting misrepresentation of the origin of that material, or
+ requiring that modified versions of such material be marked in
+ reasonable ways as different from the original version; or
+
+ d) Limiting the use for publicity purposes of names of licensors or
+ authors of the material; or
+
+ e) Declining to grant rights under trademark law for use of some
+ trade names, trademarks, or service marks; or
+
+ f) Requiring indemnification of licensors and authors of that
+ material by anyone who conveys the material (or modified versions of
+ it) with contractual assumptions of liability to the recipient, for
+ any liability that these contractual assumptions directly impose on
+ those licensors and authors.
+
+ All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10. If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term. If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+ If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+ Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+ 8. Termination.
+
+ You may not propagate or modify a covered work except as expressly
+provided under this License. Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+ However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+ Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+ Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License. If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+ 9. Acceptance Not Required for Having Copies.
+
+ You are not required to accept this License in order to receive or
+run a copy of the Program. Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance. However,
+nothing other than this License grants you permission to propagate or
+modify any covered work. These actions infringe copyright if you do
+not accept this License. Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+ 10. Automatic Licensing of Downstream Recipients.
+
+ Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License. You are not responsible
+for enforcing compliance by third parties with this License.
+
+ An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations. If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+ You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License. For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+ 11. Patents.
+
+ A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based. The
+work thus licensed is called the contributor's "contributor version".
+
+ A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version. For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+ Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+ In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement). To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+ If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients. "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+ If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+ A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License. You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+ Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+ 12. No Surrender of Others' Freedom.
+
+ If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all. For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+ 13. Use with the GNU Affero General Public License.
+
+ Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work. The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+ 14. Revised Versions of this License.
+
+ The Free Software Foundation may publish revised and/or new versions of
+the GNU General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation. If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+ If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+ Later license versions may give you additional or different
+permissions. However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+ 15. Disclaimer of Warranty.
+
+ THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. Limitation of Liability.
+
+ IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+ 17. Interpretation of Sections 15 and 16.
+
+ If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+Also add information on how to contact you by electronic and paper mail.
+
+ If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+ <program> Copyright (C) <year> <name of author>
+ This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+ You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+<http://www.gnu.org/licenses/>.
+
+ The GNU General Public License does not permit incorporating your program
+into proprietary programs. If your program is a subroutine library, you
+may consider it more useful to permit linking proprietary applications with
+the library. If this is what you want to do, use the GNU Lesser General
+Public License instead of this License. But first, please read
+<http://www.gnu.org/philosophy/why-not-lgpl.html>.
+
diff --git a/NEWS b/NEWS
index c21661d..0f285bf 100644
--- a/NEWS
+++ b/NEWS
@@ -1,2 +1,9 @@
-1
-* initial release \ No newline at end of file
+NEWS
+
+3
+* Rebased on Python
+* Spiral layout of all color combinations
+* Saves new colors (in most Sugar environments)
+
+2
+* initial release as a Javascript program run inside of Browse
diff --git a/XOEditorActivity.py b/XOEditorActivity.py
new file mode 100644
index 0000000..ac17622
--- /dev/null
+++ b/XOEditorActivity.py
@@ -0,0 +1,153 @@
+# -*- coding: utf-8 -*-
+#Copyright (c) 2012 Walter Bender
+
+# 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with this library; if not, write to the Free Software
+# Foundation, 51 Franklin Street, Suite 500 Boston, MA 02110-1335 USA
+
+
+import gtk
+import gconf
+
+from sugar.activity import activity
+from sugar import profile
+try:
+ from sugar.graphics.toolbarbox import ToolbarBox
+ _have_toolbox = True
+except ImportError:
+ _have_toolbox = False
+
+if _have_toolbox:
+ from sugar.activity.widgets import ActivityToolbarButton
+ from sugar.activity.widgets import StopButton
+from sugar.graphics.objectchooser import ObjectChooser
+from sugar.graphics.alert import ConfirmationAlert, NotifyAlert
+
+from toolbar_utils import button_factory, radio_factory, separator_factory
+
+from gettext import gettext as _
+
+from game import Game
+
+import logging
+_logger = logging.getLogger('xo-editor-activity')
+
+
+class XOEditorActivity(activity.Activity):
+ """ Change the XO colors """
+
+ def __init__(self, handle):
+ """ Initialize the toolbars and the game board """
+ try:
+ super(XOEditorActivity, self).__init__(handle)
+ except dbus.exceptions.DBusException, e:
+ _logger.error(str(e))
+
+ self.nick = profile.get_nick_name()
+ if profile.get_color() is not None:
+ self.colors = profile.get_color().to_string().split(',')
+ else:
+ self.colors = ['#A0FFA0', '#FF8080']
+
+ self.level = 0
+
+ self._setup_toolbars(_have_toolbox)
+
+ # Create a canvas
+ canvas = gtk.DrawingArea()
+ canvas.set_size_request(gtk.gdk.screen_width(), \
+ gtk.gdk.screen_height())
+ self.set_canvas(canvas)
+ canvas.show()
+ self.show_all()
+
+ self._game = Game(canvas, parent=self, mycolors=self.colors)
+
+ def _setup_toolbars(self, have_toolbox):
+ """ Setup the toolbars. """
+
+ self.max_participants = 1 # No sharing
+
+ if have_toolbox:
+ toolbox = ToolbarBox()
+
+ # Activity toolbar
+ activity_button = ActivityToolbarButton(self)
+
+ toolbox.toolbar.insert(activity_button, 0)
+ activity_button.show()
+
+ self.set_toolbar_box(toolbox)
+ toolbox.show()
+ self.toolbar = toolbox.toolbar
+
+ else:
+ # Use pre-0.86 toolbar design
+ games_toolbar = gtk.Toolbar()
+ toolbox = activity.ActivityToolbox(self)
+ self.set_toolbox(toolbox)
+ toolbox.add_toolbar(_('Game'), games_toolbar)
+ toolbox.show()
+ toolbox.set_current_toolbar(1)
+ self.toolbar = games_toolbar
+
+ _rotate_button = button_factory(
+ 'view-refresh', self.toolbar, self._rotate_cb,
+ tooltip=_('Rotate colors'))
+
+ if _have_toolbox:
+ separator_factory(toolbox.toolbar, True, False)
+
+ self._save_colors_button = button_factory(
+ 'document-save', self.toolbar, self._save_colors_cb,
+ tooltip=_('Save colors'))
+
+ if _have_toolbox:
+ stop_button = StopButton(self)
+ stop_button.props.accelerator = '<Ctrl>q'
+ toolbox.toolbar.insert(stop_button, -1)
+ stop_button.show()
+
+ def _save_colors_cb(self, button=None):
+ ''' Save the new XO colors. '''
+ ''' We warn the user if the plugin was previously loaded '''
+ alert = ConfirmationAlert()
+ alert.props.title = _('Saving colors')
+ alert.props.msg = _('Do you want to save these colors?')
+
+ def _change_colors_alert_response_cb(alert, response_id, self):
+ if response_id is gtk.RESPONSE_OK:
+ _logger.debug('saving colors')
+ self.remove_alert(alert)
+ self._confirm_save()
+ elif response_id is gtk.RESPONSE_CANCEL:
+ _logger.debug('cancel save')
+ self.remove_alert(alert)
+
+ alert.connect('response', _change_colors_alert_response_cb, self)
+ self.add_alert(alert)
+ alert.show()
+
+ def _confirm_save(self):
+ ''' Called from confirmation alert '''
+ client = gconf.client_get_default()
+ client.set_string('/desktop/sugar/user/color', '%s,%s' % (
+ self._game.colors[0], self._game.colors[1]))
+ alert = NotifyAlert()
+ alert.props.title = _('Saving colors')
+ alert.props.msg = _('Restart required before new colors will appear.')
+
+ def _notification_alert_response_cb(alert, response_id, self):
+ self.remove_alert(alert)
+
+ alert.connect('response', _notification_alert_response_cb, self)
+ self.add_alert(alert)
+ alert.show()
+
+ def _rotate_cb(self, button=None):
+ self._game.rotate()
diff --git a/activity/activity.info b/activity/activity.info
index cddaf82..0875555 100644
--- a/activity/activity.info
+++ b/activity/activity.info
@@ -1,8 +1,8 @@
-[Activity]
-name = xoEditor
-activity_version = 1
-host_version = 1
-icon = activity-xoEditor
-service_name = org.laptop.xoEditorActivity
-class = xoEditorActivity.xoEditorActivity
-show_launcher = 1
+[Activity]
+name = xoEditor
+exec = sugar-activity XOEditorActivity.XOEditorActivity
+bundle_id = org.laptop.xoEditorActivity
+icon = activity-xo-editor
+activity_version = 3
+show_launcher = yes
+license=GPLv3
diff --git a/game.py b/game.py
new file mode 100644
index 0000000..010380c
--- /dev/null
+++ b/game.py
@@ -0,0 +1,293 @@
+# -*- coding: utf-8 -*-
+#Copyright (c) 2012 Walter Bender
+
+# 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with this library; if not, write to the Free Software
+# Foundation, 51 Franklin Street, Suite 500 Boston, MA 02110-1335 USA
+
+import gtk
+import cairo
+import gobject
+
+from math import atan2, sin, cos, sqrt, pi
+
+from gettext import gettext as _
+
+import logging
+_logger = logging.getLogger('xo-editor-activity')
+
+try:
+ from sugar.graphics import style
+ GRID_CELL_SIZE = style.GRID_CELL_SIZE
+except ImportError:
+ GRID_CELL_SIZE = 0
+from sugar.graphics.xocolor import colors
+
+from sprites import Sprites, Sprite
+
+
+class Game():
+ ''' OLPC XO man color changer designed in memory of Nat Jacobson '''
+
+ def __init__(self, canvas, parent=None, mycolors=['#A0FFA0', '#FF8080']):
+ self._activity = parent
+ self.colors = [mycolors[0]]
+ self.colors.append(mycolors[1])
+
+ self._canvas = canvas
+ if parent is not None:
+ parent.show_all()
+ self._parent = parent
+
+ self._canvas.set_flags(gtk.CAN_FOCUS)
+ self._canvas.add_events(gtk.gdk.BUTTON_PRESS_MASK)
+ self._canvas.connect("expose-event", self._expose_cb)
+ self._canvas.connect("button-press-event", self._button_press_cb)
+
+ self._width = gtk.gdk.screen_width()
+ self._height = gtk.gdk.screen_height() - GRID_CELL_SIZE
+ self._scale = self._width / 1200.
+
+ self._dot_cache = {}
+ self._xo_cache = {}
+
+ self._radius = 22.5
+ self._stroke_width = 9.5
+
+ # Generate the sprites we'll need...
+ self._sprites = Sprites(self._canvas)
+ self._dots = []
+ self._xoman = None
+ self._generate_bg('#FFF')
+
+ # First dot, starting angle
+ self._cxy = [self._width / 2, self._height / 2]
+ self._xy = [self._width / 2 + 120 * self._scale,
+ self._height / 2 - self._radius * self._scale]
+ self._angle = 0
+ self._dot_size_plus = self._radius * 3 * self._scale
+ self._min = -self._dot_size_plus / 3
+ self._max = self._height - (self._dot_size_plus / 2.2)
+
+ self._generate_grid()
+
+ def _calc_next_dot_position(self):
+ ''' calculate spiral coordinates '''
+ dx = self._xy[0] - self._cxy[0]
+ dy = self._xy[1] - self._cxy[1]
+ r = sqrt(dx * dx + dy * dy)
+ c = 2 * r * pi
+ a = atan2(dy, dx)
+ da = (self._dot_size_plus / c) * 2 * pi
+ a += da
+ r += self._dot_size_plus / (c / self._dot_size_plus)
+ self._xy[0] = r * cos(a) + self._cxy[0]
+ self._xy[1] = r * sin(a) + self._cxy[1]
+ if self._xy[1] < self._min or self._xy[1] > self._max:
+ self._calc_next_dot_position()
+
+ def _generate_grid(self):
+ ''' Make a new set of dots for a grid of size edge '''
+ _logger.debug('%d colors' % (len(colors)))
+ for i in range(len(colors)):
+ self._dots.append(
+ Sprite(self._sprites, self._xy[0], self._xy[1],
+ self._new_dot(colors[i])))
+ self._dots[-1].type = i
+ self._calc_next_dot_position()
+ if self._xoman is None:
+ x = 510 * self._scale
+ y = 280 * self._scale
+ self._xoman = Sprite(self._sprites, x, y,
+ self._new_xo_man(self.colors))
+ self._xoman.type = None
+
+ def rotate(self):
+ x, y = self._dots[0].get_xy()
+ for i in range(len(colors) - 1):
+ self._dots[i].move(self._dots[i + 1].get_xy())
+ self._dots[-1].move((x, y))
+
+ def _generate_bg(self, color):
+ ''' a background color '''
+ self._bg = Sprite(self._sprites, 0, 0, self._new_background(color))
+ self._bg.set_layer(0)
+ self._bg.type = None
+
+ def adj_background(self, color):
+ ''' Change background '''
+ self._bg.set_image(self._new_background(color))
+ self._bg.set_layer(0)
+
+ def _button_press_cb(self, win, event):
+ win.grab_focus()
+ x, y = map(int, event.get_coords())
+
+ spr = self._sprites.find_sprite((x, y))
+ if spr == None:
+ return
+
+ if type(spr.type) == int:
+ self.i = spr.type
+ _logger.debug('%d' % (self.i))
+ self._new_surface()
+ else:
+ _logger.debug(type(spr.type))
+
+ def _new_surface(self):
+ self.colors[0] = colors[self.i][0]
+ self.colors[1] = colors[self.i][1]
+ self._xoman.set_image(self._new_xo_man(colors[self.i]))
+ self._xoman.set_layer(100)
+
+ def _expose_cb(self, win, event):
+ self.do_expose_event(event)
+
+ def do_expose_event(self, event):
+ ''' Handle the expose-event by drawing '''
+ # Restrict Cairo to the exposed area
+ cr = self._canvas.window.cairo_create()
+ cr.rectangle(event.area.x, event.area.y,
+ event.area.width, event.area.height)
+ cr.clip()
+ # Refresh sprite list
+ self._sprites.redraw_sprites(cr=cr)
+
+ def _destroy_cb(self, win, event):
+ gtk.main_quit()
+
+ def _new_dot(self, color):
+ ''' generate a dot of a color color '''
+ if True: # not color in self._dot_cache:
+ self._stroke = color[0]
+ self._fill = color[1]
+ self._svg_width = int(60 * self._scale)
+ self._svg_height = int(60 * self._scale)
+ pixbuf = svg_str_to_pixbuf(
+ self._header() + \
+ '<circle cx="%f" cy="%f" r="%f" stroke="%s" fill="%s" \
+stroke-width="%f" visibility="visible" />' % (
+ 30 * self._scale, 30 * self._scale,
+ self._radius * self._scale, self._stroke,
+ self._fill, self._stroke_width * self._scale) + \
+ self._footer())
+
+ surface = cairo.ImageSurface(cairo.FORMAT_ARGB32,
+ self._svg_width, self._svg_height)
+ context = cairo.Context(surface)
+ context = gtk.gdk.CairoContext(context)
+ context.set_source_pixbuf(pixbuf, 0, 0)
+ context.rectangle(0, 0, self._svg_width, self._svg_height)
+ context.fill()
+ # self._dot_cache[color] = surface
+
+ return surface # self._dot_cache[color]
+
+ def _new_background(self, color):
+ ''' Background color '''
+ self._svg_width = int(self._width)
+ self._svg_height = int(self._height)
+ string = \
+ self._header() + \
+ '<rect width="%f" height="%f" x="%f" \
+y="%f" fill="%s" stroke="none" visibility="visible" />' % (
+ self._width, self._height, 0, 0, color) + \
+ self._footer()
+ pixbuf = svg_str_to_pixbuf(string)
+ surface = cairo.ImageSurface(cairo.FORMAT_ARGB32,
+ self._svg_width, self._svg_height)
+ context = cairo.Context(surface)
+ context = gtk.gdk.CairoContext(context)
+ context.set_source_pixbuf(pixbuf, 0, 0)
+ context.rectangle(0, 0, self._svg_width, self._svg_height)
+ context.fill()
+ return surface
+
+ def _new_xo_man(self, color):
+ ''' generate a xo-man of a color color '''
+ if True: # not color in self._xo_cache:
+ self._stroke = color[0]
+ self._fill = color[1]
+ self._svg_width = int(240. * self._scale)
+ self._svg_height = int(260. * self._scale)
+ string = \
+ self._header() + \
+ '<g>' + \
+ '<g id="XO">' + \
+ '<path id="Line1" d="M%f,%f C%f,%f %f,%f %f,%f" stroke="%s" \
+stroke-width="%f" stroke-linecap="round" fill="none" visibility="visible" />' \
+% (
+ 165.5 * self._scale, 97 * self._scale,
+ 120 * self._scale, 140.5 * self._scale,
+ 120 * self._scale, 140.5 * self._scale,
+ 74.5 * self._scale, 188 * self._scale,
+ self._stroke, 37 * self._scale) + \
+ '<path id="Line2" d="M%f,%f C%f,%f %f,%f %f,%f" stroke="%s" \
+stroke-width="%f" stroke-linecap="round" fill="none" visibility="visible" />' \
+% (
+ 165.5 * self._scale, 188 * self._scale,
+ 120 * self._scale, 140.5 * self._scale,
+ 120 * self._scale, 140.5 * self._scale,
+ 74.5 * self._scale, 97 * self._scale,
+ self._stroke, 37 * self._scale) + \
+ '<path id="Fill1" d="M%f,%f C%f,%f %f,%f %f,%f" stroke="%s" \
+stroke-width="%f" stroke-linecap="round" fill="none" visibility="visible" />' \
+% (
+ 165.5 * self._scale, 97 * self._scale,
+ 120 * self._scale, 140.5 * self._scale,
+ 120 * self._scale, 140.5 * self._scale,
+ 74.5 * self._scale, 188 * self._scale,
+ self._fill, 17 * self._scale) + \
+ '<path id="Fill2" d="M%f,%f C%f,%f %f,%f %f,%f" stroke="%s" \
+stroke-width="%f" stroke-linecap="round" fill="none" visibility="visible" />' \
+% (
+ 165.5 * self._scale, 188 * self._scale,
+ 120 * self._scale, 140.5 * self._scale,
+ 120 * self._scale, 140.5 * self._scale,
+ 74.5 * self._scale, 97 * self._scale,
+ self._fill, 17 * self._scale) + \
+ '<circle id="Circle" cx="%f" cy="%f" r="%f" \
+fill="%s" stroke="%s" stroke-width="%f" visibility="visible" />' % (
+ 120 * self._scale, 61.5 * self._scale,
+ 27.5 * self._scale,
+ self._fill, self._stroke, 11 * self._scale) + \
+ '</g></g>' + \
+ self._footer()
+ pixbuf = svg_str_to_pixbuf(string)
+
+ surface = cairo.ImageSurface(cairo.FORMAT_ARGB32,
+ self._svg_width, self._svg_height)
+ context = cairo.Context(surface)
+ context = gtk.gdk.CairoContext(context)
+ context.set_source_pixbuf(pixbuf, 0, 0)
+ context.rectangle(0, 0, self._svg_width, self._svg_height)
+ context.fill()
+ # self._xo_cache[color] = surface
+ return surface # self._xo_cache[color]
+
+ def _header(self):
+ return '<svg\n' + 'xmlns:svg="http:#www.w3.org/2000/svg"\n' + \
+ 'xmlns="http://www.w3.org/2000/svg"\n' + \
+ 'xmlns:xlink="http://www.w3.org/1999/xlink"\n' + \
+ 'version="1.1"\n' + 'width="' + str(self._svg_width) + '"\n' + \
+ 'height="' + str(self._svg_height) + '">\n'
+
+ def _footer(self):
+ return '</svg>\n'
+
+def svg_str_to_pixbuf(svg_string):
+ """ Load pixbuf from SVG string """
+ pl = gtk.gdk.PixbufLoader('svg')
+ pl.write(svg_string)
+ pl.close()
+ pixbuf = pl.get_pixbuf()
+ return pixbuf
+
+
+def _to_hex(rgb):
+ return('#%02x%02x%02x' % (rgb[0], rgb[1], rgb[2]))
diff --git a/html/.svn/all-wcprops b/html/.svn/all-wcprops
deleted file mode 100644
index 52c3d52..0000000
--- a/html/.svn/all-wcprops
+++ /dev/null
@@ -1,17 +0,0 @@
-K 25
-svn:wc:ra_dav:version-url
-V 56
-/public-svn/!svn/ver/308/xoEditor/xoEditor.activity/html
-END
-xo-color.xml
-K 25
-svn:wc:ra_dav:version-url
-V 69
-/public-svn/!svn/ver/308/xoEditor/xoEditor.activity/html/xo-color.xml
-END
-prototype.js
-K 25
-svn:wc:ra_dav:version-url
-V 69
-/public-svn/!svn/ver/304/xoEditor/xoEditor.activity/html/prototype.js
-END
diff --git a/html/.svn/entries b/html/.svn/entries
deleted file mode 100644
index 7082565..0000000
--- a/html/.svn/entries
+++ /dev/null
@@ -1,52 +0,0 @@
-8
-
-dir
-311
-http://mediamods.com/public-svn/xoEditor/xoEditor.activity/html
-http://mediamods.com/public-svn
-
-
-
-2007-08-15T22:25:38.011753Z
-308
-erikb
-
-
-svn:special svn:externals svn:needs-lock
-
-
-
-
-
-
-
-
-
-
-
-574bc980-5f2d-0410-acbc-c8f9f0eb14e0
-
-prototype.js
-file
-
-
-
-
-2007-08-15T20:51:58.000000Z
-c88ad55f47e32f870a79c85e6ed7b9e1
-2007-08-15T21:14:58.627518Z
-304
-erikb
-
-xo-color.xml
-file
-
-
-
-
-2007-08-15T22:02:52.000000Z
-c8d70ba4d7c5d8d179388fdd098c3de6
-2007-08-15T22:25:38.011753Z
-308
-erikb
-
diff --git a/html/.svn/format b/html/.svn/format
deleted file mode 100644
index 45a4fb7..0000000
--- a/html/.svn/format
+++ /dev/null
@@ -1 +0,0 @@
-8
diff --git a/html/.svn/text-base/prototype.js.svn-base b/html/.svn/text-base/prototype.js.svn-base
deleted file mode 100644
index 5806f35..0000000
--- a/html/.svn/text-base/prototype.js.svn-base
+++ /dev/null
@@ -1,3277 +0,0 @@
-/* Prototype JavaScript framework, version 1.5.1.1
- * (c) 2005-2007 Sam Stephenson
- *
- * Prototype is freely distributable under the terms of an MIT-style license.
- * For details, see the Prototype web site: http://www.prototypejs.org/
- *
-/*--------------------------------------------------------------------------*/
-
-var Prototype = {
- Version: '1.5.1.1',
-
- Browser: {
- IE: !!(window.attachEvent && !window.opera),
- Opera: !!window.opera,
- WebKit: navigator.userAgent.indexOf('AppleWebKit/') > -1,
- Gecko: navigator.userAgent.indexOf('Gecko') > -1 && navigator.userAgent.indexOf('KHTML') == -1
- },
-
- BrowserFeatures: {
- XPath: !!document.evaluate,
- ElementExtensions: !!window.HTMLElement,
- SpecificElementExtensions:
- (document.createElement('div').__proto__ !==
- document.createElement('form').__proto__)
- },
-
- ScriptFragment: '<script[^>]*>([\\S\\s]*?)<\/script>',
- JSONFilter: /^\/\*-secure-([\s\S]*)\*\/\s*$/,
-
- emptyFunction: function() { },
- K: function(x) { return x }
-}
-
-var Class = {
- create: function() {
- return function() {
- this.initialize.apply(this, arguments);
- }
- }
-}
-
-var Abstract = new Object();
-
-Object.extend = function(destination, source) {
- for (var property in source) {
- destination[property] = source[property];
- }
- return destination;
-}
-
-Object.extend(Object, {
- inspect: function(object) {
- try {
- if (object === undefined) return 'undefined';
- if (object === null) return 'null';
- return object.inspect ? object.inspect() : object.toString();
- } catch (e) {
- if (e instanceof RangeError) return '...';
- throw e;
- }
- },
-
- toJSON: function(object) {
- var type = typeof object;
- switch(type) {
- case 'undefined':
- case 'function':
- case 'unknown': return;
- case 'boolean': return object.toString();
- }
- if (object === null) return 'null';
- if (object.toJSON) return object.toJSON();
- if (object.ownerDocument === document) return;
- var results = [];
- for (var property in object) {
- var value = Object.toJSON(object[property]);
- if (value !== undefined)
- results.push(property.toJSON() + ': ' + value);
- }
- return '{' + results.join(', ') + '}';
- },
-
- keys: function(object) {
- var keys = [];
- for (var property in object)
- keys.push(property);
- return keys;
- },
-
- values: function(object) {
- var values = [];
- for (var property in object)
- values.push(object[property]);
- return values;
- },
-
- clone: function(object) {
- return Object.extend({}, object);
- }
-});
-
-Function.prototype.bind = function() {
- var __method = this, args = $A(arguments), object = args.shift();
- return function() {
- return __method.apply(object, args.concat($A(arguments)));
- }
-}
-
-Function.prototype.bindAsEventListener = function(object) {
- var __method = this, args = $A(arguments), object = args.shift();
- return function(event) {
- return __method.apply(object, [event || window.event].concat(args));
- }
-}
-
-Object.extend(Number.prototype, {
- toColorPart: function() {
- return this.toPaddedString(2, 16);
- },
-
- succ: function() {
- return this + 1;
- },
-
- times: function(iterator) {
- $R(0, this, true).each(iterator);
- return this;
- },
-
- toPaddedString: function(length, radix) {
- var string = this.toString(radix || 10);
- return '0'.times(length - string.length) + string;
- },
-
- toJSON: function() {
- return isFinite(this) ? this.toString() : 'null';
- }
-});
-
-Date.prototype.toJSON = function() {
- return '"' + this.getFullYear() + '-' +
- (this.getMonth() + 1).toPaddedString(2) + '-' +
- this.getDate().toPaddedString(2) + 'T' +
- this.getHours().toPaddedString(2) + ':' +
- this.getMinutes().toPaddedString(2) + ':' +
- this.getSeconds().toPaddedString(2) + '"';
-};
-
-var Try = {
- these: function() {
- var returnValue;
-
- for (var i = 0, length = arguments.length; i < length; i++) {
- var lambda = arguments[i];
- try {
- returnValue = lambda();
- break;
- } catch (e) {}
- }
-
- return returnValue;
- }
-}
-
-/*--------------------------------------------------------------------------*/
-
-var PeriodicalExecuter = Class.create();
-PeriodicalExecuter.prototype = {
- initialize: function(callback, frequency) {
- this.callback = callback;
- this.frequency = frequency;
- this.currentlyExecuting = false;
-
- this.registerCallback();
- },
-
- registerCallback: function() {
- this.timer = setInterval(this.onTimerEvent.bind(this), this.frequency * 1000);
- },
-
- stop: function() {
- if (!this.timer) return;
- clearInterval(this.timer);
- this.timer = null;
- },
-
- onTimerEvent: function() {
- if (!this.currentlyExecuting) {
- try {
- this.currentlyExecuting = true;
- this.callback(this);
- } finally {
- this.currentlyExecuting = false;
- }
- }
- }
-}
-Object.extend(String, {
- interpret: function(value) {
- return value == null ? '' : String(value);
- },
- specialChar: {
- '\b': '\\b',
- '\t': '\\t',
- '\n': '\\n',
- '\f': '\\f',
- '\r': '\\r',
- '\\': '\\\\'
- }
-});
-
-Object.extend(String.prototype, {
- gsub: function(pattern, replacement) {
- var result = '', source = this, match;
- replacement = arguments.callee.prepareReplacement(replacement);
-
- while (source.length > 0) {
- if (match = source.match(pattern)) {
- result += source.slice(0, match.index);
- result += String.interpret(replacement(match));
- source = source.slice(match.index + match[0].length);
- } else {
- result += source, source = '';
- }
- }
- return result;
- },
-
- sub: function(pattern, replacement, count) {
- replacement = this.gsub.prepareReplacement(replacement);
- count = count === undefined ? 1 : count;
-
- return this.gsub(pattern, function(match) {
- if (--count < 0) return match[0];
- return replacement(match);
- });
- },
-
- scan: function(pattern, iterator) {
- this.gsub(pattern, iterator);
- return this;
- },
-
- truncate: function(length, truncation) {
- length = length || 30;
- truncation = truncation === undefined ? '...' : truncation;
- return this.length > length ?
- this.slice(0, length - truncation.length) + truncation : this;
- },
-
- strip: function() {
- return this.replace(/^\s+/, '').replace(/\s+$/, '');
- },
-
- stripTags: function() {
- return this.replace(/<\/?[^>]+>/gi, '');
- },
-
- stripScripts: function() {
- return this.replace(new RegExp(Prototype.ScriptFragment, 'img'), '');
- },
-
- extractScripts: function() {
- var matchAll = new RegExp(Prototype.ScriptFragment, 'img');
- var matchOne = new RegExp(Prototype.ScriptFragment, 'im');
- return (this.match(matchAll) || []).map(function(scriptTag) {
- return (scriptTag.match(matchOne) || ['', ''])[1];
- });
- },
-
- evalScripts: function() {
- return this.extractScripts().map(function(script) { return eval(script) });
- },
-
- escapeHTML: function() {
- var self = arguments.callee;
- self.text.data = this;
- return self.div.innerHTML;
- },
-
- unescapeHTML: function() {
- var div = document.createElement('div');
- div.innerHTML = this.stripTags();
- return div.childNodes[0] ? (div.childNodes.length > 1 ?
- $A(div.childNodes).inject('', function(memo, node) { return memo+node.nodeValue }) :
- div.childNodes[0].nodeValue) : '';
- },
-
- toQueryParams: function(separator) {
- var match = this.strip().match(/([^?#]*)(#.*)?$/);
- if (!match) return {};
-
- return match[1].split(separator || '&').inject({}, function(hash, pair) {
- if ((pair = pair.split('='))[0]) {
- var key = decodeURIComponent(pair.shift());
- var value = pair.length > 1 ? pair.join('=') : pair[0];
- if (value != undefined) value = decodeURIComponent(value);
-
- if (key in hash) {
- if (hash[key].constructor != Array) hash[key] = [hash[key]];
- hash[key].push(value);
- }
- else hash[key] = value;
- }
- return hash;
- });
- },
-
- toArray: function() {
- return this.split('');
- },
-
- succ: function() {
- return this.slice(0, this.length - 1) +
- String.fromCharCode(this.charCodeAt(this.length - 1) + 1);
- },
-
- times: function(count) {
- var result = '';
- for (var i = 0; i < count; i++) result += this;
- return result;
- },
-
- camelize: function() {
- var parts = this.split('-'), len = parts.length;
- if (len == 1) return parts[0];
-
- var camelized = this.charAt(0) == '-'
- ? parts[0].charAt(0).toUpperCase() + parts[0].substring(1)
- : parts[0];
-
- for (var i = 1; i < len; i++)
- camelized += parts[i].charAt(0).toUpperCase() + parts[i].substring(1);
-
- return camelized;
- },
-
- capitalize: function() {
- return this.charAt(0).toUpperCase() + this.substring(1).toLowerCase();
- },
-
- underscore: function() {
- return this.gsub(/::/, '/').gsub(/([A-Z]+)([A-Z][a-z])/,'#{1}_#{2}').gsub(/([a-z\d])([A-Z])/,'#{1}_#{2}').gsub(/-/,'_').toLowerCase();
- },
-
- dasherize: function() {
- return this.gsub(/_/,'-');
- },
-
- inspect: function(useDoubleQuotes) {
- var escapedString = this.gsub(/[\x00-\x1f\\]/, function(match) {
- var character = String.specialChar[match[0]];
- return character ? character : '\\u00' + match[0].charCodeAt().toPaddedString(2, 16);
- });
- if (useDoubleQuotes) return '"' + escapedString.replace(/"/g, '\\"') + '"';
- return "'" + escapedString.replace(/'/g, '\\\'') + "'";
- },
-
- toJSON: function() {
- return this.inspect(true);
- },
-
- unfilterJSON: function(filter) {
- return this.sub(filter || Prototype.JSONFilter, '#{1}');
- },
-
- isJSON: function() {
- var str = this.replace(/\\./g, '@').replace(/"[^"\\\n\r]*"/g, '');
- return (/^[,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t]*$/).test(str);
- },
-
- evalJSON: function(sanitize) {
- var json = this.unfilterJSON();
- try {
- if (!sanitize || json.isJSON()) return eval('(' + json + ')');
- } catch (e) { }
- throw new SyntaxError('Badly formed JSON string: ' + this.inspect());
- },
-
- include: function(pattern) {
- return this.indexOf(pattern) > -1;
- },
-
- startsWith: function(pattern) {
- return this.indexOf(pattern) === 0;
- },
-
- endsWith: function(pattern) {
- var d = this.length - pattern.length;
- return d >= 0 && this.lastIndexOf(pattern) === d;
- },
-
- empty: function() {
- return this == '';
- },
-
- blank: function() {
- return /^\s*$/.test(this);
- }
-});
-
-if (Prototype.Browser.WebKit || Prototype.Browser.IE) Object.extend(String.prototype, {
- escapeHTML: function() {
- return this.replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;');
- },
- unescapeHTML: function() {
- return this.replace(/&amp;/g,'&').replace(/&lt;/g,'<').replace(/&gt;/g,'>');
- }
-});
-
-String.prototype.gsub.prepareReplacement = function(replacement) {
- if (typeof replacement == 'function') return replacement;
- var template = new Template(replacement);
- return function(match) { return template.evaluate(match) };
-}
-
-String.prototype.parseQuery = String.prototype.toQueryParams;
-
-Object.extend(String.prototype.escapeHTML, {
- div: document.createElement('div'),
- text: document.createTextNode('')
-});
-
-with (String.prototype.escapeHTML) div.appendChild(text);
-
-var Template = Class.create();
-Template.Pattern = /(^|.|\r|\n)(#\{(.*?)\})/;
-Template.prototype = {
- initialize: function(template, pattern) {
- this.template = template.toString();
- this.pattern = pattern || Template.Pattern;
- },
-
- evaluate: function(object) {
- return this.template.gsub(this.pattern, function(match) {
- var before = match[1];
- if (before == '\\') return match[2];
- return before + String.interpret(object[match[3]]);
- });
- }
-}
-
-var $break = {}, $continue = new Error('"throw $continue" is deprecated, use "return" instead');
-
-var Enumerable = {
- each: function(iterator) {
- var index = 0;
- try {
- this._each(function(value) {
- iterator(value, index++);
- });
- } catch (e) {
- if (e != $break) throw e;
- }
- return this;
- },
-
- eachSlice: function(number, iterator) {
- var index = -number, slices = [], array = this.toArray();
- while ((index += number) < array.length)
- slices.push(array.slice(index, index+number));
- return slices.map(iterator);
- },
-
- all: function(iterator) {
- var result = true;
- this.each(function(value, index) {
- result = result && !!(iterator || Prototype.K)(value, index);
- if (!result) throw $break;
- });
- return result;
- },
-
- any: function(iterator) {
- var result = false;
- this.each(function(value, index) {
- if (result = !!(iterator || Prototype.K)(value, index))
- throw $break;
- });
- return result;
- },
-
- collect: function(iterator) {
- var results = [];
- this.each(function(value, index) {
- results.push((iterator || Prototype.K)(value, index));
- });
- return results;
- },
-
- detect: function(iterator) {
- var result;
- this.each(function(value, index) {
- if (iterator(value, index)) {
- result = value;
- throw $break;
- }
- });
- return result;
- },
-
- findAll: function(iterator) {
- var results = [];
- this.each(function(value, index) {
- if (iterator(value, index))
- results.push(value);
- });
- return results;
- },
-
- grep: function(pattern, iterator) {
- var results = [];
- this.each(function(value, index) {
- var stringValue = value.toString();
- if (stringValue.match(pattern))
- results.push((iterator || Prototype.K)(value, index));
- })
- return results;
- },
-
- include: function(object) {
- var found = false;
- this.each(function(value) {
- if (value == object) {
- found = true;
- throw $break;
- }
- });
- return found;
- },
-
- inGroupsOf: function(number, fillWith) {
- fillWith = fillWith === undefined ? null : fillWith;
- return this.eachSlice(number, function(slice) {
- while(slice.length < number) slice.push(fillWith);
- return slice;
- });
- },
-
- inject: function(memo, iterator) {
- this.each(function(value, index) {
- memo = iterator(memo, value, index);
- });
- return memo;
- },
-
- invoke: function(method) {
- var args = $A(arguments).slice(1);
- return this.map(function(value) {
- return value[method].apply(value, args);
- });
- },
-
- max: function(iterator) {
- var result;
- this.each(function(value, index) {
- value = (iterator || Prototype.K)(value, index);
- if (result == undefined || value >= result)
- result = value;
- });
- return result;
- },
-
- min: function(iterator) {
- var result;
- this.each(function(value, index) {
- value = (iterator || Prototype.K)(value, index);
- if (result == undefined || value < result)
- result = value;
- });
- return result;
- },
-
- partition: function(iterator) {
- var trues = [], falses = [];
- this.each(function(value, index) {
- ((iterator || Prototype.K)(value, index) ?
- trues : falses).push(value);
- });
- return [trues, falses];
- },
-
- pluck: function(property) {
- var results = [];
- this.each(function(value, index) {
- results.push(value[property]);
- });
- return results;
- },
-
- reject: function(iterator) {
- var results = [];
- this.each(function(value, index) {
- if (!iterator(value, index))
- results.push(value);
- });
- return results;
- },
-
- sortBy: function(iterator) {
- return this.map(function(value, index) {
- return {value: value, criteria: iterator(value, index)};
- }).sort(function(left, right) {
- var a = left.criteria, b = right.criteria;
- return a < b ? -1 : a > b ? 1 : 0;
- }).pluck('value');
- },
-
- toArray: function() {
- return this.map();
- },
-
- zip: function() {
- var iterator = Prototype.K, args = $A(arguments);
- if (typeof args.last() == 'function')
- iterator = args.pop();
-
- var collections = [this].concat(args).map($A);
- return this.map(function(value, index) {
- return iterator(collections.pluck(index));
- });
- },
-
- size: function() {
- return this.toArray().length;
- },
-
- inspect: function() {
- return '#<Enumerable:' + this.toArray().inspect() + '>';
- }
-}
-
-Object.extend(Enumerable, {
- map: Enumerable.collect,
- find: Enumerable.detect,
- select: Enumerable.findAll,
- member: Enumerable.include,
- entries: Enumerable.toArray
-});
-var $A = Array.from = function(iterable) {
- if (!iterable) return [];
- if (iterable.toArray) {
- return iterable.toArray();
- } else {
- var results = [];
- for (var i = 0, length = iterable.length; i < length; i++)
- results.push(iterable[i]);
- return results;
- }
-}
-
-if (Prototype.Browser.WebKit) {
- $A = Array.from = function(iterable) {
- if (!iterable) return [];
- if (!(typeof iterable == 'function' && iterable == '[object NodeList]') &&
- iterable.toArray) {
- return iterable.toArray();
- } else {
- var results = [];
- for (var i = 0, length = iterable.length; i < length; i++)
- results.push(iterable[i]);
- return results;
- }
- }
-}
-
-Object.extend(Array.prototype, Enumerable);
-
-if (!Array.prototype._reverse)
- Array.prototype._reverse = Array.prototype.reverse;
-
-Object.extend(Array.prototype, {
- _each: function(iterator) {
- for (var i = 0, length = this.length; i < length; i++)
- iterator(this[i]);
- },
-
- clear: function() {
- this.length = 0;
- return this;
- },
-
- first: function() {
- return this[0];
- },
-
- last: function() {
- return this[this.length - 1];
- },
-
- compact: function() {
- return this.select(function(value) {
- return value != null;
- });
- },
-
- flatten: function() {
- return this.inject([], function(array, value) {
- return array.concat(value && value.constructor == Array ?
- value.flatten() : [value]);
- });
- },
-
- without: function() {
- var values = $A(arguments);
- return this.select(function(value) {
- return !values.include(value);
- });
- },
-
- indexOf: function(object) {
- for (var i = 0, length = this.length; i < length; i++)
- if (this[i] == object) return i;
- return -1;
- },
-
- reverse: function(inline) {
- return (inline !== false ? this : this.toArray())._reverse();
- },
-
- reduce: function() {
- return this.length > 1 ? this : this[0];
- },
-
- uniq: function(sorted) {
- return this.inject([], function(array, value, index) {
- if (0 == index || (sorted ? array.last() != value : !array.include(value)))
- array.push(value);
- return array;
- });
- },
-
- clone: function() {
- return [].concat(this);
- },
-
- size: function() {
- return this.length;
- },
-
- inspect: function() {
- return '[' + this.map(Object.inspect).join(', ') + ']';
- },
-
- toJSON: function() {
- var results = [];
- this.each(function(object) {
- var value = Object.toJSON(object);
- if (value !== undefined) results.push(value);
- });
- return '[' + results.join(', ') + ']';
- }
-});
-
-Array.prototype.toArray = Array.prototype.clone;
-
-function $w(string) {
- string = string.strip();
- return string ? string.split(/\s+/) : [];
-}
-
-if (Prototype.Browser.Opera){
- Array.prototype.concat = function() {
- var array = [];
- for (var i = 0, length = this.length; i < length; i++) array.push(this[i]);
- for (var i = 0, length = arguments.length; i < length; i++) {
- if (arguments[i].constructor == Array) {
- for (var j = 0, arrayLength = arguments[i].length; j < arrayLength; j++)
- array.push(arguments[i][j]);
- } else {
- array.push(arguments[i]);
- }
- }
- return array;
- }
-}
-var Hash = function(object) {
- if (object instanceof Hash) this.merge(object);
- else Object.extend(this, object || {});
-};
-
-Object.extend(Hash, {
- toQueryString: function(obj) {
- var parts = [];
- parts.add = arguments.callee.addPair;
-
- this.prototype._each.call(obj, function(pair) {
- if (!pair.key) return;
- var value = pair.value;
-
- if (value && typeof value == 'object') {
- if (value.constructor == Array) value.each(function(value) {
- parts.add(pair.key, value);
- });
- return;
- }
- parts.add(pair.key, value);
- });
-
- return parts.join('&');
- },
-
- toJSON: function(object) {
- var results = [];
- this.prototype._each.call(object, function(pair) {
- var value = Object.toJSON(pair.value);
- if (value !== undefined) results.push(pair.key.toJSON() + ': ' + value);
- });
- return '{' + results.join(', ') + '}';
- }
-});
-
-Hash.toQueryString.addPair = function(key, value, prefix) {
- key = encodeURIComponent(key);
- if (value === undefined) this.push(key);
- else this.push(key + '=' + (value == null ? '' : encodeURIComponent(value)));
-}
-
-Object.extend(Hash.prototype, Enumerable);
-Object.extend(Hash.prototype, {
- _each: function(iterator) {
- for (var key in this) {
- var value = this[key];
- if (value && value == Hash.prototype[key]) continue;
-
- var pair = [key, value];
- pair.key = key;
- pair.value = value;
- iterator(pair);
- }
- },
-
- keys: function() {
- return this.pluck('key');
- },
-
- values: function() {
- return this.pluck('value');
- },
-
- merge: function(hash) {
- return $H(hash).inject(this, function(mergedHash, pair) {
- mergedHash[pair.key] = pair.value;
- return mergedHash;
- });
- },
-
- remove: function() {
- var result;
- for(var i = 0, length = arguments.length; i < length; i++) {
- var value = this[arguments[i]];
- if (value !== undefined){
- if (result === undefined) result = value;
- else {
- if (result.constructor != Array) result = [result];
- result.push(value)
- }
- }
- delete this[arguments[i]];
- }
- return result;
- },
-
- toQueryString: function() {
- return Hash.toQueryString(this);
- },
-
- inspect: function() {
- return '#<Hash:{' + this.map(function(pair) {
- return pair.map(Object.inspect).join(': ');
- }).join(', ') + '}>';
- },
-
- toJSON: function() {
- return Hash.toJSON(this);
- }
-});
-
-function $H(object) {
- if (object instanceof Hash) return object;
- return new Hash(object);
-};
-
-// Safari iterates over shadowed properties
-if (function() {
- var i = 0, Test = function(value) { this.key = value };
- Test.prototype.key = 'foo';
- for (var property in new Test('bar')) i++;
- return i > 1;
-}()) Hash.prototype._each = function(iterator) {
- var cache = [];
- for (var key in this) {
- var value = this[key];
- if ((value && value == Hash.prototype[key]) || cache.include(key)) continue;
- cache.push(key);
- var pair = [key, value];
- pair.key = key;
- pair.value = value;
- iterator(pair);
- }
-};
-ObjectRange = Class.create();
-Object.extend(ObjectRange.prototype, Enumerable);
-Object.extend(ObjectRange.prototype, {
- initialize: function(start, end, exclusive) {
- this.start = start;
- this.end = end;
- this.exclusive = exclusive;
- },
-
- _each: function(iterator) {
- var value = this.start;
- while (this.include(value)) {
- iterator(value);
- value = value.succ();
- }
- },
-
- include: function(value) {
- if (value < this.start)
- return false;
- if (this.exclusive)
- return value < this.end;
- return value <= this.end;
- }
-});
-
-var $R = function(start, end, exclusive) {
- return new ObjectRange(start, end, exclusive);
-}
-
-var Ajax = {
- getTransport: function() {
- return Try.these(
- function() {return new XMLHttpRequest()},
- function() {return new ActiveXObject('Msxml2.XMLHTTP')},
- function() {return new ActiveXObject('Microsoft.XMLHTTP')}
- ) || false;
- },
-
- activeRequestCount: 0
-}
-
-Ajax.Responders = {
- responders: [],
-
- _each: function(iterator) {
- this.responders._each(iterator);
- },
-
- register: function(responder) {
- if (!this.include(responder))
- this.responders.push(responder);
- },
-
- unregister: function(responder) {
- this.responders = this.responders.without(responder);
- },
-
- dispatch: function(callback, request, transport, json) {
- this.each(function(responder) {
- if (typeof responder[callback] == 'function') {
- try {
- responder[callback].apply(responder, [request, transport, json]);
- } catch (e) {}
- }
- });
- }
-};
-
-Object.extend(Ajax.Responders, Enumerable);
-
-Ajax.Responders.register({
- onCreate: function() {
- Ajax.activeRequestCount++;
- },
- onComplete: function() {
- Ajax.activeRequestCount--;
- }
-});
-
-Ajax.Base = function() {};
-Ajax.Base.prototype = {
- setOptions: function(options) {
- this.options = {
- method: 'post',
- asynchronous: true,
- contentType: 'application/x-www-form-urlencoded',
- encoding: 'UTF-8',
- parameters: ''
- }
- Object.extend(this.options, options || {});
-
- this.options.method = this.options.method.toLowerCase();
- if (typeof this.options.parameters == 'string')
- this.options.parameters = this.options.parameters.toQueryParams();
- }
-}
-
-Ajax.Request = Class.create();
-Ajax.Request.Events =
- ['Uninitialized', 'Loading', 'Loaded', 'Interactive', 'Complete'];
-
-Ajax.Request.prototype = Object.extend(new Ajax.Base(), {
- _complete: false,
-
- initialize: function(url, options) {
- this.transport = Ajax.getTransport();
- this.setOptions(options);
- this.request(url);
- },
-
- request: function(url) {
- this.url = url;
- this.method = this.options.method;
- var params = Object.clone(this.options.parameters);
-
- if (!['get', 'post'].include(this.method)) {
- // simulate other verbs over post
- params['_method'] = this.method;
- this.method = 'post';
- }
-
- this.parameters = params;
-
- if (params = Hash.toQueryString(params)) {
- // when GET, append parameters to URL
- if (this.method == 'get')
- this.url += (this.url.include('?') ? '&' : '?') + params;
- else if (/Konqueror|Safari|KHTML/.test(navigator.userAgent))
- params += '&_=';
- }
-
- try {
- if (this.options.onCreate) this.options.onCreate(this.transport);
- Ajax.Responders.dispatch('onCreate', this, this.transport);
-
- this.transport.open(this.method.toUpperCase(), this.url,
- this.options.asynchronous);
-
- if (this.options.asynchronous)
- setTimeout(function() { this.respondToReadyState(1) }.bind(this), 10);
-
- this.transport.onreadystatechange = this.onStateChange.bind(this);
- this.setRequestHeaders();
-
- this.body = this.method == 'post' ? (this.options.postBody || params) : null;
- this.transport.send(this.body);
-
- /* Force Firefox to handle ready state 4 for synchronous requests */
- if (!this.options.asynchronous && this.transport.overrideMimeType)
- this.onStateChange();
-
- }
- catch (e) {
- this.dispatchException(e);
- }
- },
-
- onStateChange: function() {
- var readyState = this.transport.readyState;
- if (readyState > 1 && !((readyState == 4) && this._complete))
- this.respondToReadyState(this.transport.readyState);
- },
-
- setRequestHeaders: function() {
- var headers = {
- 'X-Requested-With': 'XMLHttpRequest',
- 'X-Prototype-Version': Prototype.Version,
- 'Accept': 'text/javascript, text/html, application/xml, text/xml, */*'
- };
-
- if (this.method == 'post') {
- headers['Content-type'] = this.options.contentType +
- (this.options.encoding ? '; charset=' + this.options.encoding : '');
-
- /* Force "Connection: close" for older Mozilla browsers to work
- * around a bug where XMLHttpRequest sends an incorrect
- * Content-length header. See Mozilla Bugzilla #246651.
- */
- if (this.transport.overrideMimeType &&
- (navigator.userAgent.match(/Gecko\/(\d{4})/) || [0,2005])[1] < 2005)
- headers['Connection'] = 'close';
- }
-
- // user-defined headers
- if (typeof this.options.requestHeaders == 'object') {
- var extras = this.options.requestHeaders;
-
- if (typeof extras.push == 'function')
- for (var i = 0, length = extras.length; i < length; i += 2)
- headers[extras[i]] = extras[i+1];
- else
- $H(extras).each(function(pair) { headers[pair.key] = pair.value });
- }
-
- for (var name in headers)
- this.transport.setRequestHeader(name, headers[name]);
- },
-
- success: function() {
- return !this.transport.status
- || (this.transport.status >= 200 && this.transport.status < 300);
- },
-
- respondToReadyState: function(readyState) {
- var state = Ajax.Request.Events[readyState];
- var transport = this.transport, json = this.evalJSON();
-
- if (state == 'Complete') {
- try {
- this._complete = true;
- (this.options['on' + this.transport.status]
- || this.options['on' + (this.success() ? 'Success' : 'Failure')]
- || Prototype.emptyFunction)(transport, json);
- } catch (e) {
- this.dispatchException(e);
- }
-
- var contentType = this.getHeader('Content-type');
- if (contentType && contentType.strip().
- match(/^(text|application)\/(x-)?(java|ecma)script(;.*)?$/i))
- this.evalResponse();
- }
-
- try {
- (this.options['on' + state] || Prototype.emptyFunction)(transport, json);
- Ajax.Responders.dispatch('on' + state, this, transport, json);
- } catch (e) {
- this.dispatchException(e);
- }
-
- if (state == 'Complete') {
- // avoid memory leak in MSIE: clean up
- this.transport.onreadystatechange = Prototype.emptyFunction;
- }
- },
-
- getHeader: function(name) {
- try {
- return this.transport.getResponseHeader(name);
- } catch (e) { return null }
- },
-
- evalJSON: function() {
- try {
- var json = this.getHeader('X-JSON');
- return json ? json.evalJSON() : null;
- } catch (e) { return null }
- },
-
- evalResponse: function() {
- try {
- return eval((this.transport.responseText || '').unfilterJSON());
- } catch (e) {
- this.dispatchException(e);
- }
- },
-
- dispatchException: function(exception) {
- (this.options.onException || Prototype.emptyFunction)(this, exception);
- Ajax.Responders.dispatch('onException', this, exception);
- }
-});
-
-Ajax.Updater = Class.create();
-
-Object.extend(Object.extend(Ajax.Updater.prototype, Ajax.Request.prototype), {
- initialize: function(container, url, options) {
- this.container = {
- success: (container.success || container),
- failure: (container.failure || (container.success ? null : container))
- }
-
- this.transport = Ajax.getTransport();
- this.setOptions(options);
-
- var onComplete = this.options.onComplete || Prototype.emptyFunction;
- this.options.onComplete = (function(transport, param) {
- this.updateContent();
- onComplete(transport, param);
- }).bind(this);
-
- this.request(url);
- },
-
- updateContent: function() {
- var receiver = this.container[this.success() ? 'success' : 'failure'];
- var response = this.transport.responseText;
-
- if (!this.options.evalScripts) response = response.stripScripts();
-
- if (receiver = $(receiver)) {
- if (this.options.insertion)
- new this.options.insertion(receiver, response);
- else
- receiver.update(response);
- }
-
- if (this.success()) {
- if (this.onComplete)
- setTimeout(this.onComplete.bind(this), 10);
- }
- }
-});
-
-Ajax.PeriodicalUpdater = Class.create();
-Ajax.PeriodicalUpdater.prototype = Object.extend(new Ajax.Base(), {
- initialize: function(container, url, options) {
- this.setOptions(options);
- this.onComplete = this.options.onComplete;
-
- this.frequency = (this.options.frequency || 2);
- this.decay = (this.options.decay || 1);
-
- this.updater = {};
- this.container = container;
- this.url = url;
-
- this.start();
- },
-
- start: function() {
- this.options.onComplete = this.updateComplete.bind(this);
- this.onTimerEvent();
- },
-
- stop: function() {
- this.updater.options.onComplete = undefined;
- clearTimeout(this.timer);
- (this.onComplete || Prototype.emptyFunction).apply(this, arguments);
- },
-
- updateComplete: function(request) {
- if (this.options.decay) {
- this.decay = (request.responseText == this.lastText ?
- this.decay * this.options.decay : 1);
-
- this.lastText = request.responseText;
- }
- this.timer = setTimeout(this.onTimerEvent.bind(this),
- this.decay * this.frequency * 1000);
- },
-
- onTimerEvent: function() {
- this.updater = new Ajax.Updater(this.container, this.url, this.options);
- }
-});
-function $(element) {
- if (arguments.length > 1) {
- for (var i = 0, elements = [], length = arguments.length; i < length; i++)
- elements.push($(arguments[i]));
- return elements;
- }
- if (typeof element == 'string')
- element = document.getElementById(element);
- return Element.extend(element);
-}
-
-if (Prototype.BrowserFeatures.XPath) {
- document._getElementsByXPath = function(expression, parentElement) {
- var results = [];
- var query = document.evaluate(expression, $(parentElement) || document,
- null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
- for (var i = 0, length = query.snapshotLength; i < length; i++)
- results.push(query.snapshotItem(i));
- return results;
- };
-
- document.getElementsByClassName = function(className, parentElement) {
- var q = ".//*[contains(concat(' ', @class, ' '), ' " + className + " ')]";
- return document._getElementsByXPath(q, parentElement);
- }
-
-} else document.getElementsByClassName = function(className, parentElement) {
- var children = ($(parentElement) || document.body).getElementsByTagName('*');
- var elements = [], child, pattern = new RegExp("(^|\\s)" + className + "(\\s|$)");
- for (var i = 0, length = children.length; i < length; i++) {
- child = children[i];
- var elementClassName = child.className;
- if (elementClassName.length == 0) continue;
- if (elementClassName == className || elementClassName.match(pattern))
- elements.push(Element.extend(child));
- }
- return elements;
-};
-
-/*--------------------------------------------------------------------------*/
-
-if (!window.Element) var Element = {};
-
-Element.extend = function(element) {
- var F = Prototype.BrowserFeatures;
- if (!element || !element.tagName || element.nodeType == 3 ||
- element._extended || F.SpecificElementExtensions || element == window)
- return element;
-
- var methods = {}, tagName = element.tagName, cache = Element.extend.cache,
- T = Element.Methods.ByTag;
-
- // extend methods for all tags (Safari doesn't need this)
- if (!F.ElementExtensions) {
- Object.extend(methods, Element.Methods),
- Object.extend(methods, Element.Methods.Simulated);
- }
-
- // extend methods for specific tags
- if (T[tagName]) Object.extend(methods, T[tagName]);
-
- for (var property in methods) {
- var value = methods[property];
- if (typeof value == 'function' && !(property in element))
- element[property] = cache.findOrStore(value);
- }
-
- element._extended = Prototype.emptyFunction;
- return element;
-};
-
-Element.extend.cache = {
- findOrStore: function(value) {
- return this[value] = this[value] || function() {
- return value.apply(null, [this].concat($A(arguments)));
- }
- }
-};
-
-Element.Methods = {
- visible: function(element) {
- return $(element).style.display != 'none';
- },
-
- toggle: function(element) {
- element = $(element);
- Element[Element.visible(element) ? 'hide' : 'show'](element);
- return element;
- },
-
- hide: function(element) {
- $(element).style.display = 'none';
- return element;
- },
-
- show: function(element) {
- $(element).style.display = '';
- return element;
- },
-
- remove: function(element) {
- element = $(element);
- element.parentNode.removeChild(element);
- return element;
- },
-
- update: function(element, html) {
- html = typeof html == 'undefined' ? '' : html.toString();
- $(element).innerHTML = html.stripScripts();
- setTimeout(function() {html.evalScripts()}, 10);
- return element;
- },
-
- replace: function(element, html) {
- element = $(element);
- html = typeof html == 'undefined' ? '' : html.toString();
- if (element.outerHTML) {
- element.outerHTML = html.stripScripts();
- } else {
- var range = element.ownerDocument.createRange();
- range.selectNodeContents(element);
- element.parentNode.replaceChild(
- range.createContextualFragment(html.stripScripts()), element);
- }
- setTimeout(function() {html.evalScripts()}, 10);
- return element;
- },
-
- inspect: function(element) {
- element = $(element);
- var result = '<' + element.tagName.toLowerCase();
- $H({'id': 'id', 'className': 'class'}).each(function(pair) {
- var property = pair.first(), attribute = pair.last();
- var value = (element[property] || '').toString();
- if (value) result += ' ' + attribute + '=' + value.inspect(true);
- });
- return result + '>';
- },
-
- recursivelyCollect: function(element, property) {
- element = $(element);
- var elements = [];
- while (element = element[property])
- if (element.nodeType == 1)
- elements.push(Element.extend(element));
- return elements;
- },
-
- ancestors: function(element) {
- return $(element).recursivelyCollect('parentNode');
- },
-
- descendants: function(element) {
- return $A($(element).getElementsByTagName('*')).each(Element.extend);
- },
-
- firstDescendant: function(element) {
- element = $(element).firstChild;
- while (element && element.nodeType != 1) element = element.nextSibling;
- return $(element);
- },
-
- immediateDescendants: function(element) {
- if (!(element = $(element).firstChild)) return [];
- while (element && element.nodeType != 1) element = element.nextSibling;
- if (element) return [element].concat($(element).nextSiblings());
- return [];
- },
-
- previousSiblings: function(element) {
- return $(element).recursivelyCollect('previousSibling');
- },
-
- nextSiblings: function(element) {
- return $(element).recursivelyCollect('nextSibling');
- },
-
- siblings: function(element) {
- element = $(element);
- return element.previousSiblings().reverse().concat(element.nextSiblings());
- },
-
- match: function(element, selector) {
- if (typeof selector == 'string')
- selector = new Selector(selector);
- return selector.match($(element));
- },
-
- up: function(element, expression, index) {
- element = $(element);
- if (arguments.length == 1) return $(element.parentNode);
- var ancestors = element.ancestors();
- return expression ? Selector.findElement(ancestors, expression, index) :
- ancestors[index || 0];
- },
-
- down: function(element, expression, index) {
- element = $(element);
- if (arguments.length == 1) return element.firstDescendant();
- var descendants = element.descendants();
- return expression ? Selector.findElement(descendants, expression, index) :
- descendants[index || 0];
- },
-
- previous: function(element, expression, index) {
- element = $(element);
- if (arguments.length == 1) return $(Selector.handlers.previousElementSibling(element));
- var previousSiblings = element.previousSiblings();
- return expression ? Selector.findElement(previousSiblings, expression, index) :
- previousSiblings[index || 0];
- },
-
- next: function(element, expression, index) {
- element = $(element);
- if (arguments.length == 1) return $(Selector.handlers.nextElementSibling(element));
- var nextSiblings = element.nextSiblings();
- return expression ? Selector.findElement(nextSiblings, expression, index) :
- nextSiblings[index || 0];
- },
-
- getElementsBySelector: function() {
- var args = $A(arguments), element = $(args.shift());
- return Selector.findChildElements(element, args);
- },
-
- getElementsByClassName: function(element, className) {
- return document.getElementsByClassName(className, element);
- },
-
- readAttribute: function(element, name) {
- element = $(element);
- if (Prototype.Browser.IE) {
- if (!element.attributes) return null;
- var t = Element._attributeTranslations;
- if (t.values[name]) return t.values[name](element, name);
- if (t.names[name]) name = t.names[name];
- var attribute = element.attributes[name];
- return attribute ? attribute.nodeValue : null;
- }
- return element.getAttribute(name);
- },
-
- getHeight: function(element) {
- return $(element).getDimensions().height;
- },
-
- getWidth: function(element) {
- return $(element).getDimensions().width;
- },
-
- classNames: function(element) {
- return new Element.ClassNames(element);
- },
-
- hasClassName: function(element, className) {
- if (!(element = $(element))) return;
- var elementClassName = element.className;
- if (elementClassName.length == 0) return false;
- if (elementClassName == className ||
- elementClassName.match(new RegExp("(^|\\s)" + className + "(\\s|$)")))
- return true;
- return false;
- },
-
- addClassName: function(element, className) {
- if (!(element = $(element))) return;
- Element.classNames(element).add(className);
- return element;
- },
-
- removeClassName: function(element, className) {
- if (!(element = $(element))) return;
- Element.classNames(element).remove(className);
- return element;
- },
-
- toggleClassName: function(element, className) {
- if (!(element = $(element))) return;
- Element.classNames(element)[element.hasClassName(className) ? 'remove' : 'add'](className);
- return element;
- },
-
- observe: function() {
- Event.observe.apply(Event, arguments);
- return $A(arguments).first();
- },
-
- stopObserving: function() {
- Event.stopObserving.apply(Event, arguments);
- return $A(arguments).first();
- },
-
- // removes whitespace-only text node children
- cleanWhitespace: function(element) {
- element = $(element);
- var node = element.firstChild;
- while (node) {
- var nextNode = node.nextSibling;
- if (node.nodeType == 3 && !/\S/.test(node.nodeValue))
- element.removeChild(node);
- node = nextNode;
- }
- return element;
- },
-
- empty: function(element) {
- return $(element).innerHTML.blank();
- },
-
- descendantOf: function(element, ancestor) {
- element = $(element), ancestor = $(ancestor);
- while (element = element.parentNode)
- if (element == ancestor) return true;
- return false;
- },
-
- scrollTo: function(element) {
- element = $(element);
- var pos = Position.cumulativeOffset(element);
- window.scrollTo(pos[0], pos[1]);
- return element;
- },
-
- getStyle: function(element, style) {
- element = $(element);
- style = style == 'float' ? 'cssFloat' : style.camelize();
- var value = element.style[style];
- if (!value) {
- var css = document.defaultView.getComputedStyle(element, null);
- value = css ? css[style] : null;
- }
- if (style == 'opacity') return value ? parseFloat(value) : 1.0;
- return value == 'auto' ? null : value;
- },
-
- getOpacity: function(element) {
- return $(element).getStyle('opacity');
- },
-
- setStyle: function(element, styles, camelized) {
- element = $(element);
- var elementStyle = element.style;
-
- for (var property in styles)
- if (property == 'opacity') element.setOpacity(styles[property])
- else
- elementStyle[(property == 'float' || property == 'cssFloat') ?
- (elementStyle.styleFloat === undefined ? 'cssFloat' : 'styleFloat') :
- (camelized ? property : property.camelize())] = styles[property];
-
- return element;
- },
-
- setOpacity: function(element, value) {
- element = $(element);
- element.style.opacity = (value == 1 || value === '') ? '' :
- (value < 0.00001) ? 0 : value;
- return element;
- },
-
- getDimensions: function(element) {
- element = $(element);
- var display = $(element).getStyle('display');
- if (display != 'none' && display != null) // Safari bug
- return {width: element.offsetWidth, height: element.offsetHeight};
-
- // All *Width and *Height properties give 0 on elements with display none,
- // so enable the element temporarily
- var els = element.style;
- var originalVisibility = els.visibility;
- var originalPosition = els.position;
- var originalDisplay = els.display;
- els.visibility = 'hidden';
- els.position = 'absolute';
- els.display = 'block';
- var originalWidth = element.clientWidth;
- var originalHeight = element.clientHeight;
- els.display = originalDisplay;
- els.position = originalPosition;
- els.visibility = originalVisibility;
- return {width: originalWidth, height: originalHeight};
- },
-
- makePositioned: function(element) {
- element = $(element);
- var pos = Element.getStyle(element, 'position');
- if (pos == 'static' || !pos) {
- element._madePositioned = true;
- element.style.position = 'relative';
- // Opera returns the offset relative to the positioning context, when an
- // element is position relative but top and left have not been defined
- if (window.opera) {
- element.style.top = 0;
- element.style.left = 0;
- }
- }
- return element;
- },
-
- undoPositioned: function(element) {
- element = $(element);
- if (element._madePositioned) {
- element._madePositioned = undefined;
- element.style.position =
- element.style.top =
- element.style.left =
- element.style.bottom =
- element.style.right = '';
- }
- return element;
- },
-
- makeClipping: function(element) {
- element = $(element);
- if (element._overflow) return element;
- element._overflow = element.style.overflow || 'auto';
- if ((Element.getStyle(element, 'overflow') || 'visible') != 'hidden')
- element.style.overflow = 'hidden';
- return element;
- },
-
- undoClipping: function(element) {
- element = $(element);
- if (!element._overflow) return element;
- element.style.overflow = element._overflow == 'auto' ? '' : element._overflow;
- element._overflow = null;
- return element;
- }
-};
-
-Object.extend(Element.Methods, {
- childOf: Element.Methods.descendantOf,
- childElements: Element.Methods.immediateDescendants
-});
-
-if (Prototype.Browser.Opera) {
- Element.Methods._getStyle = Element.Methods.getStyle;
- Element.Methods.getStyle = function(element, style) {
- switch(style) {
- case 'left':
- case 'top':
- case 'right':
- case 'bottom':
- if (Element._getStyle(element, 'position') == 'static') return null;
- default: return Element._getStyle(element, style);
- }
- };
-}
-else if (Prototype.Browser.IE) {
- Element.Methods.getStyle = function(element, style) {
- element = $(element);
- style = (style == 'float' || style == 'cssFloat') ? 'styleFloat' : style.camelize();
- var value = element.style[style];
- if (!value && element.currentStyle) value = element.currentStyle[style];
-
- if (style == 'opacity') {
- if (value = (element.getStyle('filter') || '').match(/alpha\(opacity=(.*)\)/))
- if (value[1]) return parseFloat(value[1]) / 100;
- return 1.0;
- }
-
- if (value == 'auto') {
- if ((style == 'width' || style == 'height') && (element.getStyle('display') != 'none'))
- return element['offset'+style.capitalize()] + 'px';
- return null;
- }
- return value;
- };
-
- Element.Methods.setOpacity = function(element, value) {
- element = $(element);
- var filter = element.getStyle('filter'), style = element.style;
- if (value == 1 || value === '') {
- style.filter = filter.replace(/alpha\([^\)]*\)/gi,'');
- return element;
- } else if (value < 0.00001) value = 0;
- style.filter = filter.replace(/alpha\([^\)]*\)/gi, '') +
- 'alpha(opacity=' + (value * 100) + ')';
- return element;
- };
-
- // IE is missing .innerHTML support for TABLE-related elements
- Element.Methods.update = function(element, html) {
- element = $(element);
- html = typeof html == 'undefined' ? '' : html.toString();
- var tagName = element.tagName.toUpperCase();
- if (['THEAD','TBODY','TR','TD'].include(tagName)) {
- var div = document.createElement('div');
- switch (tagName) {
- case 'THEAD':
- case 'TBODY':
- div.innerHTML = '<table><tbody>' + html.stripScripts() + '</tbody></table>';
- depth = 2;
- break;
- case 'TR':
- div.innerHTML = '<table><tbody><tr>' + html.stripScripts() + '</tr></tbody></table>';
- depth = 3;
- break;
- case 'TD':
- div.innerHTML = '<table><tbody><tr><td>' + html.stripScripts() + '</td></tr></tbody></table>';
- depth = 4;
- }
- $A(element.childNodes).each(function(node) { element.removeChild(node) });
- depth.times(function() { div = div.firstChild });
- $A(div.childNodes).each(function(node) { element.appendChild(node) });
- } else {
- element.innerHTML = html.stripScripts();
- }
- setTimeout(function() { html.evalScripts() }, 10);
- return element;
- }
-}
-else if (Prototype.Browser.Gecko) {
- Element.Methods.setOpacity = function(element, value) {
- element = $(element);
- element.style.opacity = (value == 1) ? 0.999999 :
- (value === '') ? '' : (value < 0.00001) ? 0 : value;
- return element;
- };
-}
-
-Element._attributeTranslations = {
- names: {
- colspan: "colSpan",
- rowspan: "rowSpan",
- valign: "vAlign",
- datetime: "dateTime",
- accesskey: "accessKey",
- tabindex: "tabIndex",
- enctype: "encType",
- maxlength: "maxLength",
- readonly: "readOnly",
- longdesc: "longDesc"
- },
- values: {
- _getAttr: function(element, attribute) {
- return element.getAttribute(attribute, 2);
- },
- _flag: function(element, attribute) {
- return $(element).hasAttribute(attribute) ? attribute : null;
- },
- style: function(element) {
- return element.style.cssText.toLowerCase();
- },
- title: function(element) {
- var node = element.getAttributeNode('title');
- return node.specified ? node.nodeValue : null;
- }
- }
-};
-
-(function() {
- Object.extend(this, {
- href: this._getAttr,
- src: this._getAttr,
- type: this._getAttr,
- disabled: this._flag,
- checked: this._flag,
- readonly: this._flag,
- multiple: this._flag
- });
-}).call(Element._attributeTranslations.values);
-
-Element.Methods.Simulated = {
- hasAttribute: function(element, attribute) {
- var t = Element._attributeTranslations, node;
- attribute = t.names[attribute] || attribute;
- node = $(element).getAttributeNode(attribute);
- return node && node.specified;
- }
-};
-
-Element.Methods.ByTag = {};
-
-Object.extend(Element, Element.Methods);
-
-if (!Prototype.BrowserFeatures.ElementExtensions &&
- document.createElement('div').__proto__) {
- window.HTMLElement = {};
- window.HTMLElement.prototype = document.createElement('div').__proto__;
- Prototype.BrowserFeatures.ElementExtensions = true;
-}
-
-Element.hasAttribute = function(element, attribute) {
- if (element.hasAttribute) return element.hasAttribute(attribute);
- return Element.Methods.Simulated.hasAttribute(element, attribute);
-};
-
-Element.addMethods = function(methods) {
- var F = Prototype.BrowserFeatures, T = Element.Methods.ByTag;
-
- if (!methods) {
- Object.extend(Form, Form.Methods);
- Object.extend(Form.Element, Form.Element.Methods);
- Object.extend(Element.Methods.ByTag, {
- "FORM": Object.clone(Form.Methods),
- "INPUT": Object.clone(Form.Element.Methods),
- "SELECT": Object.clone(Form.Element.Methods),
- "TEXTAREA": Object.clone(Form.Element.Methods)
- });
- }
-
- if (arguments.length == 2) {
- var tagName = methods;
- methods = arguments[1];
- }
-
- if (!tagName) Object.extend(Element.Methods, methods || {});
- else {
- if (tagName.constructor == Array) tagName.each(extend);
- else extend(tagName);
- }
-
- function extend(tagName) {
- tagName = tagName.toUpperCase();
- if (!Element.Methods.ByTag[tagName])
- Element.Methods.ByTag[tagName] = {};
- Object.extend(Element.Methods.ByTag[tagName], methods);
- }
-
- function copy(methods, destination, onlyIfAbsent) {
- onlyIfAbsent = onlyIfAbsent || false;
- var cache = Element.extend.cache;
- for (var property in methods) {
- var value = methods[property];
- if (!onlyIfAbsent || !(property in destination))
- destination[property] = cache.findOrStore(value);
- }
- }
-
- function findDOMClass(tagName) {
- var klass;
- var trans = {
- "OPTGROUP": "OptGroup", "TEXTAREA": "TextArea", "P": "Paragraph",
- "FIELDSET": "FieldSet", "UL": "UList", "OL": "OList", "DL": "DList",
- "DIR": "Directory", "H1": "Heading", "H2": "Heading", "H3": "Heading",
- "H4": "Heading", "H5": "Heading", "H6": "Heading", "Q": "Quote",
- "INS": "Mod", "DEL": "Mod", "A": "Anchor", "IMG": "Image", "CAPTION":
- "TableCaption", "COL": "TableCol", "COLGROUP": "TableCol", "THEAD":
- "TableSection", "TFOOT": "TableSection", "TBODY": "TableSection", "TR":
- "TableRow", "TH": "TableCell", "TD": "TableCell", "FRAMESET":
- "FrameSet", "IFRAME": "IFrame"
- };
- if (trans[tagName]) klass = 'HTML' + trans[tagName] + 'Element';
- if (window[klass]) return window[klass];
- klass = 'HTML' + tagName + 'Element';
- if (window[klass]) return window[klass];
- klass = 'HTML' + tagName.capitalize() + 'Element';
- if (window[klass]) return window[klass];
-
- window[klass] = {};
- window[klass].prototype = document.createElement(tagName).__proto__;
- return window[klass];
- }
-
- if (F.ElementExtensions) {
- copy(Element.Methods, HTMLElement.prototype);
- copy(Element.Methods.Simulated, HTMLElement.prototype, true);
- }
-
- if (F.SpecificElementExtensions) {
- for (var tag in Element.Methods.ByTag) {
- var klass = findDOMClass(tag);
- if (typeof klass == "undefined") continue;
- copy(T[tag], klass.prototype);
- }
- }
-
- Object.extend(Element, Element.Methods);
- delete Element.ByTag;
-};
-
-var Toggle = { display: Element.toggle };
-
-/*--------------------------------------------------------------------------*/
-
-Abstract.Insertion = function(adjacency) {
- this.adjacency = adjacency;
-}
-
-Abstract.Insertion.prototype = {
- initialize: function(element, content) {
- this.element = $(element);
- this.content = content.stripScripts();
-
- if (this.adjacency && this.element.insertAdjacentHTML) {
- try {
- this.element.insertAdjacentHTML(this.adjacency, this.content);
- } catch (e) {
- var tagName = this.element.tagName.toUpperCase();
- if (['TBODY', 'TR'].include(tagName)) {
- this.insertContent(this.contentFromAnonymousTable());
- } else {
- throw e;
- }
- }
- } else {
- this.range = this.element.ownerDocument.createRange();
- if (this.initializeRange) this.initializeRange();
- this.insertContent([this.range.createContextualFragment(this.content)]);
- }
-
- setTimeout(function() {content.evalScripts()}, 10);
- },
-
- contentFromAnonymousTable: function() {
- var div = document.createElement('div');
- div.innerHTML = '<table><tbody>' + this.content + '</tbody></table>';
- return $A(div.childNodes[0].childNodes[0].childNodes);
- }
-}
-
-var Insertion = new Object();
-
-Insertion.Before = Class.create();
-Insertion.Before.prototype = Object.extend(new Abstract.Insertion('beforeBegin'), {
- initializeRange: function() {
- this.range.setStartBefore(this.element);
- },
-
- insertContent: function(fragments) {
- fragments.each((function(fragment) {
- this.element.parentNode.insertBefore(fragment, this.element);
- }).bind(this));
- }
-});
-
-Insertion.Top = Class.create();
-Insertion.Top.prototype = Object.extend(new Abstract.Insertion('afterBegin'), {
- initializeRange: function() {
- this.range.selectNodeContents(this.element);
- this.range.collapse(true);
- },
-
- insertContent: function(fragments) {
- fragments.reverse(false).each((function(fragment) {
- this.element.insertBefore(fragment, this.element.firstChild);
- }).bind(this));
- }
-});
-
-Insertion.Bottom = Class.create();
-Insertion.Bottom.prototype = Object.extend(new Abstract.Insertion('beforeEnd'), {
- initializeRange: function() {
- this.range.selectNodeContents(this.element);
- this.range.collapse(this.element);
- },
-
- insertContent: function(fragments) {
- fragments.each((function(fragment) {
- this.element.appendChild(fragment);
- }).bind(this));
- }
-});
-
-Insertion.After = Class.create();
-Insertion.After.prototype = Object.extend(new Abstract.Insertion('afterEnd'), {
- initializeRange: function() {
- this.range.setStartAfter(this.element);
- },
-
- insertContent: function(fragments) {
- fragments.each((function(fragment) {
- this.element.parentNode.insertBefore(fragment,
- this.element.nextSibling);
- }).bind(this));
- }
-});
-
-/*--------------------------------------------------------------------------*/
-
-Element.ClassNames = Class.create();
-Element.ClassNames.prototype = {
- initialize: function(element) {
- this.element = $(element);
- },
-
- _each: function(iterator) {
- this.element.className.split(/\s+/).select(function(name) {
- return name.length > 0;
- })._each(iterator);
- },
-
- set: function(className) {
- this.element.className = className;
- },
-
- add: function(classNameToAdd) {
- if (this.include(classNameToAdd)) return;
- this.set($A(this).concat(classNameToAdd).join(' '));
- },
-
- remove: function(classNameToRemove) {
- if (!this.include(classNameToRemove)) return;
- this.set($A(this).without(classNameToRemove).join(' '));
- },
-
- toString: function() {
- return $A(this).join(' ');
- }
-};
-
-Object.extend(Element.ClassNames.prototype, Enumerable);
-/* Portions of the Selector class are derived from Jack Slocum’s DomQuery,
- * part of YUI-Ext version 0.40, distributed under the terms of an MIT-style
- * license. Please see http://www.yui-ext.com/ for more information. */
-
-var Selector = Class.create();
-
-Selector.prototype = {
- initialize: function(expression) {
- this.expression = expression.strip();
- this.compileMatcher();
- },
-
- compileMatcher: function() {
- // Selectors with namespaced attributes can't use the XPath version
- if (Prototype.BrowserFeatures.XPath && !(/\[[\w-]*?:/).test(this.expression))
- return this.compileXPathMatcher();
-
- var e = this.expression, ps = Selector.patterns, h = Selector.handlers,
- c = Selector.criteria, le, p, m;
-
- if (Selector._cache[e]) {
- this.matcher = Selector._cache[e]; return;
- }
- this.matcher = ["this.matcher = function(root) {",
- "var r = root, h = Selector.handlers, c = false, n;"];
-
- while (e && le != e && (/\S/).test(e)) {
- le = e;
- for (var i in ps) {
- p = ps[i];
- if (m = e.match(p)) {
- this.matcher.push(typeof c[i] == 'function' ? c[i](m) :
- new Template(c[i]).evaluate(m));
- e = e.replace(m[0], '');
- break;
- }
- }
- }
-
- this.matcher.push("return h.unique(n);\n}");
- eval(this.matcher.join('\n'));
- Selector._cache[this.expression] = this.matcher;
- },
-
- compileXPathMatcher: function() {
- var e = this.expression, ps = Selector.patterns,
- x = Selector.xpath, le, m;
-
- if (Selector._cache[e]) {
- this.xpath = Selector._cache[e]; return;
- }
-
- this.matcher = ['.//*'];
- while (e && le != e && (/\S/).test(e)) {
- le = e;
- for (var i in ps) {
- if (m = e.match(ps[i])) {
- this.matcher.push(typeof x[i] == 'function' ? x[i](m) :
- new Template(x[i]).evaluate(m));
- e = e.replace(m[0], '');
- break;
- }
- }
- }
-
- this.xpath = this.matcher.join('');
- Selector._cache[this.expression] = this.xpath;
- },
-
- findElements: function(root) {
- root = root || document;
- if (this.xpath) return document._getElementsByXPath(this.xpath, root);
- return this.matcher(root);
- },
-
- match: function(element) {
- return this.findElements(document).include(element);
- },
-
- toString: function() {
- return this.expression;
- },
-
- inspect: function() {
- return "#<Selector:" + this.expression.inspect() + ">";
- }
-};
-
-Object.extend(Selector, {
- _cache: {},
-
- xpath: {
- descendant: "//*",
- child: "/*",
- adjacent: "/following-sibling::*[1]",
- laterSibling: '/following-sibling::*',
- tagName: function(m) {
- if (m[1] == '*') return '';
- return "[local-name()='" + m[1].toLowerCase() +
- "' or local-name()='" + m[1].toUpperCase() + "']";
- },
- className: "[contains(concat(' ', @class, ' '), ' #{1} ')]",
- id: "[@id='#{1}']",
- attrPresence: "[@#{1}]",
- attr: function(m) {
- m[3] = m[5] || m[6];
- return new Template(Selector.xpath.operators[m[2]]).evaluate(m);
- },
- pseudo: function(m) {
- var h = Selector.xpath.pseudos[m[1]];
- if (!h) return '';
- if (typeof h === 'function') return h(m);
- return new Template(Selector.xpath.pseudos[m[1]]).evaluate(m);
- },
- operators: {
- '=': "[@#{1}='#{3}']",
- '!=': "[@#{1}!='#{3}']",
- '^=': "[starts-with(@#{1}, '#{3}')]",
- '$=': "[substring(@#{1}, (string-length(@#{1}) - string-length('#{3}') + 1))='#{3}']",
- '*=': "[contains(@#{1}, '#{3}')]",
- '~=': "[contains(concat(' ', @#{1}, ' '), ' #{3} ')]",
- '|=': "[contains(concat('-', @#{1}, '-'), '-#{3}-')]"
- },
- pseudos: {
- 'first-child': '[not(preceding-sibling::*)]',
- 'last-child': '[not(following-sibling::*)]',
- 'only-child': '[not(preceding-sibling::* or following-sibling::*)]',
- 'empty': "[count(*) = 0 and (count(text()) = 0 or translate(text(), ' \t\r\n', '') = '')]",
- 'checked': "[@checked]",
- 'disabled': "[@disabled]",
- 'enabled': "[not(@disabled)]",
- 'not': function(m) {
- var e = m[6], p = Selector.patterns,
- x = Selector.xpath, le, m, v;
-
- var exclusion = [];
- while (e && le != e && (/\S/).test(e)) {
- le = e;
- for (var i in p) {
- if (m = e.match(p[i])) {
- v = typeof x[i] == 'function' ? x[i](m) : new Template(x[i]).evaluate(m);
- exclusion.push("(" + v.substring(1, v.length - 1) + ")");
- e = e.replace(m[0], '');
- break;
- }
- }
- }
- return "[not(" + exclusion.join(" and ") + ")]";
- },
- 'nth-child': function(m) {
- return Selector.xpath.pseudos.nth("(count(./preceding-sibling::*) + 1) ", m);
- },
- 'nth-last-child': function(m) {
- return Selector.xpath.pseudos.nth("(count(./following-sibling::*) + 1) ", m);
- },
- 'nth-of-type': function(m) {
- return Selector.xpath.pseudos.nth("position() ", m);
- },
- 'nth-last-of-type': function(m) {
- return Selector.xpath.pseudos.nth("(last() + 1 - position()) ", m);
- },
- 'first-of-type': function(m) {
- m[6] = "1"; return Selector.xpath.pseudos['nth-of-type'](m);
- },
- 'last-of-type': function(m) {
- m[6] = "1"; return Selector.xpath.pseudos['nth-last-of-type'](m);
- },
- 'only-of-type': function(m) {
- var p = Selector.xpath.pseudos; return p['first-of-type'](m) + p['last-of-type'](m);
- },
- nth: function(fragment, m) {
- var mm, formula = m[6], predicate;
- if (formula == 'even') formula = '2n+0';
- if (formula == 'odd') formula = '2n+1';
- if (mm = formula.match(/^(\d+)$/)) // digit only
- return '[' + fragment + "= " + mm[1] + ']';
- if (mm = formula.match(/^(-?\d*)?n(([+-])(\d+))?/)) { // an+b
- if (mm[1] == "-") mm[1] = -1;
- var a = mm[1] ? Number(mm[1]) : 1;
- var b = mm[2] ? Number(mm[2]) : 0;
- predicate = "[((#{fragment} - #{b}) mod #{a} = 0) and " +
- "((#{fragment} - #{b}) div #{a} >= 0)]";
- return new Template(predicate).evaluate({
- fragment: fragment, a: a, b: b });
- }
- }
- }
- },
-
- criteria: {
- tagName: 'n = h.tagName(n, r, "#{1}", c); c = false;',
- className: 'n = h.className(n, r, "#{1}", c); c = false;',
- id: 'n = h.id(n, r, "#{1}", c); c = false;',
- attrPresence: 'n = h.attrPresence(n, r, "#{1}"); c = false;',
- attr: function(m) {
- m[3] = (m[5] || m[6]);
- return new Template('n = h.attr(n, r, "#{1}", "#{3}", "#{2}"); c = false;').evaluate(m);
- },
- pseudo: function(m) {
- if (m[6]) m[6] = m[6].replace(/"/g, '\\"');
- return new Template('n = h.pseudo(n, "#{1}", "#{6}", r, c); c = false;').evaluate(m);
- },
- descendant: 'c = "descendant";',
- child: 'c = "child";',
- adjacent: 'c = "adjacent";',
- laterSibling: 'c = "laterSibling";'
- },
-
- patterns: {
- // combinators must be listed first
- // (and descendant needs to be last combinator)
- laterSibling: /^\s*~\s*/,
- child: /^\s*>\s*/,
- adjacent: /^\s*\+\s*/,
- descendant: /^\s/,
-
- // selectors follow
- tagName: /^\s*(\*|[\w\-]+)(\b|$)?/,
- id: /^#([\w\-\*]+)(\b|$)/,
- className: /^\.([\w\-\*]+)(\b|$)/,
- pseudo: /^:((first|last|nth|nth-last|only)(-child|-of-type)|empty|checked|(en|dis)abled|not)(\((.*?)\))?(\b|$|\s|(?=:))/,
- attrPresence: /^\[([\w]+)\]/,
- attr: /\[((?:[\w-]*:)?[\w-]+)\s*(?:([!^$*~|]?=)\s*((['"])([^\]]*?)\4|([^'"][^\]]*?)))?\]/
- },
-
- handlers: {
- // UTILITY FUNCTIONS
- // joins two collections
- concat: function(a, b) {
- for (var i = 0, node; node = b[i]; i++)
- a.push(node);
- return a;
- },
-
- // marks an array of nodes for counting
- mark: function(nodes) {
- for (var i = 0, node; node = nodes[i]; i++)
- node._counted = true;
- return nodes;
- },
-
- unmark: function(nodes) {
- for (var i = 0, node; node = nodes[i]; i++)
- node._counted = undefined;
- return nodes;
- },
-
- // mark each child node with its position (for nth calls)
- // "ofType" flag indicates whether we're indexing for nth-of-type
- // rather than nth-child
- index: function(parentNode, reverse, ofType) {
- parentNode._counted = true;
- if (reverse) {
- for (var nodes = parentNode.childNodes, i = nodes.length - 1, j = 1; i >= 0; i--) {
- node = nodes[i];
- if (node.nodeType == 1 && (!ofType || node._counted)) node.nodeIndex = j++;
- }
- } else {
- for (var i = 0, j = 1, nodes = parentNode.childNodes; node = nodes[i]; i++)
- if (node.nodeType == 1 && (!ofType || node._counted)) node.nodeIndex = j++;
- }
- },
-
- // filters out duplicates and extends all nodes
- unique: function(nodes) {
- if (nodes.length == 0) return nodes;
- var results = [], n;
- for (var i = 0, l = nodes.length; i < l; i++)
- if (!(n = nodes[i])._counted) {
- n._counted = true;
- results.push(Element.extend(n));
- }
- return Selector.handlers.unmark(results);
- },
-
- // COMBINATOR FUNCTIONS
- descendant: function(nodes) {
- var h = Selector.handlers;
- for (var i = 0, results = [], node; node = nodes[i]; i++)
- h.concat(results, node.getElementsByTagName('*'));
- return results;
- },
-
- child: function(nodes) {
- var h = Selector.handlers;
- for (var i = 0, results = [], node; node = nodes[i]; i++) {
- for (var j = 0, children = [], child; child = node.childNodes[j]; j++)
- if (child.nodeType == 1 && child.tagName != '!') results.push(child);
- }
- return results;
- },
-
- adjacent: function(nodes) {
- for (var i = 0, results = [], node; node = nodes[i]; i++) {
- var next = this.nextElementSibling(node);
- if (next) results.push(next);
- }
- return results;
- },
-
- laterSibling: function(nodes) {
- var h = Selector.handlers;
- for (var i = 0, results = [], node; node = nodes[i]; i++)
- h.concat(results, Element.nextSiblings(node));
- return results;
- },
-
- nextElementSibling: function(node) {
- while (node = node.nextSibling)
- if (node.nodeType == 1) return node;
- return null;
- },
-
- previousElementSibling: function(node) {
- while (node = node.previousSibling)
- if (node.nodeType == 1) return node;
- return null;
- },
-
- // TOKEN FUNCTIONS
- tagName: function(nodes, root, tagName, combinator) {
- tagName = tagName.toUpperCase();
- var results = [], h = Selector.handlers;
- if (nodes) {
- if (combinator) {
- // fastlane for ordinary descendant combinators
- if (combinator == "descendant") {
- for (var i = 0, node; node = nodes[i]; i++)
- h.concat(results, node.getElementsByTagName(tagName));
- return results;
- } else nodes = this[combinator](nodes);
- if (tagName == "*") return nodes;
- }
- for (var i = 0, node; node = nodes[i]; i++)
- if (node.tagName.toUpperCase() == tagName) results.push(node);
- return results;
- } else return root.getElementsByTagName(tagName);
- },
-
- id: function(nodes, root, id, combinator) {
- var targetNode = $(id), h = Selector.handlers;
- if (!nodes && root == document) return targetNode ? [targetNode] : [];
- if (nodes) {
- if (combinator) {
- if (combinator == 'child') {
- for (var i = 0, node; node = nodes[i]; i++)
- if (targetNode.parentNode == node) return [targetNode];
- } else if (combinator == 'descendant') {
- for (var i = 0, node; node = nodes[i]; i++)
- if (Element.descendantOf(targetNode, node)) return [targetNode];
- } else if (combinator == 'adjacent') {
- for (var i = 0, node; node = nodes[i]; i++)
- if (Selector.handlers.previousElementSibling(targetNode) == node)
- return [targetNode];
- } else nodes = h[combinator](nodes);
- }
- for (var i = 0, node; node = nodes[i]; i++)
- if (node == targetNode) return [targetNode];
- return [];
- }
- return (targetNode && Element.descendantOf(targetNode, root)) ? [targetNode] : [];
- },
-
- className: function(nodes, root, className, combinator) {
- if (nodes && combinator) nodes = this[combinator](nodes);
- return Selector.handlers.byClassName(nodes, root, className);
- },
-
- byClassName: function(nodes, root, className) {
- if (!nodes) nodes = Selector.handlers.descendant([root]);
- var needle = ' ' + className + ' ';
- for (var i = 0, results = [], node, nodeClassName; node = nodes[i]; i++) {
- nodeClassName = node.className;
- if (nodeClassName.length == 0) continue;
- if (nodeClassName == className || (' ' + nodeClassName + ' ').include(needle))
- results.push(node);
- }
- return results;
- },
-
- attrPresence: function(nodes, root, attr) {
- var results = [];
- for (var i = 0, node; node = nodes[i]; i++)
- if (Element.hasAttribute(node, attr)) results.push(node);
- return results;
- },
-
- attr: function(nodes, root, attr, value, operator) {
- if (!nodes) nodes = root.getElementsByTagName("*");
- var handler = Selector.operators[operator], results = [];
- for (var i = 0, node; node = nodes[i]; i++) {
- var nodeValue = Element.readAttribute(node, attr);
- if (nodeValue === null) continue;
- if (handler(nodeValue, value)) results.push(node);
- }
- return results;
- },
-
- pseudo: function(nodes, name, value, root, combinator) {
- if (nodes && combinator) nodes = this[combinator](nodes);
- if (!nodes) nodes = root.getElementsByTagName("*");
- return Selector.pseudos[name](nodes, value, root);
- }
- },
-
- pseudos: {
- 'first-child': function(nodes, value, root) {
- for (var i = 0, results = [], node; node = nodes[i]; i++) {
- if (Selector.handlers.previousElementSibling(node)) continue;
- results.push(node);
- }
- return results;
- },
- 'last-child': function(nodes, value, root) {
- for (var i = 0, results = [], node; node = nodes[i]; i++) {
- if (Selector.handlers.nextElementSibling(node)) continue;
- results.push(node);
- }
- return results;
- },
- 'only-child': function(nodes, value, root) {
- var h = Selector.handlers;
- for (var i = 0, results = [], node; node = nodes[i]; i++)
- if (!h.previousElementSibling(node) && !h.nextElementSibling(node))
- results.push(node);
- return results;
- },
- 'nth-child': function(nodes, formula, root) {
- return Selector.pseudos.nth(nodes, formula, root);
- },
- 'nth-last-child': function(nodes, formula, root) {
- return Selector.pseudos.nth(nodes, formula, root, true);
- },
- 'nth-of-type': function(nodes, formula, root) {
- return Selector.pseudos.nth(nodes, formula, root, false, true);
- },
- 'nth-last-of-type': function(nodes, formula, root) {
- return Selector.pseudos.nth(nodes, formula, root, true, true);
- },
- 'first-of-type': function(nodes, formula, root) {
- return Selector.pseudos.nth(nodes, "1", root, false, true);
- },
- 'last-of-type': function(nodes, formula, root) {
- return Selector.pseudos.nth(nodes, "1", root, true, true);
- },
- 'only-of-type': function(nodes, formula, root) {
- var p = Selector.pseudos;
- return p['last-of-type'](p['first-of-type'](nodes, formula, root), formula, root);
- },
-
- // handles the an+b logic
- getIndices: function(a, b, total) {
- if (a == 0) return b > 0 ? [b] : [];
- return $R(1, total).inject([], function(memo, i) {
- if (0 == (i - b) % a && (i - b) / a >= 0) memo.push(i);
- return memo;
- });
- },
-
- // handles nth(-last)-child, nth(-last)-of-type, and (first|last)-of-type
- nth: function(nodes, formula, root, reverse, ofType) {
- if (nodes.length == 0) return [];
- if (formula == 'even') formula = '2n+0';
- if (formula == 'odd') formula = '2n+1';
- var h = Selector.handlers, results = [], indexed = [], m;
- h.mark(nodes);
- for (var i = 0, node; node = nodes[i]; i++) {
- if (!node.parentNode._counted) {
- h.index(node.parentNode, reverse, ofType);
- indexed.push(node.parentNode);
- }
- }
- if (formula.match(/^\d+$/)) { // just a number
- formula = Number(formula);
- for (var i = 0, node; node = nodes[i]; i++)
- if (node.nodeIndex == formula) results.push(node);
- } else if (m = formula.match(/^(-?\d*)?n(([+-])(\d+))?/)) { // an+b
- if (m[1] == "-") m[1] = -1;
- var a = m[1] ? Number(m[1]) : 1;
- var b = m[2] ? Number(m[2]) : 0;
- var indices = Selector.pseudos.getIndices(a, b, nodes.length);
- for (var i = 0, node, l = indices.length; node = nodes[i]; i++) {
- for (var j = 0; j < l; j++)
- if (node.nodeIndex == indices[j]) results.push(node);
- }
- }
- h.unmark(nodes);
- h.unmark(indexed);
- return results;
- },
-
- 'empty': function(nodes, value, root) {
- for (var i = 0, results = [], node; node = nodes[i]; i++) {
- // IE treats comments as element nodes
- if (node.tagName == '!' || (node.firstChild && !node.innerHTML.match(/^\s*$/))) continue;
- results.push(node);
- }
- return results;
- },
-
- 'not': function(nodes, selector, root) {
- var h = Selector.handlers, selectorType, m;
- var exclusions = new Selector(selector).findElements(root);
- h.mark(exclusions);
- for (var i = 0, results = [], node; node = nodes[i]; i++)
- if (!node._counted) results.push(node);
- h.unmark(exclusions);
- return results;
- },
-
- 'enabled': function(nodes, value, root) {
- for (var i = 0, results = [], node; node = nodes[i]; i++)
- if (!node.disabled) results.push(node);
- return results;
- },
-
- 'disabled': function(nodes, value, root) {
- for (var i = 0, results = [], node; node = nodes[i]; i++)
- if (node.disabled) results.push(node);
- return results;
- },
-
- 'checked': function(nodes, value, root) {
- for (var i = 0, results = [], node; node = nodes[i]; i++)
- if (node.checked) results.push(node);
- return results;
- }
- },
-
- operators: {
- '=': function(nv, v) { return nv == v; },
- '!=': function(nv, v) { return nv != v; },
- '^=': function(nv, v) { return nv.startsWith(v); },
- '$=': function(nv, v) { return nv.endsWith(v); },
- '*=': function(nv, v) { return nv.include(v); },
- '~=': function(nv, v) { return (' ' + nv + ' ').include(' ' + v + ' '); },
- '|=': function(nv, v) { return ('-' + nv.toUpperCase() + '-').include('-' + v.toUpperCase() + '-'); }
- },
-
- matchElements: function(elements, expression) {
- var matches = new Selector(expression).findElements(), h = Selector.handlers;
- h.mark(matches);
- for (var i = 0, results = [], element; element = elements[i]; i++)
- if (element._counted) results.push(element);
- h.unmark(matches);
- return results;
- },
-
- findElement: function(elements, expression, index) {
- if (typeof expression == 'number') {
- index = expression; expression = false;
- }
- return Selector.matchElements(elements, expression || '*')[index || 0];
- },
-
- findChildElements: function(element, expressions) {
- var exprs = expressions.join(','), expressions = [];
- exprs.scan(/(([\w#:.~>+()\s-]+|\*|\[.*?\])+)\s*(,|$)/, function(m) {
- expressions.push(m[1].strip());
- });
- var results = [], h = Selector.handlers;
- for (var i = 0, l = expressions.length, selector; i < l; i++) {
- selector = new Selector(expressions[i].strip());
- h.concat(results, selector.findElements(element));
- }
- return (l > 1) ? h.unique(results) : results;
- }
-});
-
-function $$() {
- return Selector.findChildElements(document, $A(arguments));
-}
-var Form = {
- reset: function(form) {
- $(form).reset();
- return form;
- },
-
- serializeElements: function(elements, getHash) {
- var data = elements.inject({}, function(result, element) {
- if (!element.disabled && element.name) {
- var key = element.name, value = $(element).getValue();
- if (value != null) {
- if (key in result) {
- if (result[key].constructor != Array) result[key] = [result[key]];
- result[key].push(value);
- }
- else result[key] = value;
- }
- }
- return result;
- });
-
- return getHash ? data : Hash.toQueryString(data);
- }
-};
-
-Form.Methods = {
- serialize: function(form, getHash) {
- return Form.serializeElements(Form.getElements(form), getHash);
- },
-
- getElements: function(form) {
- return $A($(form).getElementsByTagName('*')).inject([],
- function(elements, child) {
- if (Form.Element.Serializers[child.tagName.toLowerCase()])
- elements.push(Element.extend(child));
- return elements;
- }
- );
- },
-
- getInputs: function(form, typeName, name) {
- form = $(form);
- var inputs = form.getElementsByTagName('input');
-
- if (!typeName && !name) return $A(inputs).map(Element.extend);
-
- for (var i = 0, matchingInputs = [], length = inputs.length; i < length; i++) {
- var input = inputs[i];
- if ((typeName && input.type != typeName) || (name && input.name != name))
- continue;
- matchingInputs.push(Element.extend(input));
- }
-
- return matchingInputs;
- },
-
- disable: function(form) {
- form = $(form);
- Form.getElements(form).invoke('disable');
- return form;
- },
-
- enable: function(form) {
- form = $(form);
- Form.getElements(form).invoke('enable');
- return form;
- },
-
- findFirstElement: function(form) {
- return $(form).getElements().find(function(element) {
- return element.type != 'hidden' && !element.disabled &&
- ['input', 'select', 'textarea'].include(element.tagName.toLowerCase());
- });
- },
-
- focusFirstElement: function(form) {
- form = $(form);
- form.findFirstElement().activate();
- return form;
- },
-
- request: function(form, options) {
- form = $(form), options = Object.clone(options || {});
-
- var params = options.parameters;
- options.parameters = form.serialize(true);
-
- if (params) {
- if (typeof params == 'string') params = params.toQueryParams();
- Object.extend(options.parameters, params);
- }
-
- if (form.hasAttribute('method') && !options.method)
- options.method = form.method;
-
- return new Ajax.Request(form.readAttribute('action'), options);
- }
-}
-
-/*--------------------------------------------------------------------------*/
-
-Form.Element = {
- focus: function(element) {
- $(element).focus();
- return element;
- },
-
- select: function(element) {
- $(element).select();
- return element;
- }
-}
-
-Form.Element.Methods = {
- serialize: function(element) {
- element = $(element);
- if (!element.disabled && element.name) {
- var value = element.getValue();
- if (value != undefined) {
- var pair = {};
- pair[element.name] = value;
- return Hash.toQueryString(pair);
- }
- }
- return '';
- },
-
- getValue: function(element) {
- element = $(element);
- var method = element.tagName.toLowerCase();
- return Form.Element.Serializers[method](element);
- },
-
- clear: function(element) {
- $(element).value = '';
- return element;
- },
-
- present: function(element) {
- return $(element).value != '';
- },
-
- activate: function(element) {
- element = $(element);
- try {
- element.focus();
- if (element.select && (element.tagName.toLowerCase() != 'input' ||
- !['button', 'reset', 'submit'].include(element.type)))
- element.select();
- } catch (e) {}
- return element;
- },
-
- disable: function(element) {
- element = $(element);
- element.blur();
- element.disabled = true;
- return element;
- },
-
- enable: function(element) {
- element = $(element);
- element.disabled = false;
- return element;
- }
-}
-
-/*--------------------------------------------------------------------------*/
-
-var Field = Form.Element;
-var $F = Form.Element.Methods.getValue;
-
-/*--------------------------------------------------------------------------*/
-
-Form.Element.Serializers = {
- input: function(element) {
- switch (element.type.toLowerCase()) {
- case 'checkbox':
- case 'radio':
- return Form.Element.Serializers.inputSelector(element);
- default:
- return Form.Element.Serializers.textarea(element);
- }
- },
-
- inputSelector: function(element) {
- return element.checked ? element.value : null;
- },
-
- textarea: function(element) {
- return element.value;
- },
-
- select: function(element) {
- return this[element.type == 'select-one' ?
- 'selectOne' : 'selectMany'](element);
- },
-
- selectOne: function(element) {
- var index = element.selectedIndex;
- return index >= 0 ? this.optionValue(element.options[index]) : null;
- },
-
- selectMany: function(element) {
- var values, length = element.length;
- if (!length) return null;
-
- for (var i = 0, values = []; i < length; i++) {
- var opt = element.options[i];
- if (opt.selected) values.push(this.optionValue(opt));
- }
- return values;
- },
-
- optionValue: function(opt) {
- // extend element because hasAttribute may not be native
- return Element.extend(opt).hasAttribute('value') ? opt.value : opt.text;
- }
-}
-
-/*--------------------------------------------------------------------------*/
-
-Abstract.TimedObserver = function() {}
-Abstract.TimedObserver.prototype = {
- initialize: function(element, frequency, callback) {
- this.frequency = frequency;
- this.element = $(element);
- this.callback = callback;
-
- this.lastValue = this.getValue();
- this.registerCallback();
- },
-
- registerCallback: function() {
- setInterval(this.onTimerEvent.bind(this), this.frequency * 1000);
- },
-
- onTimerEvent: function() {
- var value = this.getValue();
- var changed = ('string' == typeof this.lastValue && 'string' == typeof value
- ? this.lastValue != value : String(this.lastValue) != String(value));
- if (changed) {
- this.callback(this.element, value);
- this.lastValue = value;
- }
- }
-}
-
-Form.Element.Observer = Class.create();
-Form.Element.Observer.prototype = Object.extend(new Abstract.TimedObserver(), {
- getValue: function() {
- return Form.Element.getValue(this.element);
- }
-});
-
-Form.Observer = Class.create();
-Form.Observer.prototype = Object.extend(new Abstract.TimedObserver(), {
- getValue: function() {
- return Form.serialize(this.element);
- }
-});
-
-/*--------------------------------------------------------------------------*/
-
-Abstract.EventObserver = function() {}
-Abstract.EventObserver.prototype = {
- initialize: function(element, callback) {
- this.element = $(element);
- this.callback = callback;
-
- this.lastValue = this.getValue();
- if (this.element.tagName.toLowerCase() == 'form')
- this.registerFormCallbacks();
- else
- this.registerCallback(this.element);
- },
-
- onElementEvent: function() {
- var value = this.getValue();
- if (this.lastValue != value) {
- this.callback(this.element, value);
- this.lastValue = value;
- }
- },
-
- registerFormCallbacks: function() {
- Form.getElements(this.element).each(this.registerCallback.bind(this));
- },
-
- registerCallback: function(element) {
- if (element.type) {
- switch (element.type.toLowerCase()) {
- case 'checkbox':
- case 'radio':
- Event.observe(element, 'click', this.onElementEvent.bind(this));
- break;
- default:
- Event.observe(element, 'change', this.onElementEvent.bind(this));
- break;
- }
- }
- }
-}
-
-Form.Element.EventObserver = Class.create();
-Form.Element.EventObserver.prototype = Object.extend(new Abstract.EventObserver(), {
- getValue: function() {
- return Form.Element.getValue(this.element);
- }
-});
-
-Form.EventObserver = Class.create();
-Form.EventObserver.prototype = Object.extend(new Abstract.EventObserver(), {
- getValue: function() {
- return Form.serialize(this.element);
- }
-});
-if (!window.Event) {
- var Event = new Object();
-}
-
-Object.extend(Event, {
- KEY_BACKSPACE: 8,
- KEY_TAB: 9,
- KEY_RETURN: 13,
- KEY_ESC: 27,
- KEY_LEFT: 37,
- KEY_UP: 38,
- KEY_RIGHT: 39,
- KEY_DOWN: 40,
- KEY_DELETE: 46,
- KEY_HOME: 36,
- KEY_END: 35,
- KEY_PAGEUP: 33,
- KEY_PAGEDOWN: 34,
-
- element: function(event) {
- return $(event.target || event.srcElement);
- },
-
- isLeftClick: function(event) {
- return (((event.which) && (event.which == 1)) ||
- ((event.button) && (event.button == 1)));
- },
-
- pointerX: function(event) {
- return event.pageX || (event.clientX +
- (document.documentElement.scrollLeft || document.body.scrollLeft));
- },
-
- pointerY: function(event) {
- return event.pageY || (event.clientY +
- (document.documentElement.scrollTop || document.body.scrollTop));
- },
-
- stop: function(event) {
- if (event.preventDefault) {
- event.preventDefault();
- event.stopPropagation();
- } else {
- event.returnValue = false;
- event.cancelBubble = true;
- }
- },
-
- // find the first node with the given tagName, starting from the
- // node the event was triggered on; traverses the DOM upwards
- findElement: function(event, tagName) {
- var element = Event.element(event);
- while (element.parentNode && (!element.tagName ||
- (element.tagName.toUpperCase() != tagName.toUpperCase())))
- element = element.parentNode;
- return element;
- },
-
- observers: false,
-
- _observeAndCache: function(element, name, observer, useCapture) {
- if (!this.observers) this.observers = [];
- if (element.addEventListener) {
- this.observers.push([element, name, observer, useCapture]);
- element.addEventListener(name, observer, useCapture);
- } else if (element.attachEvent) {
- this.observers.push([element, name, observer, useCapture]);
- element.attachEvent('on' + name, observer);
- }
- },
-
- unloadCache: function() {
- if (!Event.observers) return;
- for (var i = 0, length = Event.observers.length; i < length; i++) {
- Event.stopObserving.apply(this, Event.observers[i]);
- Event.observers[i][0] = null;
- }
- Event.observers = false;
- },
-
- observe: function(element, name, observer, useCapture) {
- element = $(element);
- useCapture = useCapture || false;
-
- if (name == 'keypress' &&
- (Prototype.Browser.WebKit || element.attachEvent))
- name = 'keydown';
-
- Event._observeAndCache(element, name, observer, useCapture);
- },
-
- stopObserving: function(element, name, observer, useCapture) {
- element = $(element);
- useCapture = useCapture || false;
-
- if (name == 'keypress' &&
- (Prototype.Browser.WebKit || element.attachEvent))
- name = 'keydown';
-
- if (element.removeEventListener) {
- element.removeEventListener(name, observer, useCapture);
- } else if (element.detachEvent) {
- try {
- element.detachEvent('on' + name, observer);
- } catch (e) {}
- }
- }
-});
-
-/* prevent memory leaks in IE */
-if (Prototype.Browser.IE)
- Event.observe(window, 'unload', Event.unloadCache, false);
-var Position = {
- // set to true if needed, warning: firefox performance problems
- // NOT neeeded for page scrolling, only if draggable contained in
- // scrollable elements
- includeScrollOffsets: false,
-
- // must be called before calling withinIncludingScrolloffset, every time the
- // page is scrolled
- prepare: function() {
- this.deltaX = window.pageXOffset
- || document.documentElement.scrollLeft
- || document.body.scrollLeft
- || 0;
- this.deltaY = window.pageYOffset
- || document.documentElement.scrollTop
- || document.body.scrollTop
- || 0;
- },
-
- realOffset: function(element) {
- var valueT = 0, valueL = 0;
- do {
- valueT += element.scrollTop || 0;
- valueL += element.scrollLeft || 0;
- element = element.parentNode;
- } while (element);
- return [valueL, valueT];
- },
-
- cumulativeOffset: function(element) {
- var valueT = 0, valueL = 0;
- do {
- valueT += element.offsetTop || 0;
- valueL += element.offsetLeft || 0;
- element = element.offsetParent;
- } while (element);
- return [valueL, valueT];
- },
-
- positionedOffset: function(element) {
- var valueT = 0, valueL = 0;
- do {
- valueT += element.offsetTop || 0;
- valueL += element.offsetLeft || 0;
- element = element.offsetParent;
- if (element) {
- if(element.tagName=='BODY') break;
- var p = Element.getStyle(element, 'position');
- if (p == 'relative' || p == 'absolute') break;
- }
- } while (element);
- return [valueL, valueT];
- },
-
- offsetParent: function(element) {
- if (element.offsetParent) return element.offsetParent;
- if (element == document.body) return element;
-
- while ((element = element.parentNode) && element != document.body)
- if (Element.getStyle(element, 'position') != 'static')
- return element;
-
- return document.body;
- },
-
- // caches x/y coordinate pair to use with overlap
- within: function(element, x, y) {
- if (this.includeScrollOffsets)
- return this.withinIncludingScrolloffsets(element, x, y);
- this.xcomp = x;
- this.ycomp = y;
- this.offset = this.cumulativeOffset(element);
-
- return (y >= this.offset[1] &&
- y < this.offset[1] + element.offsetHeight &&
- x >= this.offset[0] &&
- x < this.offset[0] + element.offsetWidth);
- },
-
- withinIncludingScrolloffsets: function(element, x, y) {
- var offsetcache = this.realOffset(element);
-
- this.xcomp = x + offsetcache[0] - this.deltaX;
- this.ycomp = y + offsetcache[1] - this.deltaY;
- this.offset = this.cumulativeOffset(element);
-
- return (this.ycomp >= this.offset[1] &&
- this.ycomp < this.offset[1] + element.offsetHeight &&
- this.xcomp >= this.offset[0] &&
- this.xcomp < this.offset[0] + element.offsetWidth);
- },
-
- // within must be called directly before
- overlap: function(mode, element) {
- if (!mode) return 0;
- if (mode == 'vertical')
- return ((this.offset[1] + element.offsetHeight) - this.ycomp) /
- element.offsetHeight;
- if (mode == 'horizontal')
- return ((this.offset[0] + element.offsetWidth) - this.xcomp) /
- element.offsetWidth;
- },
-
- page: function(forElement) {
- var valueT = 0, valueL = 0;
-
- var element = forElement;
- do {
- valueT += element.offsetTop || 0;
- valueL += element.offsetLeft || 0;
-
- // Safari fix
- if (element.offsetParent == document.body)
- if (Element.getStyle(element,'position')=='absolute') break;
-
- } while (element = element.offsetParent);
-
- element = forElement;
- do {
- if (!window.opera || element.tagName=='BODY') {
- valueT -= element.scrollTop || 0;
- valueL -= element.scrollLeft || 0;
- }
- } while (element = element.parentNode);
-
- return [valueL, valueT];
- },
-
- clone: function(source, target) {
- var options = Object.extend({
- setLeft: true,
- setTop: true,
- setWidth: true,
- setHeight: true,
- offsetTop: 0,
- offsetLeft: 0
- }, arguments[2] || {})
-
- // find page position of source
- source = $(source);
- var p = Position.page(source);
-
- // find coordinate system to use
- target = $(target);
- var delta = [0, 0];
- var parent = null;
- // delta [0,0] will do fine with position: fixed elements,
- // position:absolute needs offsetParent deltas
- if (Element.getStyle(target,'position') == 'absolute') {
- parent = Position.offsetParent(target);
- delta = Position.page(parent);
- }
-
- // correct by body offsets (fixes Safari)
- if (parent == document.body) {
- delta[0] -= document.body.offsetLeft;
- delta[1] -= document.body.offsetTop;
- }
-
- // set position
- if(options.setLeft) target.style.left = (p[0] - delta[0] + options.offsetLeft) + 'px';
- if(options.setTop) target.style.top = (p[1] - delta[1] + options.offsetTop) + 'px';
- if(options.setWidth) target.style.width = source.offsetWidth + 'px';
- if(options.setHeight) target.style.height = source.offsetHeight + 'px';
- },
-
- absolutize: function(element) {
- element = $(element);
- if (element.style.position == 'absolute') return;
- Position.prepare();
-
- var offsets = Position.positionedOffset(element);
- var top = offsets[1];
- var left = offsets[0];
- var width = element.clientWidth;
- var height = element.clientHeight;
-
- element._originalLeft = left - parseFloat(element.style.left || 0);
- element._originalTop = top - parseFloat(element.style.top || 0);
- element._originalWidth = element.style.width;
- element._originalHeight = element.style.height;
-
- element.style.position = 'absolute';
- element.style.top = top + 'px';
- element.style.left = left + 'px';
- element.style.width = width + 'px';
- element.style.height = height + 'px';
- },
-
- relativize: function(element) {
- element = $(element);
- if (element.style.position == 'relative') return;
- Position.prepare();
-
- element.style.position = 'relative';
- var top = parseFloat(element.style.top || 0) - (element._originalTop || 0);
- var left = parseFloat(element.style.left || 0) - (element._originalLeft || 0);
-
- element.style.top = top + 'px';
- element.style.left = left + 'px';
- element.style.height = element._originalHeight;
- element.style.width = element._originalWidth;
- }
-}
-
-// Safari returns margins on body which is incorrect if the child is absolutely
-// positioned. For performance reasons, redefine Position.cumulativeOffset for
-// KHTML/WebKit only.
-if (Prototype.Browser.WebKit) {
- Position.cumulativeOffset = function(element) {
- var valueT = 0, valueL = 0;
- do {
- valueT += element.offsetTop || 0;
- valueL += element.offsetLeft || 0;
- if (element.offsetParent == document.body)
- if (Element.getStyle(element, 'position') == 'absolute') break;
-
- element = element.offsetParent;
- } while (element);
-
- return [valueL, valueT];
- }
-}
-
-Element.addMethods(); \ No newline at end of file
diff --git a/html/.svn/text-base/xo-color.xml.svn-base b/html/.svn/text-base/xo-color.xml.svn-base
deleted file mode 100644
index 3fb9cee..0000000
--- a/html/.svn/text-base/xo-color.xml.svn-base
+++ /dev/null
@@ -1,964 +0,0 @@
-<html xmlns="http://www.w3.org/1999/xhtml">
-<head>
- <title>change the XO colors and shape</title>
-
-<!--
-Author: Walter Bender (walter@laptop.org)
-(CC-PD) Public Domain (do what you want to do...)
-
-<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" [
- <!ENTITY ns_svg "http://www.w3.org/2000/svg">
- <!ENTITY ns_xlink "http://www.w3.org/1999/xlink">
-]>
--->
-
-
-
-
-// SVG version of OLPC XO man color changer and shape shifter
-// Created by: Walter Bender (walter@laptop.org) on 27 January 2007
-// Last modified by: Walter Bender (walter@laptop.org) on 28 June 2007
-// Color tool designed in memory of: Nat Jacobson
-// ajax hooks: Erik Blankinship (erikb@mediamods.com) on 15 August 2007
-
-<script type="text/javascript">
-<![CDATA[
- var fillcolors = [
- // red, orange, yellow, green, blue, purple
- "rgb(255,43,52)", "rgb(255,143,0)", "rgb(248,232,0)", "rgb(0,234,17)", "rgb(0,160,255)", "rgb(172,50,255)"
- ];
-
-
- var strokecolors = [
- // M A+ C- C C+ A-
- // dark fill
- // red
- "rgb(178,0,8)", "rgb(154,82,0)", "rgb(128,117,0)", "rgb(0,128,9)", "rgb(0,88,140)", "rgb(94,0,140)",
- // orange
- "rgb(154,82,0)", "rgb(128,117,0)", "rgb(0,128,9)", "rgb(0,88,140)", "rgb(94,0,140)", "rgb(178,0,8)",
- // yellow
- "rgb(128,117,0)", "rgb(0,128,9)", "rgb(0,88,140)", "rgb(94,0,140)", "rgb(178,0,8)", "rgb(154,82,0)",
- // green
- "rgb(0,128,9)", "rgb(0,88,140)", "rgb(94,0,140)", "rgb(178,0,8)", "rgb(154,82,0)", "rgb(128,117,0)",
- // blue
- "rgb(0,88,140)", "rgb(94,0,140)", "rgb(178,0,8)", "rgb(154,82,0)", "rgb(128,117,0)", "rgb(0,128,9)",
- // purple
- "rgb(94,0,140)", "rgb(178,0,8)", "rgb(154,82,0)", "rgb(128,117,0)", "rgb(0,128,9)", "rgb(0,88,140)",
-
- // medium fill
- // red
- "rgb(230,0,10)", "rgb(255,143,0)", "rgb(190,158,0)", "rgb(0,178,13)", "rgb(0,95,228)", "rgb(127,0,191)",
- // orange
- "rgb(201,126,0)", "rgb(190,158,0)", "rgb(0,178,13)", "rgb(0,95,228)", "rgb(167,0,255)", "rgb(255,43,52)",
- // yellow
- "rgb(190,158,0)", "rgb(0,234,17)", "rgb(0,160,255)", "rgb(172,50,255)", "rgb(255,43,52)", "rgb(255,143,0)",
- // green
- "rgb(0,178,13)", "rgb(0,95,228)", "rgb(127,0,191)", "rgb(255,43,52)", "rgb(255,143,0)", "rgb(190,158,0)",
- // blue
- "rgb(0,95,228)", "rgb(153,0,230)", "rgb(255,43,52)", "rgb(255,143,0)", "rgb(190,158,0)", "rgb(0,178,13)",
- // purple
- "rgb(127,0,191)", "rgb(255,43,52)", "rgb(255,143,0)", "rgb(190,158,0)", "rgb(0,178,13)", "rgb(0,95,228)",
-
- // light fill
- // red
- "rgb(255,173,206)", "rgb(255,193,105)", "rgb(248,232,0)", "rgb(139,255,122)", "rgb(188,205,255)", "rgb(209,163,255)",
- // orange
- "rgb(255,193,105)", "rgb(248,232,0)", "rgb(139,255,122)", "rgb(188,205,255)", "rgb(209,163,255)", "rgb(255,173,206)",
- // yellow
- "rgb(255,250,0)", "rgb(139,255,122)", "rgb(188,206,255)", "rgb(209,163,255)", "rgb(255,173,206)", "rgb(255,193,105)",
- // green
- "rgb(139,255,122)", "rgb(188,205,255)", "rgb(209,163,255)", "rgb(255,173,206)", "rgb(255,193,105)", "rgb(248,232,0)",
- // blue
- "rgb(188,205,255)", "rgb(209,163,255)", "rgb(255,173,206)", "rgb(255,193,105)", "rgb(248,232,0)", "rgb(139,255,122)",
- // purple
- "rgb(209,163,255)", "rgb(255,173,206)", "rgb(255,193,105)", "rgb(248,232,0)", "rgb(139,255,122)", "rgb(188,205,255)"
- ];
-
-// stroke values
-var strokeLight = 2;
-var strokeMedium = 1;
-var strokeDark = 0;
-var strokeCurrent = strokeMedium;
-
-//
-var flip = 0;
-var square = 0;
-var xoff = 0;
-var yoff = 2;
-
-// color variables
-var strokeH = 0;
-var fillH = 0;
-
-// Sugar stuff
-// gridbox centers
-var grid = [37.5, 112.5, 187.5, 262.5, 337.5, 412.5, 485.5, 562.5, 637.5, 712.5, 785.5, 862.5, 937.5, 1012.5, 1087.5, 1162.5];
-var radius = 22.5;
-var strokeW = 9.5;
-
-var circlex1 = [0,1,2,3,4,5];
-var circley1 = [0,1,2,3,4,5];
-var circlex2 = [0,1,2,3,4,5];
-var circley2 = [0,1,2,3,4,5];
-var circlex3 = [0,1,2,3,4,5];
-var circley3 = [0,1,2,3,4,5];
-var circlex4 = [0,1,2,3,4,5];
-var circley4 = [0,1,2,3,4,5];
-var circlex5 = [0,1,2,3,4,5];
-var circley5 = [0,1,2,3,4,5];
-var circlex6 = [0,1,2,3,4,5];
-var circley6 = [0,1,2,3,4,5];
-
-// Stuff needed for moving the xo man end and knot points
-var xoL1X1=554.5;
-var xoL1Y1=448;
-var xoL1X2=645.5;
-var xoL1Y2=357;
-var xoL1K1X=580;
-var xoL1K1Y=420.5;
-var xoL1K2X=620;
-var xoL1K2Y=380.5;
-var xoL2X1=554.5;
-var xoL2Y1=357;
-var xoL2X2=645.5;
-var xoL2Y2=448;
-var xoL2K1X=580;
-var xoL2K1Y=380.5;
-var xoL2K2X=620;
-var xoL2K2Y=420.5;
-var xoCX=600;
-var xoCY=318.5;
-var xoL1X1Reset=554.5;
-var xoL1Y1Reset=448;
-var xoL1X2Reset=645.5;
-var xoL1Y2Reset=357;
-var xoL1K1XReset=580;
-var xoL1K1YReset=420.5;
-var xoL1K2XReset=620;
-var xoL1K2YReset=380.5;
-var xoL2X1Reset=554.5;
-var xoL2Y1Reset=357;
-var xoL2X2Reset=645.5;
-var xoL2Y2Reset=448;
-var xoL2K1XReset=580;
-var xoL2K1YReset=380.5;
-var xoL2K2XReset=620;
-var xoL2K2YReset=420.5;
-var xoCXReset=600;
-var xoCYReset=318.5;
-var xoCenterX = (xoL1X1+xoL1X2)/2;
-var xoCenterY = (xoL1Y1+xoL1Y2)/2;
-var moveOn=0;
-var moveID="";
-
-// calculate circle coordinates
-function sincos (evt) {
-var a;
-var i;
-var r1=75;
-var r2=245;
-var cx = [0,1,2,3,4,5];
-var cy = [0,1,2,3,4,5];
-
-
- for( i=0; i< 6; i++ )
- {
- a = 1.05;
- a *= i;
- cx[i] = 600-r2*Math.sin(a);
- cy[i] = 375-r2*Math.cos(a);
- }
-
- for( i=0; i< 6; i++ )
- {
- a = 1.05;
- a *= i;
- circlex1[i] = r1*Math.sin(a)+cx[0];
- circley1[i] = r1*Math.cos(a)+cy[0];
- circlex2[i] = r1*Math.sin(a)+cx[1];
- circley2[i] = r1*Math.cos(a)+cy[1];
- circlex3[i] = r1*Math.sin(a)+cx[2];
- circley3[i] = r1*Math.cos(a)+cy[2];
- circlex4[i] = r1*Math.sin(a)+cx[3];
- circley4[i] = r1*Math.cos(a)+cy[3];
- circlex5[i] = r1*Math.sin(a)+cx[4];
- circley5[i] = r1*Math.cos(a)+cy[4];
- circlex6[i] = r1*Math.sin(a)+cx[5];
- circley6[i] = r1*Math.cos(a)+cy[5];
- }
-}
-
-function positionButton(evt,id,x,y) {
- e = evt.target.ownerDocument.getElementById(id);
- e.setAttribute("cx",grid[x]);
- e.setAttribute("cy",grid[y]);
-}
-
-function positionButtonOffset(evt,id,x,y) {
- if( y < 0 ) { y+=6; }
- e = evt.target.ownerDocument.getElementById(id);
- e.setAttribute("cx",grid[x+xoff]);
- e.setAttribute("cy",grid[y+yoff]);
-}
-
-function positionCircle(evt,id,r,a) {
- if( a > -1 && a < 6 )
- {
- e = evt.target.ownerDocument.getElementById(id);
- switch (r)
- {
- case 0:
- e.setAttribute("cx",circlex1[a]);
- e.setAttribute("cy",circley1[a]);
- break;
- case 1:
- e.setAttribute("cx",circlex2[a]);
- e.setAttribute("cy",circley2[a]);
- break;
- case 2:
- e.setAttribute("cx",circlex3[a]);
- e.setAttribute("cy",circley3[a]);
- break;
- case 3:
- e.setAttribute("cx",circlex4[a]);
- e.setAttribute("cy",circley4[a]);
- break;
- case 4:
- e.setAttribute("cx",circlex5[a]);
- e.setAttribute("cy",circley5[a]);
- break;
- case 5:
- e.setAttribute("cx",circlex6[a]);
- e.setAttribute("cy",circley6[a]);
- break;
- default :
- }
- }
-}
-
-function buttonInit(evt) {
- if( square == 1 )
- {
- buttonInitSquare(evt);
- } else {
- buttonInitHex(evt);
- }
-
-}
-
-// scale and position buttons in circles
-function buttonInitHex(evt) {
-
- positionCircle(evt,"X",0,0);
-
- positionCircle(evt,"R",0,0);
- positionCircle(evt,"YR",1,1);
- positionCircle(evt,"Y",2,2);
- positionCircle(evt,"G",3,3);
- positionCircle(evt,"B",4,4);
- positionCircle(evt,"P",5,5);
-
- positionCircle(evt,"RAm",0,1);
- positionCircle(evt,"YRAm",1,2);
- positionCircle(evt,"YAm",2,3);
- positionCircle(evt,"GAm",3,4);
- positionCircle(evt,"BAm",4,5);
- positionCircle(evt,"PAm",5,0);
-
- positionCircle(evt,"RCp",0,2);
- positionCircle(evt,"YRCp",1,3);
- positionCircle(evt,"YCp",2,4);
- positionCircle(evt,"GCp",3,5);
- positionCircle(evt,"BCp",4,0);
- positionCircle(evt,"PCp",5,1);
-
- positionCircle(evt,"RC",0,3);
- positionCircle(evt,"YRC",1,4);
- positionCircle(evt,"YC",2,5);
- positionCircle(evt,"GC",3,0);
- positionCircle(evt,"BC",4,1);
- positionCircle(evt,"PC",5,2);
-
- positionCircle(evt,"RCm",0,4);
- positionCircle(evt,"YRCm",1,5);
- positionCircle(evt,"YCm",2,0);
- positionCircle(evt,"GCm",3,1);
- positionCircle(evt,"BCm",4,2);
- positionCircle(evt,"PCm",5,3);
-
- positionCircle(evt,"RAp",0,5);
- positionCircle(evt,"YRAp",1,0);
- positionCircle(evt,"YAp",2,1);
- positionCircle(evt,"GAp",3,2);
- positionCircle(evt,"BAp",4,3);
- positionCircle(evt,"PAp",5,4);
-}
-
-// scale and position buttons on grid (col,row)
-function buttonInitSquare(evt) {
-
- positionButtonOffset(evt,"X",0,0);
-
- positionButtonOffset(evt, "R",0,0);
- positionButtonOffset(evt, "YR",5,5);
- positionButtonOffset(evt, "Y",4,4);
- positionButtonOffset(evt, "G",3,3);
- positionButtonOffset(evt, "B",2,2);
- positionButtonOffset(evt, "P",1,1);
-
- positionButtonOffset(evt, "RAm",0,1);
- positionButtonOffset(evt,"YRAm",5,0);
- positionButtonOffset(evt, "YAm",4,5);
- positionButtonOffset(evt, "GAm",3,4);
- positionButtonOffset(evt, "BAm",2,3);
- positionButtonOffset(evt, "PAm",1,2);
-
- positionButtonOffset(evt, "RCp",0,2);
- positionButtonOffset(evt,"YRCp",5,1);
- positionButtonOffset(evt, "YCp",4,0);
- positionButtonOffset(evt, "GCp",3,5);
- positionButtonOffset(evt, "BCp",2,4);
- positionButtonOffset(evt, "PCp",1,3);
-
- positionButtonOffset(evt, "RC",0,3);
- positionButtonOffset(evt, "YRC",5,2);
- positionButtonOffset(evt, "YC",4,1);
- positionButtonOffset(evt, "GC",3,0);
- positionButtonOffset(evt, "BC",2,5);
- positionButtonOffset(evt, "PC",1,4);
-
- positionButtonOffset(evt, "RCm",0,4);
- positionButtonOffset(evt,"YRCm",5,3);
- positionButtonOffset(evt, "YCm",4,2);
- positionButtonOffset(evt, "GCm",3,1);
- positionButtonOffset(evt, "BCm",2,0);
- positionButtonOffset(evt, "PCm",1,5);
-
- positionButtonOffset(evt, "RAp",0,5);
- positionButtonOffset(evt,"YRAp",5,4);
- positionButtonOffset(evt, "YAp",4,3);
- positionButtonOffset(evt, "GAp",3,2);
- positionButtonOffset(evt, "BAp",2,1);
- positionButtonOffset(evt, "PAp",1,0);
-}
-
-// recompute button color
-// fill hue is 0,1,2,3,4,5 for r,o,y,g,b,p
-// stroke hue is 0,1,2,3,4,5 for m,a+,c-,c,c+,a- plus an offset of 6*fillhue and 36*valuelevel
-function colorButton(evt,id,fh,sh,sv) {
-var e;
- e = evt.target.ownerDocument.getElementById(id);
- if( flip == 0 )
- {
- e.setAttribute("stroke",strokecolors[fh*6+sv*36+sh]);
- e.setAttribute("fill",fillcolors[fh]);
- } else {
- e.setAttribute("fill",strokecolors[fh*6+sv*36+sh]);
- e.setAttribute("stroke",fillcolors[fh]);
- }
-}
-
-// update XO man and all buttons based on current hue and value
-function colorUpdate(evt) {
-var e;
-var tmp;
-
- // update XO Man
- colorButton(evt,"Circle",fillH,strokeH,strokeCurrent);
- colorButton(evt,"iconCircle",fillH,strokeH,strokeCurrent);
- if( flip == 0 )
- {
- e = evt.target.ownerDocument.getElementById("Line1");
- e.setAttribute("stroke",strokecolors[fillH*6+strokeCurrent*36+strokeH]);
- e = evt.target.ownerDocument.getElementById("Line2");
- e.setAttribute("stroke",strokecolors[fillH*6+strokeCurrent*36+strokeH]);
- e = evt.target.ownerDocument.getElementById("Fill1");
- e.setAttribute("stroke",fillcolors[fillH]);
- e = evt.target.ownerDocument.getElementById("Fill2");
- e.setAttribute("stroke",fillcolors[fillH]);
- e = evt.target.ownerDocument.getElementById("iconLine1");
- e.setAttribute("stroke",strokecolors[fillH*6+strokeCurrent*36+strokeH]);
- e = evt.target.ownerDocument.getElementById("iconLine2");
- e.setAttribute("stroke",strokecolors[fillH*6+strokeCurrent*36+strokeH]);
- e = evt.target.ownerDocument.getElementById("iconFill1");
- e.setAttribute("stroke",fillcolors[fillH]);
- e = evt.target.ownerDocument.getElementById("iconFill2");
- e.setAttribute("stroke",fillcolors[fillH]);
- } else {
- e = evt.target.ownerDocument.getElementById("Line1");
- e.setAttribute("stroke",fillcolors[fillH]);
- e = evt.target.ownerDocument.getElementById("Line2");
- e.setAttribute("stroke",fillcolors[fillH]);
- e = evt.target.ownerDocument.getElementById("Fill1");
- e.setAttribute("stroke",strokecolors[fillH*6+strokeCurrent*36+strokeH]);
- e = evt.target.ownerDocument.getElementById("Fill2");
- e.setAttribute("stroke",strokecolors[fillH*6+strokeCurrent*36+strokeH]);
- e = evt.target.ownerDocument.getElementById("iconLine1");
- e.setAttribute("stroke",fillcolors[fillH]);
- e = evt.target.ownerDocument.getElementById("iconLine2");
- e.setAttribute("stroke",fillcolors[fillH]);
- e = evt.target.ownerDocument.getElementById("iconFill1");
- e.setAttribute("stroke",strokecolors[fillH*6+strokeCurrent*36+strokeH]);
- e = evt.target.ownerDocument.getElementById("iconFill2");
- e.setAttribute("stroke",strokecolors[fillH*6+strokeCurrent*36+strokeH]);
- }
-
- tmp = flip;
- flip = 0;
- colorButton(evt,"vd",fillH,strokeH,strokeDark);
- colorButton(evt,"vm",fillH,strokeH,strokeMedium);
- colorButton(evt,"vl",fillH,strokeH,strokeLight);
- flip = 1;
- colorButton(evt,"vdf",fillH,strokeH,strokeDark);
- colorButton(evt,"vmf",fillH,strokeH,strokeMedium);
- flip = tmp;
-
- colorButton(evt,"R",0,0,strokeCurrent);
- colorButton(evt,"YR",1,0,strokeCurrent);
- colorButton(evt,"Y",2,0,strokeCurrent);
- colorButton(evt,"G",3,0,strokeCurrent);
- colorButton(evt,"B",4,0,strokeCurrent);
- colorButton(evt,"P",5,0,strokeCurrent);
- colorButton(evt,"RAp",0,1,strokeCurrent);
- colorButton(evt,"YRAp",1,1,strokeCurrent);
- colorButton(evt,"YAp",2,1,strokeCurrent);
- colorButton(evt,"GAp",3,1,strokeCurrent);
- colorButton(evt,"BAp",4,1,strokeCurrent);
- colorButton(evt,"PAp",5,1,strokeCurrent);
- colorButton(evt,"RCm",0,2,strokeCurrent);
- colorButton(evt,"YRCm",1,2,strokeCurrent);
- colorButton(evt,"YCm",2,2,strokeCurrent);
- colorButton(evt,"GCm",3,2,strokeCurrent);
- colorButton(evt,"BCm",4,2,strokeCurrent);
- colorButton(evt,"PCm",5,2,strokeCurrent);
- colorButton(evt,"RC",0,3,strokeCurrent);
- colorButton(evt,"YRC",1,3,strokeCurrent);
- colorButton(evt,"YC",2,3,strokeCurrent);
- colorButton(evt,"GC",3,3,strokeCurrent);
- colorButton(evt,"BC",4,3,strokeCurrent);
- colorButton(evt,"PC",5,3,strokeCurrent);
- colorButton(evt,"RCp",0,4,strokeCurrent);
- colorButton(evt,"YRCp",1,4,strokeCurrent);
- colorButton(evt,"YCp",2,4,strokeCurrent);
- colorButton(evt,"GCp",3,4,strokeCurrent);
- colorButton(evt,"BCp",4,4,strokeCurrent);
- colorButton(evt,"PCp",5,4,strokeCurrent);
- colorButton(evt,"RAm",0,5,strokeCurrent);
- colorButton(evt,"YRAm",1,5,strokeCurrent);
- colorButton(evt,"YAm",2,5,strokeCurrent);
- colorButton(evt,"GAm",3,5,strokeCurrent);
- colorButton(evt,"BAm",4,5,strokeCurrent);
- colorButton(evt,"PAm",5,5,strokeCurrent);
-
- saveXo()
-}
-
-function saveXo( )
-{
- var upXoDude = document.getElementById('upXo');
- var xos = "";
- for (var i=0; i<upXoDude.childNodes.length; i++)
- { xoi = upXoDude.childNodes[i];
- if (xoi.nodeType == 1)
- { xos = xos + "<" + xoi.nodeName + " ";
- for (var j=0; j<xoi.attributes.length; j++)
- { xoj = xoi.attributes[j];
- xos = xos + xoj.nodeName + "=\"" + xoj.nodeValue + "\" ";
- }
- xos = xos+ "/>";
- }
- }
-
- //alert( xos );
- new Ajax.Request( 'saveXo', {method:'get', parameters:'upXo='+xos} );
-}
-
-// individual button functions
-function updater(evt,fh,dh,a) {
- fillHUndo = fillH;
- fillH = fh;
- strokeHUndo = strokeH;
- strokeH = dh;
- if( square == 1 )
- {
- // a complete kludge because the order of the grid
- // does not reflect the order of the delta hues
- switch(fh)
- {
- case 0:
- if( dh > 0 ) { dh = 6-dh; }
- positionButtonOffset(evt,"X",0,dh);
- break;
- case 1:
- positionButtonOffset(evt,"X",5,5-dh);
- break;
- case 2:
- positionButtonOffset(evt,"X",4,4-dh);
- break;
- case 3:
- positionButtonOffset(evt,"X",3,3-dh);
- break;
- case 4:
- positionButtonOffset(evt,"X",2,2-dh);
- break;
- case 5:
- positionButtonOffset(evt,"X",1,1-dh);
- break;
- }
- } else {
- // a kludge of a different sort fo the similar reasons as above
- positionCircle(evt,"X",fh,a);
- }
- colorUpdate(evt);
-}
-
-function valueDark(evt) {
- strokeCurrent = strokeDark;
- flip = 0;
- e = evt.target.ownerDocument.getElementById("bgd");
- e.setAttribute("visibility","visible");
- e = evt.target.ownerDocument.getElementById("bgdf");
- e.setAttribute("visibility","hidden");
- e = evt.target.ownerDocument.getElementById("bgm");
- e.setAttribute("visibility","hidden");
- e = evt.target.ownerDocument.getElementById("bgmf");
- e.setAttribute("visibility","hidden");
- e = evt.target.ownerDocument.getElementById("bgl");
- e.setAttribute("visibility","hidden");
- colorUpdate(evt);
-}
-
-function valueDarkFlip(evt) {
- strokeCurrent = strokeDark;
- flip = 1;
- e = evt.target.ownerDocument.getElementById("bgd");
- e.setAttribute("visibility","hidden");
- e = evt.target.ownerDocument.getElementById("bgdf");
- e.setAttribute("visibility","visible");
- e = evt.target.ownerDocument.getElementById("bgm");
- e.setAttribute("visibility","hidden");
- e = evt.target.ownerDocument.getElementById("bgmf");
- e.setAttribute("visibility","hidden");
- e = evt.target.ownerDocument.getElementById("bgl");
- e.setAttribute("visibility","hidden");
- colorUpdate(evt);
-}
-
-function valueMedium(evt) {
- strokeCurrent = strokeMedium;
- flip = 0;
- e = evt.target.ownerDocument.getElementById("bgd");
- e.setAttribute("visibility","hidden");
- e = evt.target.ownerDocument.getElementById("bgdf");
- e.setAttribute("visibility","hidden");
- e = evt.target.ownerDocument.getElementById("bgm");
- e.setAttribute("visibility","visible");
- e = evt.target.ownerDocument.getElementById("bgmf");
- e.setAttribute("visibility","hidden");
- e = evt.target.ownerDocument.getElementById("bgl");
- e.setAttribute("visibility","hidden");
- colorUpdate(evt);
-}
-
-function valueMediumFlip(evt) {
- strokeCurrent = strokeMedium;
- flip = 1;
- e = evt.target.ownerDocument.getElementById("bgd");
- e.setAttribute("visibility","hidden");
- e = evt.target.ownerDocument.getElementById("bgdf");
- e.setAttribute("visibility","hidden");
- e = evt.target.ownerDocument.getElementById("bgm");
- e.setAttribute("visibility","hidden");
- e = evt.target.ownerDocument.getElementById("bgmf");
- e.setAttribute("visibility","visible");
- e = evt.target.ownerDocument.getElementById("bgl");
- e.setAttribute("visibility","hidden");
- colorUpdate(evt);
-}
-
-function valueLight(evt) {
- strokeCurrent = strokeLight;
- flip = 0;
- e = evt.target.ownerDocument.getElementById("bgd");
- e.setAttribute("visibility","hidden");
- e = evt.target.ownerDocument.getElementById("bgdf");
- e.setAttribute("visibility","hidden");
- e = evt.target.ownerDocument.getElementById("bgm");
- e.setAttribute("visibility","hidden");
- e = evt.target.ownerDocument.getElementById("bgmf");
- e.setAttribute("visibility","hidden");
- e = evt.target.ownerDocument.getElementById("bgl");
- e.setAttribute("visibility","visible");
- colorUpdate(evt);
-}
-
-function hexGrid(evt) {
- square = 0;
- e = evt.target.ownerDocument.getElementById("bgsq");
- e.setAttribute("visibility","hidden");
- e = evt.target.ownerDocument.getElementById("bghex");
- e.setAttribute("visibility","visible");
- buttonInit(evt);
-}
-
-function sqGrid(evt) {
- square = 1;
- e = evt.target.ownerDocument.getElementById("bgsq");
- e.setAttribute("visibility","visible");
- e = evt.target.ownerDocument.getElementById("bghex");
- e.setAttribute("visibility","hidden");
- buttonInit(evt);
-}
-
-function background(evt,a) {
- e = evt.target.ownerDocument.getElementById("backgroundW");
- if( a == 0 )
- {
- e.setAttribute("visibility","visible");
- } else {
- e.setAttribute("visibility","hidden");
- }
- e = evt.target.ownerDocument.getElementById("backgroundW");
- if( a == 0 )
- {
- e.setAttribute("visibility","visible");
- } else {
- e.setAttribute("visibility","hidden");
- }
- e = evt.target.ownerDocument.getElementById("backgroundL");
- if( a == 1 )
- {
- e.setAttribute("visibility","visible");
- } else {
- e.setAttribute("visibility","hidden");
- }
- e = evt.target.ownerDocument.getElementById("backgroundM");
- if( a == 2 )
- {
- e.setAttribute("visibility","visible");
- } else {
- e.setAttribute("visibility","hidden");
- }
- e = evt.target.ownerDocument.getElementById("backgroundK");
- if( a == 3 )
- {
- e.setAttribute("visibility","visible");
- } else {
- e.setAttribute("visibility","hidden");
- }
-}
-
-
-// the rest of these functions are for moving knot points
-function showpoints(evt)
-{
-var e;
-
- e = evt.target.ownerDocument.getElementById("L1Knot1");
- e.setAttribute("visibility", "visible");
- e.setAttribute("cx",xoL1K1X);
- e.setAttribute("cy",xoL1K1Y);
- e = evt.target.ownerDocument.getElementById("L1Knot2");
- e.setAttribute("visibility", "visible");
- e.setAttribute("cx",xoL1K2X);
- e.setAttribute("cy",xoL1K2Y);
- e = evt.target.ownerDocument.getElementById("L2Knot1");
- e.setAttribute("visibility", "visible");
- e.setAttribute("cx",xoL2K1X);
- e.setAttribute("cy",xoL2K1Y);
- e = evt.target.ownerDocument.getElementById("L2Knot2");
- e.setAttribute("visibility", "visible");
- e.setAttribute("cx",xoL2K2X);
- e.setAttribute("cy",xoL2K2Y);
- e = evt.target.ownerDocument.getElementById("L1End1");
- e.setAttribute("visibility", "visible");
- e.setAttribute("cx",xoL1X1);
- e.setAttribute("cy",xoL1Y1);
- e = evt.target.ownerDocument.getElementById("L2End1");
- e.setAttribute("visibility", "visible");
- e.setAttribute("cx",xoL2X1);
- e.setAttribute("cy",xoL2Y1);
- e = evt.target.ownerDocument.getElementById("L1End2");
- e.setAttribute("visibility", "visible");
- e.setAttribute("cx",xoL1X2);
- e.setAttribute("cy",xoL1Y2);
- e = evt.target.ownerDocument.getElementById("L2End2");
- e.setAttribute("visibility", "visible");
- e.setAttribute("cx",xoL2X2);
- e.setAttribute("cy",xoL2Y2);
- e = evt.target.ownerDocument.getElementById("Center");
- e.setAttribute("visibility", "visible");
- e.setAttribute("cx",xoCX);
- e.setAttribute("cy",xoCY);
-}
-
-function hidepoints(evt)
-{
- e = evt.target.ownerDocument.getElementById("L1Knot1");
- e.setAttribute("visibility", "hidden");
- e = evt.target.ownerDocument.getElementById("L1Knot2");
- e.setAttribute("visibility", "hidden");
- e = evt.target.ownerDocument.getElementById("L2Knot1");
- e.setAttribute("visibility", "hidden");
- e = evt.target.ownerDocument.getElementById("L2Knot2");
- e.setAttribute("visibility", "hidden");
- e = evt.target.ownerDocument.getElementById("L1End1");
- e.setAttribute("visibility", "hidden");
- e = evt.target.ownerDocument.getElementById("L1End2");
- e.setAttribute("visibility", "hidden");
- e = evt.target.ownerDocument.getElementById("L2End1");
- e.setAttribute("visibility", "hidden");
- e = evt.target.ownerDocument.getElementById("L2End2");
- e.setAttribute("visibility", "hidden");
- e = evt.target.ownerDocument.getElementById("Center");
- e.setAttribute("visibility", "hidden");
-}
-
-// moves are constrained by level and restricted to XO box
-function move(evt)
-{
-var x,y;
-
- if( moveOn == 1 )
- {
- //bug, see: http://dev.laptop.org/ticket/1657
- x = evt.clientX;
- x = x * 1.43;
- y = evt.clientY;
- y = y * 1.43;
-
- if( x < (xoCenterX-80) ) { x = xoCenterX-80; }
- if( x > (xoCenterX+80) ) { x = xoCenterX+80; }
- if( y < (xoCenterY-100) ) { y = xoCenterY-100; }
- if( y > (xoCenterY+80) ) { y = xoCenterY+80; }
- e = evt.target.ownerDocument.getElementById(moveID);
- e.setAttribute("cx",x);
- e.setAttribute("cy",y);
- switch (moveID)
- {
- case "Center":
- xoCX = x;
- xoCY = y;
- break;
- case "L1End1":
- xoL1X1 = x;
- xoL1Y1 = y;
- break;
- case "L1End2":
- xoL1X2 = x;
- xoL1Y2 = y;
- break;
- case "L2End1":
- xoL2X1 = x;
- xoL2Y1 = y;
- break;
- case "L2End2":
- xoL2X2 = x;
- xoL2Y2 = y;
- break;
- case "L1Knot1":
- xoL1K1X = x;
- xoL1K1Y = y;
- break;
- case "L1Knot2":
- xoL1K2X = x;
- xoL1K2Y = y;
- break;
- case "L2Knot1":
- xoL2K1X = x;
- xoL2K1Y = y;
- break;
- case "L2Knot2":
- xoL2K2X = x;
- xoL2K2Y = y;
- break;
- default :
- }
- }
-}
-
-function setID (evt, id)
-{
- moveID = id;
-}
-
-function startmove(evt)
-{
- moveOn = 1;
-}
-
-function stopmove(evt)
-{
- moveOn = 0;
- moveID = "";
- e = evt.target.ownerDocument.getElementById("Circle");
- e.setAttribute("cx",xoCX);
- e.setAttribute("cy",xoCY);
- e = evt.target.ownerDocument.getElementById("Line1");
- e.setAttribute("d", "M"+xoL1X1+","+xoL1Y1+" C"+xoL1K1X+","+xoL1K1Y+" "+xoL1K2X+","+xoL1K2Y+" "+xoL1X2+","+xoL1Y2);
- e = evt.target.ownerDocument.getElementById("Fill1");
- e.setAttribute("d", "M"+xoL1X1+","+xoL1Y1+" C"+xoL1K1X+","+xoL1K1Y+" "+xoL1K2X+","+xoL1K2Y+" "+xoL1X2+","+xoL1Y2);
- e = evt.target.ownerDocument.getElementById("Line2");
- e.setAttribute("d", "M"+xoL2X1+","+xoL2Y1+" C"+xoL2K1X+","+xoL2K1Y+" "+xoL2K2X+","+xoL2K2Y+" "+xoL2X2+","+xoL2Y2);
- e = evt.target.ownerDocument.getElementById("Fill2");
- e.setAttribute("d", "M"+xoL2X1+","+xoL2Y1+" C"+xoL2K1X+","+xoL2K1Y+" "+xoL2K2X+","+xoL2K2Y+" "+xoL2X2+","+xoL2Y2);
-}
-
-function resetXO (evt)
-{
-xoL1X1=xoL1X1Reset;
-xoL1Y1=xoL1Y1Reset;
-xoL1X2=xoL1X2Reset;
-xoL1Y2=xoL1Y2Reset;
-xoL1K1X=xoL1K1XReset;
-xoL1K1Y=xoL1K1YReset;
-xoL1K2X=xoL1K2XReset;
-xoL1K2Y=xoL1K2YReset;
-xoL2X1=xoL2X1Reset;
-xoL2Y1=xoL2Y1Reset;
-xoL2X2=xoL2X2Reset;
-xoL2Y2=xoL2Y2Reset;
-xoL2K1X=xoL2K1XReset;
-xoL2K1Y=xoL2K1YReset;
-xoL2K2X=xoL2K2XReset;
-xoL2K2Y=xoL2K2YReset;
-xoCX=xoCXReset;
-xoCY=xoCYReset;
-
- e = evt.target.ownerDocument.getElementById("Circle");
- e.setAttribute("cx",xoCX);
- e.setAttribute("cy",xoCY);
- e = evt.target.ownerDocument.getElementById("Line1");
- e.setAttribute("d", "M"+xoL1X1+","+xoL1Y1+" C"+xoL1K1X+","+xoL1K1Y+" "+xoL1K2X+","+xoL1K2Y+" "+xoL1X2+","+xoL1Y2);
- e = evt.target.ownerDocument.getElementById("Fill1");
- e.setAttribute("d", "M"+xoL1X1+","+xoL1Y1+" C"+xoL1K1X+","+xoL1K1Y+" "+xoL1K2X+","+xoL1K2Y+" "+xoL1X2+","+xoL1Y2);
- e = evt.target.ownerDocument.getElementById("Line2");
- e.setAttribute("d", "M"+xoL2X1+","+xoL2Y1+" C"+xoL2K1X+","+xoL2K1Y+" "+xoL2K2X+","+xoL2K2Y+" "+xoL2X2+","+xoL2Y2);
- e = evt.target.ownerDocument.getElementById("Fill2");
- e.setAttribute("d", "M"+xoL2X1+","+xoL2Y1+" C"+xoL2K1X+","+xoL2K1Y+" "+xoL2K2X+","+xoL2K2Y+" "+xoL2X2+","+xoL2Y2);
-}
-
-]]>
-</script>
-<script src="prototype.js" type="text/javascript"></script>
-</head>
-
-<body>
-<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www,w3,org/1999/xlink" onload="colorUpdate(evt); sincos(evt); buttonInit(evt)">
-
-
-// SVG elements
-// begin backgrounds
- <rect id="backgroundM" width="1200" height="900" x="0" y="0" fill="rgb(76,77,79)" stroke="rgb(76,77,79)" stroke-width="1" visibility="hidden" />
- <rect id="backgroundL" width="1200" height="900" x="0" y="0" fill="rgb(231,231,233)" stroke="rgb(231,231,233)" stroke-width="1" visibility="hidden" />
- <rect id="backgroundW" width="1200" height="900" x="0" y="0" fill="rgb(255,255,255)" stroke="rgb(255,255,255)" stroke-width="1" visibility="hidden" />
- <rect id="backgroundK" width="1200" height="900" x="0" y="0" fill="rgb(0,0,0)" stroke="rgb(0,0,0)" stroke-width="1" visibility="visible" />
-// end background
-
-// start XO group
-<g onmouseover="showpoints(evt)" onmouseout="hidepoints(evt)" onmousedown="startmove(evt)" onmouseup="stopmove(evt)" onmousemove="move(evt)" onkeyup="textProcess(evt)">
-<g id="upXo"> // begin XO man
-<path id="Line1" d="M645.5,357 C600,400.5 600,400.5 554.5,448" stroke="rgb(216,75,24)" stroke-width="37" stroke-linecap="round" fill="none" visibility="visible" />
-<path id="Line2" d="M645.5,448 C600,400.5 600,400.5 554.5,357" stroke="rgb(216,75,24)" stroke-width="37" stroke-linecap="round" fill="none" visibility="visible" />
-<path id="Fill1" d="M645.5,357 C600,400.5 600,400.5 554.5,448" stroke="rgb(52,192,210)" stroke-width="19" stroke-linecap="round" fill="none" visibility="visible" />
-<path id="Fill2" d="M645.5,448 C600,400.5 600,400.5 554.5,357" stroke="rgb(52,192,210)" stroke-width="19" stroke-linecap="round" fill="none" visibility="visible" />
-<circle id="Circle" cx="600" cy="318.5" r="28.5" fill="rgb(52,192,210)" stroke="rgb(216,75,24)" stroke-width="9" visibility="visible" />
-</g> // end XO man
-<g>
-// knot points
-<circle id="L1Knot1" cx="112.5" cy="112.5" r="12" fill="rgb(255,255,0)" stroke="rgb(0,0,0)" stroke-width="3" visibility="hidden" onmousedown="setID(evt,'L1Knot1')" />
-<circle id="L1Knot2" cx="112.5" cy="112.5" r="12" fill="rgb(255,255,0)" stroke="rgb(0,0,0)" stroke-width="3" visibility="hidden" onmousedown="setID(evt,'L1Knot2')" />
-<circle id="L2Knot1" cx="112.5" cy="112.5" r="12" fill="rgb(255,0,255)" stroke="rgb(0,0,0)" stroke-width="3" visibility="hidden" onmousedown="setID(evt,'L2Knot1')" />
-<circle id="L2Knot2" cx="112.5" cy="112.5" r="12" fill="rgb(255,0,255)" stroke="rgb(0,0,0)" stroke-width="3" visibility="hidden" onmousedown="setID(evt,'L2Knot2')" />
-// end points
-<circle id="L1End1" cx="112.5" cy="112.5" r="12" fill="rgb(255,255,0)" stroke="rgb(0,0,0)" stroke-width="3" visibility="hidden" onmousedown="setID(evt,'L1End1')" />
-<circle id="L1End2" cx="112.5" cy="112.5" r="12" fill="rgb(255,255,0)" stroke="rgb(0,0,0)" stroke-width="3" visibility="hidden" onmousedown="setID(evt,'L1End2')" />
-<circle id="L2End1" cx="112.5" cy="112.5" r="12" fill="rgb(255,0,255)" stroke="rgb(0,0,0)" stroke-width="3" visibility="hidden" onmousedown="setID(evt,'L2End1')" />
-<circle id="L2End2" cx="112.5" cy="112.5" r="12" fill="rgb(255,0,255)" stroke="rgb(0,0,0)" stroke-width="3" visibility="hidden" onmousedown="setID(evt,'L2End2')" />
-// center point
-<circle id="Center" cx="112.5" cy="112.5" r="12" fill="rgb(0,255,255)" stroke="rgb(0,0,0)" stroke-width="3" visibility="hidden" onmousedown="setID(evt,'Center')" />
-// end knot points
-</g>
-</g>
-// end XO group
-
-// "cursor"
-<circle id="X" title="X" alt="X marks the spot" cx="0" cy="0" r="36" stroke="rgb(160,160,160)" fill="rgb(160,160,160)" stroke-width="9.5" visibility="visible" />
-
-// color buttons
-<circle id="R" title="red" alt="red fill" cx="0" cy="0" r="22.5" stroke="rgb(0,0,0)" fill="rgb(0,0,0)" stroke-width="9.5" onclick="updater(evt,0,0,0)" visibility="visible" />
-<circle id="YR" title="orange" alt="orange fill" cx="0" cy="0" r="22.5" stroke="rgb(0,0,0)" fill="rgb(0,0,0)" stroke-width="9.5" onclick="updater(evt,1,0,1)" visibility="visible" />
-<circle id="Y" title="yellow" alt="yellow fill" cx="0" cy="0" r="22.5" stroke="rgb(0,0,0)" fill="rgb(0,0,0)" stroke-width="9.5" onclick="updater(evt,2,0,2)" visibility="visible" />
-<circle id="G" title="green" alt="green fill" cx="0" cy="0" r="22.5" stroke="rgb(0,0,0)" fill="rgb(0,0,0)" stroke-width="9.5" onclick="updater(evt,3,0,3)" visibility="visible" />
-<circle id="B" title="blue" alt="blue fill" cx="0" cy="0" r="22.5" stroke="rgb(0,0,0)" fill="rgb(0,0,0)" stroke-width="9.5" onclick="updater(evt,4,0,4)" visibility="visible" />
-<circle id="P" title="purple" alt="purple fill" cx="0" cy="0" r="22.5" stroke="rgb(0,0,0)" fill="rgb(0,0,0)" stroke-width="9.5" onclick="updater(evt,5,0,5)" visibility="visible" />
-
-<circle id="RC" title="red" alt="red fill" cx="0" cy="0" r="22.5" stroke="rgb(0,0,0)" fill="rgb(0,0,0)" stroke-width="9.5" onclick="updater(evt,0,3,3)" visibility="visible" />
-<circle id="YRC" title="orange" alt="orange fill" cx="0" cy="0" r="22.5" stroke="rgb(0,0,0)" fill="rgb(0,0,0)" stroke-width="9.5" onclick="updater(evt,1,3,4)" visibility="visible" />
-<circle id="YC" title="yellow" alt="yellow fill" cx="0" cy="0" r="22.5" stroke="rgb(0,0,0)" fill="rgb(0,0,0)" stroke-width="9.5" onclick="updater(evt,2,3,5)" visibility="visible" />
-<circle id="GC" title="green" alt="green fill" cx="0" cy="0" r="22.5" stroke="rgb(0,0,0)" fill="rgb(0,0,0)" stroke-width="9.5" onclick="updater(evt,3,3,0)" visibility="visible" />
-<circle id="BC" title="blue" alt="blue fill" cx="0" cy="0" r="22.5" stroke="rgb(0,0,0)" fill="rgb(0,0,0)" stroke-width="9.5" onclick="updater(evt,4,3,1)" visibility="visible" />
-<circle id="PC" title="purple" alt="purple fill" cx="0" cy="0" r="22.5" stroke="rgb(0,0,0)" fill="rgb(0,0,0)" stroke-width="9.5" onclick="updater(evt,5,3,2)" visibility="visible" />
-
-<circle id="RCp" title="red" alt="red fill" cx="0" cy="0" r="22.5" stroke="rgb(0,0,0)" fill="rgb(0,0,0)" stroke-width="9.5" onclick="updater(evt,0,4,2)" visibility="visible" />
-<circle id="YRCp" title="orange" alt="orange fill" cx="0" cy="0" r="22.5" stroke="rgb(0,0,0)" fill="rgb(0,0,0)" stroke-width="9.5" onclick="updater(evt,1,4,3)" visibility="visible" />
-<circle id="YCp" title="yellow" alt="yellow fill" cx="0" cy="0" r="22.5" stroke="rgb(0,0,0)" fill="rgb(0,0,0)" stroke-width="9.5" onclick="updater(evt,2,4,4)" visibility="visible" />
-<circle id="GCp" title="green" alt="green fill" cx="0" cy="0" r="22.5" stroke="rgb(0,0,0)" fill="rgb(0,0,0)" stroke-width="9.5" onclick="updater(evt,3,4,5)" visibility="visible" />
-<circle id="BCp" title="blue" alt="blue fill" cx="0" cy="0" r="22.5" stroke="rgb(0,0,0)" fill="rgb(0,0,0)" stroke-width="9.5" onclick="updater(evt,4,4,0)" visibility="visible" />
-<circle id="PCp" title="purple" alt="purple fill" cx="0" cy="0" r="22.5" stroke="rgb(0,0,0)" fill="rgb(0,0,0)" stroke-width="9.5" onclick="updater(evt,5,4,1)" visibility="visible" />
-
-<circle id="RCm" title="red" alt="red fill" cx="0" cy="0" r="22.5" stroke="rgb(0,0,0)" fill="rgb(0,0,0)" stroke-width="9.5" onclick="updater(evt,0,2,4)" visibility="visible" />
-<circle id="YRCm" title="orange" alt="orange fill" cx="0" cy="0" r="22.5" stroke="rgb(0,0,0)" fill="rgb(0,0,0)" stroke-width="9.5" onclick="updater(evt,1,2,5)" visibility="visible" />
-<circle id="YCm" title="yellow" alt="yellow fill" cx="0" cy="0" r="22.5" stroke="rgb(0,0,0)" fill="rgb(0,0,0)" stroke-width="9.5" onclick="updater(evt,2,2,0)" visibility="visible" />
-<circle id="GCm" title="green" alt="green fill" cx="0" cy="0" r="22.5" stroke="rgb(0,0,0)" fill="rgb(0,0,0)" stroke-width="9.5" onclick="updater(evt,3,2,1)" visibility="visible" />
-<circle id="BCm" title="blue" alt="blue fill" cx="0" cy="0" r="22.5" stroke="rgb(0,0,0)" fill="rgb(0,0,0)" stroke-width="9.5" onclick="updater(evt,4,2,2)" visibility="visible" />
-<circle id="PCm" title="purple" alt="purple fill" cx="0" cy="0" r="22.5" stroke="rgb(0,0,0)" fill="rgb(0,0,0)" stroke-width="9.5" onclick="updater(evt,5,2,3)" visibility="visible" />
-
-<circle id="RAp" title="red" alt="red fill" cx="0" cy="0" r="22.5" stroke="rgb(0,0,0)" fill="rgb(0,0,0)" stroke-width="9.5" onclick="updater(evt,0,1,5)" visibility="visible" />
-<circle id="YRAp" title="orange" alt="orange fill" cx="0" cy="0" r="22.5" stroke="rgb(0,0,0)" fill="rgb(0,0,0)" stroke-width="9.5" onclick="updater(evt,1,1,0)" visibility="visible" />
-<circle id="YAp" title="yellow" alt="yellow fill" cx="0" cy="0" r="22.5" stroke="rgb(0,0,0)" fill="rgb(0,0,0)" stroke-width="9.5" onclick="updater(evt,2,1,1)" visibility="visible" />
-<circle id="GAp" title="green" alt="green fill" cx="0" cy="0" r="22.5" stroke="rgb(0,0,0)" fill="rgb(0,0,0)" stroke-width="9.5" onclick="updater(evt,3,1,2)" visibility="visible" />
-<circle id="BAp" title="blue" alt="blue fill" cx="0" cy="0" r="22.5" stroke="rgb(0,0,0)" fill="rgb(0,0,0)" stroke-width="9.5" onclick="updater(evt,4,1,3)" visibility="visible" />
-<circle id="PAp" title="purple" alt="purple fill" cx="0" cy="0" r="22.5" stroke="rgb(0,0,0)" fill="rgb(0,0,0)" stroke-width="9.5" onclick="updater(evt,5,1,4)" visibility="visible" />
-
-<circle id="RAm" title="red" alt="red fill" cx="0" cy="0" r="22.5" stroke="rgb(0,0,0)" fill="rgb(0,0,0)" stroke-width="9.5" onclick="updater(evt,0,5,1)" visibility="visible" />
-<circle id="YRAm" title="orange" alt="orange fill" cx="0" cy="0" r="22.5" stroke="rgb(0,0,0)" fill="rgb(0,0,0)" stroke-width="9.5" onclick="updater(evt,1,5,2)" visibility="visible" />
-<circle id="YAm" title="yellow" alt="yellow fill" cx="0" cy="0" r="22.5" stroke="rgb(0,0,0)" fill="rgb(0,0,0)" stroke-width="9.5" onclick="updater(evt,2,5,3)" visibility="visible" />
-<circle id="GAm" title="green" alt="green fill" cx="0" cy="0" r="22.5" stroke="rgb(0,0,0)" fill="rgb(0,0,0)" stroke-width="9.5" onclick="updater(evt,3,5,4)" visibility="visible" />
-<circle id="BAm" title="blue" alt="blue fill" cx="0" cy="0" r="22.5" stroke="rgb(0,0,0)" fill="rgb(0,0,0)" stroke-width="9.5" onclick="updater(evt,4,5,5)" visibility="visible" />
-<circle id="PAm" title="purple" alt="purple fill" cx="0" cy="0" r="22.5" stroke="rgb(0,0,0)" fill="rgb(0,0,0)" stroke-width="9.5" onclick="updater(evt,5,5,0)" visibility="visible" />
-
-// controls
-<rect id="bgd" width="75" height="75" x="0" y="0" fill="rgb(160,160,160)" stroke="rgb(160,160,160)" stroke-width="1" visibility="hidden" />
-<rect id="bgdf" width="75" height="75" x="75" y="0" fill="rgb(160,160,160)" stroke="rgb(160,160,160)" stroke-width="1" visibility="hidden" />
-<rect id="bgm" width="75" height="75" x="150" y="0" fill="rgb(160,160,160)" stroke="rgb(160,160,160)" stroke-width="1" visibility="visible" />
-<rect id="bgmf" width="75" height="75" x="225" y="0" fill="rgb(160,160,160)" stroke="rgb(160,160,160)" stroke-width="1" visibility="hidden" />
-<rect id="bgl" width="75" height="75" x="300" y="0" fill="rgb(160,160,160)" stroke="rgb(160,160,160)" stroke-width="1" visibility="hidden" />
-<circle id="vd" title="dark" alt="dark stroke" cx="37.5" cy="37.5" r="22.5" stroke="rgb(0,0,0)" fill="rgb(0,0,0)" stroke-width="9.5" onclick="valueDark(evt)" visibility="visible" />
-<circle id="vdf" title="darkflip" alt="dark flip" cx="112.5" cy="37.5" r="22.5" stroke="rgb(0,0,0)" fill="rgb(0,0,0)" stroke-width="9.5" onclick="valueDarkFlip(evt)" visibility="visible" />
-<circle id="vm" title="medium" alt="medium stroke" cx="187.5" cy="37.5" r="22.5" stroke="rgb(0,0,0)" fill="rgb(0,0,0)" stroke-width="9.5" onclick="valueMedium(evt)" visibility="visible" />
-<circle id="vmf" title="mediumflip" alt="medium flip" cx="262.5" cy="37.5" r="22.5" stroke="rgb(0,0,0)" fill="rgb(0,0,0)" stroke-width="9.5" onclick="valueMediumFlip(evt)" visibility="visible" />
-<circle id="vl" title="light" alt="light stroke" cx="337.5" cy="37.5" r="22.5" stroke="rgb(0,0,0)" fill="rgb(0,0,0)" stroke-width="9.5" onclick="valueLight(evt)" visibility="visible" />
-
-<rect id="bghex" width="75" height="75" x="150" y="675" fill="rgb(160,160,160)" stroke="rgb(160,160,160)" stroke-width="1" visibility="visible" />
-<rect id="bgsq" width="75" height="75" x="75" y="675" fill="rgb(160,160,160)" stroke="rgb(160,160,160)" stroke-width="1" visibility="hidden" />
-<circle id="hex" title="hex grid" alt="hex grid" cx="187.5" cy="712.5" r="22.5" stroke="rgb(100,100,100)" fill="rgb(100,100,100)" stroke-width="9.5" onclick="hexGrid(evt)" visibility="visible" />
-<rect id="sq" title="square grid" alt="square gird" width="45" height="45" x="90" y="690" fill="rgb(100,100,100)" stroke="rgb(100,100,100)" stroke-width="1" onclick="sqGrid(evt)" visibility="visible" />
-
-<g onclick="resetXO(evt)"> // begin XO man icon
-<path id="iconLine1" d="M53,700 C37.5,715.5 37.5,715.5 22,731" stroke="rgb(230,0,10)" stroke-width="11.5" stroke-linecap="round" fill="none" visibility="visible" />
-<path id="iconLine2" d="M53,731 C37.5,715.5 37.5,715.5 22,700" stroke="rgb(230,0,10)" stroke-width="11.5" stroke-linecap="round" fill="none" visibility="visible" />
-<path id="iconFill1" d="M53,700 C37.5,715.5 37.5,715.5 22,731" stroke="rgb(255,43,52)" stroke-width="4.5" stroke-linecap="round" fill="none" visibility="visible" />
-<path id="iconFill2" d="M53,731 C37.5,715.5 37.5,715.5 22,700" stroke="rgb(255,43,52)" stroke-width="4.5" stroke-linecap="round" fill="none" visibility="visible" />
-<circle id="iconCircle" cx="37.5" cy="690" r="8" fill="rgb(255,43,52)" stroke="rgb(230,0,10)" stroke-width="3.5" visibility="visible" />
-</g> // end XO man icon
-
-// background controls
-
-<rect id="icon" width="75" height="75" x="1125" y="0" fill="rgb(255,255,255)" stroke="rgb(255,255,255)" stroke-width="1" visibility="visible" onclick="background(evt,0)" />
-<rect id="icon" width="75" height="75" x="1050" y="0" fill="rgb(231,231,233)" stroke="rgb(231,231,233)" stroke-width="1" visibility="visible" onclick="background(evt,1)" />
-<rect id="icon" width="75" height="75" x="975" y="0" fill="rgb(76,77,79)" stroke="rgb(76,77,79)" stroke-width="1" visibility="visible" onclick="background(evt,2)" />
-<rect id="icon" width="75" height="75" x="900" y="0" fill="rgb(0,0,0)" stroke="rgb(0,0,0)" stroke-width="1" visibility="visible" onclick="background(evt,3)" />
-</svg>
-</body>
-</html>
diff --git a/html/prototype.js b/html/prototype.js
deleted file mode 100644
index 5806f35..0000000
--- a/html/prototype.js
+++ /dev/null
@@ -1,3277 +0,0 @@
-/* Prototype JavaScript framework, version 1.5.1.1
- * (c) 2005-2007 Sam Stephenson
- *
- * Prototype is freely distributable under the terms of an MIT-style license.
- * For details, see the Prototype web site: http://www.prototypejs.org/
- *
-/*--------------------------------------------------------------------------*/
-
-var Prototype = {
- Version: '1.5.1.1',
-
- Browser: {
- IE: !!(window.attachEvent && !window.opera),
- Opera: !!window.opera,
- WebKit: navigator.userAgent.indexOf('AppleWebKit/') > -1,
- Gecko: navigator.userAgent.indexOf('Gecko') > -1 && navigator.userAgent.indexOf('KHTML') == -1
- },
-
- BrowserFeatures: {
- XPath: !!document.evaluate,
- ElementExtensions: !!window.HTMLElement,
- SpecificElementExtensions:
- (document.createElement('div').__proto__ !==
- document.createElement('form').__proto__)
- },
-
- ScriptFragment: '<script[^>]*>([\\S\\s]*?)<\/script>',
- JSONFilter: /^\/\*-secure-([\s\S]*)\*\/\s*$/,
-
- emptyFunction: function() { },
- K: function(x) { return x }
-}
-
-var Class = {
- create: function() {
- return function() {
- this.initialize.apply(this, arguments);
- }
- }
-}
-
-var Abstract = new Object();
-
-Object.extend = function(destination, source) {
- for (var property in source) {
- destination[property] = source[property];
- }
- return destination;
-}
-
-Object.extend(Object, {
- inspect: function(object) {
- try {
- if (object === undefined) return 'undefined';
- if (object === null) return 'null';
- return object.inspect ? object.inspect() : object.toString();
- } catch (e) {
- if (e instanceof RangeError) return '...';
- throw e;
- }
- },
-
- toJSON: function(object) {
- var type = typeof object;
- switch(type) {
- case 'undefined':
- case 'function':
- case 'unknown': return;
- case 'boolean': return object.toString();
- }
- if (object === null) return 'null';
- if (object.toJSON) return object.toJSON();
- if (object.ownerDocument === document) return;
- var results = [];
- for (var property in object) {
- var value = Object.toJSON(object[property]);
- if (value !== undefined)
- results.push(property.toJSON() + ': ' + value);
- }
- return '{' + results.join(', ') + '}';
- },
-
- keys: function(object) {
- var keys = [];
- for (var property in object)
- keys.push(property);
- return keys;
- },
-
- values: function(object) {
- var values = [];
- for (var property in object)
- values.push(object[property]);
- return values;
- },
-
- clone: function(object) {
- return Object.extend({}, object);
- }
-});
-
-Function.prototype.bind = function() {
- var __method = this, args = $A(arguments), object = args.shift();
- return function() {
- return __method.apply(object, args.concat($A(arguments)));
- }
-}
-
-Function.prototype.bindAsEventListener = function(object) {
- var __method = this, args = $A(arguments), object = args.shift();
- return function(event) {
- return __method.apply(object, [event || window.event].concat(args));
- }
-}
-
-Object.extend(Number.prototype, {
- toColorPart: function() {
- return this.toPaddedString(2, 16);
- },
-
- succ: function() {
- return this + 1;
- },
-
- times: function(iterator) {
- $R(0, this, true).each(iterator);
- return this;
- },
-
- toPaddedString: function(length, radix) {
- var string = this.toString(radix || 10);
- return '0'.times(length - string.length) + string;
- },
-
- toJSON: function() {
- return isFinite(this) ? this.toString() : 'null';
- }
-});
-
-Date.prototype.toJSON = function() {
- return '"' + this.getFullYear() + '-' +
- (this.getMonth() + 1).toPaddedString(2) + '-' +
- this.getDate().toPaddedString(2) + 'T' +
- this.getHours().toPaddedString(2) + ':' +
- this.getMinutes().toPaddedString(2) + ':' +
- this.getSeconds().toPaddedString(2) + '"';
-};
-
-var Try = {
- these: function() {
- var returnValue;
-
- for (var i = 0, length = arguments.length; i < length; i++) {
- var lambda = arguments[i];
- try {
- returnValue = lambda();
- break;
- } catch (e) {}
- }
-
- return returnValue;
- }
-}
-
-/*--------------------------------------------------------------------------*/
-
-var PeriodicalExecuter = Class.create();
-PeriodicalExecuter.prototype = {
- initialize: function(callback, frequency) {
- this.callback = callback;
- this.frequency = frequency;
- this.currentlyExecuting = false;
-
- this.registerCallback();
- },
-
- registerCallback: function() {
- this.timer = setInterval(this.onTimerEvent.bind(this), this.frequency * 1000);
- },
-
- stop: function() {
- if (!this.timer) return;
- clearInterval(this.timer);
- this.timer = null;
- },
-
- onTimerEvent: function() {
- if (!this.currentlyExecuting) {
- try {
- this.currentlyExecuting = true;
- this.callback(this);
- } finally {
- this.currentlyExecuting = false;
- }
- }
- }
-}
-Object.extend(String, {
- interpret: function(value) {
- return value == null ? '' : String(value);
- },
- specialChar: {
- '\b': '\\b',
- '\t': '\\t',
- '\n': '\\n',
- '\f': '\\f',
- '\r': '\\r',
- '\\': '\\\\'
- }
-});
-
-Object.extend(String.prototype, {
- gsub: function(pattern, replacement) {
- var result = '', source = this, match;
- replacement = arguments.callee.prepareReplacement(replacement);
-
- while (source.length > 0) {
- if (match = source.match(pattern)) {
- result += source.slice(0, match.index);
- result += String.interpret(replacement(match));
- source = source.slice(match.index + match[0].length);
- } else {
- result += source, source = '';
- }
- }
- return result;
- },
-
- sub: function(pattern, replacement, count) {
- replacement = this.gsub.prepareReplacement(replacement);
- count = count === undefined ? 1 : count;
-
- return this.gsub(pattern, function(match) {
- if (--count < 0) return match[0];
- return replacement(match);
- });
- },
-
- scan: function(pattern, iterator) {
- this.gsub(pattern, iterator);
- return this;
- },
-
- truncate: function(length, truncation) {
- length = length || 30;
- truncation = truncation === undefined ? '...' : truncation;
- return this.length > length ?
- this.slice(0, length - truncation.length) + truncation : this;
- },
-
- strip: function() {
- return this.replace(/^\s+/, '').replace(/\s+$/, '');
- },
-
- stripTags: function() {
- return this.replace(/<\/?[^>]+>/gi, '');
- },
-
- stripScripts: function() {
- return this.replace(new RegExp(Prototype.ScriptFragment, 'img'), '');
- },
-
- extractScripts: function() {
- var matchAll = new RegExp(Prototype.ScriptFragment, 'img');
- var matchOne = new RegExp(Prototype.ScriptFragment, 'im');
- return (this.match(matchAll) || []).map(function(scriptTag) {
- return (scriptTag.match(matchOne) || ['', ''])[1];
- });
- },
-
- evalScripts: function() {
- return this.extractScripts().map(function(script) { return eval(script) });
- },
-
- escapeHTML: function() {
- var self = arguments.callee;
- self.text.data = this;
- return self.div.innerHTML;
- },
-
- unescapeHTML: function() {
- var div = document.createElement('div');
- div.innerHTML = this.stripTags();
- return div.childNodes[0] ? (div.childNodes.length > 1 ?
- $A(div.childNodes).inject('', function(memo, node) { return memo+node.nodeValue }) :
- div.childNodes[0].nodeValue) : '';
- },
-
- toQueryParams: function(separator) {
- var match = this.strip().match(/([^?#]*)(#.*)?$/);
- if (!match) return {};
-
- return match[1].split(separator || '&').inject({}, function(hash, pair) {
- if ((pair = pair.split('='))[0]) {
- var key = decodeURIComponent(pair.shift());
- var value = pair.length > 1 ? pair.join('=') : pair[0];
- if (value != undefined) value = decodeURIComponent(value);
-
- if (key in hash) {
- if (hash[key].constructor != Array) hash[key] = [hash[key]];
- hash[key].push(value);
- }
- else hash[key] = value;
- }
- return hash;
- });
- },
-
- toArray: function() {
- return this.split('');
- },
-
- succ: function() {
- return this.slice(0, this.length - 1) +
- String.fromCharCode(this.charCodeAt(this.length - 1) + 1);
- },
-
- times: function(count) {
- var result = '';
- for (var i = 0; i < count; i++) result += this;
- return result;
- },
-
- camelize: function() {
- var parts = this.split('-'), len = parts.length;
- if (len == 1) return parts[0];
-
- var camelized = this.charAt(0) == '-'
- ? parts[0].charAt(0).toUpperCase() + parts[0].substring(1)
- : parts[0];
-
- for (var i = 1; i < len; i++)
- camelized += parts[i].charAt(0).toUpperCase() + parts[i].substring(1);
-
- return camelized;
- },
-
- capitalize: function() {
- return this.charAt(0).toUpperCase() + this.substring(1).toLowerCase();
- },
-
- underscore: function() {
- return this.gsub(/::/, '/').gsub(/([A-Z]+)([A-Z][a-z])/,'#{1}_#{2}').gsub(/([a-z\d])([A-Z])/,'#{1}_#{2}').gsub(/-/,'_').toLowerCase();
- },
-
- dasherize: function() {
- return this.gsub(/_/,'-');
- },
-
- inspect: function(useDoubleQuotes) {
- var escapedString = this.gsub(/[\x00-\x1f\\]/, function(match) {
- var character = String.specialChar[match[0]];
- return character ? character : '\\u00' + match[0].charCodeAt().toPaddedString(2, 16);
- });
- if (useDoubleQuotes) return '"' + escapedString.replace(/"/g, '\\"') + '"';
- return "'" + escapedString.replace(/'/g, '\\\'') + "'";
- },
-
- toJSON: function() {
- return this.inspect(true);
- },
-
- unfilterJSON: function(filter) {
- return this.sub(filter || Prototype.JSONFilter, '#{1}');
- },
-
- isJSON: function() {
- var str = this.replace(/\\./g, '@').replace(/"[^"\\\n\r]*"/g, '');
- return (/^[,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t]*$/).test(str);
- },
-
- evalJSON: function(sanitize) {
- var json = this.unfilterJSON();
- try {
- if (!sanitize || json.isJSON()) return eval('(' + json + ')');
- } catch (e) { }
- throw new SyntaxError('Badly formed JSON string: ' + this.inspect());
- },
-
- include: function(pattern) {
- return this.indexOf(pattern) > -1;
- },
-
- startsWith: function(pattern) {
- return this.indexOf(pattern) === 0;
- },
-
- endsWith: function(pattern) {
- var d = this.length - pattern.length;
- return d >= 0 && this.lastIndexOf(pattern) === d;
- },
-
- empty: function() {
- return this == '';
- },
-
- blank: function() {
- return /^\s*$/.test(this);
- }
-});
-
-if (Prototype.Browser.WebKit || Prototype.Browser.IE) Object.extend(String.prototype, {
- escapeHTML: function() {
- return this.replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;');
- },
- unescapeHTML: function() {
- return this.replace(/&amp;/g,'&').replace(/&lt;/g,'<').replace(/&gt;/g,'>');
- }
-});
-
-String.prototype.gsub.prepareReplacement = function(replacement) {
- if (typeof replacement == 'function') return replacement;
- var template = new Template(replacement);
- return function(match) { return template.evaluate(match) };
-}
-
-String.prototype.parseQuery = String.prototype.toQueryParams;
-
-Object.extend(String.prototype.escapeHTML, {
- div: document.createElement('div'),
- text: document.createTextNode('')
-});
-
-with (String.prototype.escapeHTML) div.appendChild(text);
-
-var Template = Class.create();
-Template.Pattern = /(^|.|\r|\n)(#\{(.*?)\})/;
-Template.prototype = {
- initialize: function(template, pattern) {
- this.template = template.toString();
- this.pattern = pattern || Template.Pattern;
- },
-
- evaluate: function(object) {
- return this.template.gsub(this.pattern, function(match) {
- var before = match[1];
- if (before == '\\') return match[2];
- return before + String.interpret(object[match[3]]);
- });
- }
-}
-
-var $break = {}, $continue = new Error('"throw $continue" is deprecated, use "return" instead');
-
-var Enumerable = {
- each: function(iterator) {
- var index = 0;
- try {
- this._each(function(value) {
- iterator(value, index++);
- });
- } catch (e) {
- if (e != $break) throw e;
- }
- return this;
- },
-
- eachSlice: function(number, iterator) {
- var index = -number, slices = [], array = this.toArray();
- while ((index += number) < array.length)
- slices.push(array.slice(index, index+number));
- return slices.map(iterator);
- },
-
- all: function(iterator) {
- var result = true;
- this.each(function(value, index) {
- result = result && !!(iterator || Prototype.K)(value, index);
- if (!result) throw $break;
- });
- return result;
- },
-
- any: function(iterator) {
- var result = false;
- this.each(function(value, index) {
- if (result = !!(iterator || Prototype.K)(value, index))
- throw $break;
- });
- return result;
- },
-
- collect: function(iterator) {
- var results = [];
- this.each(function(value, index) {
- results.push((iterator || Prototype.K)(value, index));
- });
- return results;
- },
-
- detect: function(iterator) {
- var result;
- this.each(function(value, index) {
- if (iterator(value, index)) {
- result = value;
- throw $break;
- }
- });
- return result;
- },
-
- findAll: function(iterator) {
- var results = [];
- this.each(function(value, index) {
- if (iterator(value, index))
- results.push(value);
- });
- return results;
- },
-
- grep: function(pattern, iterator) {
- var results = [];
- this.each(function(value, index) {
- var stringValue = value.toString();
- if (stringValue.match(pattern))
- results.push((iterator || Prototype.K)(value, index));
- })
- return results;
- },
-
- include: function(object) {
- var found = false;
- this.each(function(value) {
- if (value == object) {
- found = true;
- throw $break;
- }
- });
- return found;
- },
-
- inGroupsOf: function(number, fillWith) {
- fillWith = fillWith === undefined ? null : fillWith;
- return this.eachSlice(number, function(slice) {
- while(slice.length < number) slice.push(fillWith);
- return slice;
- });
- },
-
- inject: function(memo, iterator) {
- this.each(function(value, index) {
- memo = iterator(memo, value, index);
- });
- return memo;
- },
-
- invoke: function(method) {
- var args = $A(arguments).slice(1);
- return this.map(function(value) {
- return value[method].apply(value, args);
- });
- },
-
- max: function(iterator) {
- var result;
- this.each(function(value, index) {
- value = (iterator || Prototype.K)(value, index);
- if (result == undefined || value >= result)
- result = value;
- });
- return result;
- },
-
- min: function(iterator) {
- var result;
- this.each(function(value, index) {
- value = (iterator || Prototype.K)(value, index);
- if (result == undefined || value < result)
- result = value;
- });
- return result;
- },
-
- partition: function(iterator) {
- var trues = [], falses = [];
- this.each(function(value, index) {
- ((iterator || Prototype.K)(value, index) ?
- trues : falses).push(value);
- });
- return [trues, falses];
- },
-
- pluck: function(property) {
- var results = [];
- this.each(function(value, index) {
- results.push(value[property]);
- });
- return results;
- },
-
- reject: function(iterator) {
- var results = [];
- this.each(function(value, index) {
- if (!iterator(value, index))
- results.push(value);
- });
- return results;
- },
-
- sortBy: function(iterator) {
- return this.map(function(value, index) {
- return {value: value, criteria: iterator(value, index)};
- }).sort(function(left, right) {
- var a = left.criteria, b = right.criteria;
- return a < b ? -1 : a > b ? 1 : 0;
- }).pluck('value');
- },
-
- toArray: function() {
- return this.map();
- },
-
- zip: function() {
- var iterator = Prototype.K, args = $A(arguments);
- if (typeof args.last() == 'function')
- iterator = args.pop();
-
- var collections = [this].concat(args).map($A);
- return this.map(function(value, index) {
- return iterator(collections.pluck(index));
- });
- },
-
- size: function() {
- return this.toArray().length;
- },
-
- inspect: function() {
- return '#<Enumerable:' + this.toArray().inspect() + '>';
- }
-}
-
-Object.extend(Enumerable, {
- map: Enumerable.collect,
- find: Enumerable.detect,
- select: Enumerable.findAll,
- member: Enumerable.include,
- entries: Enumerable.toArray
-});
-var $A = Array.from = function(iterable) {
- if (!iterable) return [];
- if (iterable.toArray) {
- return iterable.toArray();
- } else {
- var results = [];
- for (var i = 0, length = iterable.length; i < length; i++)
- results.push(iterable[i]);
- return results;
- }
-}
-
-if (Prototype.Browser.WebKit) {
- $A = Array.from = function(iterable) {
- if (!iterable) return [];
- if (!(typeof iterable == 'function' && iterable == '[object NodeList]') &&
- iterable.toArray) {
- return iterable.toArray();
- } else {
- var results = [];
- for (var i = 0, length = iterable.length; i < length; i++)
- results.push(iterable[i]);
- return results;
- }
- }
-}
-
-Object.extend(Array.prototype, Enumerable);
-
-if (!Array.prototype._reverse)
- Array.prototype._reverse = Array.prototype.reverse;
-
-Object.extend(Array.prototype, {
- _each: function(iterator) {
- for (var i = 0, length = this.length; i < length; i++)
- iterator(this[i]);
- },
-
- clear: function() {
- this.length = 0;
- return this;
- },
-
- first: function() {
- return this[0];
- },
-
- last: function() {
- return this[this.length - 1];
- },
-
- compact: function() {
- return this.select(function(value) {
- return value != null;
- });
- },
-
- flatten: function() {
- return this.inject([], function(array, value) {
- return array.concat(value && value.constructor == Array ?
- value.flatten() : [value]);
- });
- },
-
- without: function() {
- var values = $A(arguments);
- return this.select(function(value) {
- return !values.include(value);
- });
- },
-
- indexOf: function(object) {
- for (var i = 0, length = this.length; i < length; i++)
- if (this[i] == object) return i;
- return -1;
- },
-
- reverse: function(inline) {
- return (inline !== false ? this : this.toArray())._reverse();
- },
-
- reduce: function() {
- return this.length > 1 ? this : this[0];
- },
-
- uniq: function(sorted) {
- return this.inject([], function(array, value, index) {
- if (0 == index || (sorted ? array.last() != value : !array.include(value)))
- array.push(value);
- return array;
- });
- },
-
- clone: function() {
- return [].concat(this);
- },
-
- size: function() {
- return this.length;
- },
-
- inspect: function() {
- return '[' + this.map(Object.inspect).join(', ') + ']';
- },
-
- toJSON: function() {
- var results = [];
- this.each(function(object) {
- var value = Object.toJSON(object);
- if (value !== undefined) results.push(value);
- });
- return '[' + results.join(', ') + ']';
- }
-});
-
-Array.prototype.toArray = Array.prototype.clone;
-
-function $w(string) {
- string = string.strip();
- return string ? string.split(/\s+/) : [];
-}
-
-if (Prototype.Browser.Opera){
- Array.prototype.concat = function() {
- var array = [];
- for (var i = 0, length = this.length; i < length; i++) array.push(this[i]);
- for (var i = 0, length = arguments.length; i < length; i++) {
- if (arguments[i].constructor == Array) {
- for (var j = 0, arrayLength = arguments[i].length; j < arrayLength; j++)
- array.push(arguments[i][j]);
- } else {
- array.push(arguments[i]);
- }
- }
- return array;
- }
-}
-var Hash = function(object) {
- if (object instanceof Hash) this.merge(object);
- else Object.extend(this, object || {});
-};
-
-Object.extend(Hash, {
- toQueryString: function(obj) {
- var parts = [];
- parts.add = arguments.callee.addPair;
-
- this.prototype._each.call(obj, function(pair) {
- if (!pair.key) return;
- var value = pair.value;
-
- if (value && typeof value == 'object') {
- if (value.constructor == Array) value.each(function(value) {
- parts.add(pair.key, value);
- });
- return;
- }
- parts.add(pair.key, value);
- });
-
- return parts.join('&');
- },
-
- toJSON: function(object) {
- var results = [];
- this.prototype._each.call(object, function(pair) {
- var value = Object.toJSON(pair.value);
- if (value !== undefined) results.push(pair.key.toJSON() + ': ' + value);
- });
- return '{' + results.join(', ') + '}';
- }
-});
-
-Hash.toQueryString.addPair = function(key, value, prefix) {
- key = encodeURIComponent(key);
- if (value === undefined) this.push(key);
- else this.push(key + '=' + (value == null ? '' : encodeURIComponent(value)));
-}
-
-Object.extend(Hash.prototype, Enumerable);
-Object.extend(Hash.prototype, {
- _each: function(iterator) {
- for (var key in this) {
- var value = this[key];
- if (value && value == Hash.prototype[key]) continue;
-
- var pair = [key, value];
- pair.key = key;
- pair.value = value;
- iterator(pair);
- }
- },
-
- keys: function() {
- return this.pluck('key');
- },
-
- values: function() {
- return this.pluck('value');
- },
-
- merge: function(hash) {
- return $H(hash).inject(this, function(mergedHash, pair) {
- mergedHash[pair.key] = pair.value;
- return mergedHash;
- });
- },
-
- remove: function() {
- var result;
- for(var i = 0, length = arguments.length; i < length; i++) {
- var value = this[arguments[i]];
- if (value !== undefined){
- if (result === undefined) result = value;
- else {
- if (result.constructor != Array) result = [result];
- result.push(value)
- }
- }
- delete this[arguments[i]];
- }
- return result;
- },
-
- toQueryString: function() {
- return Hash.toQueryString(this);
- },
-
- inspect: function() {
- return '#<Hash:{' + this.map(function(pair) {
- return pair.map(Object.inspect).join(': ');
- }).join(', ') + '}>';
- },
-
- toJSON: function() {
- return Hash.toJSON(this);
- }
-});
-
-function $H(object) {
- if (object instanceof Hash) return object;
- return new Hash(object);
-};
-
-// Safari iterates over shadowed properties
-if (function() {
- var i = 0, Test = function(value) { this.key = value };
- Test.prototype.key = 'foo';
- for (var property in new Test('bar')) i++;
- return i > 1;
-}()) Hash.prototype._each = function(iterator) {
- var cache = [];
- for (var key in this) {
- var value = this[key];
- if ((value && value == Hash.prototype[key]) || cache.include(key)) continue;
- cache.push(key);
- var pair = [key, value];
- pair.key = key;
- pair.value = value;
- iterator(pair);
- }
-};
-ObjectRange = Class.create();
-Object.extend(ObjectRange.prototype, Enumerable);
-Object.extend(ObjectRange.prototype, {
- initialize: function(start, end, exclusive) {
- this.start = start;
- this.end = end;
- this.exclusive = exclusive;
- },
-
- _each: function(iterator) {
- var value = this.start;
- while (this.include(value)) {
- iterator(value);
- value = value.succ();
- }
- },
-
- include: function(value) {
- if (value < this.start)
- return false;
- if (this.exclusive)
- return value < this.end;
- return value <= this.end;
- }
-});
-
-var $R = function(start, end, exclusive) {
- return new ObjectRange(start, end, exclusive);
-}
-
-var Ajax = {
- getTransport: function() {
- return Try.these(
- function() {return new XMLHttpRequest()},
- function() {return new ActiveXObject('Msxml2.XMLHTTP')},
- function() {return new ActiveXObject('Microsoft.XMLHTTP')}
- ) || false;
- },
-
- activeRequestCount: 0
-}
-
-Ajax.Responders = {
- responders: [],
-
- _each: function(iterator) {
- this.responders._each(iterator);
- },
-
- register: function(responder) {
- if (!this.include(responder))
- this.responders.push(responder);
- },
-
- unregister: function(responder) {
- this.responders = this.responders.without(responder);
- },
-
- dispatch: function(callback, request, transport, json) {
- this.each(function(responder) {
- if (typeof responder[callback] == 'function') {
- try {
- responder[callback].apply(responder, [request, transport, json]);
- } catch (e) {}
- }
- });
- }
-};
-
-Object.extend(Ajax.Responders, Enumerable);
-
-Ajax.Responders.register({
- onCreate: function() {
- Ajax.activeRequestCount++;
- },
- onComplete: function() {
- Ajax.activeRequestCount--;
- }
-});
-
-Ajax.Base = function() {};
-Ajax.Base.prototype = {
- setOptions: function(options) {
- this.options = {
- method: 'post',
- asynchronous: true,
- contentType: 'application/x-www-form-urlencoded',
- encoding: 'UTF-8',
- parameters: ''
- }
- Object.extend(this.options, options || {});
-
- this.options.method = this.options.method.toLowerCase();
- if (typeof this.options.parameters == 'string')
- this.options.parameters = this.options.parameters.toQueryParams();
- }
-}
-
-Ajax.Request = Class.create();
-Ajax.Request.Events =
- ['Uninitialized', 'Loading', 'Loaded', 'Interactive', 'Complete'];
-
-Ajax.Request.prototype = Object.extend(new Ajax.Base(), {
- _complete: false,
-
- initialize: function(url, options) {
- this.transport = Ajax.getTransport();
- this.setOptions(options);
- this.request(url);
- },
-
- request: function(url) {
- this.url = url;
- this.method = this.options.method;
- var params = Object.clone(this.options.parameters);
-
- if (!['get', 'post'].include(this.method)) {
- // simulate other verbs over post
- params['_method'] = this.method;
- this.method = 'post';
- }
-
- this.parameters = params;
-
- if (params = Hash.toQueryString(params)) {
- // when GET, append parameters to URL
- if (this.method == 'get')
- this.url += (this.url.include('?') ? '&' : '?') + params;
- else if (/Konqueror|Safari|KHTML/.test(navigator.userAgent))
- params += '&_=';
- }
-
- try {
- if (this.options.onCreate) this.options.onCreate(this.transport);
- Ajax.Responders.dispatch('onCreate', this, this.transport);
-
- this.transport.open(this.method.toUpperCase(), this.url,
- this.options.asynchronous);
-
- if (this.options.asynchronous)
- setTimeout(function() { this.respondToReadyState(1) }.bind(this), 10);
-
- this.transport.onreadystatechange = this.onStateChange.bind(this);
- this.setRequestHeaders();
-
- this.body = this.method == 'post' ? (this.options.postBody || params) : null;
- this.transport.send(this.body);
-
- /* Force Firefox to handle ready state 4 for synchronous requests */
- if (!this.options.asynchronous && this.transport.overrideMimeType)
- this.onStateChange();
-
- }
- catch (e) {
- this.dispatchException(e);
- }
- },
-
- onStateChange: function() {
- var readyState = this.transport.readyState;
- if (readyState > 1 && !((readyState == 4) && this._complete))
- this.respondToReadyState(this.transport.readyState);
- },
-
- setRequestHeaders: function() {
- var headers = {
- 'X-Requested-With': 'XMLHttpRequest',
- 'X-Prototype-Version': Prototype.Version,
- 'Accept': 'text/javascript, text/html, application/xml, text/xml, */*'
- };
-
- if (this.method == 'post') {
- headers['Content-type'] = this.options.contentType +
- (this.options.encoding ? '; charset=' + this.options.encoding : '');
-
- /* Force "Connection: close" for older Mozilla browsers to work
- * around a bug where XMLHttpRequest sends an incorrect
- * Content-length header. See Mozilla Bugzilla #246651.
- */
- if (this.transport.overrideMimeType &&
- (navigator.userAgent.match(/Gecko\/(\d{4})/) || [0,2005])[1] < 2005)
- headers['Connection'] = 'close';
- }
-
- // user-defined headers
- if (typeof this.options.requestHeaders == 'object') {
- var extras = this.options.requestHeaders;
-
- if (typeof extras.push == 'function')
- for (var i = 0, length = extras.length; i < length; i += 2)
- headers[extras[i]] = extras[i+1];
- else
- $H(extras).each(function(pair) { headers[pair.key] = pair.value });
- }
-
- for (var name in headers)
- this.transport.setRequestHeader(name, headers[name]);
- },
-
- success: function() {
- return !this.transport.status
- || (this.transport.status >= 200 && this.transport.status < 300);
- },
-
- respondToReadyState: function(readyState) {
- var state = Ajax.Request.Events[readyState];
- var transport = this.transport, json = this.evalJSON();
-
- if (state == 'Complete') {
- try {
- this._complete = true;
- (this.options['on' + this.transport.status]
- || this.options['on' + (this.success() ? 'Success' : 'Failure')]
- || Prototype.emptyFunction)(transport, json);
- } catch (e) {
- this.dispatchException(e);
- }
-
- var contentType = this.getHeader('Content-type');
- if (contentType && contentType.strip().
- match(/^(text|application)\/(x-)?(java|ecma)script(;.*)?$/i))
- this.evalResponse();
- }
-
- try {
- (this.options['on' + state] || Prototype.emptyFunction)(transport, json);
- Ajax.Responders.dispatch('on' + state, this, transport, json);
- } catch (e) {
- this.dispatchException(e);
- }
-
- if (state == 'Complete') {
- // avoid memory leak in MSIE: clean up
- this.transport.onreadystatechange = Prototype.emptyFunction;
- }
- },
-
- getHeader: function(name) {
- try {
- return this.transport.getResponseHeader(name);
- } catch (e) { return null }
- },
-
- evalJSON: function() {
- try {
- var json = this.getHeader('X-JSON');
- return json ? json.evalJSON() : null;
- } catch (e) { return null }
- },
-
- evalResponse: function() {
- try {
- return eval((this.transport.responseText || '').unfilterJSON());
- } catch (e) {
- this.dispatchException(e);
- }
- },
-
- dispatchException: function(exception) {
- (this.options.onException || Prototype.emptyFunction)(this, exception);
- Ajax.Responders.dispatch('onException', this, exception);
- }
-});
-
-Ajax.Updater = Class.create();
-
-Object.extend(Object.extend(Ajax.Updater.prototype, Ajax.Request.prototype), {
- initialize: function(container, url, options) {
- this.container = {
- success: (container.success || container),
- failure: (container.failure || (container.success ? null : container))
- }
-
- this.transport = Ajax.getTransport();
- this.setOptions(options);
-
- var onComplete = this.options.onComplete || Prototype.emptyFunction;
- this.options.onComplete = (function(transport, param) {
- this.updateContent();
- onComplete(transport, param);
- }).bind(this);
-
- this.request(url);
- },
-
- updateContent: function() {
- var receiver = this.container[this.success() ? 'success' : 'failure'];
- var response = this.transport.responseText;
-
- if (!this.options.evalScripts) response = response.stripScripts();
-
- if (receiver = $(receiver)) {
- if (this.options.insertion)
- new this.options.insertion(receiver, response);
- else
- receiver.update(response);
- }
-
- if (this.success()) {
- if (this.onComplete)
- setTimeout(this.onComplete.bind(this), 10);
- }
- }
-});
-
-Ajax.PeriodicalUpdater = Class.create();
-Ajax.PeriodicalUpdater.prototype = Object.extend(new Ajax.Base(), {
- initialize: function(container, url, options) {
- this.setOptions(options);
- this.onComplete = this.options.onComplete;
-
- this.frequency = (this.options.frequency || 2);
- this.decay = (this.options.decay || 1);
-
- this.updater = {};
- this.container = container;
- this.url = url;
-
- this.start();
- },
-
- start: function() {
- this.options.onComplete = this.updateComplete.bind(this);
- this.onTimerEvent();
- },
-
- stop: function() {
- this.updater.options.onComplete = undefined;
- clearTimeout(this.timer);
- (this.onComplete || Prototype.emptyFunction).apply(this, arguments);
- },
-
- updateComplete: function(request) {
- if (this.options.decay) {
- this.decay = (request.responseText == this.lastText ?
- this.decay * this.options.decay : 1);
-
- this.lastText = request.responseText;
- }
- this.timer = setTimeout(this.onTimerEvent.bind(this),
- this.decay * this.frequency * 1000);
- },
-
- onTimerEvent: function() {
- this.updater = new Ajax.Updater(this.container, this.url, this.options);
- }
-});
-function $(element) {
- if (arguments.length > 1) {
- for (var i = 0, elements = [], length = arguments.length; i < length; i++)
- elements.push($(arguments[i]));
- return elements;
- }
- if (typeof element == 'string')
- element = document.getElementById(element);
- return Element.extend(element);
-}
-
-if (Prototype.BrowserFeatures.XPath) {
- document._getElementsByXPath = function(expression, parentElement) {
- var results = [];
- var query = document.evaluate(expression, $(parentElement) || document,
- null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
- for (var i = 0, length = query.snapshotLength; i < length; i++)
- results.push(query.snapshotItem(i));
- return results;
- };
-
- document.getElementsByClassName = function(className, parentElement) {
- var q = ".//*[contains(concat(' ', @class, ' '), ' " + className + " ')]";
- return document._getElementsByXPath(q, parentElement);
- }
-
-} else document.getElementsByClassName = function(className, parentElement) {
- var children = ($(parentElement) || document.body).getElementsByTagName('*');
- var elements = [], child, pattern = new RegExp("(^|\\s)" + className + "(\\s|$)");
- for (var i = 0, length = children.length; i < length; i++) {
- child = children[i];
- var elementClassName = child.className;
- if (elementClassName.length == 0) continue;
- if (elementClassName == className || elementClassName.match(pattern))
- elements.push(Element.extend(child));
- }
- return elements;
-};
-
-/*--------------------------------------------------------------------------*/
-
-if (!window.Element) var Element = {};
-
-Element.extend = function(element) {
- var F = Prototype.BrowserFeatures;
- if (!element || !element.tagName || element.nodeType == 3 ||
- element._extended || F.SpecificElementExtensions || element == window)
- return element;
-
- var methods = {}, tagName = element.tagName, cache = Element.extend.cache,
- T = Element.Methods.ByTag;
-
- // extend methods for all tags (Safari doesn't need this)
- if (!F.ElementExtensions) {
- Object.extend(methods, Element.Methods),
- Object.extend(methods, Element.Methods.Simulated);
- }
-
- // extend methods for specific tags
- if (T[tagName]) Object.extend(methods, T[tagName]);
-
- for (var property in methods) {
- var value = methods[property];
- if (typeof value == 'function' && !(property in element))
- element[property] = cache.findOrStore(value);
- }
-
- element._extended = Prototype.emptyFunction;
- return element;
-};
-
-Element.extend.cache = {
- findOrStore: function(value) {
- return this[value] = this[value] || function() {
- return value.apply(null, [this].concat($A(arguments)));
- }
- }
-};
-
-Element.Methods = {
- visible: function(element) {
- return $(element).style.display != 'none';
- },
-
- toggle: function(element) {
- element = $(element);
- Element[Element.visible(element) ? 'hide' : 'show'](element);
- return element;
- },
-
- hide: function(element) {
- $(element).style.display = 'none';
- return element;
- },
-
- show: function(element) {
- $(element).style.display = '';
- return element;
- },
-
- remove: function(element) {
- element = $(element);
- element.parentNode.removeChild(element);
- return element;
- },
-
- update: function(element, html) {
- html = typeof html == 'undefined' ? '' : html.toString();
- $(element).innerHTML = html.stripScripts();
- setTimeout(function() {html.evalScripts()}, 10);
- return element;
- },
-
- replace: function(element, html) {
- element = $(element);
- html = typeof html == 'undefined' ? '' : html.toString();
- if (element.outerHTML) {
- element.outerHTML = html.stripScripts();
- } else {
- var range = element.ownerDocument.createRange();
- range.selectNodeContents(element);
- element.parentNode.replaceChild(
- range.createContextualFragment(html.stripScripts()), element);
- }
- setTimeout(function() {html.evalScripts()}, 10);
- return element;
- },
-
- inspect: function(element) {
- element = $(element);
- var result = '<' + element.tagName.toLowerCase();
- $H({'id': 'id', 'className': 'class'}).each(function(pair) {
- var property = pair.first(), attribute = pair.last();
- var value = (element[property] || '').toString();
- if (value) result += ' ' + attribute + '=' + value.inspect(true);
- });
- return result + '>';
- },
-
- recursivelyCollect: function(element, property) {
- element = $(element);
- var elements = [];
- while (element = element[property])
- if (element.nodeType == 1)
- elements.push(Element.extend(element));
- return elements;
- },
-
- ancestors: function(element) {
- return $(element).recursivelyCollect('parentNode');
- },
-
- descendants: function(element) {
- return $A($(element).getElementsByTagName('*')).each(Element.extend);
- },
-
- firstDescendant: function(element) {
- element = $(element).firstChild;
- while (element && element.nodeType != 1) element = element.nextSibling;
- return $(element);
- },
-
- immediateDescendants: function(element) {
- if (!(element = $(element).firstChild)) return [];
- while (element && element.nodeType != 1) element = element.nextSibling;
- if (element) return [element].concat($(element).nextSiblings());
- return [];
- },
-
- previousSiblings: function(element) {
- return $(element).recursivelyCollect('previousSibling');
- },
-
- nextSiblings: function(element) {
- return $(element).recursivelyCollect('nextSibling');
- },
-
- siblings: function(element) {
- element = $(element);
- return element.previousSiblings().reverse().concat(element.nextSiblings());
- },
-
- match: function(element, selector) {
- if (typeof selector == 'string')
- selector = new Selector(selector);
- return selector.match($(element));
- },
-
- up: function(element, expression, index) {
- element = $(element);
- if (arguments.length == 1) return $(element.parentNode);
- var ancestors = element.ancestors();
- return expression ? Selector.findElement(ancestors, expression, index) :
- ancestors[index || 0];
- },
-
- down: function(element, expression, index) {
- element = $(element);
- if (arguments.length == 1) return element.firstDescendant();
- var descendants = element.descendants();
- return expression ? Selector.findElement(descendants, expression, index) :
- descendants[index || 0];
- },
-
- previous: function(element, expression, index) {
- element = $(element);
- if (arguments.length == 1) return $(Selector.handlers.previousElementSibling(element));
- var previousSiblings = element.previousSiblings();
- return expression ? Selector.findElement(previousSiblings, expression, index) :
- previousSiblings[index || 0];
- },
-
- next: function(element, expression, index) {
- element = $(element);
- if (arguments.length == 1) return $(Selector.handlers.nextElementSibling(element));
- var nextSiblings = element.nextSiblings();
- return expression ? Selector.findElement(nextSiblings, expression, index) :
- nextSiblings[index || 0];
- },
-
- getElementsBySelector: function() {
- var args = $A(arguments), element = $(args.shift());
- return Selector.findChildElements(element, args);
- },
-
- getElementsByClassName: function(element, className) {
- return document.getElementsByClassName(className, element);
- },
-
- readAttribute: function(element, name) {
- element = $(element);
- if (Prototype.Browser.IE) {
- if (!element.attributes) return null;
- var t = Element._attributeTranslations;
- if (t.values[name]) return t.values[name](element, name);
- if (t.names[name]) name = t.names[name];
- var attribute = element.attributes[name];
- return attribute ? attribute.nodeValue : null;
- }
- return element.getAttribute(name);
- },
-
- getHeight: function(element) {
- return $(element).getDimensions().height;
- },
-
- getWidth: function(element) {
- return $(element).getDimensions().width;
- },
-
- classNames: function(element) {
- return new Element.ClassNames(element);
- },
-
- hasClassName: function(element, className) {
- if (!(element = $(element))) return;
- var elementClassName = element.className;
- if (elementClassName.length == 0) return false;
- if (elementClassName == className ||
- elementClassName.match(new RegExp("(^|\\s)" + className + "(\\s|$)")))
- return true;
- return false;
- },
-
- addClassName: function(element, className) {
- if (!(element = $(element))) return;
- Element.classNames(element).add(className);
- return element;
- },
-
- removeClassName: function(element, className) {
- if (!(element = $(element))) return;
- Element.classNames(element).remove(className);
- return element;
- },
-
- toggleClassName: function(element, className) {
- if (!(element = $(element))) return;
- Element.classNames(element)[element.hasClassName(className) ? 'remove' : 'add'](className);
- return element;
- },
-
- observe: function() {
- Event.observe.apply(Event, arguments);
- return $A(arguments).first();
- },
-
- stopObserving: function() {
- Event.stopObserving.apply(Event, arguments);
- return $A(arguments).first();
- },
-
- // removes whitespace-only text node children
- cleanWhitespace: function(element) {
- element = $(element);
- var node = element.firstChild;
- while (node) {
- var nextNode = node.nextSibling;
- if (node.nodeType == 3 && !/\S/.test(node.nodeValue))
- element.removeChild(node);
- node = nextNode;
- }
- return element;
- },
-
- empty: function(element) {
- return $(element).innerHTML.blank();
- },
-
- descendantOf: function(element, ancestor) {
- element = $(element), ancestor = $(ancestor);
- while (element = element.parentNode)
- if (element == ancestor) return true;
- return false;
- },
-
- scrollTo: function(element) {
- element = $(element);
- var pos = Position.cumulativeOffset(element);
- window.scrollTo(pos[0], pos[1]);
- return element;
- },
-
- getStyle: function(element, style) {
- element = $(element);
- style = style == 'float' ? 'cssFloat' : style.camelize();
- var value = element.style[style];
- if (!value) {
- var css = document.defaultView.getComputedStyle(element, null);
- value = css ? css[style] : null;
- }
- if (style == 'opacity') return value ? parseFloat(value) : 1.0;
- return value == 'auto' ? null : value;
- },
-
- getOpacity: function(element) {
- return $(element).getStyle('opacity');
- },
-
- setStyle: function(element, styles, camelized) {
- element = $(element);
- var elementStyle = element.style;
-
- for (var property in styles)
- if (property == 'opacity') element.setOpacity(styles[property])
- else
- elementStyle[(property == 'float' || property == 'cssFloat') ?
- (elementStyle.styleFloat === undefined ? 'cssFloat' : 'styleFloat') :
- (camelized ? property : property.camelize())] = styles[property];
-
- return element;
- },
-
- setOpacity: function(element, value) {
- element = $(element);
- element.style.opacity = (value == 1 || value === '') ? '' :
- (value < 0.00001) ? 0 : value;
- return element;
- },
-
- getDimensions: function(element) {
- element = $(element);
- var display = $(element).getStyle('display');
- if (display != 'none' && display != null) // Safari bug
- return {width: element.offsetWidth, height: element.offsetHeight};
-
- // All *Width and *Height properties give 0 on elements with display none,
- // so enable the element temporarily
- var els = element.style;
- var originalVisibility = els.visibility;
- var originalPosition = els.position;
- var originalDisplay = els.display;
- els.visibility = 'hidden';
- els.position = 'absolute';
- els.display = 'block';
- var originalWidth = element.clientWidth;
- var originalHeight = element.clientHeight;
- els.display = originalDisplay;
- els.position = originalPosition;
- els.visibility = originalVisibility;
- return {width: originalWidth, height: originalHeight};
- },
-
- makePositioned: function(element) {
- element = $(element);
- var pos = Element.getStyle(element, 'position');
- if (pos == 'static' || !pos) {
- element._madePositioned = true;
- element.style.position = 'relative';
- // Opera returns the offset relative to the positioning context, when an
- // element is position relative but top and left have not been defined
- if (window.opera) {
- element.style.top = 0;
- element.style.left = 0;
- }
- }
- return element;
- },
-
- undoPositioned: function(element) {
- element = $(element);
- if (element._madePositioned) {
- element._madePositioned = undefined;
- element.style.position =
- element.style.top =
- element.style.left =
- element.style.bottom =
- element.style.right = '';
- }
- return element;
- },
-
- makeClipping: function(element) {
- element = $(element);
- if (element._overflow) return element;
- element._overflow = element.style.overflow || 'auto';
- if ((Element.getStyle(element, 'overflow') || 'visible') != 'hidden')
- element.style.overflow = 'hidden';
- return element;
- },
-
- undoClipping: function(element) {
- element = $(element);
- if (!element._overflow) return element;
- element.style.overflow = element._overflow == 'auto' ? '' : element._overflow;
- element._overflow = null;
- return element;
- }
-};
-
-Object.extend(Element.Methods, {
- childOf: Element.Methods.descendantOf,
- childElements: Element.Methods.immediateDescendants
-});
-
-if (Prototype.Browser.Opera) {
- Element.Methods._getStyle = Element.Methods.getStyle;
- Element.Methods.getStyle = function(element, style) {
- switch(style) {
- case 'left':
- case 'top':
- case 'right':
- case 'bottom':
- if (Element._getStyle(element, 'position') == 'static') return null;
- default: return Element._getStyle(element, style);
- }
- };
-}
-else if (Prototype.Browser.IE) {
- Element.Methods.getStyle = function(element, style) {
- element = $(element);
- style = (style == 'float' || style == 'cssFloat') ? 'styleFloat' : style.camelize();
- var value = element.style[style];
- if (!value && element.currentStyle) value = element.currentStyle[style];
-
- if (style == 'opacity') {
- if (value = (element.getStyle('filter') || '').match(/alpha\(opacity=(.*)\)/))
- if (value[1]) return parseFloat(value[1]) / 100;
- return 1.0;
- }
-
- if (value == 'auto') {
- if ((style == 'width' || style == 'height') && (element.getStyle('display') != 'none'))
- return element['offset'+style.capitalize()] + 'px';
- return null;
- }
- return value;
- };
-
- Element.Methods.setOpacity = function(element, value) {
- element = $(element);
- var filter = element.getStyle('filter'), style = element.style;
- if (value == 1 || value === '') {
- style.filter = filter.replace(/alpha\([^\)]*\)/gi,'');
- return element;
- } else if (value < 0.00001) value = 0;
- style.filter = filter.replace(/alpha\([^\)]*\)/gi, '') +
- 'alpha(opacity=' + (value * 100) + ')';
- return element;
- };
-
- // IE is missing .innerHTML support for TABLE-related elements
- Element.Methods.update = function(element, html) {
- element = $(element);
- html = typeof html == 'undefined' ? '' : html.toString();
- var tagName = element.tagName.toUpperCase();
- if (['THEAD','TBODY','TR','TD'].include(tagName)) {
- var div = document.createElement('div');
- switch (tagName) {
- case 'THEAD':
- case 'TBODY':
- div.innerHTML = '<table><tbody>' + html.stripScripts() + '</tbody></table>';
- depth = 2;
- break;
- case 'TR':
- div.innerHTML = '<table><tbody><tr>' + html.stripScripts() + '</tr></tbody></table>';
- depth = 3;
- break;
- case 'TD':
- div.innerHTML = '<table><tbody><tr><td>' + html.stripScripts() + '</td></tr></tbody></table>';
- depth = 4;
- }
- $A(element.childNodes).each(function(node) { element.removeChild(node) });
- depth.times(function() { div = div.firstChild });
- $A(div.childNodes).each(function(node) { element.appendChild(node) });
- } else {
- element.innerHTML = html.stripScripts();
- }
- setTimeout(function() { html.evalScripts() }, 10);
- return element;
- }
-}
-else if (Prototype.Browser.Gecko) {
- Element.Methods.setOpacity = function(element, value) {
- element = $(element);
- element.style.opacity = (value == 1) ? 0.999999 :
- (value === '') ? '' : (value < 0.00001) ? 0 : value;
- return element;
- };
-}
-
-Element._attributeTranslations = {
- names: {
- colspan: "colSpan",
- rowspan: "rowSpan",
- valign: "vAlign",
- datetime: "dateTime",
- accesskey: "accessKey",
- tabindex: "tabIndex",
- enctype: "encType",
- maxlength: "maxLength",
- readonly: "readOnly",
- longdesc: "longDesc"
- },
- values: {
- _getAttr: function(element, attribute) {
- return element.getAttribute(attribute, 2);
- },
- _flag: function(element, attribute) {
- return $(element).hasAttribute(attribute) ? attribute : null;
- },
- style: function(element) {
- return element.style.cssText.toLowerCase();
- },
- title: function(element) {
- var node = element.getAttributeNode('title');
- return node.specified ? node.nodeValue : null;
- }
- }
-};
-
-(function() {
- Object.extend(this, {
- href: this._getAttr,
- src: this._getAttr,
- type: this._getAttr,
- disabled: this._flag,
- checked: this._flag,
- readonly: this._flag,
- multiple: this._flag
- });
-}).call(Element._attributeTranslations.values);
-
-Element.Methods.Simulated = {
- hasAttribute: function(element, attribute) {
- var t = Element._attributeTranslations, node;
- attribute = t.names[attribute] || attribute;
- node = $(element).getAttributeNode(attribute);
- return node && node.specified;
- }
-};
-
-Element.Methods.ByTag = {};
-
-Object.extend(Element, Element.Methods);
-
-if (!Prototype.BrowserFeatures.ElementExtensions &&
- document.createElement('div').__proto__) {
- window.HTMLElement = {};
- window.HTMLElement.prototype = document.createElement('div').__proto__;
- Prototype.BrowserFeatures.ElementExtensions = true;
-}
-
-Element.hasAttribute = function(element, attribute) {
- if (element.hasAttribute) return element.hasAttribute(attribute);
- return Element.Methods.Simulated.hasAttribute(element, attribute);
-};
-
-Element.addMethods = function(methods) {
- var F = Prototype.BrowserFeatures, T = Element.Methods.ByTag;
-
- if (!methods) {
- Object.extend(Form, Form.Methods);
- Object.extend(Form.Element, Form.Element.Methods);
- Object.extend(Element.Methods.ByTag, {
- "FORM": Object.clone(Form.Methods),
- "INPUT": Object.clone(Form.Element.Methods),
- "SELECT": Object.clone(Form.Element.Methods),
- "TEXTAREA": Object.clone(Form.Element.Methods)
- });
- }
-
- if (arguments.length == 2) {
- var tagName = methods;
- methods = arguments[1];
- }
-
- if (!tagName) Object.extend(Element.Methods, methods || {});
- else {
- if (tagName.constructor == Array) tagName.each(extend);
- else extend(tagName);
- }
-
- function extend(tagName) {
- tagName = tagName.toUpperCase();
- if (!Element.Methods.ByTag[tagName])
- Element.Methods.ByTag[tagName] = {};
- Object.extend(Element.Methods.ByTag[tagName], methods);
- }
-
- function copy(methods, destination, onlyIfAbsent) {
- onlyIfAbsent = onlyIfAbsent || false;
- var cache = Element.extend.cache;
- for (var property in methods) {
- var value = methods[property];
- if (!onlyIfAbsent || !(property in destination))
- destination[property] = cache.findOrStore(value);
- }
- }
-
- function findDOMClass(tagName) {
- var klass;
- var trans = {
- "OPTGROUP": "OptGroup", "TEXTAREA": "TextArea", "P": "Paragraph",
- "FIELDSET": "FieldSet", "UL": "UList", "OL": "OList", "DL": "DList",
- "DIR": "Directory", "H1": "Heading", "H2": "Heading", "H3": "Heading",
- "H4": "Heading", "H5": "Heading", "H6": "Heading", "Q": "Quote",
- "INS": "Mod", "DEL": "Mod", "A": "Anchor", "IMG": "Image", "CAPTION":
- "TableCaption", "COL": "TableCol", "COLGROUP": "TableCol", "THEAD":
- "TableSection", "TFOOT": "TableSection", "TBODY": "TableSection", "TR":
- "TableRow", "TH": "TableCell", "TD": "TableCell", "FRAMESET":
- "FrameSet", "IFRAME": "IFrame"
- };
- if (trans[tagName]) klass = 'HTML' + trans[tagName] + 'Element';
- if (window[klass]) return window[klass];
- klass = 'HTML' + tagName + 'Element';
- if (window[klass]) return window[klass];
- klass = 'HTML' + tagName.capitalize() + 'Element';
- if (window[klass]) return window[klass];
-
- window[klass] = {};
- window[klass].prototype = document.createElement(tagName).__proto__;
- return window[klass];
- }
-
- if (F.ElementExtensions) {
- copy(Element.Methods, HTMLElement.prototype);
- copy(Element.Methods.Simulated, HTMLElement.prototype, true);
- }
-
- if (F.SpecificElementExtensions) {
- for (var tag in Element.Methods.ByTag) {
- var klass = findDOMClass(tag);
- if (typeof klass == "undefined") continue;
- copy(T[tag], klass.prototype);
- }
- }
-
- Object.extend(Element, Element.Methods);
- delete Element.ByTag;
-};
-
-var Toggle = { display: Element.toggle };
-
-/*--------------------------------------------------------------------------*/
-
-Abstract.Insertion = function(adjacency) {
- this.adjacency = adjacency;
-}
-
-Abstract.Insertion.prototype = {
- initialize: function(element, content) {
- this.element = $(element);
- this.content = content.stripScripts();
-
- if (this.adjacency && this.element.insertAdjacentHTML) {
- try {
- this.element.insertAdjacentHTML(this.adjacency, this.content);
- } catch (e) {
- var tagName = this.element.tagName.toUpperCase();
- if (['TBODY', 'TR'].include(tagName)) {
- this.insertContent(this.contentFromAnonymousTable());
- } else {
- throw e;
- }
- }
- } else {
- this.range = this.element.ownerDocument.createRange();
- if (this.initializeRange) this.initializeRange();
- this.insertContent([this.range.createContextualFragment(this.content)]);
- }
-
- setTimeout(function() {content.evalScripts()}, 10);
- },
-
- contentFromAnonymousTable: function() {
- var div = document.createElement('div');
- div.innerHTML = '<table><tbody>' + this.content + '</tbody></table>';
- return $A(div.childNodes[0].childNodes[0].childNodes);
- }
-}
-
-var Insertion = new Object();
-
-Insertion.Before = Class.create();
-Insertion.Before.prototype = Object.extend(new Abstract.Insertion('beforeBegin'), {
- initializeRange: function() {
- this.range.setStartBefore(this.element);
- },
-
- insertContent: function(fragments) {
- fragments.each((function(fragment) {
- this.element.parentNode.insertBefore(fragment, this.element);
- }).bind(this));
- }
-});
-
-Insertion.Top = Class.create();
-Insertion.Top.prototype = Object.extend(new Abstract.Insertion('afterBegin'), {
- initializeRange: function() {
- this.range.selectNodeContents(this.element);
- this.range.collapse(true);
- },
-
- insertContent: function(fragments) {
- fragments.reverse(false).each((function(fragment) {
- this.element.insertBefore(fragment, this.element.firstChild);
- }).bind(this));
- }
-});
-
-Insertion.Bottom = Class.create();
-Insertion.Bottom.prototype = Object.extend(new Abstract.Insertion('beforeEnd'), {
- initializeRange: function() {
- this.range.selectNodeContents(this.element);
- this.range.collapse(this.element);
- },
-
- insertContent: function(fragments) {
- fragments.each((function(fragment) {
- this.element.appendChild(fragment);
- }).bind(this));
- }
-});
-
-Insertion.After = Class.create();
-Insertion.After.prototype = Object.extend(new Abstract.Insertion('afterEnd'), {
- initializeRange: function() {
- this.range.setStartAfter(this.element);
- },
-
- insertContent: function(fragments) {
- fragments.each((function(fragment) {
- this.element.parentNode.insertBefore(fragment,
- this.element.nextSibling);
- }).bind(this));
- }
-});
-
-/*--------------------------------------------------------------------------*/
-
-Element.ClassNames = Class.create();
-Element.ClassNames.prototype = {
- initialize: function(element) {
- this.element = $(element);
- },
-
- _each: function(iterator) {
- this.element.className.split(/\s+/).select(function(name) {
- return name.length > 0;
- })._each(iterator);
- },
-
- set: function(className) {
- this.element.className = className;
- },
-
- add: function(classNameToAdd) {
- if (this.include(classNameToAdd)) return;
- this.set($A(this).concat(classNameToAdd).join(' '));
- },
-
- remove: function(classNameToRemove) {
- if (!this.include(classNameToRemove)) return;
- this.set($A(this).without(classNameToRemove).join(' '));
- },
-
- toString: function() {
- return $A(this).join(' ');
- }
-};
-
-Object.extend(Element.ClassNames.prototype, Enumerable);
-/* Portions of the Selector class are derived from Jack Slocum’s DomQuery,
- * part of YUI-Ext version 0.40, distributed under the terms of an MIT-style
- * license. Please see http://www.yui-ext.com/ for more information. */
-
-var Selector = Class.create();
-
-Selector.prototype = {
- initialize: function(expression) {
- this.expression = expression.strip();
- this.compileMatcher();
- },
-
- compileMatcher: function() {
- // Selectors with namespaced attributes can't use the XPath version
- if (Prototype.BrowserFeatures.XPath && !(/\[[\w-]*?:/).test(this.expression))
- return this.compileXPathMatcher();
-
- var e = this.expression, ps = Selector.patterns, h = Selector.handlers,
- c = Selector.criteria, le, p, m;
-
- if (Selector._cache[e]) {
- this.matcher = Selector._cache[e]; return;
- }
- this.matcher = ["this.matcher = function(root) {",
- "var r = root, h = Selector.handlers, c = false, n;"];
-
- while (e && le != e && (/\S/).test(e)) {
- le = e;
- for (var i in ps) {
- p = ps[i];
- if (m = e.match(p)) {
- this.matcher.push(typeof c[i] == 'function' ? c[i](m) :
- new Template(c[i]).evaluate(m));
- e = e.replace(m[0], '');
- break;
- }
- }
- }
-
- this.matcher.push("return h.unique(n);\n}");
- eval(this.matcher.join('\n'));
- Selector._cache[this.expression] = this.matcher;
- },
-
- compileXPathMatcher: function() {
- var e = this.expression, ps = Selector.patterns,
- x = Selector.xpath, le, m;
-
- if (Selector._cache[e]) {
- this.xpath = Selector._cache[e]; return;
- }
-
- this.matcher = ['.//*'];
- while (e && le != e && (/\S/).test(e)) {
- le = e;
- for (var i in ps) {
- if (m = e.match(ps[i])) {
- this.matcher.push(typeof x[i] == 'function' ? x[i](m) :
- new Template(x[i]).evaluate(m));
- e = e.replace(m[0], '');
- break;
- }
- }
- }
-
- this.xpath = this.matcher.join('');
- Selector._cache[this.expression] = this.xpath;
- },
-
- findElements: function(root) {
- root = root || document;
- if (this.xpath) return document._getElementsByXPath(this.xpath, root);
- return this.matcher(root);
- },
-
- match: function(element) {
- return this.findElements(document).include(element);
- },
-
- toString: function() {
- return this.expression;
- },
-
- inspect: function() {
- return "#<Selector:" + this.expression.inspect() + ">";
- }
-};
-
-Object.extend(Selector, {
- _cache: {},
-
- xpath: {
- descendant: "//*",
- child: "/*",
- adjacent: "/following-sibling::*[1]",
- laterSibling: '/following-sibling::*',
- tagName: function(m) {
- if (m[1] == '*') return '';
- return "[local-name()='" + m[1].toLowerCase() +
- "' or local-name()='" + m[1].toUpperCase() + "']";
- },
- className: "[contains(concat(' ', @class, ' '), ' #{1} ')]",
- id: "[@id='#{1}']",
- attrPresence: "[@#{1}]",
- attr: function(m) {
- m[3] = m[5] || m[6];
- return new Template(Selector.xpath.operators[m[2]]).evaluate(m);
- },
- pseudo: function(m) {
- var h = Selector.xpath.pseudos[m[1]];
- if (!h) return '';
- if (typeof h === 'function') return h(m);
- return new Template(Selector.xpath.pseudos[m[1]]).evaluate(m);
- },
- operators: {
- '=': "[@#{1}='#{3}']",
- '!=': "[@#{1}!='#{3}']",
- '^=': "[starts-with(@#{1}, '#{3}')]",
- '$=': "[substring(@#{1}, (string-length(@#{1}) - string-length('#{3}') + 1))='#{3}']",
- '*=': "[contains(@#{1}, '#{3}')]",
- '~=': "[contains(concat(' ', @#{1}, ' '), ' #{3} ')]",
- '|=': "[contains(concat('-', @#{1}, '-'), '-#{3}-')]"
- },
- pseudos: {
- 'first-child': '[not(preceding-sibling::*)]',
- 'last-child': '[not(following-sibling::*)]',
- 'only-child': '[not(preceding-sibling::* or following-sibling::*)]',
- 'empty': "[count(*) = 0 and (count(text()) = 0 or translate(text(), ' \t\r\n', '') = '')]",
- 'checked': "[@checked]",
- 'disabled': "[@disabled]",
- 'enabled': "[not(@disabled)]",
- 'not': function(m) {
- var e = m[6], p = Selector.patterns,
- x = Selector.xpath, le, m, v;
-
- var exclusion = [];
- while (e && le != e && (/\S/).test(e)) {
- le = e;
- for (var i in p) {
- if (m = e.match(p[i])) {
- v = typeof x[i] == 'function' ? x[i](m) : new Template(x[i]).evaluate(m);
- exclusion.push("(" + v.substring(1, v.length - 1) + ")");
- e = e.replace(m[0], '');
- break;
- }
- }
- }
- return "[not(" + exclusion.join(" and ") + ")]";
- },
- 'nth-child': function(m) {
- return Selector.xpath.pseudos.nth("(count(./preceding-sibling::*) + 1) ", m);
- },
- 'nth-last-child': function(m) {
- return Selector.xpath.pseudos.nth("(count(./following-sibling::*) + 1) ", m);
- },
- 'nth-of-type': function(m) {
- return Selector.xpath.pseudos.nth("position() ", m);
- },
- 'nth-last-of-type': function(m) {
- return Selector.xpath.pseudos.nth("(last() + 1 - position()) ", m);
- },
- 'first-of-type': function(m) {
- m[6] = "1"; return Selector.xpath.pseudos['nth-of-type'](m);
- },
- 'last-of-type': function(m) {
- m[6] = "1"; return Selector.xpath.pseudos['nth-last-of-type'](m);
- },
- 'only-of-type': function(m) {
- var p = Selector.xpath.pseudos; return p['first-of-type'](m) + p['last-of-type'](m);
- },
- nth: function(fragment, m) {
- var mm, formula = m[6], predicate;
- if (formula == 'even') formula = '2n+0';
- if (formula == 'odd') formula = '2n+1';
- if (mm = formula.match(/^(\d+)$/)) // digit only
- return '[' + fragment + "= " + mm[1] + ']';
- if (mm = formula.match(/^(-?\d*)?n(([+-])(\d+))?/)) { // an+b
- if (mm[1] == "-") mm[1] = -1;
- var a = mm[1] ? Number(mm[1]) : 1;
- var b = mm[2] ? Number(mm[2]) : 0;
- predicate = "[((#{fragment} - #{b}) mod #{a} = 0) and " +
- "((#{fragment} - #{b}) div #{a} >= 0)]";
- return new Template(predicate).evaluate({
- fragment: fragment, a: a, b: b });
- }
- }
- }
- },
-
- criteria: {
- tagName: 'n = h.tagName(n, r, "#{1}", c); c = false;',
- className: 'n = h.className(n, r, "#{1}", c); c = false;',
- id: 'n = h.id(n, r, "#{1}", c); c = false;',
- attrPresence: 'n = h.attrPresence(n, r, "#{1}"); c = false;',
- attr: function(m) {
- m[3] = (m[5] || m[6]);
- return new Template('n = h.attr(n, r, "#{1}", "#{3}", "#{2}"); c = false;').evaluate(m);
- },
- pseudo: function(m) {
- if (m[6]) m[6] = m[6].replace(/"/g, '\\"');
- return new Template('n = h.pseudo(n, "#{1}", "#{6}", r, c); c = false;').evaluate(m);
- },
- descendant: 'c = "descendant";',
- child: 'c = "child";',
- adjacent: 'c = "adjacent";',
- laterSibling: 'c = "laterSibling";'
- },
-
- patterns: {
- // combinators must be listed first
- // (and descendant needs to be last combinator)
- laterSibling: /^\s*~\s*/,
- child: /^\s*>\s*/,
- adjacent: /^\s*\+\s*/,
- descendant: /^\s/,
-
- // selectors follow
- tagName: /^\s*(\*|[\w\-]+)(\b|$)?/,
- id: /^#([\w\-\*]+)(\b|$)/,
- className: /^\.([\w\-\*]+)(\b|$)/,
- pseudo: /^:((first|last|nth|nth-last|only)(-child|-of-type)|empty|checked|(en|dis)abled|not)(\((.*?)\))?(\b|$|\s|(?=:))/,
- attrPresence: /^\[([\w]+)\]/,
- attr: /\[((?:[\w-]*:)?[\w-]+)\s*(?:([!^$*~|]?=)\s*((['"])([^\]]*?)\4|([^'"][^\]]*?)))?\]/
- },
-
- handlers: {
- // UTILITY FUNCTIONS
- // joins two collections
- concat: function(a, b) {
- for (var i = 0, node; node = b[i]; i++)
- a.push(node);
- return a;
- },
-
- // marks an array of nodes for counting
- mark: function(nodes) {
- for (var i = 0, node; node = nodes[i]; i++)
- node._counted = true;
- return nodes;
- },
-
- unmark: function(nodes) {
- for (var i = 0, node; node = nodes[i]; i++)
- node._counted = undefined;
- return nodes;
- },
-
- // mark each child node with its position (for nth calls)
- // "ofType" flag indicates whether we're indexing for nth-of-type
- // rather than nth-child
- index: function(parentNode, reverse, ofType) {
- parentNode._counted = true;
- if (reverse) {
- for (var nodes = parentNode.childNodes, i = nodes.length - 1, j = 1; i >= 0; i--) {
- node = nodes[i];
- if (node.nodeType == 1 && (!ofType || node._counted)) node.nodeIndex = j++;
- }
- } else {
- for (var i = 0, j = 1, nodes = parentNode.childNodes; node = nodes[i]; i++)
- if (node.nodeType == 1 && (!ofType || node._counted)) node.nodeIndex = j++;
- }
- },
-
- // filters out duplicates and extends all nodes
- unique: function(nodes) {
- if (nodes.length == 0) return nodes;
- var results = [], n;
- for (var i = 0, l = nodes.length; i < l; i++)
- if (!(n = nodes[i])._counted) {
- n._counted = true;
- results.push(Element.extend(n));
- }
- return Selector.handlers.unmark(results);
- },
-
- // COMBINATOR FUNCTIONS
- descendant: function(nodes) {
- var h = Selector.handlers;
- for (var i = 0, results = [], node; node = nodes[i]; i++)
- h.concat(results, node.getElementsByTagName('*'));
- return results;
- },
-
- child: function(nodes) {
- var h = Selector.handlers;
- for (var i = 0, results = [], node; node = nodes[i]; i++) {
- for (var j = 0, children = [], child; child = node.childNodes[j]; j++)
- if (child.nodeType == 1 && child.tagName != '!') results.push(child);
- }
- return results;
- },
-
- adjacent: function(nodes) {
- for (var i = 0, results = [], node; node = nodes[i]; i++) {
- var next = this.nextElementSibling(node);
- if (next) results.push(next);
- }
- return results;
- },
-
- laterSibling: function(nodes) {
- var h = Selector.handlers;
- for (var i = 0, results = [], node; node = nodes[i]; i++)
- h.concat(results, Element.nextSiblings(node));
- return results;
- },
-
- nextElementSibling: function(node) {
- while (node = node.nextSibling)
- if (node.nodeType == 1) return node;
- return null;
- },
-
- previousElementSibling: function(node) {
- while (node = node.previousSibling)
- if (node.nodeType == 1) return node;
- return null;
- },
-
- // TOKEN FUNCTIONS
- tagName: function(nodes, root, tagName, combinator) {
- tagName = tagName.toUpperCase();
- var results = [], h = Selector.handlers;
- if (nodes) {
- if (combinator) {
- // fastlane for ordinary descendant combinators
- if (combinator == "descendant") {
- for (var i = 0, node; node = nodes[i]; i++)
- h.concat(results, node.getElementsByTagName(tagName));
- return results;
- } else nodes = this[combinator](nodes);
- if (tagName == "*") return nodes;
- }
- for (var i = 0, node; node = nodes[i]; i++)
- if (node.tagName.toUpperCase() == tagName) results.push(node);
- return results;
- } else return root.getElementsByTagName(tagName);
- },
-
- id: function(nodes, root, id, combinator) {
- var targetNode = $(id), h = Selector.handlers;
- if (!nodes && root == document) return targetNode ? [targetNode] : [];
- if (nodes) {
- if (combinator) {
- if (combinator == 'child') {
- for (var i = 0, node; node = nodes[i]; i++)
- if (targetNode.parentNode == node) return [targetNode];
- } else if (combinator == 'descendant') {
- for (var i = 0, node; node = nodes[i]; i++)
- if (Element.descendantOf(targetNode, node)) return [targetNode];
- } else if (combinator == 'adjacent') {
- for (var i = 0, node; node = nodes[i]; i++)
- if (Selector.handlers.previousElementSibling(targetNode) == node)
- return [targetNode];
- } else nodes = h[combinator](nodes);
- }
- for (var i = 0, node; node = nodes[i]; i++)
- if (node == targetNode) return [targetNode];
- return [];
- }
- return (targetNode && Element.descendantOf(targetNode, root)) ? [targetNode] : [];
- },
-
- className: function(nodes, root, className, combinator) {
- if (nodes && combinator) nodes = this[combinator](nodes);
- return Selector.handlers.byClassName(nodes, root, className);
- },
-
- byClassName: function(nodes, root, className) {
- if (!nodes) nodes = Selector.handlers.descendant([root]);
- var needle = ' ' + className + ' ';
- for (var i = 0, results = [], node, nodeClassName; node = nodes[i]; i++) {
- nodeClassName = node.className;
- if (nodeClassName.length == 0) continue;
- if (nodeClassName == className || (' ' + nodeClassName + ' ').include(needle))
- results.push(node);
- }
- return results;
- },
-
- attrPresence: function(nodes, root, attr) {
- var results = [];
- for (var i = 0, node; node = nodes[i]; i++)
- if (Element.hasAttribute(node, attr)) results.push(node);
- return results;
- },
-
- attr: function(nodes, root, attr, value, operator) {
- if (!nodes) nodes = root.getElementsByTagName("*");
- var handler = Selector.operators[operator], results = [];
- for (var i = 0, node; node = nodes[i]; i++) {
- var nodeValue = Element.readAttribute(node, attr);
- if (nodeValue === null) continue;
- if (handler(nodeValue, value)) results.push(node);
- }
- return results;
- },
-
- pseudo: function(nodes, name, value, root, combinator) {
- if (nodes && combinator) nodes = this[combinator](nodes);
- if (!nodes) nodes = root.getElementsByTagName("*");
- return Selector.pseudos[name](nodes, value, root);
- }
- },
-
- pseudos: {
- 'first-child': function(nodes, value, root) {
- for (var i = 0, results = [], node; node = nodes[i]; i++) {
- if (Selector.handlers.previousElementSibling(node)) continue;
- results.push(node);
- }
- return results;
- },
- 'last-child': function(nodes, value, root) {
- for (var i = 0, results = [], node; node = nodes[i]; i++) {
- if (Selector.handlers.nextElementSibling(node)) continue;
- results.push(node);
- }
- return results;
- },
- 'only-child': function(nodes, value, root) {
- var h = Selector.handlers;
- for (var i = 0, results = [], node; node = nodes[i]; i++)
- if (!h.previousElementSibling(node) && !h.nextElementSibling(node))
- results.push(node);
- return results;
- },
- 'nth-child': function(nodes, formula, root) {
- return Selector.pseudos.nth(nodes, formula, root);
- },
- 'nth-last-child': function(nodes, formula, root) {
- return Selector.pseudos.nth(nodes, formula, root, true);
- },
- 'nth-of-type': function(nodes, formula, root) {
- return Selector.pseudos.nth(nodes, formula, root, false, true);
- },
- 'nth-last-of-type': function(nodes, formula, root) {
- return Selector.pseudos.nth(nodes, formula, root, true, true);
- },
- 'first-of-type': function(nodes, formula, root) {
- return Selector.pseudos.nth(nodes, "1", root, false, true);
- },
- 'last-of-type': function(nodes, formula, root) {
- return Selector.pseudos.nth(nodes, "1", root, true, true);
- },
- 'only-of-type': function(nodes, formula, root) {
- var p = Selector.pseudos;
- return p['last-of-type'](p['first-of-type'](nodes, formula, root), formula, root);
- },
-
- // handles the an+b logic
- getIndices: function(a, b, total) {
- if (a == 0) return b > 0 ? [b] : [];
- return $R(1, total).inject([], function(memo, i) {
- if (0 == (i - b) % a && (i - b) / a >= 0) memo.push(i);
- return memo;
- });
- },
-
- // handles nth(-last)-child, nth(-last)-of-type, and (first|last)-of-type
- nth: function(nodes, formula, root, reverse, ofType) {
- if (nodes.length == 0) return [];
- if (formula == 'even') formula = '2n+0';
- if (formula == 'odd') formula = '2n+1';
- var h = Selector.handlers, results = [], indexed = [], m;
- h.mark(nodes);
- for (var i = 0, node; node = nodes[i]; i++) {
- if (!node.parentNode._counted) {
- h.index(node.parentNode, reverse, ofType);
- indexed.push(node.parentNode);
- }
- }
- if (formula.match(/^\d+$/)) { // just a number
- formula = Number(formula);
- for (var i = 0, node; node = nodes[i]; i++)
- if (node.nodeIndex == formula) results.push(node);
- } else if (m = formula.match(/^(-?\d*)?n(([+-])(\d+))?/)) { // an+b
- if (m[1] == "-") m[1] = -1;
- var a = m[1] ? Number(m[1]) : 1;
- var b = m[2] ? Number(m[2]) : 0;
- var indices = Selector.pseudos.getIndices(a, b, nodes.length);
- for (var i = 0, node, l = indices.length; node = nodes[i]; i++) {
- for (var j = 0; j < l; j++)
- if (node.nodeIndex == indices[j]) results.push(node);
- }
- }
- h.unmark(nodes);
- h.unmark(indexed);
- return results;
- },
-
- 'empty': function(nodes, value, root) {
- for (var i = 0, results = [], node; node = nodes[i]; i++) {
- // IE treats comments as element nodes
- if (node.tagName == '!' || (node.firstChild && !node.innerHTML.match(/^\s*$/))) continue;
- results.push(node);
- }
- return results;
- },
-
- 'not': function(nodes, selector, root) {
- var h = Selector.handlers, selectorType, m;
- var exclusions = new Selector(selector).findElements(root);
- h.mark(exclusions);
- for (var i = 0, results = [], node; node = nodes[i]; i++)
- if (!node._counted) results.push(node);
- h.unmark(exclusions);
- return results;
- },
-
- 'enabled': function(nodes, value, root) {
- for (var i = 0, results = [], node; node = nodes[i]; i++)
- if (!node.disabled) results.push(node);
- return results;
- },
-
- 'disabled': function(nodes, value, root) {
- for (var i = 0, results = [], node; node = nodes[i]; i++)
- if (node.disabled) results.push(node);
- return results;
- },
-
- 'checked': function(nodes, value, root) {
- for (var i = 0, results = [], node; node = nodes[i]; i++)
- if (node.checked) results.push(node);
- return results;
- }
- },
-
- operators: {
- '=': function(nv, v) { return nv == v; },
- '!=': function(nv, v) { return nv != v; },
- '^=': function(nv, v) { return nv.startsWith(v); },
- '$=': function(nv, v) { return nv.endsWith(v); },
- '*=': function(nv, v) { return nv.include(v); },
- '~=': function(nv, v) { return (' ' + nv + ' ').include(' ' + v + ' '); },
- '|=': function(nv, v) { return ('-' + nv.toUpperCase() + '-').include('-' + v.toUpperCase() + '-'); }
- },
-
- matchElements: function(elements, expression) {
- var matches = new Selector(expression).findElements(), h = Selector.handlers;
- h.mark(matches);
- for (var i = 0, results = [], element; element = elements[i]; i++)
- if (element._counted) results.push(element);
- h.unmark(matches);
- return results;
- },
-
- findElement: function(elements, expression, index) {
- if (typeof expression == 'number') {
- index = expression; expression = false;
- }
- return Selector.matchElements(elements, expression || '*')[index || 0];
- },
-
- findChildElements: function(element, expressions) {
- var exprs = expressions.join(','), expressions = [];
- exprs.scan(/(([\w#:.~>+()\s-]+|\*|\[.*?\])+)\s*(,|$)/, function(m) {
- expressions.push(m[1].strip());
- });
- var results = [], h = Selector.handlers;
- for (var i = 0, l = expressions.length, selector; i < l; i++) {
- selector = new Selector(expressions[i].strip());
- h.concat(results, selector.findElements(element));
- }
- return (l > 1) ? h.unique(results) : results;
- }
-});
-
-function $$() {
- return Selector.findChildElements(document, $A(arguments));
-}
-var Form = {
- reset: function(form) {
- $(form).reset();
- return form;
- },
-
- serializeElements: function(elements, getHash) {
- var data = elements.inject({}, function(result, element) {
- if (!element.disabled && element.name) {
- var key = element.name, value = $(element).getValue();
- if (value != null) {
- if (key in result) {
- if (result[key].constructor != Array) result[key] = [result[key]];
- result[key].push(value);
- }
- else result[key] = value;
- }
- }
- return result;
- });
-
- return getHash ? data : Hash.toQueryString(data);
- }
-};
-
-Form.Methods = {
- serialize: function(form, getHash) {
- return Form.serializeElements(Form.getElements(form), getHash);
- },
-
- getElements: function(form) {
- return $A($(form).getElementsByTagName('*')).inject([],
- function(elements, child) {
- if (Form.Element.Serializers[child.tagName.toLowerCase()])
- elements.push(Element.extend(child));
- return elements;
- }
- );
- },
-
- getInputs: function(form, typeName, name) {
- form = $(form);
- var inputs = form.getElementsByTagName('input');
-
- if (!typeName && !name) return $A(inputs).map(Element.extend);
-
- for (var i = 0, matchingInputs = [], length = inputs.length; i < length; i++) {
- var input = inputs[i];
- if ((typeName && input.type != typeName) || (name && input.name != name))
- continue;
- matchingInputs.push(Element.extend(input));
- }
-
- return matchingInputs;
- },
-
- disable: function(form) {
- form = $(form);
- Form.getElements(form).invoke('disable');
- return form;
- },
-
- enable: function(form) {
- form = $(form);
- Form.getElements(form).invoke('enable');
- return form;
- },
-
- findFirstElement: function(form) {
- return $(form).getElements().find(function(element) {
- return element.type != 'hidden' && !element.disabled &&
- ['input', 'select', 'textarea'].include(element.tagName.toLowerCase());
- });
- },
-
- focusFirstElement: function(form) {
- form = $(form);
- form.findFirstElement().activate();
- return form;
- },
-
- request: function(form, options) {
- form = $(form), options = Object.clone(options || {});
-
- var params = options.parameters;
- options.parameters = form.serialize(true);
-
- if (params) {
- if (typeof params == 'string') params = params.toQueryParams();
- Object.extend(options.parameters, params);
- }
-
- if (form.hasAttribute('method') && !options.method)
- options.method = form.method;
-
- return new Ajax.Request(form.readAttribute('action'), options);
- }
-}
-
-/*--------------------------------------------------------------------------*/
-
-Form.Element = {
- focus: function(element) {
- $(element).focus();
- return element;
- },
-
- select: function(element) {
- $(element).select();
- return element;
- }
-}
-
-Form.Element.Methods = {
- serialize: function(element) {
- element = $(element);
- if (!element.disabled && element.name) {
- var value = element.getValue();
- if (value != undefined) {
- var pair = {};
- pair[element.name] = value;
- return Hash.toQueryString(pair);
- }
- }
- return '';
- },
-
- getValue: function(element) {
- element = $(element);
- var method = element.tagName.toLowerCase();
- return Form.Element.Serializers[method](element);
- },
-
- clear: function(element) {
- $(element).value = '';
- return element;
- },
-
- present: function(element) {
- return $(element).value != '';
- },
-
- activate: function(element) {
- element = $(element);
- try {
- element.focus();
- if (element.select && (element.tagName.toLowerCase() != 'input' ||
- !['button', 'reset', 'submit'].include(element.type)))
- element.select();
- } catch (e) {}
- return element;
- },
-
- disable: function(element) {
- element = $(element);
- element.blur();
- element.disabled = true;
- return element;
- },
-
- enable: function(element) {
- element = $(element);
- element.disabled = false;
- return element;
- }
-}
-
-/*--------------------------------------------------------------------------*/
-
-var Field = Form.Element;
-var $F = Form.Element.Methods.getValue;
-
-/*--------------------------------------------------------------------------*/
-
-Form.Element.Serializers = {
- input: function(element) {
- switch (element.type.toLowerCase()) {
- case 'checkbox':
- case 'radio':
- return Form.Element.Serializers.inputSelector(element);
- default:
- return Form.Element.Serializers.textarea(element);
- }
- },
-
- inputSelector: function(element) {
- return element.checked ? element.value : null;
- },
-
- textarea: function(element) {
- return element.value;
- },
-
- select: function(element) {
- return this[element.type == 'select-one' ?
- 'selectOne' : 'selectMany'](element);
- },
-
- selectOne: function(element) {
- var index = element.selectedIndex;
- return index >= 0 ? this.optionValue(element.options[index]) : null;
- },
-
- selectMany: function(element) {
- var values, length = element.length;
- if (!length) return null;
-
- for (var i = 0, values = []; i < length; i++) {
- var opt = element.options[i];
- if (opt.selected) values.push(this.optionValue(opt));
- }
- return values;
- },
-
- optionValue: function(opt) {
- // extend element because hasAttribute may not be native
- return Element.extend(opt).hasAttribute('value') ? opt.value : opt.text;
- }
-}
-
-/*--------------------------------------------------------------------------*/
-
-Abstract.TimedObserver = function() {}
-Abstract.TimedObserver.prototype = {
- initialize: function(element, frequency, callback) {
- this.frequency = frequency;
- this.element = $(element);
- this.callback = callback;
-
- this.lastValue = this.getValue();
- this.registerCallback();
- },
-
- registerCallback: function() {
- setInterval(this.onTimerEvent.bind(this), this.frequency * 1000);
- },
-
- onTimerEvent: function() {
- var value = this.getValue();
- var changed = ('string' == typeof this.lastValue && 'string' == typeof value
- ? this.lastValue != value : String(this.lastValue) != String(value));
- if (changed) {
- this.callback(this.element, value);
- this.lastValue = value;
- }
- }
-}
-
-Form.Element.Observer = Class.create();
-Form.Element.Observer.prototype = Object.extend(new Abstract.TimedObserver(), {
- getValue: function() {
- return Form.Element.getValue(this.element);
- }
-});
-
-Form.Observer = Class.create();
-Form.Observer.prototype = Object.extend(new Abstract.TimedObserver(), {
- getValue: function() {
- return Form.serialize(this.element);
- }
-});
-
-/*--------------------------------------------------------------------------*/
-
-Abstract.EventObserver = function() {}
-Abstract.EventObserver.prototype = {
- initialize: function(element, callback) {
- this.element = $(element);
- this.callback = callback;
-
- this.lastValue = this.getValue();
- if (this.element.tagName.toLowerCase() == 'form')
- this.registerFormCallbacks();
- else
- this.registerCallback(this.element);
- },
-
- onElementEvent: function() {
- var value = this.getValue();
- if (this.lastValue != value) {
- this.callback(this.element, value);
- this.lastValue = value;
- }
- },
-
- registerFormCallbacks: function() {
- Form.getElements(this.element).each(this.registerCallback.bind(this));
- },
-
- registerCallback: function(element) {
- if (element.type) {
- switch (element.type.toLowerCase()) {
- case 'checkbox':
- case 'radio':
- Event.observe(element, 'click', this.onElementEvent.bind(this));
- break;
- default:
- Event.observe(element, 'change', this.onElementEvent.bind(this));
- break;
- }
- }
- }
-}
-
-Form.Element.EventObserver = Class.create();
-Form.Element.EventObserver.prototype = Object.extend(new Abstract.EventObserver(), {
- getValue: function() {
- return Form.Element.getValue(this.element);
- }
-});
-
-Form.EventObserver = Class.create();
-Form.EventObserver.prototype = Object.extend(new Abstract.EventObserver(), {
- getValue: function() {
- return Form.serialize(this.element);
- }
-});
-if (!window.Event) {
- var Event = new Object();
-}
-
-Object.extend(Event, {
- KEY_BACKSPACE: 8,
- KEY_TAB: 9,
- KEY_RETURN: 13,
- KEY_ESC: 27,
- KEY_LEFT: 37,
- KEY_UP: 38,
- KEY_RIGHT: 39,
- KEY_DOWN: 40,
- KEY_DELETE: 46,
- KEY_HOME: 36,
- KEY_END: 35,
- KEY_PAGEUP: 33,
- KEY_PAGEDOWN: 34,
-
- element: function(event) {
- return $(event.target || event.srcElement);
- },
-
- isLeftClick: function(event) {
- return (((event.which) && (event.which == 1)) ||
- ((event.button) && (event.button == 1)));
- },
-
- pointerX: function(event) {
- return event.pageX || (event.clientX +
- (document.documentElement.scrollLeft || document.body.scrollLeft));
- },
-
- pointerY: function(event) {
- return event.pageY || (event.clientY +
- (document.documentElement.scrollTop || document.body.scrollTop));
- },
-
- stop: function(event) {
- if (event.preventDefault) {
- event.preventDefault();
- event.stopPropagation();
- } else {
- event.returnValue = false;
- event.cancelBubble = true;
- }
- },
-
- // find the first node with the given tagName, starting from the
- // node the event was triggered on; traverses the DOM upwards
- findElement: function(event, tagName) {
- var element = Event.element(event);
- while (element.parentNode && (!element.tagName ||
- (element.tagName.toUpperCase() != tagName.toUpperCase())))
- element = element.parentNode;
- return element;
- },
-
- observers: false,
-
- _observeAndCache: function(element, name, observer, useCapture) {
- if (!this.observers) this.observers = [];
- if (element.addEventListener) {
- this.observers.push([element, name, observer, useCapture]);
- element.addEventListener(name, observer, useCapture);
- } else if (element.attachEvent) {
- this.observers.push([element, name, observer, useCapture]);
- element.attachEvent('on' + name, observer);
- }
- },
-
- unloadCache: function() {
- if (!Event.observers) return;
- for (var i = 0, length = Event.observers.length; i < length; i++) {
- Event.stopObserving.apply(this, Event.observers[i]);
- Event.observers[i][0] = null;
- }
- Event.observers = false;
- },
-
- observe: function(element, name, observer, useCapture) {
- element = $(element);
- useCapture = useCapture || false;
-
- if (name == 'keypress' &&
- (Prototype.Browser.WebKit || element.attachEvent))
- name = 'keydown';
-
- Event._observeAndCache(element, name, observer, useCapture);
- },
-
- stopObserving: function(element, name, observer, useCapture) {
- element = $(element);
- useCapture = useCapture || false;
-
- if (name == 'keypress' &&
- (Prototype.Browser.WebKit || element.attachEvent))
- name = 'keydown';
-
- if (element.removeEventListener) {
- element.removeEventListener(name, observer, useCapture);
- } else if (element.detachEvent) {
- try {
- element.detachEvent('on' + name, observer);
- } catch (e) {}
- }
- }
-});
-
-/* prevent memory leaks in IE */
-if (Prototype.Browser.IE)
- Event.observe(window, 'unload', Event.unloadCache, false);
-var Position = {
- // set to true if needed, warning: firefox performance problems
- // NOT neeeded for page scrolling, only if draggable contained in
- // scrollable elements
- includeScrollOffsets: false,
-
- // must be called before calling withinIncludingScrolloffset, every time the
- // page is scrolled
- prepare: function() {
- this.deltaX = window.pageXOffset
- || document.documentElement.scrollLeft
- || document.body.scrollLeft
- || 0;
- this.deltaY = window.pageYOffset
- || document.documentElement.scrollTop
- || document.body.scrollTop
- || 0;
- },
-
- realOffset: function(element) {
- var valueT = 0, valueL = 0;
- do {
- valueT += element.scrollTop || 0;
- valueL += element.scrollLeft || 0;
- element = element.parentNode;
- } while (element);
- return [valueL, valueT];
- },
-
- cumulativeOffset: function(element) {
- var valueT = 0, valueL = 0;
- do {
- valueT += element.offsetTop || 0;
- valueL += element.offsetLeft || 0;
- element = element.offsetParent;
- } while (element);
- return [valueL, valueT];
- },
-
- positionedOffset: function(element) {
- var valueT = 0, valueL = 0;
- do {
- valueT += element.offsetTop || 0;
- valueL += element.offsetLeft || 0;
- element = element.offsetParent;
- if (element) {
- if(element.tagName=='BODY') break;
- var p = Element.getStyle(element, 'position');
- if (p == 'relative' || p == 'absolute') break;
- }
- } while (element);
- return [valueL, valueT];
- },
-
- offsetParent: function(element) {
- if (element.offsetParent) return element.offsetParent;
- if (element == document.body) return element;
-
- while ((element = element.parentNode) && element != document.body)
- if (Element.getStyle(element, 'position') != 'static')
- return element;
-
- return document.body;
- },
-
- // caches x/y coordinate pair to use with overlap
- within: function(element, x, y) {
- if (this.includeScrollOffsets)
- return this.withinIncludingScrolloffsets(element, x, y);
- this.xcomp = x;
- this.ycomp = y;
- this.offset = this.cumulativeOffset(element);
-
- return (y >= this.offset[1] &&
- y < this.offset[1] + element.offsetHeight &&
- x >= this.offset[0] &&
- x < this.offset[0] + element.offsetWidth);
- },
-
- withinIncludingScrolloffsets: function(element, x, y) {
- var offsetcache = this.realOffset(element);
-
- this.xcomp = x + offsetcache[0] - this.deltaX;
- this.ycomp = y + offsetcache[1] - this.deltaY;
- this.offset = this.cumulativeOffset(element);
-
- return (this.ycomp >= this.offset[1] &&
- this.ycomp < this.offset[1] + element.offsetHeight &&
- this.xcomp >= this.offset[0] &&
- this.xcomp < this.offset[0] + element.offsetWidth);
- },
-
- // within must be called directly before
- overlap: function(mode, element) {
- if (!mode) return 0;
- if (mode == 'vertical')
- return ((this.offset[1] + element.offsetHeight) - this.ycomp) /
- element.offsetHeight;
- if (mode == 'horizontal')
- return ((this.offset[0] + element.offsetWidth) - this.xcomp) /
- element.offsetWidth;
- },
-
- page: function(forElement) {
- var valueT = 0, valueL = 0;
-
- var element = forElement;
- do {
- valueT += element.offsetTop || 0;
- valueL += element.offsetLeft || 0;
-
- // Safari fix
- if (element.offsetParent == document.body)
- if (Element.getStyle(element,'position')=='absolute') break;
-
- } while (element = element.offsetParent);
-
- element = forElement;
- do {
- if (!window.opera || element.tagName=='BODY') {
- valueT -= element.scrollTop || 0;
- valueL -= element.scrollLeft || 0;
- }
- } while (element = element.parentNode);
-
- return [valueL, valueT];
- },
-
- clone: function(source, target) {
- var options = Object.extend({
- setLeft: true,
- setTop: true,
- setWidth: true,
- setHeight: true,
- offsetTop: 0,
- offsetLeft: 0
- }, arguments[2] || {})
-
- // find page position of source
- source = $(source);
- var p = Position.page(source);
-
- // find coordinate system to use
- target = $(target);
- var delta = [0, 0];
- var parent = null;
- // delta [0,0] will do fine with position: fixed elements,
- // position:absolute needs offsetParent deltas
- if (Element.getStyle(target,'position') == 'absolute') {
- parent = Position.offsetParent(target);
- delta = Position.page(parent);
- }
-
- // correct by body offsets (fixes Safari)
- if (parent == document.body) {
- delta[0] -= document.body.offsetLeft;
- delta[1] -= document.body.offsetTop;
- }
-
- // set position
- if(options.setLeft) target.style.left = (p[0] - delta[0] + options.offsetLeft) + 'px';
- if(options.setTop) target.style.top = (p[1] - delta[1] + options.offsetTop) + 'px';
- if(options.setWidth) target.style.width = source.offsetWidth + 'px';
- if(options.setHeight) target.style.height = source.offsetHeight + 'px';
- },
-
- absolutize: function(element) {
- element = $(element);
- if (element.style.position == 'absolute') return;
- Position.prepare();
-
- var offsets = Position.positionedOffset(element);
- var top = offsets[1];
- var left = offsets[0];
- var width = element.clientWidth;
- var height = element.clientHeight;
-
- element._originalLeft = left - parseFloat(element.style.left || 0);
- element._originalTop = top - parseFloat(element.style.top || 0);
- element._originalWidth = element.style.width;
- element._originalHeight = element.style.height;
-
- element.style.position = 'absolute';
- element.style.top = top + 'px';
- element.style.left = left + 'px';
- element.style.width = width + 'px';
- element.style.height = height + 'px';
- },
-
- relativize: function(element) {
- element = $(element);
- if (element.style.position == 'relative') return;
- Position.prepare();
-
- element.style.position = 'relative';
- var top = parseFloat(element.style.top || 0) - (element._originalTop || 0);
- var left = parseFloat(element.style.left || 0) - (element._originalLeft || 0);
-
- element.style.top = top + 'px';
- element.style.left = left + 'px';
- element.style.height = element._originalHeight;
- element.style.width = element._originalWidth;
- }
-}
-
-// Safari returns margins on body which is incorrect if the child is absolutely
-// positioned. For performance reasons, redefine Position.cumulativeOffset for
-// KHTML/WebKit only.
-if (Prototype.Browser.WebKit) {
- Position.cumulativeOffset = function(element) {
- var valueT = 0, valueL = 0;
- do {
- valueT += element.offsetTop || 0;
- valueL += element.offsetLeft || 0;
- if (element.offsetParent == document.body)
- if (Element.getStyle(element, 'position') == 'absolute') break;
-
- element = element.offsetParent;
- } while (element);
-
- return [valueL, valueT];
- }
-}
-
-Element.addMethods(); \ No newline at end of file
diff --git a/html/xo-color.xml b/html/xo-color.xml
deleted file mode 100644
index f7d118e..0000000
--- a/html/xo-color.xml
+++ /dev/null
@@ -1,970 +0,0 @@
-<html xmlns="http://www.w3.org/1999/xhtml">
-<head>
- <title>change the XO colors and shape</title>
-
-<!--
-Author: Walter Bender (walter@laptop.org)
-(CC-PD) Public Domain (do what you want to do...)
-
-<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" [
- <!ENTITY ns_svg "http://www.w3.org/2000/svg">
- <!ENTITY ns_xlink "http://www.w3.org/1999/xlink">
-]>
--->
-
-
-
-
-// SVG version of OLPC XO man color changer and shape shifter
-// Created by: Walter Bender (walter@laptop.org) on 27 January 2007
-// Last modified by: Walter Bender (walter@laptop.org) on 26 May 2009
-// Color tool designed in memory of: Nat Jacobson
-// ajax hooks: Erik Blankinship (erikb@mediamods.com) on 15 August 2007
-
-<script type="text/javascript">
-<![CDATA[
- var screenW = 1200, screenH = 900;
-
- var fillcolors = [
- // red, orange, yellow, green, blue, purple
- "rgb(255,43,52)", "rgb(255,143,0)", "rgb(248,232,0)", "rgb(0,234,17)", "rgb(0,160,255)", "rgb(172,50,255)"
- ];
-
- var strokecolors = [
- // M A+ C- C C+ A-
- // dark fill
- // red
- "rgb(178,0,8)", "rgb(154,82,0)", "rgb(128,117,0)", "rgb(0,128,9)", "rgb(0,88,140)", "rgb(94,0,140)",
- // orange
- "rgb(154,82,0)", "rgb(128,117,0)", "rgb(0,128,9)", "rgb(0,88,140)", "rgb(94,0,140)", "rgb(178,0,8)",
- // yellow
- "rgb(128,117,0)", "rgb(0,128,9)", "rgb(0,88,140)", "rgb(94,0,140)", "rgb(178,0,8)", "rgb(154,82,0)",
- // green
- "rgb(0,128,9)", "rgb(0,88,140)", "rgb(94,0,140)", "rgb(178,0,8)", "rgb(154,82,0)", "rgb(128,117,0)",
- // blue
- "rgb(0,88,140)", "rgb(94,0,140)", "rgb(178,0,8)", "rgb(154,82,0)", "rgb(128,117,0)", "rgb(0,128,9)",
- // purple
- "rgb(94,0,140)", "rgb(178,0,8)", "rgb(154,82,0)", "rgb(128,117,0)", "rgb(0,128,9)", "rgb(0,88,140)",
-
- // medium fill
- // red
- "rgb(230,0,10)", "rgb(255,143,0)", "rgb(190,158,0)", "rgb(0,178,13)", "rgb(0,95,228)", "rgb(127,0,191)",
- // orange
- "rgb(201,126,0)", "rgb(190,158,0)", "rgb(0,178,13)", "rgb(0,95,228)", "rgb(167,0,255)", "rgb(255,43,52)",
- // yellow
- "rgb(190,158,0)", "rgb(0,234,17)", "rgb(0,160,255)", "rgb(172,50,255)", "rgb(255,43,52)", "rgb(255,143,0)",
- // green
- "rgb(0,178,13)", "rgb(0,95,228)", "rgb(127,0,191)", "rgb(255,43,52)", "rgb(255,143,0)", "rgb(190,158,0)",
- // blue
- "rgb(0,95,228)", "rgb(153,0,230)", "rgb(255,43,52)", "rgb(255,143,0)", "rgb(190,158,0)", "rgb(0,178,13)",
- // purple
- "rgb(127,0,191)", "rgb(255,43,52)", "rgb(255,143,0)", "rgb(190,158,0)", "rgb(0,178,13)", "rgb(0,95,228)",
-
- // light fill
- // red
- "rgb(255,173,206)", "rgb(255,193,105)", "rgb(248,232,0)", "rgb(139,255,122)", "rgb(188,205,255)", "rgb(209,163,255)",
- // orange
- "rgb(255,193,105)", "rgb(248,232,0)", "rgb(139,255,122)", "rgb(188,205,255)", "rgb(209,163,255)", "rgb(255,173,206)",
- // yellow
- "rgb(255,250,0)", "rgb(139,255,122)", "rgb(188,206,255)", "rgb(209,163,255)", "rgb(255,173,206)", "rgb(255,193,105)",
- // green
- "rgb(139,255,122)", "rgb(188,205,255)", "rgb(209,163,255)", "rgb(255,173,206)", "rgb(255,193,105)", "rgb(248,232,0)",
- // blue
- "rgb(188,205,255)", "rgb(209,163,255)", "rgb(255,173,206)", "rgb(255,193,105)", "rgb(248,232,0)", "rgb(139,255,122)",
- // purple
- "rgb(209,163,255)", "rgb(255,173,206)", "rgb(255,193,105)", "rgb(248,232,0)", "rgb(139,255,122)", "rgb(188,205,255)"
- ];
-
-// stroke values
-var strokeLight = 2;
-var strokeMedium = 1;
-var strokeDark = 0;
-var strokeCurrent = strokeMedium;
-
-//
-var flip = 0;
-var square = 0;
-var xoff = 0;
-var yoff = 2;
-
-// color variables
-var strokeH = 0;
-var fillH = 0;
-
-// Sugar stuff
-// gridbox centers
-var grid = [37.5, 112.5, 187.5, 262.5, 337.5, 412.5, 485.5, 562.5, 637.5, 712.5, 785.5, 862.5, 937.5, 1012.5, 1087.5, 1162.5];
-var radius = 22.5;
-var strokeW = 9.5;
-
-var circlex1 = [0,1,2,3,4,5];
-var circley1 = [0,1,2,3,4,5];
-var circlex2 = [0,1,2,3,4,5];
-var circley2 = [0,1,2,3,4,5];
-var circlex3 = [0,1,2,3,4,5];
-var circley3 = [0,1,2,3,4,5];
-var circlex4 = [0,1,2,3,4,5];
-var circley4 = [0,1,2,3,4,5];
-var circlex5 = [0,1,2,3,4,5];
-var circley5 = [0,1,2,3,4,5];
-var circlex6 = [0,1,2,3,4,5];
-var circley6 = [0,1,2,3,4,5];
-
-// Stuff needed for moving the xo man end and knot points
-var xoL1X1=554.5;
-var xoL1Y1=448;
-var xoL1X2=645.5;
-var xoL1Y2=357;
-var xoL1K1X=580;
-var xoL1K1Y=420.5;
-var xoL1K2X=620;
-var xoL1K2Y=380.5;
-var xoL2X1=554.5;
-var xoL2Y1=357;
-var xoL2X2=645.5;
-var xoL2Y2=448;
-var xoL2K1X=580;
-var xoL2K1Y=380.5;
-var xoL2K2X=620;
-var xoL2K2Y=420.5;
-var xoCX=600;
-var xoCY=318.5;
-var xoL1X1Reset=554.5;
-var xoL1Y1Reset=448;
-var xoL1X2Reset=645.5;
-var xoL1Y2Reset=357;
-var xoL1K1XReset=580;
-var xoL1K1YReset=420.5;
-var xoL1K2XReset=620;
-var xoL1K2YReset=380.5;
-var xoL2X1Reset=554.5;
-var xoL2Y1Reset=357;
-var xoL2X2Reset=645.5;
-var xoL2Y2Reset=448;
-var xoL2K1XReset=580;
-var xoL2K1YReset=380.5;
-var xoL2K2XReset=620;
-var xoL2K2YReset=420.5;
-var xoCXReset=600;
-var xoCYReset=318.5;
-var xoCenterX = (xoL1X1+xoL1X2)/2;
-var xoCenterY = (xoL1Y1+xoL1Y2)/2;
-var moveOn=0;
-var moveID="";
-
-// calculate circle coordinates
-function sincos (evt) {
-var a;
-var i;
-var r1=75;
-var r2=245;
-var cx = [0,1,2,3,4,5];
-var cy = [0,1,2,3,4,5];
-
-
- for( i=0; i< 6; i++ )
- {
- a = 1.05;
- a *= i;
- cx[i] = 600-r2*Math.sin(a);
- cy[i] = 375-r2*Math.cos(a);
- }
-
- for( i=0; i< 6; i++ )
- {
- a = 1.05;
- a *= i;
- circlex1[i] = r1*Math.sin(a)+cx[0];
- circley1[i] = r1*Math.cos(a)+cy[0];
- circlex2[i] = r1*Math.sin(a)+cx[1];
- circley2[i] = r1*Math.cos(a)+cy[1];
- circlex3[i] = r1*Math.sin(a)+cx[2];
- circley3[i] = r1*Math.cos(a)+cy[2];
- circlex4[i] = r1*Math.sin(a)+cx[3];
- circley4[i] = r1*Math.cos(a)+cy[3];
- circlex5[i] = r1*Math.sin(a)+cx[4];
- circley5[i] = r1*Math.cos(a)+cy[4];
- circlex6[i] = r1*Math.sin(a)+cx[5];
- circley6[i] = r1*Math.cos(a)+cy[5];
- }
-}
-
-function positionButton(evt,id,x,y) {
- e = evt.target.ownerDocument.getElementById(id);
- e.setAttribute("cx",grid[x]);
- e.setAttribute("cy",grid[y]);
-}
-
-function positionButtonOffset(evt,id,x,y) {
- if( y < 0 ) { y+=6; }
- e = evt.target.ownerDocument.getElementById(id);
- e.setAttribute("cx",grid[x+xoff]);
- e.setAttribute("cy",grid[y+yoff]);
-}
-
-function positionCircle(evt,id,r,a) {
- if( a > -1 && a < 6 )
- {
- e = evt.target.ownerDocument.getElementById(id);
- switch (r)
- {
- case 0:
- e.setAttribute("cx",circlex1[a]);
- e.setAttribute("cy",circley1[a]);
- break;
- case 1:
- e.setAttribute("cx",circlex2[a]);
- e.setAttribute("cy",circley2[a]);
- break;
- case 2:
- e.setAttribute("cx",circlex3[a]);
- e.setAttribute("cy",circley3[a]);
- break;
- case 3:
- e.setAttribute("cx",circlex4[a]);
- e.setAttribute("cy",circley4[a]);
- break;
- case 4:
- e.setAttribute("cx",circlex5[a]);
- e.setAttribute("cy",circley5[a]);
- break;
- case 5:
- e.setAttribute("cx",circlex6[a]);
- e.setAttribute("cy",circley6[a]);
- break;
- default :
- }
- }
-}
-
-function buttonInit(evt) {
- if( square == 1 )
- {
- buttonInitSquare(evt);
- } else {
- buttonInitHex(evt);
- }
-
-}
-
-// scale and position buttons in circles
-function buttonInitHex(evt) {
-
- positionCircle(evt,"X",0,0);
-
- positionCircle(evt,"R",0,0);
- positionCircle(evt,"YR",1,1);
- positionCircle(evt,"Y",2,2);
- positionCircle(evt,"G",3,3);
- positionCircle(evt,"B",4,4);
- positionCircle(evt,"P",5,5);
-
- positionCircle(evt,"RAm",0,1);
- positionCircle(evt,"YRAm",1,2);
- positionCircle(evt,"YAm",2,3);
- positionCircle(evt,"GAm",3,4);
- positionCircle(evt,"BAm",4,5);
- positionCircle(evt,"PAm",5,0);
-
- positionCircle(evt,"RCp",0,2);
- positionCircle(evt,"YRCp",1,3);
- positionCircle(evt,"YCp",2,4);
- positionCircle(evt,"GCp",3,5);
- positionCircle(evt,"BCp",4,0);
- positionCircle(evt,"PCp",5,1);
-
- positionCircle(evt,"RC",0,3);
- positionCircle(evt,"YRC",1,4);
- positionCircle(evt,"YC",2,5);
- positionCircle(evt,"GC",3,0);
- positionCircle(evt,"BC",4,1);
- positionCircle(evt,"PC",5,2);
-
- positionCircle(evt,"RCm",0,4);
- positionCircle(evt,"YRCm",1,5);
- positionCircle(evt,"YCm",2,0);
- positionCircle(evt,"GCm",3,1);
- positionCircle(evt,"BCm",4,2);
- positionCircle(evt,"PCm",5,3);
-
- positionCircle(evt,"RAp",0,5);
- positionCircle(evt,"YRAp",1,0);
- positionCircle(evt,"YAp",2,1);
- positionCircle(evt,"GAp",3,2);
- positionCircle(evt,"BAp",4,3);
- positionCircle(evt,"PAp",5,4);
-}
-
-// scale and position buttons on grid (col,row)
-function buttonInitSquare(evt) {
-
- positionButtonOffset(evt,"X",0,0);
-
- positionButtonOffset(evt, "R",0,0);
- positionButtonOffset(evt, "YR",5,5);
- positionButtonOffset(evt, "Y",4,4);
- positionButtonOffset(evt, "G",3,3);
- positionButtonOffset(evt, "B",2,2);
- positionButtonOffset(evt, "P",1,1);
-
- positionButtonOffset(evt, "RAm",0,1);
- positionButtonOffset(evt,"YRAm",5,0);
- positionButtonOffset(evt, "YAm",4,5);
- positionButtonOffset(evt, "GAm",3,4);
- positionButtonOffset(evt, "BAm",2,3);
- positionButtonOffset(evt, "PAm",1,2);
-
- positionButtonOffset(evt, "RCp",0,2);
- positionButtonOffset(evt,"YRCp",5,1);
- positionButtonOffset(evt, "YCp",4,0);
- positionButtonOffset(evt, "GCp",3,5);
- positionButtonOffset(evt, "BCp",2,4);
- positionButtonOffset(evt, "PCp",1,3);
-
- positionButtonOffset(evt, "RC",0,3);
- positionButtonOffset(evt, "YRC",5,2);
- positionButtonOffset(evt, "YC",4,1);
- positionButtonOffset(evt, "GC",3,0);
- positionButtonOffset(evt, "BC",2,5);
- positionButtonOffset(evt, "PC",1,4);
-
- positionButtonOffset(evt, "RCm",0,4);
- positionButtonOffset(evt,"YRCm",5,3);
- positionButtonOffset(evt, "YCm",4,2);
- positionButtonOffset(evt, "GCm",3,1);
- positionButtonOffset(evt, "BCm",2,0);
- positionButtonOffset(evt, "PCm",1,5);
-
- positionButtonOffset(evt, "RAp",0,5);
- positionButtonOffset(evt,"YRAp",5,4);
- positionButtonOffset(evt, "YAp",4,3);
- positionButtonOffset(evt, "GAp",3,2);
- positionButtonOffset(evt, "BAp",2,1);
- positionButtonOffset(evt, "PAp",1,0);
-}
-
-// recompute button color
-// fill hue is 0,1,2,3,4,5 for r,o,y,g,b,p
-// stroke hue is 0,1,2,3,4,5 for m,a+,c-,c,c+,a- plus an offset of 6*fillhue and 36*valuelevel
-function colorButton(evt,id,fh,sh,sv) {
-var e;
- e = evt.target.ownerDocument.getElementById(id);
- if( flip == 0 )
- {
- e.setAttribute("stroke",strokecolors[fh*6+sv*36+sh]);
- e.setAttribute("fill",fillcolors[fh]);
- } else {
- e.setAttribute("fill",strokecolors[fh*6+sv*36+sh]);
- e.setAttribute("stroke",fillcolors[fh]);
- }
-}
-
-// update XO man and all buttons based on current hue and value
-function colorUpdate(evt) {
-var e;
-var tmp;
-
- // update XO Man
- colorButton(evt,"Circle",fillH,strokeH,strokeCurrent);
- colorButton(evt,"iconCircle",fillH,strokeH,strokeCurrent);
- if( flip == 0 )
- {
- e = evt.target.ownerDocument.getElementById("Line1");
- e.setAttribute("stroke",strokecolors[fillH*6+strokeCurrent*36+strokeH]);
- e = evt.target.ownerDocument.getElementById("Line2");
- e.setAttribute("stroke",strokecolors[fillH*6+strokeCurrent*36+strokeH]);
- e = evt.target.ownerDocument.getElementById("Fill1");
- e.setAttribute("stroke",fillcolors[fillH]);
- e = evt.target.ownerDocument.getElementById("Fill2");
- e.setAttribute("stroke",fillcolors[fillH]);
- e = evt.target.ownerDocument.getElementById("iconLine1");
- e.setAttribute("stroke",strokecolors[fillH*6+strokeCurrent*36+strokeH]);
- e = evt.target.ownerDocument.getElementById("iconLine2");
- e.setAttribute("stroke",strokecolors[fillH*6+strokeCurrent*36+strokeH]);
- e = evt.target.ownerDocument.getElementById("iconFill1");
- e.setAttribute("stroke",fillcolors[fillH]);
- e = evt.target.ownerDocument.getElementById("iconFill2");
- e.setAttribute("stroke",fillcolors[fillH]);
- } else {
- e = evt.target.ownerDocument.getElementById("Line1");
- e.setAttribute("stroke",fillcolors[fillH]);
- e = evt.target.ownerDocument.getElementById("Line2");
- e.setAttribute("stroke",fillcolors[fillH]);
- e = evt.target.ownerDocument.getElementById("Fill1");
- e.setAttribute("stroke",strokecolors[fillH*6+strokeCurrent*36+strokeH]);
- e = evt.target.ownerDocument.getElementById("Fill2");
- e.setAttribute("stroke",strokecolors[fillH*6+strokeCurrent*36+strokeH]);
- e = evt.target.ownerDocument.getElementById("iconLine1");
- e.setAttribute("stroke",fillcolors[fillH]);
- e = evt.target.ownerDocument.getElementById("iconLine2");
- e.setAttribute("stroke",fillcolors[fillH]);
- e = evt.target.ownerDocument.getElementById("iconFill1");
- e.setAttribute("stroke",strokecolors[fillH*6+strokeCurrent*36+strokeH]);
- e = evt.target.ownerDocument.getElementById("iconFill2");
- e.setAttribute("stroke",strokecolors[fillH*6+strokeCurrent*36+strokeH]);
- }
-
- tmp = flip;
- flip = 0;
- colorButton(evt,"vd",fillH,strokeH,strokeDark);
- colorButton(evt,"vm",fillH,strokeH,strokeMedium);
- colorButton(evt,"vl",fillH,strokeH,strokeLight);
- flip = 1;
- colorButton(evt,"vdf",fillH,strokeH,strokeDark);
- colorButton(evt,"vmf",fillH,strokeH,strokeMedium);
- flip = tmp;
-
- colorButton(evt,"R",0,0,strokeCurrent);
- colorButton(evt,"YR",1,0,strokeCurrent);
- colorButton(evt,"Y",2,0,strokeCurrent);
- colorButton(evt,"G",3,0,strokeCurrent);
- colorButton(evt,"B",4,0,strokeCurrent);
- colorButton(evt,"P",5,0,strokeCurrent);
- colorButton(evt,"RAp",0,1,strokeCurrent);
- colorButton(evt,"YRAp",1,1,strokeCurrent);
- colorButton(evt,"YAp",2,1,strokeCurrent);
- colorButton(evt,"GAp",3,1,strokeCurrent);
- colorButton(evt,"BAp",4,1,strokeCurrent);
- colorButton(evt,"PAp",5,1,strokeCurrent);
- colorButton(evt,"RCm",0,2,strokeCurrent);
- colorButton(evt,"YRCm",1,2,strokeCurrent);
- colorButton(evt,"YCm",2,2,strokeCurrent);
- colorButton(evt,"GCm",3,2,strokeCurrent);
- colorButton(evt,"BCm",4,2,strokeCurrent);
- colorButton(evt,"PCm",5,2,strokeCurrent);
- colorButton(evt,"RC",0,3,strokeCurrent);
- colorButton(evt,"YRC",1,3,strokeCurrent);
- colorButton(evt,"YC",2,3,strokeCurrent);
- colorButton(evt,"GC",3,3,strokeCurrent);
- colorButton(evt,"BC",4,3,strokeCurrent);
- colorButton(evt,"PC",5,3,strokeCurrent);
- colorButton(evt,"RCp",0,4,strokeCurrent);
- colorButton(evt,"YRCp",1,4,strokeCurrent);
- colorButton(evt,"YCp",2,4,strokeCurrent);
- colorButton(evt,"GCp",3,4,strokeCurrent);
- colorButton(evt,"BCp",4,4,strokeCurrent);
- colorButton(evt,"PCp",5,4,strokeCurrent);
- colorButton(evt,"RAm",0,5,strokeCurrent);
- colorButton(evt,"YRAm",1,5,strokeCurrent);
- colorButton(evt,"YAm",2,5,strokeCurrent);
- colorButton(evt,"GAm",3,5,strokeCurrent);
- colorButton(evt,"BAm",4,5,strokeCurrent);
- colorButton(evt,"PAm",5,5,strokeCurrent);
-
- saveXo()
-}
-
-function saveXo( )
-{
- var upXoDude = document.getElementById('upXo');
- var xos = "";
- for (var i=0; i<upXoDude.childNodes.length; i++)
- { xoi = upXoDude.childNodes[i];
- if (xoi.nodeType == 1)
- { xos = xos + "<" + xoi.nodeName + " ";
- for (var j=0; j<xoi.attributes.length; j++)
- { xoj = xoi.attributes[j];
- xos = xos + xoj.nodeName + "=\"" + xoj.nodeValue + "\" ";
- }
- xos = xos+ "/>";
- }
- }
-
- //alert( xos );
- new Ajax.Request( 'saveXo', {method:'get', parameters:'upXo='+xos} );
-}
-
-// individual button functions
-function updater(evt,fh,dh,a) {
- fillHUndo = fillH;
- fillH = fh;
- strokeHUndo = strokeH;
- strokeH = dh;
- if( square == 1 )
- {
- // a complete kludge because the order of the grid
- // does not reflect the order of the delta hues
- switch(fh)
- {
- case 0:
- if( dh > 0 ) { dh = 6-dh; }
- positionButtonOffset(evt,"X",0,dh);
- break;
- case 1:
- positionButtonOffset(evt,"X",5,5-dh);
- break;
- case 2:
- positionButtonOffset(evt,"X",4,4-dh);
- break;
- case 3:
- positionButtonOffset(evt,"X",3,3-dh);
- break;
- case 4:
- positionButtonOffset(evt,"X",2,2-dh);
- break;
- case 5:
- positionButtonOffset(evt,"X",1,1-dh);
- break;
- }
- } else {
- // a kludge of a different sort fo the similar reasons as above
- positionCircle(evt,"X",fh,a);
- }
- colorUpdate(evt);
-}
-
-function valueDark(evt) {
- strokeCurrent = strokeDark;
- flip = 0;
- e = evt.target.ownerDocument.getElementById("bgd");
- e.setAttribute("visibility","visible");
- e = evt.target.ownerDocument.getElementById("bgdf");
- e.setAttribute("visibility","hidden");
- e = evt.target.ownerDocument.getElementById("bgm");
- e.setAttribute("visibility","hidden");
- e = evt.target.ownerDocument.getElementById("bgmf");
- e.setAttribute("visibility","hidden");
- e = evt.target.ownerDocument.getElementById("bgl");
- e.setAttribute("visibility","hidden");
- colorUpdate(evt);
-}
-
-function valueDarkFlip(evt) {
- strokeCurrent = strokeDark;
- flip = 1;
- e = evt.target.ownerDocument.getElementById("bgd");
- e.setAttribute("visibility","hidden");
- e = evt.target.ownerDocument.getElementById("bgdf");
- e.setAttribute("visibility","visible");
- e = evt.target.ownerDocument.getElementById("bgm");
- e.setAttribute("visibility","hidden");
- e = evt.target.ownerDocument.getElementById("bgmf");
- e.setAttribute("visibility","hidden");
- e = evt.target.ownerDocument.getElementById("bgl");
- e.setAttribute("visibility","hidden");
- colorUpdate(evt);
-}
-
-function valueMedium(evt) {
- strokeCurrent = strokeMedium;
- flip = 0;
- e = evt.target.ownerDocument.getElementById("bgd");
- e.setAttribute("visibility","hidden");
- e = evt.target.ownerDocument.getElementById("bgdf");
- e.setAttribute("visibility","hidden");
- e = evt.target.ownerDocument.getElementById("bgm");
- e.setAttribute("visibility","visible");
- e = evt.target.ownerDocument.getElementById("bgmf");
- e.setAttribute("visibility","hidden");
- e = evt.target.ownerDocument.getElementById("bgl");
- e.setAttribute("visibility","hidden");
- colorUpdate(evt);
-}
-
-function valueMediumFlip(evt) {
- strokeCurrent = strokeMedium;
- flip = 1;
- e = evt.target.ownerDocument.getElementById("bgd");
- e.setAttribute("visibility","hidden");
- e = evt.target.ownerDocument.getElementById("bgdf");
- e.setAttribute("visibility","hidden");
- e = evt.target.ownerDocument.getElementById("bgm");
- e.setAttribute("visibility","hidden");
- e = evt.target.ownerDocument.getElementById("bgmf");
- e.setAttribute("visibility","visible");
- e = evt.target.ownerDocument.getElementById("bgl");
- e.setAttribute("visibility","hidden");
- colorUpdate(evt);
-}
-
-function valueLight(evt) {
- strokeCurrent = strokeLight;
- flip = 0;
- e = evt.target.ownerDocument.getElementById("bgd");
- e.setAttribute("visibility","hidden");
- e = evt.target.ownerDocument.getElementById("bgdf");
- e.setAttribute("visibility","hidden");
- e = evt.target.ownerDocument.getElementById("bgm");
- e.setAttribute("visibility","hidden");
- e = evt.target.ownerDocument.getElementById("bgmf");
- e.setAttribute("visibility","hidden");
- e = evt.target.ownerDocument.getElementById("bgl");
- e.setAttribute("visibility","visible");
- colorUpdate(evt);
-}
-
-function hexGrid(evt) {
- square = 0;
- e = evt.target.ownerDocument.getElementById("bgsq");
- e.setAttribute("visibility","hidden");
- e = evt.target.ownerDocument.getElementById("bghex");
- e.setAttribute("visibility","visible");
- buttonInit(evt);
-}
-
-function sqGrid(evt) {
- square = 1;
- e = evt.target.ownerDocument.getElementById("bgsq");
- e.setAttribute("visibility","visible");
- e = evt.target.ownerDocument.getElementById("bghex");
- e.setAttribute("visibility","hidden");
- buttonInit(evt);
-}
-
-function background(evt,a) {
- e = evt.target.ownerDocument.getElementById("backgroundW");
- if( a == 0 )
- {
- e.setAttribute("visibility","visible");
- e = evt.target.ownerDocument.getElementById("backgroundXO");
- e.setAttribute("fill","rgb(255,255,255)");
- } else {
- e.setAttribute("visibility","hidden");
- }
- e = evt.target.ownerDocument.getElementById("backgroundL");
- if( a == 1 )
- {
- e.setAttribute("visibility","visible");
- e = evt.target.ownerDocument.getElementById("backgroundXO");
- e.setAttribute("fill","rgb(231,231,233)");
- } else {
- e.setAttribute("visibility","hidden");
- }
- e = evt.target.ownerDocument.getElementById("backgroundM");
- if( a == 2 )
- {
- e.setAttribute("visibility","visible");
- e = evt.target.ownerDocument.getElementById("backgroundXO");
- e.setAttribute("fill","rgb(76,77,79)");
- } else {
- e.setAttribute("visibility","hidden");
- }
- e = evt.target.ownerDocument.getElementById("backgroundK");
- if( a == 3 )
- {
- e.setAttribute("visibility","visible");
- e = evt.target.ownerDocument.getElementById("backgroundXO");
- e.setAttribute("fill","rgb(0,0,0)");
- } else {
- e.setAttribute("visibility","hidden");
- }
-}
-
-
-// the rest of these functions are for moving knot points
-function showpoints(evt)
-{
-var e;
-
- e = evt.target.ownerDocument.getElementById("L1Knot1");
- e.setAttribute("visibility", "visible");
- e.setAttribute("cx",xoL1K1X);
- e.setAttribute("cy",xoL1K1Y);
- e = evt.target.ownerDocument.getElementById("L1Knot2");
- e.setAttribute("visibility", "visible");
- e.setAttribute("cx",xoL1K2X);
- e.setAttribute("cy",xoL1K2Y);
- e = evt.target.ownerDocument.getElementById("L2Knot1");
- e.setAttribute("visibility", "visible");
- e.setAttribute("cx",xoL2K1X);
- e.setAttribute("cy",xoL2K1Y);
- e = evt.target.ownerDocument.getElementById("L2Knot2");
- e.setAttribute("visibility", "visible");
- e.setAttribute("cx",xoL2K2X);
- e.setAttribute("cy",xoL2K2Y);
- e = evt.target.ownerDocument.getElementById("L1End1");
- e.setAttribute("visibility", "visible");
- e.setAttribute("cx",xoL1X1);
- e.setAttribute("cy",xoL1Y1);
- e = evt.target.ownerDocument.getElementById("L2End1");
- e.setAttribute("visibility", "visible");
- e.setAttribute("cx",xoL2X1);
- e.setAttribute("cy",xoL2Y1);
- e = evt.target.ownerDocument.getElementById("L1End2");
- e.setAttribute("visibility", "visible");
- e.setAttribute("cx",xoL1X2);
- e.setAttribute("cy",xoL1Y2);
- e = evt.target.ownerDocument.getElementById("L2End2");
- e.setAttribute("visibility", "visible");
- e.setAttribute("cx",xoL2X2);
- e.setAttribute("cy",xoL2Y2);
- e = evt.target.ownerDocument.getElementById("Center");
- e.setAttribute("visibility", "visible");
- e.setAttribute("cx",xoCX);
- e.setAttribute("cy",xoCY);
-}
-
-function hidepoints(evt)
-{
- e = evt.target.ownerDocument.getElementById("L1Knot1");
- e.setAttribute("visibility", "hidden");
- e = evt.target.ownerDocument.getElementById("L1Knot2");
- e.setAttribute("visibility", "hidden");
- e = evt.target.ownerDocument.getElementById("L2Knot1");
- e.setAttribute("visibility", "hidden");
- e = evt.target.ownerDocument.getElementById("L2Knot2");
- e.setAttribute("visibility", "hidden");
- e = evt.target.ownerDocument.getElementById("L1End1");
- e.setAttribute("visibility", "hidden");
- e = evt.target.ownerDocument.getElementById("L1End2");
- e.setAttribute("visibility", "hidden");
- e = evt.target.ownerDocument.getElementById("L2End1");
- e.setAttribute("visibility", "hidden");
- e = evt.target.ownerDocument.getElementById("L2End2");
- e.setAttribute("visibility", "hidden");
- e = evt.target.ownerDocument.getElementById("Center");
- e.setAttribute("visibility", "hidden");
-}
-
-// moves are constrained by level and restricted to XO box
-function move(evt)
-{
-var x,y;
-
- if( moveOn == 1 )
- {
- //bug, see: http://dev.laptop.org/ticket/1657
- //need to test on an XO, but the following code seems to do the correct thing in jhbuild
-
- x = evt.clientX;
- if( screen.width < 1200 )
- {
- x *= 1200;
- x /= screen.width;
- }
- y = evt.clientY;
- if( screen.height < 900 )
- {
- y *= 900;
- y /= screen.height;
- }
-
- if( x < (xoCenterX-80) ) { x = xoCenterX-80; }
- if( x > (xoCenterX+80) ) { x = xoCenterX+80; }
- if( y < (xoCenterY-100) ) { y = xoCenterY-100; }
- if( y > (xoCenterY+80) ) { y = xoCenterY+80; }
- e = evt.target.ownerDocument.getElementById(moveID);
- e.setAttribute("cx",x);
- e.setAttribute("cy",y);
- switch (moveID)
- {
- case "Center":
- xoCX = x;
- xoCY = y;
- break;
- case "L1End1":
- xoL1X1 = x;
- xoL1Y1 = y;
- break;
- case "L1End2":
- xoL1X2 = x;
- xoL1Y2 = y;
- break;
- case "L2End1":
- xoL2X1 = x;
- xoL2Y1 = y;
- break;
- case "L2End2":
- xoL2X2 = x;
- xoL2Y2 = y;
- break;
- case "L1Knot1":
- xoL1K1X = x;
- xoL1K1Y = y;
- break;
- case "L1Knot2":
- xoL1K2X = x;
- xoL1K2Y = y;
- break;
- case "L2Knot1":
- xoL2K1X = x;
- xoL2K1Y = y;
- break;
- case "L2Knot2":
- xoL2K2X = x;
- xoL2K2Y = y;
- break;
- default :
- }
- }
-}
-
-function setID (evt, id)
-{
- moveID = id;
-}
-
-function startmove(evt)
-{
- moveOn = 1;
-}
-
-function stopmove(evt)
-{
- moveOn = 0;
- moveID = "";
- e = evt.target.ownerDocument.getElementById("Circle");
- e.setAttribute("cx",xoCX);
- e.setAttribute("cy",xoCY);
- e = evt.target.ownerDocument.getElementById("Line1");
- e.setAttribute("d", "M"+xoL1X1+","+xoL1Y1+" C"+xoL1K1X+","+xoL1K1Y+" "+xoL1K2X+","+xoL1K2Y+" "+xoL1X2+","+xoL1Y2);
- e = evt.target.ownerDocument.getElementById("Fill1");
- e.setAttribute("d", "M"+xoL1X1+","+xoL1Y1+" C"+xoL1K1X+","+xoL1K1Y+" "+xoL1K2X+","+xoL1K2Y+" "+xoL1X2+","+xoL1Y2);
- e = evt.target.ownerDocument.getElementById("Line2");
- e.setAttribute("d", "M"+xoL2X1+","+xoL2Y1+" C"+xoL2K1X+","+xoL2K1Y+" "+xoL2K2X+","+xoL2K2Y+" "+xoL2X2+","+xoL2Y2);
- e = evt.target.ownerDocument.getElementById("Fill2");
- e.setAttribute("d", "M"+xoL2X1+","+xoL2Y1+" C"+xoL2K1X+","+xoL2K1Y+" "+xoL2K2X+","+xoL2K2Y+" "+xoL2X2+","+xoL2Y2);
-}
-
-function resetXO (evt)
-{
-xoL1X1=xoL1X1Reset;
-xoL1Y1=xoL1Y1Reset;
-xoL1X2=xoL1X2Reset;
-xoL1Y2=xoL1Y2Reset;
-xoL1K1X=xoL1K1XReset;
-xoL1K1Y=xoL1K1YReset;
-xoL1K2X=xoL1K2XReset;
-xoL1K2Y=xoL1K2YReset;
-xoL2X1=xoL2X1Reset;
-xoL2Y1=xoL2Y1Reset;
-xoL2X2=xoL2X2Reset;
-xoL2Y2=xoL2Y2Reset;
-xoL2K1X=xoL2K1XReset;
-xoL2K1Y=xoL2K1YReset;
-xoL2K2X=xoL2K2XReset;
-xoL2K2Y=xoL2K2YReset;
-xoCX=xoCXReset;
-xoCY=xoCYReset;
-
-stopmove(evt);
-}
-
-]]>
-</script>
-<script src="prototype.js" type="text/javascript"></script>
-</head>
-
-<body>
-<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www,w3,org/1999/xlink" onload="colorUpdate(evt); sincos(evt); buttonInit(evt)" viewBox="0 0 1200 900">
-
-
-// SVG elements
-// begin backgrounds
- <rect id="backgroundM" width="1200" height="900" x="0" y="0" fill="rgb(76,77,79)" stroke="rgb(76,77,79)" stroke-width="1" visibility="hidden" />
- <rect id="backgroundL" width="1200" height="900" x="0" y="0" fill="rgb(231,231,233)" stroke="rgb(231,231,233)" stroke-width="1" visibility="hidden" />
- <rect id="backgroundW" width="1200" height="900" x="0" y="0" fill="rgb(255,255,255)" stroke="rgb(255,255,255)" stroke-width="1" visibility="hidden" />
- <rect id="backgroundK" width="1200" height="900" x="0" y="0" fill="rgb(0,0,0)" stroke="rgb(0,0,0)" stroke-width="1" visibility="visible" />
-// end background
-
-// start XO group
-<g onmouseover="showpoints(evt)" onmouseout="hidepoints(evt)" onmousedown="startmove(evt)" onmouseup="stopmove(evt)" onmousemove="move(evt)" onkeyup="textProcess(evt)">
-
-// XO-man background
-<rect id="backgroundXO" width="240" height="260" x="480" y="250" fill="rgb(0,0,0)" stroke="none" visibility="visible" />
-
-<g id="upXo"> // begin XO man
-<path id="Line1" d="M645.5,357 C600,400.5 600,400.5 554.5,448" stroke="rgb(216,75,24)" stroke-width="37" stroke-linecap="round" fill="none" visibility="visible" />
-<path id="Line2" d="M645.5,448 C600,400.5 600,400.5 554.5,357" stroke="rgb(216,75,24)" stroke-width="37" stroke-linecap="round" fill="none" visibility="visible" />
-<path id="Fill1" d="M645.5,357 C600,400.5 600,400.5 554.5,448" stroke="rgb(52,192,210)" stroke-width="19" stroke-linecap="round" fill="none" visibility="visible" />
-<path id="Fill2" d="M645.5,448 C600,400.5 600,400.5 554.5,357" stroke="rgb(52,192,210)" stroke-width="19" stroke-linecap="round" fill="none" visibility="visible" />
-<circle id="Circle" cx="600" cy="318.5" r="28.5" fill="rgb(52,192,210)" stroke="rgb(216,75,24)" stroke-width="9" visibility="visible" />
-</g> // end XO man
-<g>
-// knot points
-<circle id="L1Knot1" cx="112.5" cy="112.5" r="12" fill="rgb(255,255,0)" stroke="rgb(0,0,0)" stroke-width="3" visibility="hidden" onmousedown="setID(evt,'L1Knot1')" />
-<circle id="L1Knot2" cx="112.5" cy="112.5" r="12" fill="rgb(255,255,0)" stroke="rgb(0,0,0)" stroke-width="3" visibility="hidden" onmousedown="setID(evt,'L1Knot2')" />
-<circle id="L2Knot1" cx="112.5" cy="112.5" r="12" fill="rgb(255,0,255)" stroke="rgb(0,0,0)" stroke-width="3" visibility="hidden" onmousedown="setID(evt,'L2Knot1')" />
-<circle id="L2Knot2" cx="112.5" cy="112.5" r="12" fill="rgb(255,0,255)" stroke="rgb(0,0,0)" stroke-width="3" visibility="hidden" onmousedown="setID(evt,'L2Knot2')" />
-// end points
-<circle id="L1End1" cx="112.5" cy="112.5" r="12" fill="rgb(255,255,0)" stroke="rgb(0,0,0)" stroke-width="3" visibility="hidden" onmousedown="setID(evt,'L1End1')" />
-<circle id="L1End2" cx="112.5" cy="112.5" r="12" fill="rgb(255,255,0)" stroke="rgb(0,0,0)" stroke-width="3" visibility="hidden" onmousedown="setID(evt,'L1End2')" />
-<circle id="L2End1" cx="112.5" cy="112.5" r="12" fill="rgb(255,0,255)" stroke="rgb(0,0,0)" stroke-width="3" visibility="hidden" onmousedown="setID(evt,'L2End1')" />
-<circle id="L2End2" cx="112.5" cy="112.5" r="12" fill="rgb(255,0,255)" stroke="rgb(0,0,0)" stroke-width="3" visibility="hidden" onmousedown="setID(evt,'L2End2')" />
-// center point
-<circle id="Center" cx="112.5" cy="112.5" r="12" fill="rgb(0,255,255)" stroke="rgb(0,0,0)" stroke-width="3" visibility="hidden" onmousedown="setID(evt,'Center')" />
-// end knot points
-</g>
-</g>
-// end XO group
-
-// "cursor"
-<circle id="X" title="X" alt="X marks the spot" cx="0" cy="0" r="36" stroke="rgb(160,160,160)" fill="rgb(160,160,160)" stroke-width="9.5" visibility="visible" />
-
-// color buttons
-<circle id="R" title="red" alt="red fill" cx="0" cy="0" r="22.5" stroke="rgb(0,0,0)" fill="rgb(0,0,0)" stroke-width="9.5" onclick="updater(evt,0,0,0)" visibility="visible" />
-<circle id="YR" title="orange" alt="orange fill" cx="0" cy="0" r="22.5" stroke="rgb(0,0,0)" fill="rgb(0,0,0)" stroke-width="9.5" onclick="updater(evt,1,0,1)" visibility="visible" />
-<circle id="Y" title="yellow" alt="yellow fill" cx="0" cy="0" r="22.5" stroke="rgb(0,0,0)" fill="rgb(0,0,0)" stroke-width="9.5" onclick="updater(evt,2,0,2)" visibility="visible" />
-<circle id="G" title="green" alt="green fill" cx="0" cy="0" r="22.5" stroke="rgb(0,0,0)" fill="rgb(0,0,0)" stroke-width="9.5" onclick="updater(evt,3,0,3)" visibility="visible" />
-<circle id="B" title="blue" alt="blue fill" cx="0" cy="0" r="22.5" stroke="rgb(0,0,0)" fill="rgb(0,0,0)" stroke-width="9.5" onclick="updater(evt,4,0,4)" visibility="visible" />
-<circle id="P" title="purple" alt="purple fill" cx="0" cy="0" r="22.5" stroke="rgb(0,0,0)" fill="rgb(0,0,0)" stroke-width="9.5" onclick="updater(evt,5,0,5)" visibility="visible" />
-
-<circle id="RC" title="red" alt="red fill" cx="0" cy="0" r="22.5" stroke="rgb(0,0,0)" fill="rgb(0,0,0)" stroke-width="9.5" onclick="updater(evt,0,3,3)" visibility="visible" />
-<circle id="YRC" title="orange" alt="orange fill" cx="0" cy="0" r="22.5" stroke="rgb(0,0,0)" fill="rgb(0,0,0)" stroke-width="9.5" onclick="updater(evt,1,3,4)" visibility="visible" />
-<circle id="YC" title="yellow" alt="yellow fill" cx="0" cy="0" r="22.5" stroke="rgb(0,0,0)" fill="rgb(0,0,0)" stroke-width="9.5" onclick="updater(evt,2,3,5)" visibility="visible" />
-<circle id="GC" title="green" alt="green fill" cx="0" cy="0" r="22.5" stroke="rgb(0,0,0)" fill="rgb(0,0,0)" stroke-width="9.5" onclick="updater(evt,3,3,0)" visibility="visible" />
-<circle id="BC" title="blue" alt="blue fill" cx="0" cy="0" r="22.5" stroke="rgb(0,0,0)" fill="rgb(0,0,0)" stroke-width="9.5" onclick="updater(evt,4,3,1)" visibility="visible" />
-<circle id="PC" title="purple" alt="purple fill" cx="0" cy="0" r="22.5" stroke="rgb(0,0,0)" fill="rgb(0,0,0)" stroke-width="9.5" onclick="updater(evt,5,3,2)" visibility="visible" />
-
-<circle id="RCp" title="red" alt="red fill" cx="0" cy="0" r="22.5" stroke="rgb(0,0,0)" fill="rgb(0,0,0)" stroke-width="9.5" onclick="updater(evt,0,4,2)" visibility="visible" />
-<circle id="YRCp" title="orange" alt="orange fill" cx="0" cy="0" r="22.5" stroke="rgb(0,0,0)" fill="rgb(0,0,0)" stroke-width="9.5" onclick="updater(evt,1,4,3)" visibility="visible" />
-<circle id="YCp" title="yellow" alt="yellow fill" cx="0" cy="0" r="22.5" stroke="rgb(0,0,0)" fill="rgb(0,0,0)" stroke-width="9.5" onclick="updater(evt,2,4,4)" visibility="visible" />
-<circle id="GCp" title="green" alt="green fill" cx="0" cy="0" r="22.5" stroke="rgb(0,0,0)" fill="rgb(0,0,0)" stroke-width="9.5" onclick="updater(evt,3,4,5)" visibility="visible" />
-<circle id="BCp" title="blue" alt="blue fill" cx="0" cy="0" r="22.5" stroke="rgb(0,0,0)" fill="rgb(0,0,0)" stroke-width="9.5" onclick="updater(evt,4,4,0)" visibility="visible" />
-<circle id="PCp" title="purple" alt="purple fill" cx="0" cy="0" r="22.5" stroke="rgb(0,0,0)" fill="rgb(0,0,0)" stroke-width="9.5" onclick="updater(evt,5,4,1)" visibility="visible" />
-
-<circle id="RCm" title="red" alt="red fill" cx="0" cy="0" r="22.5" stroke="rgb(0,0,0)" fill="rgb(0,0,0)" stroke-width="9.5" onclick="updater(evt,0,2,4)" visibility="visible" />
-<circle id="YRCm" title="orange" alt="orange fill" cx="0" cy="0" r="22.5" stroke="rgb(0,0,0)" fill="rgb(0,0,0)" stroke-width="9.5" onclick="updater(evt,1,2,5)" visibility="visible" />
-<circle id="YCm" title="yellow" alt="yellow fill" cx="0" cy="0" r="22.5" stroke="rgb(0,0,0)" fill="rgb(0,0,0)" stroke-width="9.5" onclick="updater(evt,2,2,0)" visibility="visible" />
-<circle id="GCm" title="green" alt="green fill" cx="0" cy="0" r="22.5" stroke="rgb(0,0,0)" fill="rgb(0,0,0)" stroke-width="9.5" onclick="updater(evt,3,2,1)" visibility="visible" />
-<circle id="BCm" title="blue" alt="blue fill" cx="0" cy="0" r="22.5" stroke="rgb(0,0,0)" fill="rgb(0,0,0)" stroke-width="9.5" onclick="updater(evt,4,2,2)" visibility="visible" />
-<circle id="PCm" title="purple" alt="purple fill" cx="0" cy="0" r="22.5" stroke="rgb(0,0,0)" fill="rgb(0,0,0)" stroke-width="9.5" onclick="updater(evt,5,2,3)" visibility="visible" />
-
-<circle id="RAp" title="red" alt="red fill" cx="0" cy="0" r="22.5" stroke="rgb(0,0,0)" fill="rgb(0,0,0)" stroke-width="9.5" onclick="updater(evt,0,1,5)" visibility="visible" />
-<circle id="YRAp" title="orange" alt="orange fill" cx="0" cy="0" r="22.5" stroke="rgb(0,0,0)" fill="rgb(0,0,0)" stroke-width="9.5" onclick="updater(evt,1,1,0)" visibility="visible" />
-<circle id="YAp" title="yellow" alt="yellow fill" cx="0" cy="0" r="22.5" stroke="rgb(0,0,0)" fill="rgb(0,0,0)" stroke-width="9.5" onclick="updater(evt,2,1,1)" visibility="visible" />
-<circle id="GAp" title="green" alt="green fill" cx="0" cy="0" r="22.5" stroke="rgb(0,0,0)" fill="rgb(0,0,0)" stroke-width="9.5" onclick="updater(evt,3,1,2)" visibility="visible" />
-<circle id="BAp" title="blue" alt="blue fill" cx="0" cy="0" r="22.5" stroke="rgb(0,0,0)" fill="rgb(0,0,0)" stroke-width="9.5" onclick="updater(evt,4,1,3)" visibility="visible" />
-<circle id="PAp" title="purple" alt="purple fill" cx="0" cy="0" r="22.5" stroke="rgb(0,0,0)" fill="rgb(0,0,0)" stroke-width="9.5" onclick="updater(evt,5,1,4)" visibility="visible" />
-
-<circle id="RAm" title="red" alt="red fill" cx="0" cy="0" r="22.5" stroke="rgb(0,0,0)" fill="rgb(0,0,0)" stroke-width="9.5" onclick="updater(evt,0,5,1)" visibility="visible" />
-<circle id="YRAm" title="orange" alt="orange fill" cx="0" cy="0" r="22.5" stroke="rgb(0,0,0)" fill="rgb(0,0,0)" stroke-width="9.5" onclick="updater(evt,1,5,2)" visibility="visible" />
-<circle id="YAm" title="yellow" alt="yellow fill" cx="0" cy="0" r="22.5" stroke="rgb(0,0,0)" fill="rgb(0,0,0)" stroke-width="9.5" onclick="updater(evt,2,5,3)" visibility="visible" />
-<circle id="GAm" title="green" alt="green fill" cx="0" cy="0" r="22.5" stroke="rgb(0,0,0)" fill="rgb(0,0,0)" stroke-width="9.5" onclick="updater(evt,3,5,4)" visibility="visible" />
-<circle id="BAm" title="blue" alt="blue fill" cx="0" cy="0" r="22.5" stroke="rgb(0,0,0)" fill="rgb(0,0,0)" stroke-width="9.5" onclick="updater(evt,4,5,5)" visibility="visible" />
-<circle id="PAm" title="purple" alt="purple fill" cx="0" cy="0" r="22.5" stroke="rgb(0,0,0)" fill="rgb(0,0,0)" stroke-width="9.5" onclick="updater(evt,5,5,0)" visibility="visible" />
-
-// controls
-<rect id="bgd" width="75" height="75" x="0" y="0" fill="rgb(160,160,160)" stroke="rgb(160,160,160)" stroke-width="1" visibility="hidden" />
-<rect id="bgdf" width="75" height="75" x="75" y="0" fill="rgb(160,160,160)" stroke="rgb(160,160,160)" stroke-width="1" visibility="hidden" />
-<rect id="bgm" width="75" height="75" x="150" y="0" fill="rgb(160,160,160)" stroke="rgb(160,160,160)" stroke-width="1" visibility="visible" />
-<rect id="bgmf" width="75" height="75" x="225" y="0" fill="rgb(160,160,160)" stroke="rgb(160,160,160)" stroke-width="1" visibility="hidden" />
-<rect id="bgl" width="75" height="75" x="300" y="0" fill="rgb(160,160,160)" stroke="rgb(160,160,160)" stroke-width="1" visibility="hidden" />
-<circle id="vd" title="dark" alt="dark stroke" cx="37.5" cy="37.5" r="22.5" stroke="rgb(0,0,0)" fill="rgb(0,0,0)" stroke-width="9.5" onclick="valueDark(evt)" visibility="visible" />
-<circle id="vdf" title="darkflip" alt="dark flip" cx="112.5" cy="37.5" r="22.5" stroke="rgb(0,0,0)" fill="rgb(0,0,0)" stroke-width="9.5" onclick="valueDarkFlip(evt)" visibility="visible" />
-<circle id="vm" title="medium" alt="medium stroke" cx="187.5" cy="37.5" r="22.5" stroke="rgb(0,0,0)" fill="rgb(0,0,0)" stroke-width="9.5" onclick="valueMedium(evt)" visibility="visible" />
-<circle id="vmf" title="mediumflip" alt="medium flip" cx="262.5" cy="37.5" r="22.5" stroke="rgb(0,0,0)" fill="rgb(0,0,0)" stroke-width="9.5" onclick="valueMediumFlip(evt)" visibility="visible" />
-<circle id="vl" title="light" alt="light stroke" cx="337.5" cy="37.5" r="22.5" stroke="rgb(0,0,0)" fill="rgb(0,0,0)" stroke-width="9.5" onclick="valueLight(evt)" visibility="visible" />
-
-<rect id="bghex" width="75" height="75" x="150" y="675" fill="rgb(160,160,160)" stroke="rgb(160,160,160)" stroke-width="1" visibility="visible" />
-<rect id="bgsq" width="75" height="75" x="75" y="675" fill="rgb(160,160,160)" stroke="rgb(160,160,160)" stroke-width="1" visibility="hidden" />
-<circle id="hex" title="hex grid" alt="hex grid" cx="187.5" cy="712.5" r="22.5" stroke="rgb(100,100,100)" fill="rgb(100,100,100)" stroke-width="9.5" onclick="hexGrid(evt)" visibility="visible" />
-<rect id="sq" title="square grid" alt="square gird" width="45" height="45" x="90" y="690" fill="rgb(100,100,100)" stroke="rgb(100,100,100)" stroke-width="1" onclick="sqGrid(evt)" visibility="visible" />
-
-<g onclick="resetXO(evt)"> // begin XO man icon
-<path id="iconLine1" d="M53,700 C37.5,715.5 37.5,715.5 22,731" stroke="rgb(230,0,10)" stroke-width="11.5" stroke-linecap="round" fill="none" visibility="visible" />
-<path id="iconLine2" d="M53,731 C37.5,715.5 37.5,715.5 22,700" stroke="rgb(230,0,10)" stroke-width="11.5" stroke-linecap="round" fill="none" visibility="visible" />
-<path id="iconFill1" d="M53,700 C37.5,715.5 37.5,715.5 22,731" stroke="rgb(255,43,52)" stroke-width="4.5" stroke-linecap="round" fill="none" visibility="visible" />
-<path id="iconFill2" d="M53,731 C37.5,715.5 37.5,715.5 22,700" stroke="rgb(255,43,52)" stroke-width="4.5" stroke-linecap="round" fill="none" visibility="visible" />
-<circle id="iconCircle" cx="37.5" cy="690" r="8" fill="rgb(255,43,52)" stroke="rgb(230,0,10)" stroke-width="3.5" visibility="visible" />
-</g> // end XO man icon
-
-// background controls
-
-<rect id="icon" width="75" height="75" x="1125" y="0" fill="rgb(255,255,255)" stroke="rgb(255,255,255)" stroke-width="1" visibility="visible" onclick="background(evt,0)" />
-<rect id="icon" width="75" height="75" x="1050" y="0" fill="rgb(231,231,233)" stroke="rgb(231,231,233)" stroke-width="1" visibility="visible" onclick="background(evt,1)" />
-<rect id="icon" width="75" height="75" x="975" y="0" fill="rgb(76,77,79)" stroke="rgb(76,77,79)" stroke-width="1" visibility="visible" onclick="background(evt,2)" />
-<rect id="icon" width="75" height="75" x="900" y="0" fill="rgb(0,0,0)" stroke="rgb(0,0,0)" stroke-width="1" visibility="visible" onclick="background(evt,3)" />
-</svg>
-</body>
-</html>
diff --git a/logic.py b/logic.py
deleted file mode 100644
index b035679..0000000
--- a/logic.py
+++ /dev/null
@@ -1,48 +0,0 @@
-#Copyright (c) 2007, Media Modifications Ltd.
-
-#Permission is hereby granted, free of charge, to any person obtaining a copy
-#of this software and associated documentation files (the "Software"), to deal
-#in the Software without restriction, including without limitation the rights
-#to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-#copies of the Software, and to permit persons to whom the Software is
-#furnished to do so, subject to the following conditions:
-
-#The above copyright notice and this permission notice shall be included in
-#all copies or substantial portions of the Software.
-
-#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-#IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-#FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-#AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-#LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-#OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-#THE SOFTWARE.
-
-
-from result import ServerResult
-import os
-import urllib
-
-class ServerLogic:
- def __init__(self, acty):
- self.acty = acty
-
- def doServerLogic(self, url, path, params):
- r = ServerResult()
-
- fileName = path[len(path)-1]
- if (fileName == "saveXo"):
- upXo = params[0][1]
- upXo = urllib.unquote(upXo)
- xoFile = open(os.path.join(self.acty.journalPath, "xo-dude.xml"), 'w')
- xoFile.write(upXo)
- xoFile.close()
- else:
- localfile = open(os.path.join(self.acty.htmlPath, fileName), 'r')
- localdata = localfile.read()
- localfile.close()
- r.txt = localdata
- #todo: dynamic mime type for js and xml, etc.
- r.headers.append( ("Content-type", "text/xml") )
-
- return r \ No newline at end of file
diff --git a/logic.pyc b/logic.pyc
deleted file mode 100644
index 371ac24..0000000
--- a/logic.pyc
+++ /dev/null
Binary files differ
diff --git a/result.py b/result.py
deleted file mode 100644
index 5dbef40..0000000
--- a/result.py
+++ /dev/null
@@ -1,25 +0,0 @@
-#Copyright (c) 2007, Media Modifications Ltd.
-
-#Permission is hereby granted, free of charge, to any person obtaining a copy
-#of this software and associated documentation files (the "Software"), to deal
-#in the Software without restriction, including without limitation the rights
-#to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-#copies of the Software, and to permit persons to whom the Software is
-#furnished to do so, subject to the following conditions:
-
-#The above copyright notice and this permission notice shall be included in
-#all copies or substantial portions of the Software.
-
-#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-#IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-#FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-#AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-#LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-#OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-#THE SOFTWARE.
-
-
-class ServerResult:
- def __init__(self):
- self.txt = ""
- self.headers = [] \ No newline at end of file
diff --git a/result.pyc b/result.pyc
deleted file mode 100644
index e3b4516..0000000
--- a/result.pyc
+++ /dev/null
Binary files differ
diff --git a/server.py b/server.py
deleted file mode 100644
index 25ffed8..0000000
--- a/server.py
+++ /dev/null
@@ -1,59 +0,0 @@
-#Copyright (c) 2007, Media Modifications Ltd.
-
-#Permission is hereby granted, free of charge, to any person obtaining a copy
-#of this software and associated documentation files (the "Software"), to deal
-#in the Software without restriction, including without limitation the rights
-#to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-#copies of the Software, and to permit persons to whom the Software is
-#furnished to do so, subject to the following conditions:
-
-#The above copyright notice and this permission notice shall be included in
-#all copies or substantial portions of the Software.
-
-#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-#IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-#FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-#AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-#LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-#OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-#THE SOFTWARE.
-
-
-from sugar import network
-import urlparse
-import urllib
-import posixpath
-
-class Server(network.GlibTCPServer):
- def __init__(self, server_address, acty):
- self.acty = acty
- network.GlibTCPServer.__init__(self, server_address, RegHandler)
-
-#RegHandler extends SimpleHTTPServer.py (in python 2.4)
-class RegHandler(network.ChunkedGlibHTTPRequestHandler):
- def do_POST( self ):
- self.translate_path()
-
- def do_GET( self ):
- self.translate_path()
-
- def translate_path(self):
- urlp = urlparse.urlparse(self.path)
-
- urls = urlp[2]
- urls = posixpath.normpath(urllib.unquote(urls))
- urlPath = urls.split('/')
- urlPath = filter(None, urlPath)
-
- params = urlp[4]
- parama = []
- allParams = params.split('&')
- for i in range (0, len(allParams)):
- parama.append(allParams[i].split('='))
-
- result = self.server.acty.slogic.doServerLogic(self.path,urlPath,parama)
- self.send_response(200)
- for i in range (0, len(result.headers)):
- self.send_header( result.headers[i][0], result.headers[i][1] )
- self.end_headers()
- self.wfile.write( result.txt ) \ No newline at end of file
diff --git a/server.pyc b/server.pyc
deleted file mode 100644
index a9badae..0000000
--- a/server.pyc
+++ /dev/null
Binary files differ
diff --git a/sprites.py b/sprites.py
new file mode 100644
index 0000000..2b8bb55
--- /dev/null
+++ b/sprites.py
@@ -0,0 +1,459 @@
+# -*- coding: utf-8 -*-
+
+#Copyright (c) 2007-8, Playful Invention Company.
+#Copyright (c) 2008-11 Walter Bender
+
+#Permission is hereby granted, free of charge, to any person obtaining a copy
+#of this software and associated documentation files (the "Software"), to deal
+#in the Software without restriction, including without limitation the rights
+#to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+#copies of the Software, and to permit persons to whom the Software is
+#furnished to do so, subject to the following conditions:
+
+#The above copyright notice and this permission notice shall be included in
+#all copies or substantial portions of the Software.
+
+#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+#IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+#FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+#AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+#LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+#OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+#THE SOFTWARE.
+
+'''
+
+sprites.py is a simple sprites library for managing graphics objects,
+'sprites', on a gtk.DrawingArea. It manages multiple sprites with
+methods such as move, hide, set_layer, etc.
+
+There are two classes:
+
+class Sprites maintains a collection of sprites
+class Sprite manages individual sprites within the collection.
+
+Example usage:
+ # Import the classes into your program.
+ from sprites import Sprites Sprite
+
+ # Create a new sprite collection associated with your widget
+ self.sprite_list = Sprites(widget)
+
+ # Create a "pixbuf" (in this example, from SVG).
+ my_pixbuf = svg_str_to_pixbuf("<svg>...some svg code...</svg>")
+
+ # Create a sprite at position x1, y1.
+ my_sprite = sprites.Sprite(self.sprite_list, x1, y1, my_pixbuf)
+
+ # Move the sprite to a new position.
+ my_sprite.move((x1+dx, y1+dy))
+
+ # Create another "pixbuf".
+ your_pixbuf = svg_str_to_pixbuf("<svg>...some svg code...</svg>")
+
+ # Create a sprite at position x2, y2.
+ your_sprite = sprites.Sprite(self.sprite_list, x2, y2, my_pixbuf)
+
+ # Assign the sprites to layers.
+ # In this example, your_sprite will be on top of my_sprite.
+ my_sprite.set_layer(100)
+ your_sprite.set_layer(200)
+
+ # Now put my_sprite on top of your_sprite.
+ my_sprite.set_layer(300)
+
+ cr = self.window.cairo_create()
+ # In your activity's do_expose_event, put in a call to redraw_sprites
+ self.sprites.redraw_sprites(event.area, cairo_context)
+
+# method for converting SVG to a gtk pixbuf
+def svg_str_to_pixbuf(svg_string):
+ pl = gtk.gdk.PixbufLoader('svg')
+ pl.write(svg_string)
+ pl.close()
+ pixbuf = pl.get_pixbuf()
+ return pixbuf
+
+'''
+
+import pygtk
+pygtk.require('2.0')
+import gtk
+import pango
+import pangocairo
+import cairo
+
+class Sprites:
+ ''' A class for the list of sprites and everything they share in common '''
+
+ def __init__(self, widget):
+ ''' Initialize an empty array of sprites '''
+ self.widget = widget
+ self.list = []
+ self.cr = None
+
+ def set_cairo_context(self, cr):
+ ''' Cairo context may be set or reset after __init__ '''
+ self.cr = cr
+
+ def get_sprite(self, i):
+ ''' Return a sprint from the array '''
+ if i < 0 or i > len(self.list) - 1:
+ return(None)
+ else:
+ return(self.list[i])
+
+ def length_of_list(self):
+ ''' How many sprites are there? '''
+ return(len(self.list))
+
+ def append_to_list(self, spr):
+ ''' Append a new sprite to the end of the list. '''
+ self.list.append(spr)
+
+ def insert_in_list(self, spr, i):
+ ''' Insert a sprite at position i. '''
+ if i < 0:
+ self.list.insert(0, spr)
+ elif i > len(self.list) - 1:
+ self.list.append(spr)
+ else:
+ self.list.insert(i, spr)
+
+ def remove_from_list(self, spr):
+ ''' Remove a sprite from the list. '''
+ if spr in self.list:
+ self.list.remove(spr)
+
+ def find_sprite(self, pos, inverse=False):
+ ''' Search based on (x, y) position. Return the 'top/first' one. '''
+ list = self.list[:]
+ if not inverse:
+ list.reverse()
+ for spr in list:
+ if spr.hit(pos):
+ return spr
+ return None
+
+ def redraw_sprites(self, area=None, cr=None):
+ ''' Redraw the sprites that intersect area. '''
+ # I think I need to do this to save Cairo some work
+ if cr is None:
+ cr = self.cr
+ else:
+ self.cr = cr
+ if cr is None:
+ print 'sprites.redraw_sprites: no Cairo context'
+ return
+ for spr in self.list:
+ if area == None:
+ spr.draw(cr=cr)
+ else:
+ intersection = spr.rect.intersect(area)
+ if intersection.width > 0 or intersection.height > 0:
+ spr.draw(cr=cr)
+
+
+class Sprite:
+ ''' A class for the individual sprites '''
+
+ def __init__(self, sprites, x, y, image):
+ ''' Initialize an individual sprite '''
+ self._sprites = sprites
+ self.save_xy = (x, y) # remember initial (x, y) position
+ self.rect = gtk.gdk.Rectangle(int(x), int(y), 0, 0)
+ self._scale = [12]
+ self._rescale = [True]
+ self._horiz_align = ["center"]
+ self._vert_align = ["middle"]
+ self._fd = None
+ self._bold = False
+ self._italic = False
+ self._color = None
+ self._margins = [0, 0, 0, 0]
+ self.layer = 100
+ self.labels = []
+ self.cached_surfaces = []
+ self._dx = [] # image offsets
+ self._dy = []
+ self.type = None
+ self.set_image(image)
+ self._sprites.append_to_list(self)
+
+ def set_image(self, image, i=0, dx=0, dy=0):
+ ''' Add an image to the sprite. '''
+ while len(self.cached_surfaces) < i + 1:
+ self.cached_surfaces.append(None)
+ self._dx.append(0)
+ self._dy.append(0)
+ self._dx[i] = dx
+ self._dy[i] = dy
+ if isinstance(image, gtk.gdk.Pixbuf) or \
+ isinstance(image, cairo.ImageSurface):
+ w = image.get_width()
+ h = image.get_height()
+ else:
+ w, h = image.get_size()
+ if i == 0: # Always reset width and height when base image changes.
+ self.rect.width = w + dx
+ self.rect.height = h + dy
+ else:
+ if w + dx > self.rect.width:
+ self.rect.width = w + dx
+ if h + dy > self.rect.height:
+ self.rect.height = h + dy
+ if isinstance(image, cairo.ImageSurface):
+ self.cached_surfaces[i] = image
+ else: # Convert to Cairo surface
+ surface = cairo.ImageSurface(
+ cairo.FORMAT_ARGB32, self.rect.width, self.rect.height)
+ context = cairo.Context(surface)
+ context = gtk.gdk.CairoContext(context)
+ context.set_source_pixbuf(image, 0, 0)
+ context.rectangle(0, 0, self.rect.width, self.rect.height)
+ context.fill()
+ self.cached_surfaces[i] = surface
+
+ def move(self, pos):
+ ''' Move to new (x, y) position '''
+ self.inval()
+ self.rect.x, self.rect.y = int(pos[0]), int(pos[1])
+ self.inval()
+
+ def move_relative(self, pos):
+ ''' Move to new (x+dx, y+dy) position '''
+ self.inval()
+ self.rect.x += int(pos[0])
+ self.rect.y += int(pos[1])
+ self.inval()
+
+ def get_xy(self):
+ ''' Return current (x, y) position '''
+ return (self.rect.x, self.rect.y)
+
+ def get_dimensions(self):
+ ''' Return current size '''
+ return (self.rect.width, self.rect.height)
+
+ def get_layer(self):
+ ''' Return current layer '''
+ return self.layer
+
+ def set_shape(self, image, i=0):
+ ''' Set the current image associated with the sprite '''
+ self.inval()
+ self.set_image(image, i)
+ self.inval()
+
+ def set_layer(self, layer=None):
+ ''' Set the layer for a sprite '''
+ self._sprites.remove_from_list(self)
+ if layer is not None:
+ self.layer = layer
+ for i in range(self._sprites.length_of_list()):
+ if layer < self._sprites.get_sprite(i).layer:
+ self._sprites.insert_in_list(self, i)
+ self.inval()
+ return
+ self._sprites.append_to_list(self)
+ self.inval()
+
+ def set_label(self, new_label, i=0):
+ ''' Set the label drawn on the sprite '''
+ self._extend_labels_array(i)
+ if type(new_label) is str or type(new_label) is unicode:
+ # pango doesn't like nulls
+ self.labels[i] = new_label.replace("\0", " ")
+ else:
+ self.labels[i] = str(new_label)
+ self.inval()
+
+ def set_margins(self, l=0, t=0, r=0, b=0):
+ ''' Set the margins for drawing the label '''
+ self._margins = [l, t, r, b]
+
+ def _extend_labels_array(self, i):
+ ''' Append to the labels attribute list '''
+ if self._fd is None:
+ self.set_font('Sans')
+ if self._color is None:
+ self._color = (0., 0., 0.)
+ while len(self.labels) < i + 1:
+ self.labels.append(" ")
+ self._scale.append(self._scale[0])
+ self._rescale.append(self._rescale[0])
+ self._horiz_align.append(self._horiz_align[0])
+ self._vert_align.append(self._vert_align[0])
+
+ def set_font(self, font):
+ ''' Set the font for a label '''
+ self._fd = pango.FontDescription(font)
+
+ def set_label_color(self, rgb):
+ ''' Set the font color for a label '''
+ COLORTABLE = {'black': '#000000', 'white': '#FFFFFF',
+ 'red': '#FF0000', 'yellow': '#FFFF00',
+ 'green': '#00FF00', 'cyan': '#00FFFF',
+ 'blue': '#0000FF', 'purple': '#FF00FF',
+ 'gray': '#808080'}
+ if rgb.lower() in COLORTABLE:
+ rgb = COLORTABLE[rgb.lower()]
+ # Convert from '#RRGGBB' to floats
+ self._color = (int('0x' + rgb[1:3], 16) / 256.,
+ int('0x' + rgb[3:5], 16) / 256.,
+ int('0x' + rgb[5:7], 16) / 256.)
+ return
+
+ def set_label_attributes(self, scale, rescale=True, horiz_align="center",
+ vert_align="middle", i=0):
+ ''' Set the various label attributes '''
+ self._extend_labels_array(i)
+ self._scale[i] = scale
+ self._rescale[i] = rescale
+ self._horiz_align[i] = horiz_align
+ self._vert_align[i] = vert_align
+
+ def hide(self):
+ ''' Hide a sprite '''
+ self.inval()
+ self._sprites.remove_from_list(self)
+
+ def restore(self):
+ ''' Restore a hidden sprite '''
+ self.set_layer()
+
+ def inval(self):
+ ''' Invalidate a region for gtk '''
+ self._sprites.widget.queue_draw_area(self.rect.x,
+ self.rect.y,
+ self.rect.width,
+ self.rect.height)
+
+ def draw(self, cr=None):
+ ''' Draw the sprite (and label) '''
+ if cr is None:
+ print 'sprite.draw: no Cairo context.'
+ return
+ for i, surface in enumerate(self.cached_surfaces):
+ cr.set_source_surface(surface,
+ self.rect.x + self._dx[i],
+ self.rect.y + self._dy[i])
+ cr.rectangle(self.rect.x + self._dx[i],
+ self.rect.y + self._dy[i],
+ self.rect.width,
+ self.rect.height)
+ cr.fill()
+ if len(self.labels) > 0:
+ self.draw_label(cr)
+
+ def hit(self, pos):
+ ''' Is (x, y) on top of the sprite? '''
+ x, y = pos
+ if x < self.rect.x:
+ return False
+ if x > self.rect.x + self.rect.width:
+ return False
+ if y < self.rect.y:
+ return False
+ if y > self.rect.y + self.rect.height:
+ return False
+ return True
+
+ def draw_label(self, cr):
+ ''' Draw the label based on its attributes '''
+ # Create a pangocairo context
+ cr = pangocairo.CairoContext(cr)
+ my_width = self.rect.width - self._margins[0] - self._margins[2]
+ if my_width < 0:
+ my_width = 0
+ my_height = self.rect.height - self._margins[1] - self._margins[3]
+ for i in range(len(self.labels)):
+ pl = cr.create_layout()
+ pl.set_text(str(self.labels[i]))
+ self._fd.set_size(int(self._scale[i] * pango.SCALE))
+ pl.set_font_description(self._fd)
+ w = pl.get_size()[0] / pango.SCALE
+ if w > my_width:
+ if self._rescale[i]:
+ self._fd.set_size(
+ int(self._scale[i] * pango.SCALE * my_width / w))
+ pl.set_font_description(self._fd)
+ w = pl.get_size()[0] / pango.SCALE
+ else:
+ j = len(self.labels[i]) - 1
+ while(w > my_width and j > 0):
+ pl.set_text(
+ "…" + self.labels[i][len(self.labels[i]) - j:])
+ self._fd.set_size(int(self._scale[i] * pango.SCALE))
+ pl.set_font_description(self._fd)
+ w = pl.get_size()[0] / pango.SCALE
+ j -= 1
+ if self._horiz_align[i] == "center":
+ x = int(self.rect.x + self._margins[0] + (my_width - w) / 2)
+ elif self._horiz_align[i] == 'left':
+ x = int(self.rect.x + self._margins[0])
+ else: # right
+ x = int(self.rect.x + self.rect.width - w - self._margins[2])
+ h = pl.get_size()[1] / pango.SCALE
+ if self._vert_align[i] == "middle":
+ y = int(self.rect.y + self._margins[1] + (my_height - h) / 2)
+ elif self._vert_align[i] == "top":
+ y = int(self.rect.y + self._margins[1])
+ else: # bottom
+ y = int(self.rect.y + self.rect.height - h - self._margins[3])
+ cr.save()
+ cr.translate(x, y)
+ cr.set_source_rgb(self._color[0], self._color[1], self._color[2])
+ cr.update_layout(pl)
+ cr.show_layout(pl)
+ cr.restore()
+
+ def label_width(self):
+ ''' Calculate the width of a label '''
+ cr = pangocairo.CairoContext(self._sprites.cr)
+ if cr is not None:
+ max = 0
+ for i in range(len(self.labels)):
+ pl = cr.create_layout()
+ pl.set_text(self.labels[i])
+ self._fd.set_size(int(self._scale[i] * pango.SCALE))
+ pl.set_font_description(self._fd)
+ w = pl.get_size()[0] / pango.SCALE
+ if w > max:
+ max = w
+ return max
+ else:
+ return self.rect.width
+
+ def label_safe_width(self):
+ ''' Return maximum width for a label '''
+ return self.rect.width - self._margins[0] - self._margins[2]
+
+ def label_safe_height(self):
+ ''' Return maximum height for a label '''
+ return self.rect.height - self._margins[1] - self._margins[3]
+
+ def label_left_top(self):
+ ''' Return the upper-left corner of the label safe zone '''
+ return(self._margins[0], self._margins[1])
+
+ def get_pixel(self, pos, i=0):
+ ''' Return the pixel at (x, y) '''
+ x = int(pos[0] - self.rect.x)
+ y = int(pos[1] - self.rect.y)
+ if x < 0 or x > (self.rect.width - 1) or \
+ y < 0 or y > (self.rect.height - 1):
+ return(-1, -1, -1, -1)
+
+ # create a new 1x1 cairo surface
+ cs = cairo.ImageSurface(cairo.FORMAT_RGB24, 1, 1);
+ cr = cairo.Context(cs)
+ cr.set_source_surface(self.cached_surfaces[i], -x, -y)
+ cr.rectangle(0,0,1,1)
+ cr.set_operator(cairo.OPERATOR_SOURCE)
+ cr.fill()
+ cs.flush() # ensure all writing is done
+ # Read the pixel
+ pixels = cs.get_data()
+ return (ord(pixels[2]), ord(pixels[1]), ord(pixels[0]), 0)
+
diff --git a/toolbar_utils.py b/toolbar_utils.py
new file mode 100644
index 0000000..94e6883
--- /dev/null
+++ b/toolbar_utils.py
@@ -0,0 +1,164 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2011, Walter Bender
+
+# 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with this library; if not, write to the Free Software
+# Foundation, 51 Franklin Street, Suite 500 Boston, MA 02110-1335 USA
+
+
+import gtk
+
+from sugar.graphics.radiotoolbutton import RadioToolButton
+from sugar.graphics.toolbutton import ToolButton
+from sugar.graphics.combobox import ComboBox
+from sugar.graphics.toolcombobox import ToolComboBox
+
+
+def combo_factory(combo_array, toolbar, callback, cb_arg=None,
+ tooltip=None, default=None):
+ '''Factory for making a toolbar combo box'''
+ combo = ComboBox()
+ if tooltip is not None and hasattr(combo, 'set_tooltip_text'):
+ combo.set_tooltip_text(tooltip)
+ if cb_arg is not None:
+ combo.connect('changed', callback, cb_arg)
+ else:
+ combo.connect('changed', callback)
+ for i, selection in enumerate(combo_array):
+ combo.append_item(i, selection, None)
+ combo.show()
+ toolitem = gtk.ToolItem()
+ toolitem.add(combo)
+ if hasattr(toolbar, 'insert'): # the main toolbar
+ toolbar.insert(toolitem, -1)
+ else: # or a secondary toolbar
+ toolbar.props.page.insert(toolitem, -1)
+ toolitem.show()
+ if default is not None:
+ combo.set_active(combo_array.index(default))
+ return combo
+
+
+def entry_factory(default_string, toolbar, tooltip=None, max=3):
+ ''' Factory for adding a text box to a toolbar '''
+ entry = gtk.Entry()
+ entry.set_text(default_string)
+ if tooltip is not None and hasattr(entry, 'set_tooltip_text'):
+ entry.set_tooltip_text(tooltip)
+ entry.set_width_chars(max)
+ entry.show()
+ toolitem = gtk.ToolItem()
+ toolitem.add(entry)
+ if hasattr(toolbar, 'insert'): # the main toolbar
+ toolbar.insert(toolitem, -1)
+ else: # or a secondary toolbar
+ toolbar.props.page.insert(toolitem, -1)
+ toolitem.show()
+ return entry
+
+
+def button_factory(icon_name, toolbar, callback, cb_arg=None, tooltip=None,
+ accelerator=None):
+ '''Factory for making tooplbar buttons'''
+ button = ToolButton(icon_name)
+ if tooltip is not None:
+ button.set_tooltip(tooltip)
+ button.props.sensitive = True
+ if accelerator is not None:
+ button.props.accelerator = accelerator
+ if cb_arg is not None:
+ button.connect('clicked', callback, cb_arg)
+ else:
+ button.connect('clicked', callback)
+ if hasattr(toolbar, 'insert'): # the main toolbar
+ toolbar.insert(button, -1)
+ else: # or a secondary toolbar
+ toolbar.props.page.insert(button, -1)
+ button.show()
+ return button
+
+
+def radio_factory(name, toolbar, callback, cb_arg=None, tooltip=None,
+ group=None):
+ ''' Add a radio button to a toolbar '''
+ button = RadioToolButton(group=group)
+ button.set_named_icon(name)
+ if callback is not None:
+ if cb_arg is None:
+ button.connect('clicked', callback)
+ else:
+ button.connect('clicked', callback, cb_arg)
+ if hasattr(toolbar, 'insert'): # Add button to the main toolbar...
+ toolbar.insert(button, -1)
+ else: # ...or a secondary toolbar.
+ toolbar.props.page.insert(button, -1)
+ button.show()
+ if tooltip is not None:
+ button.set_tooltip(tooltip)
+ return button
+
+
+def label_factory(toolbar, label_text, width=None):
+ ''' Factory for adding a label to a toolbar '''
+ label = gtk.Label(label_text)
+ label.set_line_wrap(True)
+ if width is not None:
+ label.set_size_request(width, -1) # doesn't work on XOs
+ label.show()
+ toolitem = gtk.ToolItem()
+ toolitem.add(label)
+ if hasattr(toolbar, 'insert'): # the main toolbar
+ toolbar.insert(toolitem, -1)
+ else: # or a secondary toolbar
+ toolbar.props.page.insert(toolitem, -1)
+ toolitem.show()
+ return label
+
+
+def separator_factory(toolbar, expand=False, visible=True):
+ ''' add a separator to a toolbar '''
+ separator = gtk.SeparatorToolItem()
+ separator.props.draw = visible
+ separator.set_expand(expand)
+ if hasattr(toolbar, 'insert'): # the main toolbar
+ toolbar.insert(separator, -1)
+ else: # or a secondary toolbar
+ toolbar.props.page.insert(separator, -1)
+ separator.show()
+
+
+def image_factory(image, toolbar, tooltip=None):
+ ''' Add an image to the toolbar '''
+ img = gtk.Image()
+ img.set_from_pixbuf(image)
+ img_tool = gtk.ToolItem()
+ img_tool.add(img)
+ if tooltip is not None:
+ img.set_tooltip_text(tooltip)
+ if hasattr(toolbar, 'insert'): # the main toolbar
+ toolbar.insert(img_tool, -1)
+ else: # or a secondary toolbar
+ toolbar.props.page.insert(img_tool, -1)
+ img_tool.show()
+ return img
+
+
+def spin_factory(default, min, max, callback, toolbar):
+ spin_adj = gtk.Adjustment(default, min, max, 1, 32, 0)
+ spin = gtk.SpinButton(spin_adj, 0, 0)
+ spin_id = spin.connect('value-changed', callback)
+ spin.set_numeric(True)
+ spin.show()
+ toolitem = gtk.ToolItem()
+ toolitem.add(spin)
+ if hasattr(toolbar, 'insert'): # the main toolbar
+ toolbar.insert(toolitem, -1)
+ else:
+ toolbar.props.page.insert(toolitem, -1)
+ toolitem.show()
+ return spin
diff --git a/webviewer.py b/webviewer.py
deleted file mode 100644
index f418f5f..0000000
--- a/webviewer.py
+++ /dev/null
@@ -1,147 +0,0 @@
-# Copyright (C) 2006, Red Hat, Inc.
-# Copyright (C) 2007, One Laptop Per Child
-#
-# 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 2 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, write to the Free Software
-# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-
-from sugar import env
-
-import logging
-import gobject
-import gtk
-import os
-import hulahop
-hulahop.startup(os.path.join(env.get_profile_path(), 'gecko'))
-import xpcom
-from xpcom.nsError import *
-from xpcom import components
-from xpcom.components import interfaces
-from hulahop.webview import WebView
-
-#import sessionstore
-#from dnd import DragDropHooks
-
-class WebViewer(WebView):
- def __init__(self):
- WebView.__init__(self)
-
- window_creator = WindowCreator(self)
- cls = components.classes['@mozilla.org/embedcomp/window-watcher;1']
- window_watcher = cls.getService(interfaces.nsIWindowWatcher)
- window_watcher.setWindowCreator(window_creator)
-
- self.connect('realize', self._realize_cb)
-
- def _realize_cb(self, widget):
- #drag_drop_hooks = DragDropHooks(self)
-
- cls = components.classes['@mozilla.org/embedcomp/command-params;1']
- cmd_params = cls.createInstance('nsICommandParams')
- #cmd_params.setISupportsValue('addhook', drag_drop_hooks)
-
- requestor = self.browser.queryInterface(interfaces.nsIInterfaceRequestor)
- command_manager = requestor.getInterface(interfaces.nsICommandManager)
- command_manager.doCommand('cmd_clipboardDragDropHook', cmd_params, self.dom_window)
-
- def get_session(self):
- return sessionstore.get_session(self)
-
- def set_session(self, session_data):
- return sessionstore.set_session(self, session_data)
-
-class WindowCreator:
- _com_interfaces_ = interfaces.nsIWindowCreator
-
- def __init__(self, browser):
- self._popup_creators = []
- self._browser = browser
-
- def createChromeWindow(self, parent, chrome_flags):
- logging.debug('createChromeWindow: %r %r' % (parent, chrome_flags))
-
- popup_creator = _PopupCreator(self._browser.get_toplevel())
- popup_creator.connect('popup-created', self._popup_created_cb)
-
- self._popup_creators.append(popup_creator)
-
- browser = popup_creator.get_embed()
-
- if chrome_flags & interfaces.nsIWebBrowserChrome.CHROME_OPENAS_CHROME:
- logging.debug('Creating chrome window.')
- browser.is_chrome = True
- item = browser.browser.queryInterface(interfaces.nsIDocShellTreeItem)
- item.itemType = interfaces.nsIDocShellTreeItem.typeChromeWrapper
- else:
- logging.debug('Creating browser window.')
- item = browser.browser.queryInterface(interfaces.nsIDocShellTreeItem)
- item.itemType = interfaces.nsIDocShellTreeItem.typeContentWrapper
-
- browser.realize()
-
- return browser.browser.containerWindow
-
- def _popup_created_cb(self, creator):
- self._popup_creators.remove(creator)
-
-class _PopupCreator(gobject.GObject):
- __gsignals__ = {
- 'popup-created': (gobject.SIGNAL_RUN_FIRST,
- gobject.TYPE_NONE, ([])),
- }
-
- def __init__(self, parent_window):
- gobject.GObject.__init__(self)
-
- logging.debug('Creating the popup widget')
-
- self._parent_window = parent_window
-
- self._dialog = gtk.Window()
- self._dialog.set_resizable(True)
-
- self._dialog.realize()
- self._dialog.window.set_type_hint(gtk.gdk.WINDOW_TYPE_HINT_DIALOG)
-
- self._embed = Browser()
- self._vis_sid = self._embed.connect('notify::visible', self._notify_visible_cb)
- self._dialog.add(self._embed)
-
- def _notify_visible_cb(self, embed, param):
- self._embed.disconnect(self._vis_sid)
-
- if self._embed.type == Browser.TYPE_POPUP or self._embed.is_chrome:
- logging.debug('Show the popup')
- self._embed.show()
- self._dialog.set_transient_for(self._parent_window)
- self._dialog.show()
- else:
- logging.debug('Open a new activity for the popup')
- self._dialog.remove(self._embed)
- self._dialog.destroy()
- self._dialog = None
-
- # FIXME We need a better way to handle this.
- # It seem like a pretty special case though, I doubt
- # other activities will need something similar.
- from webactivity import WebActivity
- from sugar.activity import activityfactory
- from sugar.activity.activityhandle import ActivityHandle
- handle = ActivityHandle(activityfactory.create_activity_id())
- activity = WebActivity(handle, self._embed)
- activity.show()
-
- self.emit('popup-created')
-
- def get_embed(self):
- return self._embed
diff --git a/webviewer.pyc b/webviewer.pyc
deleted file mode 100644
index e2c812b..0000000
--- a/webviewer.pyc
+++ /dev/null
Binary files differ
diff --git a/xoEditorActivity.py b/xoEditorActivity.py
deleted file mode 100644
index 5348025..0000000
--- a/xoEditorActivity.py
+++ /dev/null
@@ -1,74 +0,0 @@
-#!/usr/bin/env python
-#Copyright (c) 2007, Media Modifications Ltd.
-
-#Permission is hereby granted, free of charge, to any person obtaining a copy
-#of this software and associated documentation files (the "Software"), to deal
-#in the Software without restriction, including without limitation the rights
-#to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-#copies of the Software, and to permit persons to whom the Software is
-#furnished to do so, subject to the following conditions:
-
-#The above copyright notice and this permission notice shall be included in
-#all copies or substantial portions of the Software.
-
-#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-#IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-#FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-#AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-#LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-#OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-#THE SOFTWARE.
-
-import gtk
-import gobject
-import os
-
-from sugar.activity import activity
-from webviewer import WebViewer
-from server import Server
-from logic import ServerLogic
-from result import ServerResult
-
-httpPort = 8889
-title = "xo Editor"
-initHtml = "xo-color.xml"
-
-class xoEditorActivity(activity.Activity):
- def __init__(self, handle):
- activity.Activity.__init__(self, handle)
- self.set_title( title )
-
- #wait a moment so that our debug console capture mistakes
- gobject.idle_add(self._initme, None)
-
- def _initme( self, userdata=None ):
- self.basePath = activity.get_bundle_path()
- self.htmlPath = os.path.join(self.basePath, "html")
- self.journalPath = os.path.join(os.path.expanduser("~"), "Journal", title)
- if (not os.path.exists(self.journalPath)):
- os.makedirs(self.journalPath)
-
- #add sharing callback here
- #self.connect( "shared", self._shared_cb )
-
- #this includes the default sharing tab
- toolbox = activity.ActivityToolbox(self)
- self.set_toolbox(toolbox)
- toolbox.show()
-
- #add components
- self.browser = WebViewer( )
- self.set_canvas(self.browser)
- self.browser.show()
-
- #fire up the web engine, spiderman!
- self.slogic = ServerLogic(self);
- self.server = Server( ("",httpPort), self )
- self.browser.load_uri( "http://localhost:" + str(httpPort) + "/" + initHtml )
-
- #when the party's over, turn out the lights, turn out the lights
- self.connect("destroy", self.destroy)
- return False
-
- def destroy(self, *args):
- gtk.main_quit()
diff --git a/xoEditorActivity.pyc b/xoEditorActivity.pyc
deleted file mode 100644
index 3a0d89b..0000000
--- a/xoEditorActivity.pyc
+++ /dev/null
Binary files differ