Codebase list diodon / e45798b
Import Upstream version 1.8.0 Oliver Sauder 4 years ago
244 changed file(s) with 53043 addition(s) and 0 deletion(s). Raw diff Collapse all Expand all
0 version = 1
1 build_command = ./waf build
2 clean_command = ./waf clean
3 pkg_blacklist = gdk-2.0.vapi;gdk-x11-2.0.vapi;gtk+-2.0.vapi
0 Oliver Sauder <os@esite.ch>
1 Dariel Dato-on <oddrationale@gmail.com>
0 GNU GENERAL PUBLIC LICENSE
1 Version 2, June 1991
2
3 Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
4 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
5 Everyone is permitted to copy and distribute verbatim copies
6 of this license document, but changing it is not allowed.
7
8 Preamble
9
10 The licenses for most software are designed to take away your
11 freedom to share and change it. By contrast, the GNU General Public
12 License is intended to guarantee your freedom to share and change free
13 software--to make sure the software is free for all its users. This
14 General Public License applies to most of the Free Software
15 Foundation's software and to any other program whose authors commit to
16 using it. (Some other Free Software Foundation software is covered by
17 the GNU Lesser General Public License instead.) You can apply it to
18 your programs, too.
19
20 When we speak of free software, we are referring to freedom, not
21 price. Our General Public Licenses are designed to make sure that you
22 have the freedom to distribute copies of free software (and charge for
23 this service if you wish), that you receive source code or can get it
24 if you want it, that you can change the software or use pieces of it
25 in new free programs; and that you know you can do these things.
26
27 To protect your rights, we need to make restrictions that forbid
28 anyone to deny you these rights or to ask you to surrender the rights.
29 These restrictions translate to certain responsibilities for you if you
30 distribute copies of the software, or if you modify it.
31
32 For example, if you distribute copies of such a program, whether
33 gratis or for a fee, you must give the recipients all the rights that
34 you have. You must make sure that they, too, receive or can get the
35 source code. And you must show them these terms so they know their
36 rights.
37
38 We protect your rights with two steps: (1) copyright the software, and
39 (2) offer you this license which gives you legal permission to copy,
40 distribute and/or modify the software.
41
42 Also, for each author's protection and ours, we want to make certain
43 that everyone understands that there is no warranty for this free
44 software. If the software is modified by someone else and passed on, we
45 want its recipients to know that what they have is not the original, so
46 that any problems introduced by others will not reflect on the original
47 authors' reputations.
48
49 Finally, any free program is threatened constantly by software
50 patents. We wish to avoid the danger that redistributors of a free
51 program will individually obtain patent licenses, in effect making the
52 program proprietary. To prevent this, we have made it clear that any
53 patent must be licensed for everyone's free use or not licensed at all.
54
55 The precise terms and conditions for copying, distribution and
56 modification follow.
57
58 GNU GENERAL PUBLIC LICENSE
59 TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
60
61 0. This License applies to any program or other work which contains
62 a notice placed by the copyright holder saying it may be distributed
63 under the terms of this General Public License. The "Program", below,
64 refers to any such program or work, and a "work based on the Program"
65 means either the Program or any derivative work under copyright law:
66 that is to say, a work containing the Program or a portion of it,
67 either verbatim or with modifications and/or translated into another
68 language. (Hereinafter, translation is included without limitation in
69 the term "modification".) Each licensee is addressed as "you".
70
71 Activities other than copying, distribution and modification are not
72 covered by this License; they are outside its scope. The act of
73 running the Program is not restricted, and the output from the Program
74 is covered only if its contents constitute a work based on the
75 Program (independent of having been made by running the Program).
76 Whether that is true depends on what the Program does.
77
78 1. You may copy and distribute verbatim copies of the Program's
79 source code as you receive it, in any medium, provided that you
80 conspicuously and appropriately publish on each copy an appropriate
81 copyright notice and disclaimer of warranty; keep intact all the
82 notices that refer to this License and to the absence of any warranty;
83 and give any other recipients of the Program a copy of this License
84 along with the Program.
85
86 You may charge a fee for the physical act of transferring a copy, and
87 you may at your option offer warranty protection in exchange for a fee.
88
89 2. You may modify your copy or copies of the Program or any portion
90 of it, thus forming a work based on the Program, and copy and
91 distribute such modifications or work under the terms of Section 1
92 above, provided that you also meet all of these conditions:
93
94 a) You must cause the modified files to carry prominent notices
95 stating that you changed the files and the date of any change.
96
97 b) You must cause any work that you distribute or publish, that in
98 whole or in part contains or is derived from the Program or any
99 part thereof, to be licensed as a whole at no charge to all third
100 parties under the terms of this License.
101
102 c) If the modified program normally reads commands interactively
103 when run, you must cause it, when started running for such
104 interactive use in the most ordinary way, to print or display an
105 announcement including an appropriate copyright notice and a
106 notice that there is no warranty (or else, saying that you provide
107 a warranty) and that users may redistribute the program under
108 these conditions, and telling the user how to view a copy of this
109 License. (Exception: if the Program itself is interactive but
110 does not normally print such an announcement, your work based on
111 the Program is not required to print an announcement.)
112
113 These requirements apply to the modified work as a whole. If
114 identifiable sections of that work are not derived from the Program,
115 and can be reasonably considered independent and separate works in
116 themselves, then this License, and its terms, do not apply to those
117 sections when you distribute them as separate works. But when you
118 distribute the same sections as part of a whole which is a work based
119 on the Program, the distribution of the whole must be on the terms of
120 this License, whose permissions for other licensees extend to the
121 entire whole, and thus to each and every part regardless of who wrote it.
122
123 Thus, it is not the intent of this section to claim rights or contest
124 your rights to work written entirely by you; rather, the intent is to
125 exercise the right to control the distribution of derivative or
126 collective works based on the Program.
127
128 In addition, mere aggregation of another work not based on the Program
129 with the Program (or with a work based on the Program) on a volume of
130 a storage or distribution medium does not bring the other work under
131 the scope of this License.
132
133 3. You may copy and distribute the Program (or a work based on it,
134 under Section 2) in object code or executable form under the terms of
135 Sections 1 and 2 above provided that you also do one of the following:
136
137 a) Accompany it with the complete corresponding machine-readable
138 source code, which must be distributed under the terms of Sections
139 1 and 2 above on a medium customarily used for software interchange; or,
140
141 b) Accompany it with a written offer, valid for at least three
142 years, to give any third party, for a charge no more than your
143 cost of physically performing source distribution, a complete
144 machine-readable copy of the corresponding source code, to be
145 distributed under the terms of Sections 1 and 2 above on a medium
146 customarily used for software interchange; or,
147
148 c) Accompany it with the information you received as to the offer
149 to distribute corresponding source code. (This alternative is
150 allowed only for noncommercial distribution and only if you
151 received the program in object code or executable form with such
152 an offer, in accord with Subsection b above.)
153
154 The source code for a work means the preferred form of the work for
155 making modifications to it. For an executable work, complete source
156 code means all the source code for all modules it contains, plus any
157 associated interface definition files, plus the scripts used to
158 control compilation and installation of the executable. However, as a
159 special exception, the source code distributed need not include
160 anything that is normally distributed (in either source or binary
161 form) with the major components (compiler, kernel, and so on) of the
162 operating system on which the executable runs, unless that component
163 itself accompanies the executable.
164
165 If distribution of executable or object code is made by offering
166 access to copy from a designated place, then offering equivalent
167 access to copy the source code from the same place counts as
168 distribution of the source code, even though third parties are not
169 compelled to copy the source along with the object code.
170
171 4. You may not copy, modify, sublicense, or distribute the Program
172 except as expressly provided under this License. Any attempt
173 otherwise to copy, modify, sublicense or distribute the Program is
174 void, and will automatically terminate your rights under this License.
175 However, parties who have received copies, or rights, from you under
176 this License will not have their licenses terminated so long as such
177 parties remain in full compliance.
178
179 5. You are not required to accept this License, since you have not
180 signed it. However, nothing else grants you permission to modify or
181 distribute the Program or its derivative works. These actions are
182 prohibited by law if you do not accept this License. Therefore, by
183 modifying or distributing the Program (or any work based on the
184 Program), you indicate your acceptance of this License to do so, and
185 all its terms and conditions for copying, distributing or modifying
186 the Program or works based on it.
187
188 6. Each time you redistribute the Program (or any work based on the
189 Program), the recipient automatically receives a license from the
190 original licensor to copy, distribute or modify the Program subject to
191 these terms and conditions. You may not impose any further
192 restrictions on the recipients' exercise of the rights granted herein.
193 You are not responsible for enforcing compliance by third parties to
194 this License.
195
196 7. If, as a consequence of a court judgment or allegation of patent
197 infringement or for any other reason (not limited to patent issues),
198 conditions are imposed on you (whether by court order, agreement or
199 otherwise) that contradict the conditions of this License, they do not
200 excuse you from the conditions of this License. If you cannot
201 distribute so as to satisfy simultaneously your obligations under this
202 License and any other pertinent obligations, then as a consequence you
203 may not distribute the Program at all. For example, if a patent
204 license would not permit royalty-free redistribution of the Program by
205 all those who receive copies directly or indirectly through you, then
206 the only way you could satisfy both it and this License would be to
207 refrain entirely from distribution of the Program.
208
209 If any portion of this section is held invalid or unenforceable under
210 any particular circumstance, the balance of the section is intended to
211 apply and the section as a whole is intended to apply in other
212 circumstances.
213
214 It is not the purpose of this section to induce you to infringe any
215 patents or other property right claims or to contest validity of any
216 such claims; this section has the sole purpose of protecting the
217 integrity of the free software distribution system, which is
218 implemented by public license practices. Many people have made
219 generous contributions to the wide range of software distributed
220 through that system in reliance on consistent application of that
221 system; it is up to the author/donor to decide if he or she is willing
222 to distribute software through any other system and a licensee cannot
223 impose that choice.
224
225 This section is intended to make thoroughly clear what is believed to
226 be a consequence of the rest of this License.
227
228 8. If the distribution and/or use of the Program is restricted in
229 certain countries either by patents or by copyrighted interfaces, the
230 original copyright holder who places the Program under this License
231 may add an explicit geographical distribution limitation excluding
232 those countries, so that distribution is permitted only in or among
233 countries not thus excluded. In such case, this License incorporates
234 the limitation as if written in the body of this License.
235
236 9. The Free Software Foundation may publish revised and/or new versions
237 of the General Public License from time to time. Such new versions will
238 be similar in spirit to the present version, but may differ in detail to
239 address new problems or concerns.
240
241 Each version is given a distinguishing version number. If the Program
242 specifies a version number of this License which applies to it and "any
243 later version", you have the option of following the terms and conditions
244 either of that version or of any later version published by the Free
245 Software Foundation. If the Program does not specify a version number of
246 this License, you may choose any version ever published by the Free Software
247 Foundation.
248
249 10. If you wish to incorporate parts of the Program into other free
250 programs whose distribution conditions are different, write to the author
251 to ask for permission. For software which is copyrighted by the Free
252 Software Foundation, write to the Free Software Foundation; we sometimes
253 make exceptions for this. Our decision will be guided by the two goals
254 of preserving the free status of all derivatives of our free software and
255 of promoting the sharing and reuse of software generally.
256
257 NO WARRANTY
258
259 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
260 FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
261 OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
262 PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
263 OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
264 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
265 TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
266 PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
267 REPAIR OR CORRECTION.
268
269 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
270 WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
271 REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
272 INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
273 OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
274 TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
275 YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
276 PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
277 POSSIBILITY OF SUCH DAMAGES.
278
279 END OF TERMS AND CONDITIONS
280
281 How to Apply These Terms to Your New Programs
282
283 If you develop a new program, and you want it to be of the greatest
284 possible use to the public, the best way to achieve this is to make it
285 free software which everyone can redistribute and change under these terms.
286
287 To do so, attach the following notices to the program. It is safest
288 to attach them to the start of each source file to most effectively
289 convey the exclusion of warranty; and each file should have at least
290 the "copyright" line and a pointer to where the full notice is found.
291
292 <one line to give the program's name and a brief idea of what it does.>
293 Copyright (C) <year> <name of author>
294
295 This program is free software; you can redistribute it and/or modify
296 it under the terms of the GNU General Public License as published by
297 the Free Software Foundation; either version 2 of the License, or
298 (at your option) any later version.
299
300 This program is distributed in the hope that it will be useful,
301 but WITHOUT ANY WARRANTY; without even the implied warranty of
302 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
303 GNU General Public License for more details.
304
305 You should have received a copy of the GNU General Public License along
306 with this program; if not, write to the Free Software Foundation, Inc.,
307 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
308
309 Also add information on how to contact you by electronic and paper mail.
310
311 If the program is interactive, make it output a short notice like this
312 when it starts in an interactive mode:
313
314 Gnomovision version 69, Copyright (C) year name of author
315 Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
316 This is free software, and you are welcome to redistribute it
317 under certain conditions; type `show c' for details.
318
319 The hypothetical commands `show w' and `show c' should show the appropriate
320 parts of the General Public License. Of course, the commands you use may
321 be called something other than `show w' and `show c'; they could even be
322 mouse-clicks or menu items--whatever suits your program.
323
324 You should also get your employer (if you work as a programmer) or your
325 school, if any, to sign a "copyright disclaimer" for the program, if
326 necessary. Here is a sample; alter the names:
327
328 Yoyodyne, Inc., hereby disclaims all copyright interest in the program
329 `Gnomovision' (which makes passes at compilers) written by James Hacker.
330
331 <signature of Ty Coon>, 1 April 1989
332 Ty Coon, President of Vice
333
334 This General Public License does not permit incorporating your program into
335 proprietary programs. If your program is a subroutine library, you may
336 consider it more useful to permit linking proprietary applications with the
337 library. If this is what you want to do, use the GNU Lesser General
338 Public License instead of this License.
0 Build Diodon
1 =======================
2
3 Diodon uses the WAF build system. To build and install Diodon use these commands:
4
5 ./waf configure
6 ./waf build
7 sudo ./waf install
8
9 The unity scope needs to be explicitly enabled during configure if desired
10
11 ./waf configure --enable-unityscope
12
13 On distributions which do not provide packages for application-indicator
14 building of the indicator can be disabled with following command:
15
16 ./waf configure --disable-indicator-plugin
17
18 For uninstalling type this:
19
20 sudo ./waf uninstall
21
22 For developers who also want to run integration tests the following
23 command build can be run:
24
25 ./waf build --testcmd='%s --integration'
0 # Diodon
1 Aiming to be the best integrated clipboard manager for the Unity desktop.
2
3 ## Installing
4
5 For Ubuntu based distributes there is an official [stable PPA](https://launchpad.net/~diodon-team/+archive/stable).
6
7 sudo add-apt-repository ppa:diodon-team/stable
8 sudo apt-get update
9 sudo apt-get install -y diodon
10
11
12 To install Diodon on other systems download a release tarball from [launchpad](https://launchpad.net/diodon/+download).
13
14 ## Building
15
16 Diodon uses the [waf](https://waf.io) build system.
17
18 git clone https://github.com/diodon-dev/diodon.git
19 cd diodon
20 ./waf configure
21 ./waf build
22 sudo ./waf install
23
24 ## Plugins
25
26 If you would like to write your own Diodon plugin please refer to [the original blog post](http://esite.ch/2011/10/19/writing-a-plugin-for-diodon/). Feel free to add your own plugins to the list below.
27
28 | Plugin | Description |
29 | -------------------------------------------------------- | -------------------------------------------------- |
30 | [Features](https://github.com/RedHatter/diodon-plugins) | Additional features for the diodon menu. |
31 | [Numbers](https://github.com/RedHatter/diodon-plugins) | Number clipboard menu items. |
32 | [Pop Item](https://github.com/RedHatter/diodon-plugins) | Pastes and then removes the active clipboard item. |
33 | [Paste All](https://github.com/RedHatter/diodon-plugins) | Paste all recent items at once |
34 | [Edit](https://github.com/RedHatter/diodon-plugins) | Prompts to edit the active item. |
35
36 ## Support
37
38 Take part in the discussion or report a bug on the [launchpad](https://bugs.launchpad.net/diodon) page.
39
40 Join us in #diodon on irc.freenode.net if you want to get involved or need any help.
0 # this is a dummy file so valencia knows where the root is
1 # see http://redmine.yorba.org/issues/3410
0 diodon = {
1 'impl' : 'launchpad',
2 'project' : 'diodon',
3 'bug_pattern_base' : None,
4 }
0 '''
1 apport package hook for diodon
2
3 Copyright (C) 2010-2013 Diodon Team
4 Author: Oliver Sauder <os@esite.ch>
5
6 This program is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by the
8 Free Software Foundation; either version 2 of the License, or (at your
9 option) any later version. See http://www.gnu.org/copyleft/gpl.html for
10 the full text of the license.
11 '''
12
13 import apport
14 from apport.hookutils import attach_file_if_exists
15 import os
16 from os import path, getenv
17
18 def add_info(report, ui):
19 if not apport.packaging.is_distro_package(report['Package'].split()[0]):
20 report['CrashDB'] = 'diodon'
0 [Desktop Entry]
1 Type=Application
2 Version=1.0
3 Name=Diodon
4 _GenericName=Clipboard Manager
5 _Comment=GTK+ Clipboard Manager
6 Icon=diodon
7 NotShowIn=KDE;
8 Exec=diodon
9 Terminal=false
10 Categories=GTK;GNOME;Utility;
11 StartupNotify=false
12 MimeType=x-scheme-handler/clipboard;
13
Binary diff not shown
0 [Desktop Entry]
1 Type=Application
2 Version=1.0
3 Name=Diodon
4 _GenericName=Clipboard Manager
5 _Comment=GTK+ Clipboard Manager
6 Icon=diodon
7 NotShowIn=KDE;
8 Exec=diodon %u
9 Terminal=false
10 Categories=GTK;GNOME;Utility;
11 StartupNotify=false
12 MimeType=x-scheme-handler/clipboard;
13
0 prefix=@PREFIX@
1 exec_prefix=@EXEC_PREFIX@
2 libdir=@LIBDIR@
3 includedir=@INCLUDEDIR@
4 datarootdir=@DATAROOTDIR@
5 datadir=@DATADIR@
6
7 Name: diodon
8 Description: Diodon GTK+ Clipboard Manager
9 Version: @VERSION@
10 Requires: gtk+-3.0
11 Libs: -L${libdir} -ldiodon
12 Cflags: -I${includedir}/diodon
13
0 ../../../ubuntu-mono-light/status/16/diodon-panel.svg
0 ../../../ubuntu-mono-light/status/22/diodon-panel.svg
0 ../../../ubuntu-mono-light/status/24/diodon-panel.svg
0 ../../../ubuntu-mono-dark/status/16/diodon-panel.svg
0 ../../../ubuntu-mono-dark/status/22/diodon-panel.svg
0 ../../../ubuntu-mono-dark/status/24/diodon-panel.svg
0 ../../../ubuntu-mono-dark/status/16/diodon-panel.svg
0 ../../../ubuntu-mono-dark/status/22/diodon-panel.svg
0 ../../../ubuntu-mono-dark/status/24/diodon-panel.svg
0 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
1 <!-- Created with Inkscape (http://www.inkscape.org/) -->
2
3 <svg
4 xmlns:dc="http://purl.org/dc/elements/1.1/"
5 xmlns:cc="http://creativecommons.org/ns#"
6 xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
7 xmlns:svg="http://www.w3.org/2000/svg"
8 xmlns="http://www.w3.org/2000/svg"
9 xmlns:xlink="http://www.w3.org/1999/xlink"
10 xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
11 xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
12 width="16"
13 height="16"
14 id="svg25900"
15 version="1.1"
16 inkscape:version="0.48.3.1 r9886"
17 sodipodi:docname="diodon-panel.svg">
18 <defs
19 id="defs25902">
20 <radialGradient
21 inkscape:collect="always"
22 xlink:href="#SVGID_3_"
23 id="radialGradient3305"
24 gradientUnits="userSpaceOnUse"
25 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
26 cx="163.4902"
27 cy="274.86621"
28 r="2.8801" />
29 <radialGradient
30 gradientUnits="userSpaceOnUse"
31 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
32 r="2.8801"
33 cy="274.86621"
34 cx="163.4902"
35 id="SVGID_3_">
36 <stop
37 id="stop190"
38 style="stop-color:#FAF0BB"
39 offset="0.0112" />
40 <stop
41 id="stop192"
42 style="stop-color:#FAF0BD"
43 offset="0.4917" />
44 <stop
45 id="stop194"
46 style="stop-color:#FBF2C5"
47 offset="0.6648" />
48 <stop
49 id="stop196"
50 style="stop-color:#FCF6D0"
51 offset="0.7882" />
52 <stop
53 id="stop198"
54 style="stop-color:#FCF8E1"
55 offset="0.8879" />
56 <stop
57 id="stop200"
58 style="stop-color:#FFFDF7"
59 offset="0.9723" />
60 <stop
61 id="stop202"
62 style="stop-color:#FFFFFF"
63 offset="1" />
64 </radialGradient>
65 <radialGradient
66 inkscape:collect="always"
67 xlink:href="#SVGID_4_"
68 id="radialGradient3307"
69 gradientUnits="userSpaceOnUse"
70 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
71 cx="155.3242"
72 cy="310.6777"
73 r="4.4867001" />
74 <radialGradient
75 gradientUnits="userSpaceOnUse"
76 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
77 r="4.4867001"
78 cy="310.6777"
79 cx="155.3242"
80 id="SVGID_4_">
81 <stop
82 id="stop207"
83 style="stop-color:#FAF0BB"
84 offset="0.0112" />
85 <stop
86 id="stop209"
87 style="stop-color:#FAF0BD"
88 offset="0.4917" />
89 <stop
90 id="stop211"
91 style="stop-color:#FBF2C5"
92 offset="0.6648" />
93 <stop
94 id="stop213"
95 style="stop-color:#FCF6D0"
96 offset="0.7882" />
97 <stop
98 id="stop215"
99 style="stop-color:#FCF8E1"
100 offset="0.8879" />
101 <stop
102 id="stop217"
103 style="stop-color:#FFFDF7"
104 offset="0.9723" />
105 <stop
106 id="stop219"
107 style="stop-color:#FFFFFF"
108 offset="1" />
109 </radialGradient>
110 <radialGradient
111 inkscape:collect="always"
112 xlink:href="#SVGID_5_"
113 id="radialGradient3310"
114 gradientUnits="userSpaceOnUse"
115 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
116 cx="170.3125"
117 cy="302.00781"
118 r="5.0811" />
119 <radialGradient
120 gradientUnits="userSpaceOnUse"
121 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
122 r="5.0811"
123 cy="302.00781"
124 cx="170.3125"
125 id="SVGID_5_">
126 <stop
127 id="stop224"
128 style="stop-color:#FAF0BB"
129 offset="0.0112" />
130 <stop
131 id="stop226"
132 style="stop-color:#FAF0BD"
133 offset="0.4917" />
134 <stop
135 id="stop228"
136 style="stop-color:#FBF2C5"
137 offset="0.6648" />
138 <stop
139 id="stop230"
140 style="stop-color:#FCF6D0"
141 offset="0.7882" />
142 <stop
143 id="stop232"
144 style="stop-color:#FCF8E1"
145 offset="0.8879" />
146 <stop
147 id="stop234"
148 style="stop-color:#FFFDF7"
149 offset="0.9723" />
150 <stop
151 id="stop236"
152 style="stop-color:#FFFFFF"
153 offset="1" />
154 </radialGradient>
155 <radialGradient
156 inkscape:collect="always"
157 xlink:href="#SVGID_6_"
158 id="radialGradient3312"
159 gradientUnits="userSpaceOnUse"
160 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
161 cx="173.2812"
162 cy="283.68359"
163 r="2.8803999" />
164 <radialGradient
165 gradientUnits="userSpaceOnUse"
166 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
167 r="2.8803999"
168 cy="283.68359"
169 cx="173.2812"
170 id="SVGID_6_">
171 <stop
172 id="stop241"
173 style="stop-color:#FAF0BB"
174 offset="0.0112" />
175 <stop
176 id="stop243"
177 style="stop-color:#FAF0BD"
178 offset="0.4917" />
179 <stop
180 id="stop245"
181 style="stop-color:#FBF2C5"
182 offset="0.6648" />
183 <stop
184 id="stop247"
185 style="stop-color:#FCF6D0"
186 offset="0.7882" />
187 <stop
188 id="stop249"
189 style="stop-color:#FCF8E1"
190 offset="0.8879" />
191 <stop
192 id="stop251"
193 style="stop-color:#FFFDF7"
194 offset="0.9723" />
195 <stop
196 id="stop253"
197 style="stop-color:#FFFFFF"
198 offset="1" />
199 </radialGradient>
200 <radialGradient
201 inkscape:collect="always"
202 xlink:href="#SVGID_7_"
203 id="radialGradient3314"
204 gradientUnits="userSpaceOnUse"
205 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
206 cx="148.9492"
207 cy="270.04489"
208 r="2.8799" />
209 <radialGradient
210 gradientUnits="userSpaceOnUse"
211 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
212 r="2.8799"
213 cy="270.04489"
214 cx="148.9492"
215 id="SVGID_7_">
216 <stop
217 id="stop258"
218 style="stop-color:#FAF0BB"
219 offset="0.0112" />
220 <stop
221 id="stop260"
222 style="stop-color:#FAF0BD"
223 offset="0.4917" />
224 <stop
225 id="stop262"
226 style="stop-color:#FBF2C5"
227 offset="0.6648" />
228 <stop
229 id="stop264"
230 style="stop-color:#FCF6D0"
231 offset="0.7882" />
232 <stop
233 id="stop266"
234 style="stop-color:#FCF8E1"
235 offset="0.8879" />
236 <stop
237 id="stop268"
238 style="stop-color:#FFFDF7"
239 offset="0.9723" />
240 <stop
241 id="stop270"
242 style="stop-color:#FFFFFF"
243 offset="1" />
244 </radialGradient>
245 <radialGradient
246 inkscape:collect="always"
247 xlink:href="#SVGID_8_"
248 id="radialGradient3316"
249 gradientUnits="userSpaceOnUse"
250 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
251 cx="148.0723"
252 cy="319.09381"
253 r="3.9265001" />
254 <radialGradient
255 gradientUnits="userSpaceOnUse"
256 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
257 r="3.9265001"
258 cy="319.09381"
259 cx="148.0723"
260 id="SVGID_8_">
261 <stop
262 id="stop275"
263 style="stop-color:#FAF0BB"
264 offset="0.0112" />
265 <stop
266 id="stop277"
267 style="stop-color:#FAF0BD"
268 offset="0.4917" />
269 <stop
270 id="stop279"
271 style="stop-color:#FBF2C5"
272 offset="0.6648" />
273 <stop
274 id="stop281"
275 style="stop-color:#FCF6D0"
276 offset="0.7882" />
277 <stop
278 id="stop283"
279 style="stop-color:#FCF8E1"
280 offset="0.8879" />
281 <stop
282 id="stop285"
283 style="stop-color:#FFFDF7"
284 offset="0.9723" />
285 <stop
286 id="stop287"
287 style="stop-color:#FFFFFF"
288 offset="1" />
289 </radialGradient>
290 <radialGradient
291 inkscape:collect="always"
292 xlink:href="#SVGID_9_"
293 id="radialGradient3318"
294 gradientUnits="userSpaceOnUse"
295 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
296 cx="112.9551"
297 cy="315.56049"
298 r="3.0683999" />
299 <radialGradient
300 gradientUnits="userSpaceOnUse"
301 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
302 r="3.0683999"
303 cy="315.56049"
304 cx="112.9551"
305 id="SVGID_9_">
306 <stop
307 id="stop292"
308 style="stop-color:#FAF0BB"
309 offset="0.0112" />
310 <stop
311 id="stop294"
312 style="stop-color:#FAF0BD"
313 offset="0.4917" />
314 <stop
315 id="stop296"
316 style="stop-color:#FBF2C5"
317 offset="0.6648" />
318 <stop
319 id="stop298"
320 style="stop-color:#FCF6D0"
321 offset="0.7882" />
322 <stop
323 id="stop300"
324 style="stop-color:#FCF8E1"
325 offset="0.8879" />
326 <stop
327 id="stop302"
328 style="stop-color:#FFFDF7"
329 offset="0.9723" />
330 <stop
331 id="stop304"
332 style="stop-color:#FFFFFF"
333 offset="1" />
334 </radialGradient>
335 <radialGradient
336 inkscape:collect="always"
337 xlink:href="#SVGID_10_"
338 id="radialGradient3320"
339 gradientUnits="userSpaceOnUse"
340 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
341 cx="132.0938"
342 cy="320.1113"
343 r="4.1712999" />
344 <radialGradient
345 gradientUnits="userSpaceOnUse"
346 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
347 r="4.1712999"
348 cy="320.1113"
349 cx="132.0938"
350 id="SVGID_10_">
351 <stop
352 id="stop309"
353 style="stop-color:#FAF0BB"
354 offset="0.0112" />
355 <stop
356 id="stop311"
357 style="stop-color:#FAF0BD"
358 offset="0.4917" />
359 <stop
360 id="stop313"
361 style="stop-color:#FBF2C5"
362 offset="0.6648" />
363 <stop
364 id="stop315"
365 style="stop-color:#FCF6D0"
366 offset="0.7882" />
367 <stop
368 id="stop317"
369 style="stop-color:#FCF8E1"
370 offset="0.8879" />
371 <stop
372 id="stop319"
373 style="stop-color:#FFFDF7"
374 offset="0.9723" />
375 <stop
376 id="stop321"
377 style="stop-color:#FFFFFF"
378 offset="1" />
379 </radialGradient>
380 <radialGradient
381 inkscape:collect="always"
382 xlink:href="#SVGID_11_"
383 id="radialGradient3322"
384 gradientUnits="userSpaceOnUse"
385 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
386 cx="147.44189"
387 cy="301.21091"
388 r="2.5313001" />
389 <radialGradient
390 gradientUnits="userSpaceOnUse"
391 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
392 r="2.5313001"
393 cy="301.21091"
394 cx="147.44189"
395 id="SVGID_11_">
396 <stop
397 id="stop326"
398 style="stop-color:#FAF0BB"
399 offset="0.0112" />
400 <stop
401 id="stop328"
402 style="stop-color:#FAF0BD"
403 offset="0.4917" />
404 <stop
405 id="stop330"
406 style="stop-color:#FBF2C5"
407 offset="0.6648" />
408 <stop
409 id="stop332"
410 style="stop-color:#FCF6D0"
411 offset="0.7882" />
412 <stop
413 id="stop334"
414 style="stop-color:#FCF8E1"
415 offset="0.8879" />
416 <stop
417 id="stop336"
418 style="stop-color:#FFFDF7"
419 offset="0.9723" />
420 <stop
421 id="stop338"
422 style="stop-color:#FFFFFF"
423 offset="1" />
424 </radialGradient>
425 </defs>
426 <sodipodi:namedview
427 id="base"
428 pagecolor="#ffffff"
429 bordercolor="#666666"
430 borderopacity="1.0"
431 inkscape:pageopacity="0.0"
432 inkscape:pageshadow="2"
433 inkscape:zoom="11.197802"
434 inkscape:cx="16"
435 inkscape:cy="16"
436 inkscape:current-layer="layer1"
437 showgrid="true"
438 inkscape:grid-bbox="true"
439 inkscape:document-units="px"
440 inkscape:window-width="1600"
441 inkscape:window-height="876"
442 inkscape:window-x="0"
443 inkscape:window-y="24"
444 inkscape:window-maximized="1" />
445 <metadata
446 id="metadata25905">
447 <rdf:RDF>
448 <cc:Work
449 rdf:about="">
450 <dc:format>image/svg+xml</dc:format>
451 <dc:type
452 rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
453 <dc:title />
454 </cc:Work>
455 </rdf:RDF>
456 </metadata>
457 <g
458 id="layer1"
459 inkscape:label="Layer 1"
460 inkscape:groupmode="layer"
461 transform="translate(0,-16)">
462 <g
463 id="g3183"
464 transform="matrix(0.29719209,0,0,0.25546015,0.77084193,13.764694)">
465 <path
466 d="m 47.748262,36.240641 c -0.304876,-0.669777 -0.939962,-2.526029 -1.264261,-3.180039 -0.499962,-1.005938 -2.409862,-0.340737 -2.850285,-1.402107 -0.615238,-1.481949 0.402841,-3.075783 -0.26687,-4.517046 -0.51052,-1.098494 -2.320767,-1.749962 -2.830861,-2.848458 -0.374128,-0.804542 0.05785,-5.080024 -0.915894,-3.703855 -1.643875,2.32362 -3.133623,4.929999 -4.51865,7.769812 -0.227178,-0.299544 -0.460268,-0.590441 -0.699692,-0.872694 l 1.273972,-2.395837 -1.94875,1.641638 C 33.517528,26.509306 33.303862,26.293167 33.085974,26.08364 l 0.936581,-2.162914 -1.564066,1.585187 C 31.923058,25.034986 31.365246,24.598131 30.785899,24.1984 l 1.168829,-5.78896 -2.873088,4.753021 C 28.796189,23.01091 28.507361,22.866987 28.213887,22.732727 l 0.283762,-3.540102 -1.360114,3.093074 C 25.924369,21.832064 24.65631,21.526925 23.350669,21.385545 l -0.349636,-4.806419 -1.226255,4.716403 c -0.0033,0 -0.0071,0 -0.01056,0 -1.422186,-0.0066 -2.818193,0.185117 -4.164371,0.553823 l -1.190787,-2.856081 0.196351,3.163762 c -0.403261,0.139347 -0.801035,0.294459 -1.193319,0.465334 l -0.676466,-1.193086 0.243647,1.388883 c -0.482226,0.226309 -0.954317,0.47703 -1.416273,0.750127 l -2.649288,-2.676561 1.488058,3.425166 c -0.733893,0.515174 -1.434852,1.088322 -2.09654,1.715887 -0.09374,0.089 -0.187063,0.180031 -0.279538,0.271064 l -2.6176137,-1.775898 1.7557735,2.685206 c -0.2643372,0.297002 -0.5214955,0.60519 -0.7718972,0.922533 l -2.0728961,-1.396004 1.4580788,2.215805 c -0.340767,0.479065 -0.6650662,0.978474 -0.9716305,1.49568 -1.2705932,0.251233 -2.4081735,1.157486 -3.0905527,2.497041 0.00253,-0.005 0.00508,-0.01071 0.00802,-0.01578 -0.5079841,0.01071 -0.9074462,0.311242 -1.1177337,1.046115 -0.7347402,2.568744 -0.5366981,4.375156 0.1689057,5.408554 -0.1199231,0.09664 -0.2373126,0.202409 -0.3517463,0.317854 -1.90145688,1.925922 -2.20548742,5.78845 -0.6790012,8.625208 0.8470624,1.574001 2.0796522,2.501617 3.3341996,2.686733 0.6452198,1.719448 1.4880601,3.337183 2.5116286,4.809977 3.3333522,4.799809 8.4203702,7.849148 14.2412852,7.722516 5.766442,-0.126125 10.741561,-3.352949 13.962593,-8.195477 2.268826,-3.410417 3.604027,-7.536378 3.803758,-11.87187 L 41.77997,42.904823 39.623044,42.4461 c 0.003,-0.734364 -0.02618,-1.473813 -0.08952,-2.215806 l 3.332089,-2.112565 -3.537731,0.400746 C 39.264542,38.110618 39.19107,37.708348 39.108306,37.31116 l 0.959807,-0.628583 -1.067483,0.13782 c -0.02618,-0.113909 -0.05278,-0.226818 -0.08023,-0.33972 2.756541,-0.434818 5.473393,-0.393116 8.225288,0.328024 0.699694,0.183591 0.893512,0.07272 0.602574,-0.568064 z M 3.2551113,34.170284 c -0.017313,0.06662 -0.033782,0.134262 -0.04856,0.202916 -0.0114,0.05139 -0.022381,0.102733 -0.032514,0.154602 0.010132,-0.05188 0.020692,-0.10325 0.032514,-0.154602 0.01478,-0.06866 0.031247,-0.136294 0.04856,-0.202916 z m 0.4049515,-1.11121 c -0.010132,0.02085 -0.020269,0.04223 -0.030404,0.06306 0.010132,-0.02085 0.02027,-0.04222 0.030404,-0.06306 z m -0.079808,0.172404 c -0.010557,0.02339 -0.020692,0.0473 -0.030825,0.07119 0.010132,-0.02389 0.02027,-0.04782 0.030825,-0.07119 z m -0.075164,0.177488 c -0.010557,0.02644 -0.021113,0.0529 -0.031248,0.07984 0.010132,-0.02694 0.020692,-0.0534 0.031248,-0.07984 z m -0.070097,0.182573 c -0.010979,0.03002 -0.021535,0.06 -0.032092,0.09001 0.010557,-0.03002 0.021113,-0.06002 0.032092,-0.09001 z m -0.06545,0.187661 c -0.01098,0.03407 -0.021535,0.06866 -0.032515,0.103238 0.010979,-0.03458 0.021113,-0.06866 0.032515,-0.103238 z m -0.059962,0.193252 c -0.011823,0.04119 -0.023225,0.08289 -0.034626,0.124599 0.0114,-0.04172 0.022381,-0.08342 0.034626,-0.124599 z m -0.2558905,1.703683 c -8.452e-4,0.05034 -8.452e-4,0.100695 -4.223e-4,0.150535 -4.223e-4,-0.05034 -4.223e-4,-0.100705 4.223e-4,-0.150535 z m 0.1106333,-1.097477 c -0.00633,0.03458 -0.012668,0.06866 -0.018578,0.103239 0.00591,-0.03407 0.012245,-0.06866 0.018578,-0.103239 z m -0.028713,0.164775 c -0.00507,0.03153 -0.010132,0.06256 -0.01478,0.09357 0.00464,-0.03101 0.00971,-0.06204 0.01478,-0.09357 z m -0.023646,0.15867 c -0.00423,0.03053 -0.00802,0.06053 -0.011823,0.09052 0.00379,-0.03052 0.0076,-0.06054 0.011823,-0.09052 z m -0.019423,0.156131 c -0.00338,0.03002 -0.00633,0.05949 -0.00929,0.0895 0.00296,-0.03002 0.00591,-0.05951 0.00929,-0.0895 z m -0.015624,0.155617 c -0.00253,0.03002 -0.00464,0.06001 -0.00717,0.09001 0.00253,-0.03002 0.00508,-0.06001 0.00717,-0.09001 z m -0.0114,0.154604 c -0.0017,0.03154 -0.00338,0.06256 -0.00507,0.09408 0.0017,-0.03153 0.00338,-0.06256 0.00507,-0.09408 z m -0.0076,0.154095 c -0.00127,0.03662 -0.00211,0.07322 -0.00296,0.109332 4.221e-4,-0.03662 0.00127,-0.07272 0.00296,-0.109332 z m 0.1634162,1.705207 c -0.0076,-0.03203 -0.01478,-0.06407 -0.021535,-0.09611 0.00718,0.03205 0.013934,0.06407 0.021535,0.09611 z m -0.037161,-0.168331 c -0.00802,-0.03865 -0.015624,-0.07728 -0.023225,-0.115944 0.0076,0.03865 0.015624,0.07729 0.023225,0.115944 z m -0.033785,-0.176983 c -0.00507,-0.02847 -0.010132,-0.05696 -0.01478,-0.08543 0.00464,0.02795 0.010132,0.05696 0.01478,0.08543 z m -0.024491,-0.152059 c -0.00423,-0.02694 -0.00844,-0.05392 -0.012245,-0.08138 0.00379,0.02694 0.0076,0.05442 0.012245,0.08138 z m -0.021113,-0.150025 c -0.00338,-0.02694 -0.00675,-0.0534 -0.00971,-0.08086 0.00296,0.02747 0.00633,0.05442 0.00971,0.08086 z m -0.017313,-0.149518 c -0.00296,-0.02694 -0.00549,-0.05392 -0.00802,-0.08137 0.00253,0.02747 0.00508,0.05441 0.00802,0.08137 z m -0.013934,-0.150024 c -0.00211,-0.02795 -0.00423,-0.05546 -0.00591,-0.08341 0.0017,0.02747 0.00379,0.05544 0.00591,0.08341 z m -0.010132,-0.150536 c -0.0017,-0.0295 -0.00296,-0.059 -0.00423,-0.0885 0.00127,0.0295 0.00253,0.05898 0.00423,0.0885 z m -0.00675,-0.15206 c -0.00127,-0.03356 -0.0017,-0.06765 -0.00211,-0.101717 0,0.03407 8.451e-4,0.06814 0.00211,0.101717 z m 0.180307,1.313616 c 0.00633,0.02644 0.012668,0.0529 0.019424,0.07882 -0.00633,-0.02644 -0.012668,-0.05239 -0.019424,-0.07882 z m 0.1811488,1.679273 c -0.00211,9.74e-4 -0.00423,0.0021 -0.00633,0.003 0,0 0,0 4.224e-4,0 0.015624,-0.01072 0.031247,-0.02137 0.046871,-0.03205 -0.013511,0.0097 -0.027025,0.01933 -0.04096,0.02896 z M 3.2745435,37.437285 c 0.00675,0.02492 0.013511,0.04984 0.020692,0.07476 -0.00717,-0.02492 -0.013934,-0.04984 -0.020692,-0.07476 z m 0.040537,0.141888 c 0.00717,0.0244 0.014357,0.04883 0.021957,0.07272 -0.00717,-0.0244 -0.014779,-0.04832 -0.021957,-0.07272 z m 0.043072,0.139347 c 0.00802,0.02389 0.015624,0.04782 0.023646,0.0717 -0.0076,-0.02389 -0.015624,-0.04728 -0.023646,-0.0717 z m 0.046449,0.137819 c 0.00844,0.02389 0.016891,0.04782 0.025758,0.07171 -0.00844,-0.02389 -0.017313,-0.0473 -0.025758,-0.07171 z m 0.049405,0.135789 c 0.00929,0.0244 0.019001,0.04883 0.028292,0.07322 -0.00929,-0.02441 -0.019001,-0.04831 -0.028292,-0.07322 z m 0.052361,0.134256 c 0.010979,0.02747 0.022803,0.05442 0.034203,0.08188 -0.0114,-0.02747 -0.023225,-0.05442 -0.034203,-0.08188 z m 0.055317,0.13223 c 0.018158,0.04223 0.037159,0.08491 0.056584,0.12663 -0.019001,-0.04223 -0.038005,-0.0844 -0.056584,-0.12663 z m 0.081498,0.178505 c 0.012245,0.02543 0.024491,0.05086 0.036737,0.07627 -0.012668,-0.02543 -0.024491,-0.05086 -0.036737,-0.07627 z m 0.065028,0.132734 c 0.011824,0.02339 0.023646,0.04678 0.035893,0.07019 -0.012246,-0.02339 -0.024069,-0.04678 -0.035893,-0.07019 z m 0.066295,0.12714 c 0.00802,0.01423 0.015624,0.029 0.023646,0.04272 -0.012668,0.0066 -0.025336,0.01272 -0.037582,0.01933 0.012246,-0.0066 0.02449,-0.01373 0.036737,-0.01983 -0.00802,-0.01373 -0.015202,-0.02797 -0.022803,-0.04223 z"
467 id="path5"
468 inkscape:connector-curvature="0" />
469 <path
470 d="m 46.872485,35.321668 c -0.295587,-0.574676 -0.59117,-1.149351 -0.887179,-1.724024 -0.411284,-0.79946 -2.442377,-0.780135 -2.853662,-1.579594 -0.640154,-1.243435 0.339923,-3.306671 -0.300232,-4.550104 -0.487293,-0.94745 -2.164949,-1.469746 -2.652242,-2.417196 -0.272784,-0.53043 -0.355546,-1.274964 -0.330633,-1.912193 0.05237,-1.364979 0.09627,-2.14664 -0.825104,-0.815224 -1.463147,2.115108 -2.790324,4.459071 -4.019957,7.001881 0.08403,0.130191 0.166794,0.262928 0.248715,0.39617 1.867674,-0.780645 3.579534,-1.925924 5.084062,-3.359053 -1.390517,1.582138 -3.033126,2.860154 -4.860686,3.733354 0.119078,0.203934 0.236469,0.410917 0.350057,0.620953 -0.87662,-1.47788 -1.904834,-2.797597 -3.043681,-3.931183 l -0.220844,0.510597 1.016812,-2.721313 -1.72115,1.539922 0.100502,-0.101717 c -0.426911,-0.375317 -0.869023,-0.727243 -1.324646,-1.05679 l -0.259691,1.287172 0.928137,-6.116986 -3.276349,4.782515 0.695047,-1.149347 C 27.064907,22.874104 25.27366,22.28112 23.39754,22.038534 l 0.05785,0.790309 -0.581035,-4.788622 -1.425989,4.509928 0.165107,-0.635193 c -0.02449,0 -0.04899,-9.74e-4 -0.07348,-9.74e-4 -2.69658,-0.0122 -5.297306,0.706904 -7.628628,2.005263 l 0.994011,1.003896 -3.222299,-2.891682 1.639229,4.403639 -0.736427,-1.695038 c -0.777812,0.531955 -1.518886,1.130533 -2.214777,1.791154 -0.5865257,0.556877 -1.1460249,1.161557 -1.6734311,1.809973 l 0.3800423,0.25581 -2.2287093,-1.303955 1.2275217,2.117143 -0.091631,-0.139345 c -0.260959,0.36159 -0.5122061,0.73538 -0.7533194,1.120363 0,0 4.226e-4,0 4.226e-4,0 0.058698,-0.0046 0.1178119,-0.0076 0.1769282,-0.0097 0.4197311,-0.01322 0.848329,0.04476 1.274816,0.182576 0.9543158,0.307679 1.753238,0.965757 2.327517,1.82777 1.042571,-3.636727 4.259803,-5.735561 7.393005,-4.724541 3.275504,1.057303 5.220032,5.114101 4.342567,9.059015 -0.238157,1.070014 -0.659578,2.022044 -1.212743,2.819977 0.07093,0.03205 0.14188,0.06509 0.212399,0.100705 0.08361,0.04223 0.165949,0.08645 0.247024,0.132733 -2.976541,-1.313107 -6.314119,0.418546 -7.548398,3.975938 -1.2347,3.558409 0.08783,7.634533 2.955006,9.262947 -0.08446,-0.03713 -0.168483,-0.07627 -0.252515,-0.118496 -3.038191,-1.529246 -4.4722,-5.736577 -3.202452,-9.39619 0.218733,-0.629601 0.502918,-1.20224 0.839884,-1.711309 -1.472858,-0.618921 -2.639575,-1.861338 -3.348979,-3.411436 -0.588214,1.277509 -1.5788438,2.193938 -2.71769,2.574851 0.033789,0.06461 0.067143,0.129174 0.099654,0.195797 1.344911,2.750302 0.9285586,6.379401 -0.9298248,8.103932 -0.051515,0.04782 -0.1038771,0.09407 -0.1566596,0.137821 h 0 c 0.026184,-0.02694 0.05236,-0.05442 0.078121,-0.08188 8.773e-4,-0.0014 0.00167,-0.0026 0.00296,-0.0036 0.024916,-0.02694 0.049402,-0.05442 0.073895,-0.08239 0.00128,-0.0021 0.00296,-0.0036 0.00462,-0.005 0.024071,-0.02795 0.047713,-0.05545 0.070937,-0.08341 0.00167,-0.0026 0.00384,-0.0046 0.0055,-0.0071 0.023227,-0.02796 0.045607,-0.05543 0.067989,-0.08391 0.00216,-0.003 0.00423,-0.0061 0.00675,-0.0086 0.021955,-0.02847 0.043919,-0.05646 0.065029,-0.08542 0.00251,-0.003 0.00512,-0.0066 0.0072,-0.0097 0.021109,-0.02847 0.042228,-0.05696 0.062493,-0.08645 0.00251,-0.0036 0.00512,-0.0072 0.00755,-0.01071 0.020265,-0.0295 0.040538,-0.05799 0.060379,-0.08797 0.00251,-0.004 0.00512,-0.0076 0.008,-0.01121 0.01942,-0.0295 0.038848,-0.05898 0.058277,-0.08899 0.00251,-0.0046 0.00549,-0.0086 0.008,-0.0122 0.018997,-0.03002 0.037589,-0.06 0.055741,-0.09052 0.00251,-0.0046 0.00549,-0.0086 0.008,-0.01272 0.018152,-0.03052 0.036322,-0.06103 0.054051,-0.09204 0.00251,-0.0046 0.00512,-0.009 0.008,-0.01322 0.017729,-0.03153 0.035054,-0.06204 0.052361,-0.09357 0.00251,-0.005 0.00513,-0.0097 0.00755,-0.01373 0.017306,-0.03153 0.033789,-0.06306 0.050253,-0.09508 0.00251,-0.005 0.00513,-0.0097 0.00755,-0.01423 0.016464,-0.03153 0.032521,-0.06407 0.048559,-0.09613 0.00213,-0.005 0.00455,-0.0097 0.00716,-0.01425 0.015622,-0.03253 0.031254,-0.06509 0.046458,-0.09816 0.00213,-0.0046 0.00426,-0.0097 0.00677,-0.01373 0.015206,-0.03304 0.030402,-0.06713 0.045191,-0.100694 0.00213,-0.004 0.00387,-0.009 0.0059,-0.01272 0.01478,-0.03409 0.029559,-0.06865 0.043913,-0.102733 0.00175,-0.0046 0.00329,-0.0086 0.00513,-0.0122 0.014354,-0.03508 0.028291,-0.07019 0.042229,-0.105275 0.00126,-0.004 0.003,-0.0082 0.00426,-0.0112 0.013937,-0.0356 0.027449,-0.07222 0.040961,-0.108333 8.768e-4,-0.003 0.00213,-0.0061 0.00329,-0.0097 0.013511,-0.03662 0.026607,-0.07425 0.039693,-0.111368 8.769e-4,-0.0026 0.00175,-0.005 0.00251,-0.0076 0.013085,-0.03815 0.026181,-0.07627 0.038425,-0.115439 0,-9.73e-4 4.229e-4,-0.0021 8.769e-4,-0.0026 0.1570825,-0.485678 0.2630703,-1.002882 0.3166975,-1.535857 4.228e-4,-0.004 8.777e-4,-0.0082 0.00124,-0.01118 0.00383,-0.03762 0.00713,-0.07528 0.010132,-0.113404 4.219e-4,-0.0082 0.00124,-0.01576 0.00217,-0.02389 0.003,-0.03458 0.00548,-0.06968 0.00755,-0.104238 8.767e-4,-0.01071 0.00176,-0.02238 0.00248,-0.03305 0.00217,-0.03253 0.00383,-0.06561 0.00548,-0.09816 4.218e-4,-0.01322 0.00124,-0.02644 0.00217,-0.03917 0.00176,-0.03153 0.00248,-0.06306 0.00383,-0.09459 4.229e-4,-0.01474 8.778e-4,-0.03002 0.00176,-0.04425 8.777e-4,-0.03052 0.00124,-0.06053 0.00217,-0.09052 4.228e-4,-0.01627 8.777e-4,-0.03253 8.777e-4,-0.04883 4.229e-4,-0.0295 4.229e-4,-0.05799 4.229e-4,-0.08747 0,-0.01728 0,-0.03459 0,-0.05239 0,-0.02847 -4.229e-4,-0.05644 -8.778e-4,-0.08492 0,-0.01831 -4.228e-4,-0.03611 -4.228e-4,-0.05441 -4.208e-4,-0.02796 -0.00124,-0.05544 -0.00217,-0.08339 -4.229e-4,-0.0188 -8.767e-4,-0.03763 -0.00176,-0.05645 -8.767e-4,-0.02694 -0.00217,-0.0534 -0.00331,-0.08086 -8.768e-4,-0.01984 -0.00176,-0.03918 -0.003,-0.05899 -0.00124,-0.02694 -0.003,-0.0529 -0.00455,-0.07935 -0.00124,-0.02032 -0.00248,-0.04068 -0.00383,-0.06053 -0.00176,-0.02644 -0.00383,-0.05238 -0.00589,-0.07832 -0.00176,-0.02085 -0.00331,-0.04119 -0.00517,-0.06204 -0.00217,-0.02594 -0.00455,-0.05138 -0.00713,-0.0768 -0.00176,-0.02136 -0.00424,-0.04222 -0.00631,-0.06307 -0.00248,-0.02543 -0.00548,-0.05086 -0.00842,-0.07577 -0.00251,-0.02185 -0.00513,-0.04323 -0.00755,-0.06461 -0.003,-0.02492 -0.0059,-0.04985 -0.00929,-0.07425 -0.003,-0.02185 -0.0059,-0.04375 -0.0089,-0.06561 -0.00329,-0.02492 -0.00677,-0.04934 -0.01056,-0.07425 -0.00329,-0.02185 -0.00677,-0.04425 -0.010132,-0.06612 -0.00387,-0.02439 -0.00755,-0.04883 -0.011401,-0.07322 -0.00387,-0.02237 -0.00755,-0.04476 -0.011401,-0.06661 -0.00426,-0.02441 -0.00842,-0.04831 -0.01267,-0.07221 -0.00426,-0.02288 -0.00842,-0.04526 -0.01267,-0.06765 -0.00455,-0.02389 -0.0089,-0.04782 -0.013937,-0.07119 -0.00455,-0.02288 -0.00929,-0.04526 -0.013938,-0.06815 -0.00513,-0.0234 -0.00971,-0.04729 -0.015206,-0.07069 -0.00513,-0.02288 -0.010132,-0.04576 -0.015206,-0.06866 -0.00513,-0.02288 -0.010549,-0.04629 -0.016047,-0.06915 -0.00552,-0.02339 -0.010976,-0.04629 -0.01688,-0.06915 -0.00552,-0.02288 -0.010975,-0.04576 -0.01688,-0.06814 -0.0059,-0.02339 -0.011827,-0.04678 -0.018148,-0.06968 -0.0059,-0.02288 -0.011818,-0.04527 -0.018148,-0.06765 -0.0063,-0.0234 -0.01267,-0.04628 -0.019416,-0.06968 -0.0063,-0.02238 -0.01267,-0.04425 -0.018999,-0.06661 -0.00677,-0.0234 -0.013937,-0.04678 -0.021109,-0.07019 -0.00677,-0.02185 -0.013086,-0.04374 -0.019842,-0.0656 -0.00755,-0.02389 -0.015206,-0.0473 -0.022804,-0.0707 -0.00677,-0.02136 -0.013937,-0.0427 -0.020683,-0.0646 -0.00803,-0.02339 -0.016038,-0.04679 -0.024071,-0.07069 -0.00755,-0.02085 -0.014354,-0.04222 -0.021952,-0.06306 -0.00842,-0.0244 -0.017306,-0.04831 -0.026181,-0.07221 -0.00755,-0.02031 -0.01478,-0.04069 -0.022378,-0.06103 -0.0089,-0.02441 -0.018574,-0.04883 -0.027875,-0.07272 -0.00755,-0.02032 -0.015206,-0.04018 -0.022804,-0.05949 -0.00971,-0.02492 -0.019842,-0.04933 -0.029985,-0.07425 -0.00803,-0.01865 -0.015622,-0.03799 -0.023645,-0.05732 -0.010975,-0.02594 -0.021952,-0.05188 -0.033363,-0.0768 -0.00755,-0.0178 -0.015206,-0.0351 -0.022804,-0.0529 -0.01267,-0.0295 -0.026182,-0.05799 -0.039267,-0.08696 -0.00677,-0.0137 -0.01267,-0.02845 -0.019416,-0.04219 C 8.552808,41.518875 8.532531,41.476167 8.511847,41.433436 7.1669757,38.683133 4.5692051,37.851124 2.7108196,39.57515 0.85243366,41.299176 0.436081,44.928276 1.7809934,47.678578 c 0.023225,0.04782 0.046871,0.0951 0.07094,0.140872 0.0076,0.01474 0.015624,0.0295 0.023225,0.04425 0.01689,0.03153 0.033358,0.06307 0.05025,0.09459 0.00887,0.01626 0.018158,0.03307 0.027448,0.04985 0.016468,0.0295 0.032514,0.05799 0.048982,0.08645 0.00929,0.01627 0.018578,0.03253 0.028291,0.04883 0.017735,0.03002 0.035048,0.0595 0.053205,0.0885 0.00844,0.01373 0.01689,0.02795 0.025336,0.04172 0.024491,0.03917 0.048983,0.07729 0.073473,0.115944 0.00211,0.0036 0.00423,0.0072 0.00633,0.01012 0.027025,0.0417 0.054894,0.0824 0.082765,0.123071 0.00802,0.01121 0.015624,0.02237 0.023646,0.03305 0.020269,0.02896 0.040538,0.05746 0.061228,0.08595 0.00971,0.01322 0.019424,0.02694 0.029136,0.03966 0.019423,0.02644 0.038848,0.05239 0.058271,0.07729 0.00971,0.01271 0.019847,0.02594 0.029981,0.03865 0.020692,0.02694 0.041381,0.0529 0.062496,0.0783 0.00887,0.01071 0.017735,0.02185 0.026181,0.03255 0.027025,0.03305 0.054473,0.06561 0.082342,0.09764 0.00253,0.003 0.00464,0.0061 0.00718,0.0086 0.031248,0.03611 0.062496,0.07119 0.094165,0.105779 0.00591,0.0066 0.011823,0.0122 0.017735,0.0188 0.025337,0.02747 0.050671,0.05392 0.076429,0.08086 0.00887,0.0097 0.018158,0.0183 0.027448,0.02796 0.023226,0.02339 0.046027,0.0468 0.069674,0.06969 0.00929,0.0097 0.019001,0.0183 0.028292,0.02796 0.024491,0.02339 0.048982,0.04678 0.073473,0.06915 0.00802,0.0076 0.016046,0.01474 0.024069,0.02238 0.031247,0.02847 0.062496,0.05645 0.094587,0.08391 0.00127,9.74e-4 0.00253,0.0021 0.00338,0.003 0.035048,0.03002 0.070097,0.05898 0.1051438,0.08747 0.0017,0.0014 0.00338,0.003 0.00508,0.0046 0.032091,0.02594 0.064184,0.05086 0.096698,0.07527 0.00718,0.0056 0.014357,0.01073 0.021535,0.01578 0.027448,0.02085 0.055317,0.04069 0.083186,0.0605 0.00802,0.0061 0.016046,0.01121 0.024069,0.01678 0.028293,0.02032 0.057006,0.03967 0.08572,0.059 0.00633,0.004 0.012668,0.0086 0.019424,0.0122 0.1072551,0.07119 0.2166217,0.135784 0.3268326,0.193761 0.00423,0.0021 0.00887,0.0046 0.01309,0.0066 0.032515,0.01678 0.064607,0.03307 0.097121,0.04883 0.0059,0.003 0.012246,0.0061 0.018158,0.009 0.032092,0.01524 0.064607,0.03052 0.096698,0.04425 0.00464,0.0021 0.00929,0.0046 0.014356,0.0066 0.1135892,0.04933 0.2284449,0.09256 0.3433009,0.128156 0.0017,5.1e-4 0.00338,9.74e-4 0.00549,0.0014 0.035892,0.0112 0.071785,0.02187 0.1076773,0.03154 0.00464,9.73e-4 0.00929,0.0026 0.013934,0.0036 0.034626,0.0097 0.068829,0.0178 0.1034547,0.02594 0.00379,9.74e-4 0.00802,0.0021 0.011824,0.003 0.1169673,0.02694 0.2343567,0.04679 0.3517462,0.05951 l 0,0 c 0.6481757,1.849131 1.52733,3.584344 2.6163505,5.151733 3.2493206,4.67828 8.2075476,7.650825 13.8810926,7.526736 5.62076,-0.12256 10.470044,-3.267511 13.60958,-7.987475 2.711782,-4.077649 4.055427,-9.202937 3.667366,-14.468077 l -0.625796,0.397186 3.441877,-2.497548 -4.004333,0.160197 0.94925,-0.107311 c -0.220421,-1.378712 -0.556544,-2.696396 -0.990631,-3.942371 0.168484,0.428718 0.325565,0.867097 0.469134,1.315141 2.798347,-0.571116 5.565447,-0.68554 8.28863,-0.151043 0.771477,0.153076 0.933204,0.41702 0.464491,-0.493815 z m -12.799679,3.703349 c -0.150327,4.243438 -1.599116,6.202419 -3.283952,6.35143 -0.291784,0.02594 -0.581036,-0.003 -0.882953,-0.08339 0.127101,0.01169 0.25378,0.01373 0.380461,0.005 0.947982,-0.0656 1.826292,-0.718089 2.438574,-2.048996 -1.654432,-1.002882 -3.38487,-1.607564 -5.059992,-1.826755 1.684833,0.07272 3.4651,0.599086 5.159647,1.598919 0.215777,-0.520259 0.393129,-1.134093 0.522342,-1.846589 -1.866407,-0.63926 -3.746752,-0.830988 -5.497882,-0.626039 1.72875,-0.355486 3.641185,-0.255806 5.541374,0.37074 0.08615,-0.535514 0.146526,-1.122905 0.176508,-1.764709 0.0114,-0.238514 -0.003,-0.451602 -0.03927,-0.641804 -2.009135,-0.114427 -3.941838,0.243602 -5.656652,0.971863 1.643451,-0.864048 3.568132,-1.320736 5.586133,-1.236826 -0.412129,-1.186475 -1.895967,-1.250044 -3.554621,-0.903205 2.210554,-0.579759 4.250091,-0.552808 4.170283,1.68029 z m 2.44111,-7.055789 c 1.92468,-0.563996 3.721414,-1.511446 5.334888,-2.770136 -1.510441,1.419396 -3.24806,2.506191 -5.138958,3.16783 -0.06418,-0.133245 -0.129212,-0.265977 -0.19593,-0.397694 z m 0.825526,1.842519 c -0.05574,-0.141379 -0.112746,-0.282252 -0.171017,-0.421598 1.999844,-0.298525 3.997577,-0.112402 5.887635,0.505511 -1.862188,-0.401765 -3.791937,-0.442449 -5.716618,-0.08392 z"
471 id="path14"
472 style="fill:#f0a513;fill-opacity:1"
473 inkscape:connector-curvature="0" />
474 <path
475 d="m 17.971864,28.383357 c 3.029325,0.977457 4.82775,4.729117 4.016157,8.37805 -0.214087,0.963215 -0.589481,1.823193 -1.080996,2.549419 -2.202109,-0.672827 -4.51105,0.238008 -5.964907,2.257001 -2.974852,-1.022212 -4.729782,-4.734713 -3.926214,-8.347029 0.811593,-3.648933 3.926636,-5.815407 6.95596,-4.837441 z"
476 id="path16"
477 inkscape:connector-curvature="0"
478 style="fill:#ffffff" />
479 <path
480 d="m 21.46948,31.675787 c 0.688291,1.496188 0.915048,3.303109 0.518541,5.08562 -0.214087,0.963215 -0.589481,1.823193 -1.080996,2.549419 -2.202532,-0.672827 -4.511474,0.238008 -5.965329,2.257001 -1.217389,-0.418038 -2.2304,-1.28768 -2.947405,-2.415671 0.307831,0.161723 0.630018,0.298527 0.964451,0.406343 3.605716,1.163589 7.313197,-1.414313 8.279337,-5.756922 0.157927,-0.710463 0.232246,-1.423974 0.231401,-2.12579 z"
481 id="path18"
482 inkscape:connector-curvature="0"
483 style="fill:#eeeeee" />
484 <path
485 d="m 11.148494,37.665629 c -0.473779,-1.361928 -0.61397,-2.903379 -0.33232,-4.44127 -0.52952,-1.020176 -1.3685584,-1.810482 -2.4090152,-2.146133 -2.1826849,-0.704357 -4.4270197,0.856418 -5.0118558,3.484667 -0.3242991,1.457031 -0.070517,2.936437 0.5915924,4.085786 1.0683288,-0.4694 2.2489802,-0.271571 3.2581915,0.503477 0.4619579,0.354468 0.8876005,0.829465 1.2503252,1.416854 1.1793816,-0.417022 2.1776139,-1.463641 2.6530819,-2.903381 z"
486 id="path20"
487 inkscape:connector-curvature="0"
488 style="fill:#ffffff" />
489 <path
490 d="m 31.2411,51.394259 1.26637,0.637229 -2.465178,-0.01373 c -4.530473,2.179698 -9.426207,2.60994 -12.629927,1.007461 -0.08825,-0.03864 -0.176507,-0.07984 -0.264338,-0.124092 -3.038191,-1.529243 -4.472201,-5.736578 -3.202453,-9.39619 0.218732,-0.6296 0.503339,-1.202239 0.840306,-1.710803 l 0,-5.07e-4 c -1.472857,-0.618925 -2.639574,-1.861849 -3.348978,-3.411437 -0.588215,1.277507 -1.5788467,2.193936 -2.7176907,2.574848 0.033779,0.06461 0.067143,0.129175 0.099655,0.195796 1.3449097,2.750303 0.9285573,6.379402 -0.9298254,8.103935 -0.051515,0.04782 -0.1038771,0.09408 -0.1566605,0.137821 l 0,0 c -0.048979,0.05034 -0.098387,0.09866 -0.1494812,0.145956 -0.7486746,0.694696 -1.6176949,0.974406 -2.4761587,0.880322 l 0,5.08e-4 c 0.6477536,1.848622 1.5273307,3.584344 2.6159279,5.151732 3.2493226,4.678262 8.2075486,7.650298 13.8810926,7.526717 5.620762,-0.12256 10.470046,-3.268018 13.609581,-7.987982 2.123568,-3.192243 3.407673,-7.028327 3.678768,-11.070884 -1.87021,3.185631 -4.634352,5.665888 -7.651009,7.353296 z"
491 id="path183"
492 style="fill:#fdd99b"
493 inkscape:connector-curvature="0" />
494 <path
495 d="m 11.261241,44.175223 c -0.158773,-0.250722 -0.250827,-0.566539 -0.243648,-0.906768 0.01224,-0.584846 0.312898,-1.079675 0.733895,-1.291745 -0.616928,0.507545 -0.839039,1.75098 -0.173129,2.336839 0.277429,0.243604 0.439579,0.574168 0.370749,1.028824 -0.05363,0.355991 -0.262648,0.802509 -0.591168,1.144265 -0.374972,0.389558 -0.833129,0.599593 -1.228791,0.541109 0.37835,-0.112404 0.757541,-0.387016 1.06284,-0.752165 0.26307,-0.314291 0.444644,-0.675369 0.519384,-0.97542 0.14906,-0.596542 -0.181995,-0.701818 -0.450132,-1.124939 l 0,0 z m 1.895122,4.408723 c -0.233935,0.931683 -0.952208,1.610106 -1.802226,1.610106 -0.765564,0 -1.4251397,-0.551279 -1.7190352,-1.342094 0.3783472,0.632143 0.9944302,1.044078 1.6907442,1.044078 0.790057,0 1.477502,-0.530939 1.830517,-1.31209 z"
496 id="path185"
497 inkscape:connector-curvature="0" />
498 <g
499 id="g187"
500 transform="matrix(0.42226435,0,0,0.50856192,-47.726977,-111.72952)">
501 <radialGradient
502 id="radialGradient3241"
503 cx="163.4902"
504 cy="274.86621"
505 r="2.8801"
506 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
507 gradientUnits="userSpaceOnUse">
508 <stop
509 offset="0.0112"
510 style="stop-color:#FAF0BB"
511 id="stop3243" />
512 <stop
513 offset="0.4917"
514 style="stop-color:#FAF0BD"
515 id="stop3245" />
516 <stop
517 offset="0.6648"
518 style="stop-color:#FBF2C5"
519 id="stop3247" />
520 <stop
521 offset="0.7882"
522 style="stop-color:#FCF6D0"
523 id="stop3249" />
524 <stop
525 offset="0.8879"
526 style="stop-color:#FCF8E1"
527 id="stop3251" />
528 <stop
529 offset="0.9723"
530 style="stop-color:#FFFDF7"
531 id="stop3253" />
532 <stop
533 offset="1"
534 style="stop-color:#FFFFFF"
535 id="stop3255" />
536 </radialGradient>
537 <path
538 d="m 189.806,311.298 c -0.681,-0.478 -1.432,-0.68 -2.1,-0.645 -0.633,0.034 -1.217,0.284 -1.625,0.739 -0.408,0.454 -0.59,1.052 -0.559,1.676 0.034,0.653 0.305,1.364 0.834,1.98 0.577,0.671 1.35,1.108 2.143,1.244 0.845,0.145 1.679,-0.06 2.247,-0.657 0.573,-0.604 0.725,-1.448 0.515,-2.282 -0.199,-0.789 -0.713,-1.534 -1.455,-2.055 z"
539 id="path204"
540 style="fill:url(#radialGradient3305)"
541 inkscape:connector-curvature="0" />
542 <radialGradient
543 id="radialGradient3258"
544 cx="155.3242"
545 cy="310.6777"
546 r="4.4867001"
547 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
548 gradientUnits="userSpaceOnUse">
549 <stop
550 offset="0.0112"
551 style="stop-color:#FAF0BB"
552 id="stop3260" />
553 <stop
554 offset="0.4917"
555 style="stop-color:#FAF0BD"
556 id="stop3262" />
557 <stop
558 offset="0.6648"
559 style="stop-color:#FBF2C5"
560 id="stop3264" />
561 <stop
562 offset="0.7882"
563 style="stop-color:#FCF6D0"
564 id="stop3266" />
565 <stop
566 offset="0.8879"
567 style="stop-color:#FCF8E1"
568 id="stop3268" />
569 <stop
570 offset="0.9723"
571 style="stop-color:#FFFDF7"
572 id="stop3270" />
573 <stop
574 offset="1"
575 style="stop-color:#FFFFFF"
576 id="stop3272" />
577 </radialGradient>
578 <path
579 d="m 183.164,274.256 c -0.777,-0.621 -1.774,-0.996 -2.853,-1 -1.077,-0.004 -2.096,0.366 -2.89,0.992 -0.839,0.661 -1.465,1.633 -1.646,2.791 -0.197,1.263 0.167,2.499 0.961,3.449 0.841,1.005 2.124,1.644 3.592,1.617 1.455,-0.026 2.71,-0.702 3.522,-1.716 0.762,-0.951 1.106,-2.168 0.913,-3.4 -0.179,-1.131 -0.786,-2.082 -1.599,-2.733 z"
580 id="path221"
581 style="fill:url(#radialGradient3307)"
582 inkscape:connector-curvature="0" />
583 <radialGradient
584 id="radialGradient3275"
585 cx="170.3125"
586 cy="302.00781"
587 r="5.0811"
588 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
589 gradientUnits="userSpaceOnUse">
590 <stop
591 offset="0.0112"
592 style="stop-color:#FAF0BB"
593 id="stop3277" />
594 <stop
595 offset="0.4917"
596 style="stop-color:#FAF0BD"
597 id="stop3279" />
598 <stop
599 offset="0.6648"
600 style="stop-color:#FBF2C5"
601 id="stop3281" />
602 <stop
603 offset="0.7882"
604 style="stop-color:#FCF6D0"
605 id="stop3283" />
606 <stop
607 offset="0.8879"
608 style="stop-color:#FCF8E1"
609 id="stop3285" />
610 <stop
611 offset="0.9723"
612 style="stop-color:#FFFDF7"
613 id="stop3287" />
614 <stop
615 offset="1"
616 style="stop-color:#FFFFFF"
617 id="stop3289" />
618 </radialGradient>
619 <path
620 d="m 197.254,290.925 c 1.482,-0.322 2.697,-1.225 3.201,-2.604 0.5,-1.367 0.166,-2.845 -0.726,-4.066 -0.835,-1.146 -2.134,-2.023 -3.647,-2.408 -1.389,-0.352 -2.723,-0.223 -3.781,0.238 -1.011,0.439 -1.812,1.196 -2.21,2.198 -0.397,1.001 -0.335,2.12 0.108,3.146 0.468,1.083 1.377,2.112 2.666,2.812 1.407,0.762 2.987,0.989 4.389,0.684 z"
621 id="path238"
622 style="fill:url(#radialGradient3310)"
623 inkscape:connector-curvature="0" />
624 <radialGradient
625 id="radialGradient3292"
626 cx="173.2812"
627 cy="283.68359"
628 r="2.8803999"
629 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
630 gradientUnits="userSpaceOnUse">
631 <stop
632 offset="0.0112"
633 style="stop-color:#FAF0BB"
634 id="stop3294" />
635 <stop
636 offset="0.4917"
637 style="stop-color:#FAF0BD"
638 id="stop3296" />
639 <stop
640 offset="0.6648"
641 style="stop-color:#FBF2C5"
642 id="stop3298" />
643 <stop
644 offset="0.7882"
645 style="stop-color:#FCF6D0"
646 id="stop3300" />
647 <stop
648 offset="0.8879"
649 style="stop-color:#FCF8E1"
650 id="stop3302" />
651 <stop
652 offset="0.9723"
653 style="stop-color:#FFFDF7"
654 id="stop3304" />
655 <stop
656 offset="1"
657 style="stop-color:#FFFFFF"
658 id="stop3306" />
659 </radialGradient>
660 <path
661 d="m 200.538,302.533 c -0.568,-0.598 -1.402,-0.802 -2.248,-0.657 -0.792,0.136 -1.565,0.573 -2.143,1.244 -0.529,0.616 -0.8,1.327 -0.833,1.98 -0.032,0.624 0.15,1.222 0.559,1.676 0.408,0.455 0.991,0.705 1.624,0.739 0.668,0.035 1.42,-0.167 2.101,-0.645 0.741,-0.521 1.256,-1.267 1.454,-2.056 0.21,-0.833 0.058,-1.677 -0.514,-2.281 z"
662 id="path255"
663 style="fill:url(#radialGradient3312)"
664 inkscape:connector-curvature="0" />
665 <radialGradient
666 id="radialGradient3309"
667 cx="148.9492"
668 cy="270.04489"
669 r="2.8799"
670 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
671 gradientUnits="userSpaceOnUse">
672 <stop
673 offset="0.0112"
674 style="stop-color:#FAF0BB"
675 id="stop3311" />
676 <stop
677 offset="0.4917"
678 style="stop-color:#FAF0BD"
679 id="stop3313" />
680 <stop
681 offset="0.6648"
682 style="stop-color:#FBF2C5"
683 id="stop3315" />
684 <stop
685 offset="0.7882"
686 style="stop-color:#FCF6D0"
687 id="stop3317" />
688 <stop
689 offset="0.8879"
690 style="stop-color:#FCF8E1"
691 id="stop3319" />
692 <stop
693 offset="0.9723"
694 style="stop-color:#FFFDF7"
695 id="stop3321" />
696 <stop
697 offset="1"
698 style="stop-color:#FFFFFF"
699 id="stop3323" />
700 </radialGradient>
701 <path
702 d="m 173.958,315.516 c -0.793,0.136 -1.566,0.573 -2.143,1.244 -0.529,0.616 -0.801,1.327 -0.834,1.98 -0.031,0.623 0.15,1.222 0.559,1.676 0.408,0.455 0.991,0.705 1.624,0.738 0.669,0.036 1.42,-0.166 2.101,-0.645 0.741,-0.521 1.256,-1.266 1.454,-2.055 0.211,-0.834 0.06,-1.679 -0.514,-2.282 -0.568,-0.598 -1.402,-0.801 -2.247,-0.656 z"
703 id="path272"
704 style="fill:url(#radialGradient3314)"
705 inkscape:connector-curvature="0" />
706 <radialGradient
707 id="radialGradient3326"
708 cx="148.0723"
709 cy="319.09381"
710 r="3.9265001"
711 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
712 gradientUnits="userSpaceOnUse">
713 <stop
714 offset="0.0112"
715 style="stop-color:#FAF0BB"
716 id="stop3328" />
717 <stop
718 offset="0.4917"
719 style="stop-color:#FAF0BD"
720 id="stop3330" />
721 <stop
722 offset="0.6648"
723 style="stop-color:#FBF2C5"
724 id="stop3332" />
725 <stop
726 offset="0.7882"
727 style="stop-color:#FCF6D0"
728 id="stop3334" />
729 <stop
730 offset="0.8879"
731 style="stop-color:#FCF8E1"
732 id="stop3336" />
733 <stop
734 offset="0.9723"
735 style="stop-color:#FFFDF7"
736 id="stop3338" />
737 <stop
738 offset="1"
739 style="stop-color:#FFFFFF"
740 id="stop3340" />
741 </radialGradient>
742 <path
743 d="m 171.282,272.336 c 1.106,0.549 2.333,0.68 3.407,0.405 1.136,-0.291 2.049,-1.022 2.398,-2.102 0.347,-1.069 0.048,-2.201 -0.675,-3.119 -0.678,-0.861 -1.706,-1.502 -2.885,-1.756 -1.083,-0.233 -2.109,-0.095 -2.914,0.291 -0.768,0.368 -1.365,0.975 -1.645,1.76 -0.278,0.785 -0.198,1.646 0.173,2.426 0.394,0.822 1.125,1.592 2.141,2.095 z"
744 id="path289"
745 style="fill:url(#radialGradient3316)"
746 inkscape:connector-curvature="0" />
747 <radialGradient
748 id="radialGradient3343"
749 cx="112.9551"
750 cy="315.56049"
751 r="3.0683999"
752 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
753 gradientUnits="userSpaceOnUse">
754 <stop
755 offset="0.0112"
756 style="stop-color:#FAF0BB"
757 id="stop3345" />
758 <stop
759 offset="0.4917"
760 style="stop-color:#FAF0BD"
761 id="stop3347" />
762 <stop
763 offset="0.6648"
764 style="stop-color:#FBF2C5"
765 id="stop3349" />
766 <stop
767 offset="0.7882"
768 style="stop-color:#FCF6D0"
769 id="stop3351" />
770 <stop
771 offset="0.8879"
772 style="stop-color:#FCF8E1"
773 id="stop3353" />
774 <stop
775 offset="0.9723"
776 style="stop-color:#FFFDF7"
777 id="stop3355" />
778 <stop
779 offset="1"
780 style="stop-color:#FFFFFF"
781 id="stop3357" />
782 </radialGradient>
783 <path
784 d="m 140.776,270.8 c -0.132,-0.306 -0.298,-0.603 -0.496,-0.884 0,0 -0.001,-10e-4 -0.001,-10e-4 -0.031,0.02 -0.061,0.042 -0.091,0.062 -0.1,0.067 -0.199,0.135 -0.298,0.203 -0.12,0.082 -0.24,0.163 -0.358,0.246 -0.123,0.085 -0.245,0.173 -0.366,0.26 -0.096,0.068 -0.193,0.136 -0.289,0.206 -0.146,0.106 -0.29,0.213 -0.434,0.321 -0.072,0.054 -0.145,0.106 -0.216,0.161 -0.215,0.163 -0.429,0.328 -0.641,0.495 -0.223,0.175 -0.443,0.354 -0.663,0.535 -0.064,0.053 -0.129,0.107 -0.194,0.161 -0.171,0.143 -0.341,0.287 -0.51,0.432 -0.054,0.046 -0.108,0.092 -0.162,0.139 -0.193,0.167 -0.384,0.337 -0.574,0.509 -0.098,0.088 -0.196,0.178 -0.293,0.268 -0.099,0.09 -0.196,0.182 -0.294,0.274 -0.079,0.074 -0.16,0.146 -0.238,0.222 0,0 0.001,0.001 0.001,0.001 0.177,0.156 0.363,0.299 0.555,0.429 0.596,0.402 1.257,0.671 1.927,0.786 1.185,0.202 2.356,-0.083 3.152,-0.922 0.804,-0.847 1.017,-2.032 0.722,-3.202 -0.06,-0.24 -0.14,-0.473 -0.239,-0.701 z"
785 id="path306"
786 style="fill:url(#radialGradient3318)"
787 inkscape:connector-curvature="0" />
788 <radialGradient
789 id="radialGradient3360"
790 cx="132.0938"
791 cy="320.1113"
792 r="4.1712999"
793 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
794 gradientUnits="userSpaceOnUse">
795 <stop
796 offset="0.0112"
797 style="stop-color:#FAF0BB"
798 id="stop3362" />
799 <stop
800 offset="0.4917"
801 style="stop-color:#FAF0BD"
802 id="stop3364" />
803 <stop
804 offset="0.6648"
805 style="stop-color:#FBF2C5"
806 id="stop3366" />
807 <stop
808 offset="0.7882"
809 style="stop-color:#FCF6D0"
810 id="stop3368" />
811 <stop
812 offset="0.8879"
813 style="stop-color:#FCF8E1"
814 id="stop3370" />
815 <stop
816 offset="0.9723"
817 style="stop-color:#FFFDF7"
818 id="stop3372" />
819 <stop
820 offset="1"
821 style="stop-color:#FFFFFF"
822 id="stop3374" />
823 </radialGradient>
824 <path
825 d="m 160.2,265.6 c -0.85,-0.392 -1.938,-0.592 -3.115,-0.521 -1.177,0.07 -2.29,0.405 -3.157,0.906 -0.916,0.53 -1.6,1.269 -1.798,2.11 -0.216,0.917 0.182,1.777 1.05,2.403 0.918,0.663 2.32,1.032 3.923,0.914 1.588,-0.118 2.959,-0.687 3.847,-1.468 0.833,-0.732 1.209,-1.627 0.998,-2.496 -0.195,-0.799 -0.859,-1.438 -1.748,-1.848 z"
826 id="path323"
827 style="fill:url(#radialGradient3320)"
828 inkscape:connector-curvature="0" />
829 <radialGradient
830 id="radialGradient3377"
831 cx="147.44189"
832 cy="301.21091"
833 r="2.5313001"
834 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
835 gradientUnits="userSpaceOnUse">
836 <stop
837 offset="0.0112"
838 style="stop-color:#FAF0BB"
839 id="stop3379" />
840 <stop
841 offset="0.4917"
842 style="stop-color:#FAF0BD"
843 id="stop3381" />
844 <stop
845 offset="0.6648"
846 style="stop-color:#FBF2C5"
847 id="stop3383" />
848 <stop
849 offset="0.7882"
850 style="stop-color:#FCF6D0"
851 id="stop3385" />
852 <stop
853 offset="0.8879"
854 style="stop-color:#FCF8E1"
855 id="stop3387" />
856 <stop
857 offset="0.9723"
858 style="stop-color:#FFFDF7"
859 id="stop3389" />
860 <stop
861 offset="1"
862 style="stop-color:#FFFFFF"
863 id="stop3391" />
864 </radialGradient>
865 <path
866 d="m 173.961,289.2 c 0.657,-0.143 1.12,-0.506 1.265,-1.029 0.133,-0.48 -0.03,-1.015 -0.381,-1.495 -0.335,-0.458 -0.853,-0.886 -1.498,-1.196 -0.645,-0.31 -1.333,-0.461 -1.94,-0.451 -0.643,0.011 -1.223,0.2 -1.576,0.587 -0.385,0.422 -0.428,0.996 -0.152,1.584 0.291,0.622 0.925,1.231 1.811,1.642 0.876,0.408 1.77,0.51 2.471,0.358 z"
867 id="path340"
868 style="fill:url(#radialGradient3322)"
869 inkscape:connector-curvature="0" />
870 </g>
871 <path
872 d="m 32.300561,46.79686 c -0.244913,-0.207495 -0.516006,-0.294969 -0.756275,-0.27971 -0.2276,0.01425 -0.437888,0.12307 -0.584836,0.320395 -0.147371,0.197321 -0.212822,0.456181 -0.201419,0.726735 0.01182,0.283777 0.109788,0.591457 0.300228,0.85845 0.207332,0.290901 0.486027,0.480592 0.771056,0.539586 0.304451,0.06256 0.605105,-0.02543 0.809057,-0.284794 0.206488,-0.26191 0.260961,-0.628075 0.185374,-0.989662 -0.07136,-0.342262 -0.256312,-0.665199 -0.523185,-0.891 z"
873 id="path347"
874 style="fill:#000000"
875 inkscape:connector-curvature="0" />
876 <g
877 id="g349"
878 transform="matrix(0.42226435,0,0,0.50856192,-47.726977,-111.72952)">
879 <path
880 d="m 168.559,264.427 c 4.145,0.407 8.127,1.382 11.858,2.845 l 0.623,-0.856 c -3.919,-1.741 -8.161,-2.906 -12.604,-3.384 l 0.123,1.395 z"
881 id="path351"
882 inkscape:connector-curvature="0"
883 style="fill:#ffffff" />
884 <path
885 d="m 145.971,266.73 1.059,0.888 c 5.193,-2.147 10.87,-3.351 16.738,-3.403 l 0.009,-0.038 0.435,-1.388 c -0.059,0 -0.116,-0.002 -0.175,-0.002 -6.387,-0.024 -12.545,1.39 -18.066,3.943 z"
886 id="path353"
887 inkscape:connector-curvature="0"
888 style="fill:#ffffff" />
889 <path
890 d="m 185.374,269.579 c 0.97,0.527 1.917,1.087 2.84,1.683 l 0.494,-0.416 c -1.011,-0.738 -2.058,-1.431 -3.138,-2.078 l -0.196,0.811 z"
891 id="path355"
892 inkscape:connector-curvature="0"
893 style="fill:#ffffff" />
894 <path
895 d="m 190.66,272.366 -0.224,0.429 c 0.458,0.338 0.91,0.683 1.354,1.038 1.494,1.193 2.916,2.493 4.25,3.889 -1.633,-1.962 -3.44,-3.752 -5.38,-5.356 z"
896 id="path357"
897 inkscape:connector-curvature="0"
898 style="fill:#ffffff" />
899 <path
900 d="m 140.28,269.916 c 0.198,0.281 0.363,0.578 0.496,0.884 0.84,-0.514 1.699,-1.002 2.575,-1.462 l -0.52,-0.994 c -0.871,0.494 -1.721,1.019 -2.551,1.572 z"
901 id="path359"
902 inkscape:connector-curvature="0"
903 style="fill:#ffffff" />
904 <path
905 d="m 133.625,275.426 0.562,0.314 c 0.338,-0.307 0.681,-0.608 1.028,-0.904 -0.192,-0.129 -0.378,-0.272 -0.555,-0.429 -0.35,0.333 -0.696,0.673 -1.035,1.019 z"
906 id="path361"
907 inkscape:connector-curvature="0"
908 style="fill:#ffffff" />
909 <path
910 d="m 130.152,279.456 c 0.139,-0.009 0.279,-0.015 0.419,-0.019 0.538,-0.62 1.091,-1.224 1.66,-1.81 l -0.295,-0.374 c -0.618,0.713 -1.212,1.447 -1.784,2.203 z"
911 id="path363"
912 inkscape:connector-curvature="0"
913 style="fill:#ffffff" />
914 </g>
915 <path
916 d="m 11.717707,25.989048 c -0.05574,-0.15562 -0.125834,-0.306666 -0.209444,-0.44957 -0.01309,0.01012 -0.02618,0.02032 -0.03885,0.03052 -0.04223,0.03408 -0.08403,0.06866 -0.125835,0.10324 -0.05067,0.0417 -0.101339,0.08289 -0.151171,0.125104 -0.05194,0.04324 -0.103455,0.08798 -0.154549,0.132228 -0.04054,0.03459 -0.0815,0.06916 -0.122034,0.104767 -0.06165,0.0534 -0.122457,0.108333 -0.183263,0.16325 -0.03041,0.02747 -0.06122,0.05392 -0.09122,0.08188 -0.09078,0.08288 -0.181151,0.166809 -0.27067,0.251737 -0.09416,0.0895 -0.187063,0.180031 -0.279961,0.272083 -0.02703,0.02695 -0.05447,0.05442 -0.08192,0.08188 -0.07221,0.07272 -0.1439917,0.145958 -0.2153547,0.219699 -0.02281,0.02339 -0.0456,0.04679 -0.068411,0.07019 -0.081499,0.08492 -0.1621494,0.171895 -0.24238,0.258858 -0.041385,0.04477 -0.08276,0.09052 -0.1237229,0.136294 -0.041799,0.04628 -0.08276,0.09308 -0.1241459,0.139347 -0.033364,0.03762 -0.066717,0.07527 -0.1000776,0.113908 0.074741,0.07935 0.1532821,0.152062 0.2343573,0.218175 C 9.5506288,27.855494 9.7347353,27.672921 9.9217999,27.495432 10.4927,26.95178 11.092737,26.44983 11.717689,25.989072 z"
917 id="path365"
918 inkscape:connector-curvature="0"
919 style="fill:#eeeeee" />
920 <path
921 d="m 28.381526,27.537111 c 0.388483,0.0014 0.747409,0.164265 1.026947,0.433802 0.293051,0.282252 0.512205,0.694697 0.575969,1.184949 0.06968,0.534499 -0.05447,1.061878 -0.328523,1.474322 -0.292629,0.439906 -0.744451,0.732838 -1.26806,0.744027 -0.528674,0.01119 -0.990631,-0.26547 -1.292973,-0.70131 -0.286295,-0.411932 -0.417197,-0.947959 -0.345834,-1.495681 0.06503,-0.501949 0.290517,-0.923546 0.592437,-1.209867 0.28545,-0.271063 0.652399,-0.431769 1.040037,-0.430242 z"
922 id="path372"
923 style="fill:#000000"
924 inkscape:connector-curvature="0" />
925 <path
926 d="m 13.466305,55.28374 c 0.178195,0.09256 0.329787,0.214614 0.43662,0.342772 0.111901,0.134768 0.178619,0.281236 0.168063,0.408885 -0.0114,0.139346 -0.111902,0.231394 -0.271518,0.261399 -0.170172,0.03153 -0.401994,-0.0082 -0.64353,-0.129175 -0.244069,-0.12256 -0.433666,-0.295472 -0.53712,-0.467367 -0.09797,-0.162232 -0.114433,-0.316834 -0.03674,-0.425668 0.07093,-0.100193 0.209021,-0.143413 0.37117,-0.13782 0.152859,0.005 0.334856,0.05491 0.513051,0.146974 l 0,0 z m -2.368059,-0.261399 c 0.05025,0.0122 0.09585,0.04017 0.130479,0.0768 0.03588,0.03815 0.06165,0.08797 0.06671,0.140364 0.0055,0.05696 -0.01435,0.10731 -0.05278,0.141381 -0.04097,0.0356 -0.101763,0.05188 -0.169749,0.03611 -0.06883,-0.01525 -0.127102,-0.05848 -0.163417,-0.113404 -0.03463,-0.05139 -0.04772,-0.110861 -0.03463,-0.164774 0.01183,-0.04984 0.04392,-0.08594 0.0853,-0.10578 0.03885,-0.01831 0.08741,-0.02339 0.138081,-0.01071 l 0,0 z m 3.807979,2.368373 c 0.09627,0.02389 0.183263,0.07728 0.248714,0.147481 0.06925,0.07322 0.117813,0.167318 0.127101,0.267506 0.01013,0.109332 -0.02745,0.204948 -0.100915,0.270045 -0.07854,0.06866 -0.194242,0.09866 -0.324299,0.06968 -0.131324,-0.03002 -0.24238,-0.111886 -0.311631,-0.216139 -0.06545,-0.09816 -0.09122,-0.21156 -0.0663,-0.314799 0.02281,-0.09459 0.08446,-0.163757 0.162995,-0.2019 0.07515,-0.03611 0.16806,-0.04576 0.264336,-0.02185 l 0,0 z m -2.357501,-1.035942 c -0.09333,-0.04831 -0.188754,-0.07425 -0.269405,-0.0768 -0.08487,-0.003 -0.157504,0.01983 -0.194242,0.07222 -0.04054,0.05696 -0.03209,0.137821 0.01942,0.222749 0.05405,0.09052 0.153704,0.18054 0.281651,0.245128 0.126679,0.06356 0.247869,0.08391 0.337388,0.06765 0.08362,-0.01576 0.136392,-0.06407 0.142304,-0.137313 0.0055,-0.06713 -0.02956,-0.143414 -0.08783,-0.214102 -0.05658,-0.06714 -0.135969,-0.13121 -0.22929,-0.179526 z"
927 id="path374"
928 inkscape:connector-curvature="0"
929 style="fill:#d9bb7a" />
930 <path
931 d="m 32.89722,32.895826 c 0.143148,-0.434312 0.431555,-0.762333 0.795547,-0.953043 0.380884,-0.199865 0.861841,-0.255808 1.361803,-0.10325 0.544721,0.166808 1.012166,0.547722 1.313242,1.044079 0.320921,0.529412 0.440844,1.170201 0.26096,1.762675 -0.181574,0.59807 -0.618618,0.989661 -1.15236,1.129517 -0.504607,0.132224 -1.073818,0.03356 -1.579691,-0.297003 -0.464491,-0.303099 -0.791747,-0.749617 -0.960229,-1.219019 -0.160039,-0.444994 -0.182419,-0.929651 -0.03927,-1.363962 z"
932 id="path381"
933 style="fill:#000000"
934 inkscape:connector-curvature="0" />
935 <path
936 d="m 35.093418,44.08063 c -0.146948,-0.197323 -0.212399,-0.456178 -0.200998,-0.726732 0.01182,-0.28378 0.109367,-0.591461 0.299807,-0.858457 0.207754,-0.290895 0.486028,-0.480589 0.771477,-0.540093 0.304453,-0.06256 0.604685,0.02594 0.809059,0.285306 0.206487,0.261909 0.26096,0.628075 0.184952,0.989659 -0.07137,0.342262 -0.256313,0.6652 -0.523607,0.891001 -0.244913,0.207492 -0.515586,0.294965 -0.755853,0.27971 -0.227601,-0.01423 -0.437466,-0.123072 -0.584837,-0.320394 z"
937 id="path388"
938 style="fill:#000000"
939 inkscape:connector-curvature="0" />
940 <path
941 d="m 24.819304,51.017414 c -0.147371,-0.197322 -0.212821,-0.456179 -0.201421,-0.727243 0.01183,-0.283269 0.10979,-0.590948 0.30023,-0.858455 0.207333,-0.290896 0.485604,-0.481098 0.771055,-0.540089 0.304453,-0.06256 0.605106,0.02594 0.809059,0.285303 0.206487,0.261908 0.260959,0.628074 0.184952,0.989661 -0.07136,0.342263 -0.256314,0.6652 -0.523608,0.891002 -0.24449,0.207493 -0.515584,0.294964 -0.755854,0.279709 -0.2276,-0.01425 -0.437465,-0.123071 -0.584413,-0.319888 z"
942 id="path395"
943 style="fill:#000000"
944 inkscape:connector-curvature="0" />
945 <path
946 d="m 23.786446,24.445052 c 0.102186,-0.347855 0.322609,-0.616885 0.605104,-0.779624 0.296007,-0.170876 0.673933,-0.232414 1.072129,-0.128666 0.433667,0.112897 0.812438,0.396678 1.061996,0.778609 0.266026,0.406849 0.376235,0.908289 0.24829,1.382269 -0.12879,0.47805 -0.464913,0.802512 -0.882532,0.931685 -0.395661,0.12205 -0.84664,0.06357 -1.254126,-0.17952 -0.374125,-0.222751 -0.642686,-0.563996 -0.787099,-0.928635 -0.137237,-0.346331 -0.166373,-0.728261 -0.06377,-1.076118 z"
947 id="path402"
948 style="fill:#000000"
949 inkscape:connector-curvature="0" />
950 <path
951 d="m 9.3572511,27.571182 c 0.2537814,0.256316 0.5518992,0.424651 0.8555069,0.487204 0.426486,0.08747 0.848329,-0.03611 1.135047,-0.399731 0.28925,-0.367181 0.366103,-0.880828 0.259692,-1.388372 -0.0456,-0.217666 -0.123723,-0.429227 -0.230557,-0.625532 -0.344568,0.281745 -0.680268,0.577726 -1.006255,0.886932 -0.347524,0.330057 -0.6857564,0.676897 -1.0134339,1.039499 z"
952 id="path409"
953 style="fill:#000000"
954 inkscape:connector-curvature="0" />
955 <path
956 d="m 9.3572511,27.571182 c 0.081923,0.08289 0.1684839,0.15664 0.2584255,0.220208 0.1013389,-0.100194 0.2031087,-0.199865 0.3061417,-0.296999 0.5244517,-0.497883 1.0733947,-0.962708 1.6434517,-1.391936 -0.04604,-0.15867 -0.109367,-0.312257 -0.188752,-0.457195 l 0,0 c -0.02997,0.02442 -0.05996,0.04933 -0.08995,0.07425 -0.01942,0.01628 -0.03927,0.03255 -0.05869,0.04883 -0.03336,0.02747 -0.0663,0.05545 -0.09923,0.08341 l -0.04519,0.03865 c -0.03758,0.03205 -0.07474,0.06407 -0.111899,0.09613 l -0.02997,0.02594 c -0.04139,0.03611 -0.08235,0.07221 -0.123301,0.108332 l -0.02026,0.01832 c -0.04392,0.03918 -0.08741,0.07781 -0.130901,0.117485 l -0.01309,0.01169 c -0.04603,0.04223 -0.09206,0.08442 -0.13808,0.12714 l -0.0018,0.0014 c -0.04815,0.04476 -0.09585,0.0895 -0.143569,0.134769 -0.07685,0.07322 -0.15286,0.146467 -0.228867,0.221226 l -0.01098,0.01072 c -0.02026,0.02032 -0.04097,0.04018 -0.06123,0.06051 l -0.01858,0.01882 -0.05236,0.05238 -0.02956,0.03002 -0.04307,0.04376 -0.03801,0.03865 -0.01605,0.01627 -0.01562,0.01627 -0.04771,0.04883 -0.01562,0.01627 C 9.6459492,27.256383 9.50069,27.412511 9.3571211,27.571183 z"
957 id="path411"
958 inkscape:connector-curvature="0"
959 style="fill:#888678" />
960 <path
961 d="m 18.571057,23.295194 c 0.423955,-0.03051 0.815816,0.05645 1.121534,0.226311 0.320077,0.177997 0.559079,0.455163 0.629176,0.800985 0.07601,0.376844 -0.05954,0.764369 -0.359348,1.082221 -0.319232,0.338701 -0.812859,0.585354 -1.385028,0.636719 -0.577235,0.05138 -1.081841,-0.108827 -1.412472,-0.39617 -0.312477,-0.271573 -0.456047,-0.644349 -0.378351,-1.042043 0.07136,-0.364639 0.317965,-0.685034 0.647333,-0.914395 0.312897,-0.217665 0.713204,-0.363114 1.137156,-0.393628 z"
962 id="path418"
963 style="fill:#000000"
964 inkscape:connector-curvature="0" />
965 <path
966 d="m 25.268593,33.539157 c 0.209865,0.121549 0.37835,0.289372 0.487716,0.468895 0.11401,0.188169 0.167216,0.397695 0.123723,0.585864 -0.04687,0.20495 -0.198043,0.347856 -0.412131,0.403289 -0.228021,0.05951 -0.519383,0.01933 -0.804835,-0.139854 -0.288406,-0.160707 -0.494471,-0.399731 -0.589482,-0.643842 -0.08995,-0.230376 -0.07601,-0.455669 0.04941,-0.620952 0.114856,-0.152061 0.304451,-0.226311 0.51305,-0.230379 0.198043,-0.0036 0.422688,0.05543 0.632553,0.176979 z"
967 id="path425"
968 style="fill:#000000"
969 inkscape:connector-curvature="0" />
970 <polygon
971 points="188.385,321.662 183.827,319.426 190.01,322.008 182.526,321.973 "
972 id="polygon427"
973 transform="matrix(0.42226435,0,0,0.50856192,-47.726977,-111.72952)" />
974 <polygon
975 points="181.161,310.218 176.159,311.094 182.677,309.541 176.606,313.919 "
976 id="polygon429"
977 transform="matrix(0.42226435,0,0,0.50856192,-47.726977,-111.72952)" />
978 <polygon
979 points="188.996,281.271 183.955,287.956 191.129,279.553 180.144,285.178 "
980 id="polygon431"
981 transform="matrix(0.42226435,0,0,0.50856192,-47.726977,-111.72952)" />
982 <path
983 d="m 35.589578,54.524966 c -0.122034,0.197832 -0.247447,0.39312 -0.376237,0.586373 -3.139958,4.719964 -7.989242,7.864909 -13.609581,7.987982 C 15.929794,63.222902 10.97199,60.250356 7.7226683,55.572603 7.5229375,55.285266 7.3303849,54.991318 7.1445881,54.693299 c 3.5503959,4.555698 8.6741509,7.392458 14.4832419,7.265826 5.617804,-0.123069 10.532541,-3.002548 13.961748,-7.434159 z"
984 id="path440"
985 style="fill:#d9bb7a"
986 inkscape:connector-curvature="0" />
987 <path
988 d="m 16.345302,52.251694 c -2.117655,-1.929991 -2.971052,-5.408047 -1.900189,-8.495019 1.184029,-3.41245 4.302452,-5.144614 7.182295,-4.121385 -2.791167,-0.695713 -5.69128,1.060859 -6.831394,4.34617 -1.023146,2.94966 -0.321343,6.249209 1.549288,8.270234 z"
989 id="path442"
990 inkscape:connector-curvature="0"
991 style="fill:#ffffff" />
992 <path
993 d="m 7.9004418,49.211004 c 1.5839109,-1.826246 1.8765395,-5.188352 0.611861,-7.774387 -0.9606515,-1.964067 -2.560189,-2.949661 -4.0731622,-2.724366 1.4428771,-0.03307 2.911513,0.974913 3.8219146,2.837267 1.2266751,2.507718 1.0299008,5.725391 -0.3606134,7.661486 z"
994 id="path444"
995 inkscape:connector-curvature="0"
996 style="fill:#ffffff" />
997 <path
998 d="m 46.744961,35.073491 -0.497006,-0.879306 c -0.446333,-0.789288 -2.616772,-1.271403 -3.063106,-2.060692 -0.04897,-0.08645 -0.08995,-0.178504 -0.124145,-0.273607 0.02111,0.05392 0.04434,0.106285 0.07093,0.157655 0.411286,0.799459 2.442378,0.780134 2.853664,1.579592 l 0.759653,1.476358 0,0 z m -3.840919,-4.235306 c -0.02154,-1.142737 0.276584,-2.476187 -0.211554,-3.339725 -0.684068,-1.210379 -3.109133,-1.708769 -3.070285,-3.678937 0.02618,-1.300901 0.05531,-2.044928 -0.877888,-0.830484 -0.474202,0.616888 -0.933204,1.256658 -1.378271,1.918806 0.532898,-0.895579 1.084376,-1.758098 1.656966,-2.58553 0.921382,-1.331414 0.877043,-0.549754 0.825104,0.815225 -0.02492,0.63723 0.05786,1.381764 0.330634,1.912701 0.487293,0.947452 2.164949,1.469236 2.652243,2.416687 0.464492,0.901679 0.07769,2.233605 0.07305,3.371257 z"
999 id="path446"
1000 inkscape:connector-curvature="0"
1001 style="fill:#ffffff" />
1002 <path
1003 d="m 16.756588,33.897186 c 0.357235,-0.248687 0.77781,-0.246145 1.121111,-0.03865 -0.09501,0.0122 -0.189596,0.04832 -0.27785,0.109346 -0.338655,0.235464 -0.455199,0.757757 -0.25927,1.165625 0.19551,0.408372 0.629174,0.548229 0.96783,0.312255 0.08783,-0.06155 0.160883,-0.14189 0.217467,-0.234955 -0.02237,0.461773 -0.230979,0.901679 -0.588638,1.150367 -0.564566,0.39261 -1.287061,0.15918 -1.613471,-0.520769 -0.325145,-0.680454 -0.131747,-1.550096 0.432821,-1.943214 l 0,0 z m -8.4625961,1.183931 c 0.2575811,-0.179014 0.5603435,-0.177488 0.8077901,-0.02795 -0.068836,0.009 -0.1368128,0.03458 -0.2001525,0.07882 -0.2440687,0.169354 -0.327677,0.545687 -0.1866399,0.839639 0.1406128,0.293947 0.453088,0.394643 0.6971553,0.224782 0.063334,-0.04425 0.1161241,-0.102217 0.1570835,-0.16935 C 9.5527694,36.35966 9.4024339,36.676495 9.1452751,36.855507 8.7386349,37.138248 8.2179844,36.970431 7.983206,36.480169 7.7475821,35.990933 7.887351,35.363875 8.2939919,35.081114 z"
1004 id="path448"
1005 inkscape:connector-curvature="0" />
1006 <path
1007 d="m 11.148494,37.665629 c -0.260113,-0.748095 -0.420152,-1.550096 -0.46449,-2.376002 -0.533741,1.967118 -1.8647168,3.382956 -3.4389171,3.862529 0.4619579,0.354468 0.8876005,0.829465 1.2503252,1.416854 1.1793816,-0.417022 2.1776139,-1.463641 2.6530819,-2.903381 z"
1008 id="path450"
1009 inkscape:connector-curvature="0"
1010 style="fill:#eeeeee" />
1011 <path
1012 d="m 3.5654754,33.263516 c -0.2884063,0.139348 -0.5160068,0.432279 -0.656621,0.92355 -0.6697112,2.341929 -0.5459877,4.035438 0.033358,5.072397 C 3.09465,39.150129 3.25131,39.055528 3.4109259,38.975177 3.537183,38.886186 3.6659737,38.807859 3.7972979,38.739713 3.1153408,37.498312 2.8611376,35.923805 3.2065499,34.3732 3.2935369,33.980083 3.4151486,33.609339 3.5654746,33.263516 z"
1013 id="path457"
1014 style="fill:#f0a513"
1015 inkscape:connector-curvature="0" />
1016 <path
1017 d="m 9.6346789,48.851958 c 0.7959681,1.053234 2.8688621,0.917445 3.5212611,-0.268012 -0.352592,0.781151 -1.04046,1.31209 -1.830517,1.31209 -0.695891,0 -1.312395,-0.411935 -1.6907441,-1.044078 z"
1018 id="path459"
1019 inkscape:connector-curvature="0"
1020 style="fill:#ffffff" />
1021 </g>
1022 </g>
1023 </svg>
0 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
1 <!-- Created with Inkscape (http://www.inkscape.org/) -->
2
3 <svg
4 xmlns:dc="http://purl.org/dc/elements/1.1/"
5 xmlns:cc="http://creativecommons.org/ns#"
6 xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
7 xmlns:svg="http://www.w3.org/2000/svg"
8 xmlns="http://www.w3.org/2000/svg"
9 xmlns:xlink="http://www.w3.org/1999/xlink"
10 xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
11 xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
12 width="16"
13 height="16"
14 id="svg25900"
15 version="1.1"
16 inkscape:version="0.48.3.1 r9886"
17 sodipodi:docname="diodon.svg">
18 <defs
19 id="defs25902">
20 <radialGradient
21 inkscape:collect="always"
22 xlink:href="#SVGID_3_"
23 id="radialGradient3305"
24 gradientUnits="userSpaceOnUse"
25 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
26 cx="163.4902"
27 cy="274.86621"
28 r="2.8801" />
29 <radialGradient
30 gradientUnits="userSpaceOnUse"
31 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
32 r="2.8801"
33 cy="274.86621"
34 cx="163.4902"
35 id="SVGID_3_">
36 <stop
37 id="stop190"
38 style="stop-color:#FAF0BB"
39 offset="0.0112" />
40 <stop
41 id="stop192"
42 style="stop-color:#FAF0BD"
43 offset="0.4917" />
44 <stop
45 id="stop194"
46 style="stop-color:#FBF2C5"
47 offset="0.6648" />
48 <stop
49 id="stop196"
50 style="stop-color:#FCF6D0"
51 offset="0.7882" />
52 <stop
53 id="stop198"
54 style="stop-color:#FCF8E1"
55 offset="0.8879" />
56 <stop
57 id="stop200"
58 style="stop-color:#FFFDF7"
59 offset="0.9723" />
60 <stop
61 id="stop202"
62 style="stop-color:#FFFFFF"
63 offset="1" />
64 </radialGradient>
65 <radialGradient
66 inkscape:collect="always"
67 xlink:href="#SVGID_4_"
68 id="radialGradient3307"
69 gradientUnits="userSpaceOnUse"
70 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
71 cx="155.3242"
72 cy="310.6777"
73 r="4.4867001" />
74 <radialGradient
75 gradientUnits="userSpaceOnUse"
76 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
77 r="4.4867001"
78 cy="310.6777"
79 cx="155.3242"
80 id="SVGID_4_">
81 <stop
82 id="stop207"
83 style="stop-color:#FAF0BB"
84 offset="0.0112" />
85 <stop
86 id="stop209"
87 style="stop-color:#FAF0BD"
88 offset="0.4917" />
89 <stop
90 id="stop211"
91 style="stop-color:#FBF2C5"
92 offset="0.6648" />
93 <stop
94 id="stop213"
95 style="stop-color:#FCF6D0"
96 offset="0.7882" />
97 <stop
98 id="stop215"
99 style="stop-color:#FCF8E1"
100 offset="0.8879" />
101 <stop
102 id="stop217"
103 style="stop-color:#FFFDF7"
104 offset="0.9723" />
105 <stop
106 id="stop219"
107 style="stop-color:#FFFFFF"
108 offset="1" />
109 </radialGradient>
110 <radialGradient
111 inkscape:collect="always"
112 xlink:href="#SVGID_5_"
113 id="radialGradient3310"
114 gradientUnits="userSpaceOnUse"
115 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
116 cx="170.3125"
117 cy="302.00781"
118 r="5.0811" />
119 <radialGradient
120 gradientUnits="userSpaceOnUse"
121 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
122 r="5.0811"
123 cy="302.00781"
124 cx="170.3125"
125 id="SVGID_5_">
126 <stop
127 id="stop224"
128 style="stop-color:#FAF0BB"
129 offset="0.0112" />
130 <stop
131 id="stop226"
132 style="stop-color:#FAF0BD"
133 offset="0.4917" />
134 <stop
135 id="stop228"
136 style="stop-color:#FBF2C5"
137 offset="0.6648" />
138 <stop
139 id="stop230"
140 style="stop-color:#FCF6D0"
141 offset="0.7882" />
142 <stop
143 id="stop232"
144 style="stop-color:#FCF8E1"
145 offset="0.8879" />
146 <stop
147 id="stop234"
148 style="stop-color:#FFFDF7"
149 offset="0.9723" />
150 <stop
151 id="stop236"
152 style="stop-color:#FFFFFF"
153 offset="1" />
154 </radialGradient>
155 <radialGradient
156 inkscape:collect="always"
157 xlink:href="#SVGID_6_"
158 id="radialGradient3312"
159 gradientUnits="userSpaceOnUse"
160 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
161 cx="173.2812"
162 cy="283.68359"
163 r="2.8803999" />
164 <radialGradient
165 gradientUnits="userSpaceOnUse"
166 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
167 r="2.8803999"
168 cy="283.68359"
169 cx="173.2812"
170 id="SVGID_6_">
171 <stop
172 id="stop241"
173 style="stop-color:#FAF0BB"
174 offset="0.0112" />
175 <stop
176 id="stop243"
177 style="stop-color:#FAF0BD"
178 offset="0.4917" />
179 <stop
180 id="stop245"
181 style="stop-color:#FBF2C5"
182 offset="0.6648" />
183 <stop
184 id="stop247"
185 style="stop-color:#FCF6D0"
186 offset="0.7882" />
187 <stop
188 id="stop249"
189 style="stop-color:#FCF8E1"
190 offset="0.8879" />
191 <stop
192 id="stop251"
193 style="stop-color:#FFFDF7"
194 offset="0.9723" />
195 <stop
196 id="stop253"
197 style="stop-color:#FFFFFF"
198 offset="1" />
199 </radialGradient>
200 <radialGradient
201 inkscape:collect="always"
202 xlink:href="#SVGID_7_"
203 id="radialGradient3314"
204 gradientUnits="userSpaceOnUse"
205 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
206 cx="148.9492"
207 cy="270.04489"
208 r="2.8799" />
209 <radialGradient
210 gradientUnits="userSpaceOnUse"
211 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
212 r="2.8799"
213 cy="270.04489"
214 cx="148.9492"
215 id="SVGID_7_">
216 <stop
217 id="stop258"
218 style="stop-color:#FAF0BB"
219 offset="0.0112" />
220 <stop
221 id="stop260"
222 style="stop-color:#FAF0BD"
223 offset="0.4917" />
224 <stop
225 id="stop262"
226 style="stop-color:#FBF2C5"
227 offset="0.6648" />
228 <stop
229 id="stop264"
230 style="stop-color:#FCF6D0"
231 offset="0.7882" />
232 <stop
233 id="stop266"
234 style="stop-color:#FCF8E1"
235 offset="0.8879" />
236 <stop
237 id="stop268"
238 style="stop-color:#FFFDF7"
239 offset="0.9723" />
240 <stop
241 id="stop270"
242 style="stop-color:#FFFFFF"
243 offset="1" />
244 </radialGradient>
245 <radialGradient
246 inkscape:collect="always"
247 xlink:href="#SVGID_8_"
248 id="radialGradient3316"
249 gradientUnits="userSpaceOnUse"
250 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
251 cx="148.0723"
252 cy="319.09381"
253 r="3.9265001" />
254 <radialGradient
255 gradientUnits="userSpaceOnUse"
256 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
257 r="3.9265001"
258 cy="319.09381"
259 cx="148.0723"
260 id="SVGID_8_">
261 <stop
262 id="stop275"
263 style="stop-color:#FAF0BB"
264 offset="0.0112" />
265 <stop
266 id="stop277"
267 style="stop-color:#FAF0BD"
268 offset="0.4917" />
269 <stop
270 id="stop279"
271 style="stop-color:#FBF2C5"
272 offset="0.6648" />
273 <stop
274 id="stop281"
275 style="stop-color:#FCF6D0"
276 offset="0.7882" />
277 <stop
278 id="stop283"
279 style="stop-color:#FCF8E1"
280 offset="0.8879" />
281 <stop
282 id="stop285"
283 style="stop-color:#FFFDF7"
284 offset="0.9723" />
285 <stop
286 id="stop287"
287 style="stop-color:#FFFFFF"
288 offset="1" />
289 </radialGradient>
290 <radialGradient
291 inkscape:collect="always"
292 xlink:href="#SVGID_9_"
293 id="radialGradient3318"
294 gradientUnits="userSpaceOnUse"
295 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
296 cx="112.9551"
297 cy="315.56049"
298 r="3.0683999" />
299 <radialGradient
300 gradientUnits="userSpaceOnUse"
301 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
302 r="3.0683999"
303 cy="315.56049"
304 cx="112.9551"
305 id="SVGID_9_">
306 <stop
307 id="stop292"
308 style="stop-color:#FAF0BB"
309 offset="0.0112" />
310 <stop
311 id="stop294"
312 style="stop-color:#FAF0BD"
313 offset="0.4917" />
314 <stop
315 id="stop296"
316 style="stop-color:#FBF2C5"
317 offset="0.6648" />
318 <stop
319 id="stop298"
320 style="stop-color:#FCF6D0"
321 offset="0.7882" />
322 <stop
323 id="stop300"
324 style="stop-color:#FCF8E1"
325 offset="0.8879" />
326 <stop
327 id="stop302"
328 style="stop-color:#FFFDF7"
329 offset="0.9723" />
330 <stop
331 id="stop304"
332 style="stop-color:#FFFFFF"
333 offset="1" />
334 </radialGradient>
335 <radialGradient
336 inkscape:collect="always"
337 xlink:href="#SVGID_10_"
338 id="radialGradient3320"
339 gradientUnits="userSpaceOnUse"
340 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
341 cx="132.0938"
342 cy="320.1113"
343 r="4.1712999" />
344 <radialGradient
345 gradientUnits="userSpaceOnUse"
346 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
347 r="4.1712999"
348 cy="320.1113"
349 cx="132.0938"
350 id="SVGID_10_">
351 <stop
352 id="stop309"
353 style="stop-color:#FAF0BB"
354 offset="0.0112" />
355 <stop
356 id="stop311"
357 style="stop-color:#FAF0BD"
358 offset="0.4917" />
359 <stop
360 id="stop313"
361 style="stop-color:#FBF2C5"
362 offset="0.6648" />
363 <stop
364 id="stop315"
365 style="stop-color:#FCF6D0"
366 offset="0.7882" />
367 <stop
368 id="stop317"
369 style="stop-color:#FCF8E1"
370 offset="0.8879" />
371 <stop
372 id="stop319"
373 style="stop-color:#FFFDF7"
374 offset="0.9723" />
375 <stop
376 id="stop321"
377 style="stop-color:#FFFFFF"
378 offset="1" />
379 </radialGradient>
380 <radialGradient
381 inkscape:collect="always"
382 xlink:href="#SVGID_11_"
383 id="radialGradient3322"
384 gradientUnits="userSpaceOnUse"
385 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
386 cx="147.44189"
387 cy="301.21091"
388 r="2.5313001" />
389 <radialGradient
390 gradientUnits="userSpaceOnUse"
391 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
392 r="2.5313001"
393 cy="301.21091"
394 cx="147.44189"
395 id="SVGID_11_">
396 <stop
397 id="stop326"
398 style="stop-color:#FAF0BB"
399 offset="0.0112" />
400 <stop
401 id="stop328"
402 style="stop-color:#FAF0BD"
403 offset="0.4917" />
404 <stop
405 id="stop330"
406 style="stop-color:#FBF2C5"
407 offset="0.6648" />
408 <stop
409 id="stop332"
410 style="stop-color:#FCF6D0"
411 offset="0.7882" />
412 <stop
413 id="stop334"
414 style="stop-color:#FCF8E1"
415 offset="0.8879" />
416 <stop
417 id="stop336"
418 style="stop-color:#FFFDF7"
419 offset="0.9723" />
420 <stop
421 id="stop338"
422 style="stop-color:#FFFFFF"
423 offset="1" />
424 </radialGradient>
425 </defs>
426 <sodipodi:namedview
427 id="base"
428 pagecolor="#ffffff"
429 bordercolor="#666666"
430 borderopacity="1.0"
431 inkscape:pageopacity="0.0"
432 inkscape:pageshadow="2"
433 inkscape:zoom="22.395604"
434 inkscape:cx="-1.7469652"
435 inkscape:cy="9.9711386"
436 inkscape:current-layer="layer1"
437 showgrid="true"
438 inkscape:grid-bbox="true"
439 inkscape:document-units="px"
440 inkscape:window-width="1600"
441 inkscape:window-height="876"
442 inkscape:window-x="0"
443 inkscape:window-y="24"
444 inkscape:window-maximized="1">
445 <inkscape:grid
446 type="xygrid"
447 id="grid3184" />
448 </sodipodi:namedview>
449 <metadata
450 id="metadata25905">
451 <rdf:RDF>
452 <cc:Work
453 rdf:about="">
454 <dc:format>image/svg+xml</dc:format>
455 <dc:type
456 rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
457 <dc:title />
458 </cc:Work>
459 </rdf:RDF>
460 </metadata>
461 <g
462 id="layer1"
463 inkscape:label="Layer 1"
464 inkscape:groupmode="layer"
465 transform="translate(0,-16)">
466 <g
467 id="g3183"
468 transform="matrix(0.29719209,0,0,0.25546015,0.77084193,13.764694)">
469 <path
470 d="m 47.748262,36.240641 c -0.304876,-0.669777 -0.939962,-2.526029 -1.264261,-3.180039 -0.499962,-1.005938 -2.409862,-0.340737 -2.850285,-1.402107 -0.615238,-1.481949 0.402841,-3.075783 -0.26687,-4.517046 -0.51052,-1.098494 -2.320767,-1.749962 -2.830861,-2.848458 -0.374128,-0.804542 0.05785,-5.080024 -0.915894,-3.703855 -1.643875,2.32362 -3.133623,4.929999 -4.51865,7.769812 -0.227178,-0.299544 -0.460268,-0.590441 -0.699692,-0.872694 l 1.273972,-2.395837 -1.94875,1.641638 C 33.517528,26.509306 33.303862,26.293167 33.085974,26.08364 l 0.936581,-2.162914 -1.564066,1.585187 C 31.923058,25.034986 31.365246,24.598131 30.785899,24.1984 l 1.168829,-5.78896 -2.873088,4.753021 C 28.796189,23.01091 28.507361,22.866987 28.213887,22.732727 l 0.283762,-3.540102 -1.360114,3.093074 C 25.924369,21.832064 24.65631,21.526925 23.350669,21.385545 l -0.349636,-4.806419 -1.226255,4.716403 c -0.0033,0 -0.0071,0 -0.01056,0 -1.422186,-0.0066 -2.818193,0.185117 -4.164371,0.553823 l -1.190787,-2.856081 0.196351,3.163762 c -0.403261,0.139347 -0.801035,0.294459 -1.193319,0.465334 l -0.676466,-1.193086 0.243647,1.388883 c -0.482226,0.226309 -0.954317,0.47703 -1.416273,0.750127 l -2.649288,-2.676561 1.488058,3.425166 c -0.733893,0.515174 -1.434852,1.088322 -2.09654,1.715887 -0.09374,0.089 -0.187063,0.180031 -0.279538,0.271064 l -2.6176137,-1.775898 1.7557735,2.685206 c -0.2643372,0.297002 -0.5214955,0.60519 -0.7718972,0.922533 l -2.0728961,-1.396004 1.4580788,2.215805 c -0.340767,0.479065 -0.6650662,0.978474 -0.9716305,1.49568 -1.2705932,0.251233 -2.4081735,1.157486 -3.0905527,2.497041 0.00253,-0.005 0.00508,-0.01071 0.00802,-0.01578 -0.5079841,0.01071 -0.9074462,0.311242 -1.1177337,1.046115 -0.7347402,2.568744 -0.5366981,4.375156 0.1689057,5.408554 -0.1199231,0.09664 -0.2373126,0.202409 -0.3517463,0.317854 -1.90145688,1.925922 -2.20548742,5.78845 -0.6790012,8.625208 0.8470624,1.574001 2.0796522,2.501617 3.3341996,2.686733 0.6452198,1.719448 1.4880601,3.337183 2.5116286,4.809977 3.3333522,4.799809 8.4203702,7.849148 14.2412852,7.722516 5.766442,-0.126125 10.741561,-3.352949 13.962593,-8.195477 2.268826,-3.410417 3.604027,-7.536378 3.803758,-11.87187 L 41.77997,42.904823 39.623044,42.4461 c 0.003,-0.734364 -0.02618,-1.473813 -0.08952,-2.215806 l 3.332089,-2.112565 -3.537731,0.400746 C 39.264542,38.110618 39.19107,37.708348 39.108306,37.31116 l 0.959807,-0.628583 -1.067483,0.13782 c -0.02618,-0.113909 -0.05278,-0.226818 -0.08023,-0.33972 2.756541,-0.434818 5.473393,-0.393116 8.225288,0.328024 0.699694,0.183591 0.893512,0.07272 0.602574,-0.568064 z M 3.2551113,34.170284 c -0.017313,0.06662 -0.033782,0.134262 -0.04856,0.202916 -0.0114,0.05139 -0.022381,0.102733 -0.032514,0.154602 0.010132,-0.05188 0.020692,-0.10325 0.032514,-0.154602 0.01478,-0.06866 0.031247,-0.136294 0.04856,-0.202916 z m 0.4049515,-1.11121 c -0.010132,0.02085 -0.020269,0.04223 -0.030404,0.06306 0.010132,-0.02085 0.02027,-0.04222 0.030404,-0.06306 z m -0.079808,0.172404 c -0.010557,0.02339 -0.020692,0.0473 -0.030825,0.07119 0.010132,-0.02389 0.02027,-0.04782 0.030825,-0.07119 z m -0.075164,0.177488 c -0.010557,0.02644 -0.021113,0.0529 -0.031248,0.07984 0.010132,-0.02694 0.020692,-0.0534 0.031248,-0.07984 z m -0.070097,0.182573 c -0.010979,0.03002 -0.021535,0.06 -0.032092,0.09001 0.010557,-0.03002 0.021113,-0.06002 0.032092,-0.09001 z m -0.06545,0.187661 c -0.01098,0.03407 -0.021535,0.06866 -0.032515,0.103238 0.010979,-0.03458 0.021113,-0.06866 0.032515,-0.103238 z m -0.059962,0.193252 c -0.011823,0.04119 -0.023225,0.08289 -0.034626,0.124599 0.0114,-0.04172 0.022381,-0.08342 0.034626,-0.124599 z m -0.2558905,1.703683 c -8.452e-4,0.05034 -8.452e-4,0.100695 -4.223e-4,0.150535 -4.223e-4,-0.05034 -4.223e-4,-0.100705 4.223e-4,-0.150535 z m 0.1106333,-1.097477 c -0.00633,0.03458 -0.012668,0.06866 -0.018578,0.103239 0.00591,-0.03407 0.012245,-0.06866 0.018578,-0.103239 z m -0.028713,0.164775 c -0.00507,0.03153 -0.010132,0.06256 -0.01478,0.09357 0.00464,-0.03101 0.00971,-0.06204 0.01478,-0.09357 z m -0.023646,0.15867 c -0.00423,0.03053 -0.00802,0.06053 -0.011823,0.09052 0.00379,-0.03052 0.0076,-0.06054 0.011823,-0.09052 z m -0.019423,0.156131 c -0.00338,0.03002 -0.00633,0.05949 -0.00929,0.0895 0.00296,-0.03002 0.00591,-0.05951 0.00929,-0.0895 z m -0.015624,0.155617 c -0.00253,0.03002 -0.00464,0.06001 -0.00717,0.09001 0.00253,-0.03002 0.00508,-0.06001 0.00717,-0.09001 z m -0.0114,0.154604 c -0.0017,0.03154 -0.00338,0.06256 -0.00507,0.09408 0.0017,-0.03153 0.00338,-0.06256 0.00507,-0.09408 z m -0.0076,0.154095 c -0.00127,0.03662 -0.00211,0.07322 -0.00296,0.109332 4.221e-4,-0.03662 0.00127,-0.07272 0.00296,-0.109332 z m 0.1634162,1.705207 c -0.0076,-0.03203 -0.01478,-0.06407 -0.021535,-0.09611 0.00718,0.03205 0.013934,0.06407 0.021535,0.09611 z m -0.037161,-0.168331 c -0.00802,-0.03865 -0.015624,-0.07728 -0.023225,-0.115944 0.0076,0.03865 0.015624,0.07729 0.023225,0.115944 z m -0.033785,-0.176983 c -0.00507,-0.02847 -0.010132,-0.05696 -0.01478,-0.08543 0.00464,0.02795 0.010132,0.05696 0.01478,0.08543 z m -0.024491,-0.152059 c -0.00423,-0.02694 -0.00844,-0.05392 -0.012245,-0.08138 0.00379,0.02694 0.0076,0.05442 0.012245,0.08138 z m -0.021113,-0.150025 c -0.00338,-0.02694 -0.00675,-0.0534 -0.00971,-0.08086 0.00296,0.02747 0.00633,0.05442 0.00971,0.08086 z m -0.017313,-0.149518 c -0.00296,-0.02694 -0.00549,-0.05392 -0.00802,-0.08137 0.00253,0.02747 0.00508,0.05441 0.00802,0.08137 z m -0.013934,-0.150024 c -0.00211,-0.02795 -0.00423,-0.05546 -0.00591,-0.08341 0.0017,0.02747 0.00379,0.05544 0.00591,0.08341 z m -0.010132,-0.150536 c -0.0017,-0.0295 -0.00296,-0.059 -0.00423,-0.0885 0.00127,0.0295 0.00253,0.05898 0.00423,0.0885 z m -0.00675,-0.15206 c -0.00127,-0.03356 -0.0017,-0.06765 -0.00211,-0.101717 0,0.03407 8.451e-4,0.06814 0.00211,0.101717 z m 0.180307,1.313616 c 0.00633,0.02644 0.012668,0.0529 0.019424,0.07882 -0.00633,-0.02644 -0.012668,-0.05239 -0.019424,-0.07882 z m 0.1811488,1.679273 c -0.00211,9.74e-4 -0.00423,0.0021 -0.00633,0.003 0,0 0,0 4.224e-4,0 0.015624,-0.01072 0.031247,-0.02137 0.046871,-0.03205 -0.013511,0.0097 -0.027025,0.01933 -0.04096,0.02896 z M 3.2745435,37.437285 c 0.00675,0.02492 0.013511,0.04984 0.020692,0.07476 -0.00717,-0.02492 -0.013934,-0.04984 -0.020692,-0.07476 z m 0.040537,0.141888 c 0.00717,0.0244 0.014357,0.04883 0.021957,0.07272 -0.00717,-0.0244 -0.014779,-0.04832 -0.021957,-0.07272 z m 0.043072,0.139347 c 0.00802,0.02389 0.015624,0.04782 0.023646,0.0717 -0.0076,-0.02389 -0.015624,-0.04728 -0.023646,-0.0717 z m 0.046449,0.137819 c 0.00844,0.02389 0.016891,0.04782 0.025758,0.07171 -0.00844,-0.02389 -0.017313,-0.0473 -0.025758,-0.07171 z m 0.049405,0.135789 c 0.00929,0.0244 0.019001,0.04883 0.028292,0.07322 -0.00929,-0.02441 -0.019001,-0.04831 -0.028292,-0.07322 z m 0.052361,0.134256 c 0.010979,0.02747 0.022803,0.05442 0.034203,0.08188 -0.0114,-0.02747 -0.023225,-0.05442 -0.034203,-0.08188 z m 0.055317,0.13223 c 0.018158,0.04223 0.037159,0.08491 0.056584,0.12663 -0.019001,-0.04223 -0.038005,-0.0844 -0.056584,-0.12663 z m 0.081498,0.178505 c 0.012245,0.02543 0.024491,0.05086 0.036737,0.07627 -0.012668,-0.02543 -0.024491,-0.05086 -0.036737,-0.07627 z m 0.065028,0.132734 c 0.011824,0.02339 0.023646,0.04678 0.035893,0.07019 -0.012246,-0.02339 -0.024069,-0.04678 -0.035893,-0.07019 z m 0.066295,0.12714 c 0.00802,0.01423 0.015624,0.029 0.023646,0.04272 -0.012668,0.0066 -0.025336,0.01272 -0.037582,0.01933 0.012246,-0.0066 0.02449,-0.01373 0.036737,-0.01983 -0.00802,-0.01373 -0.015202,-0.02797 -0.022803,-0.04223 z"
471 id="path5"
472 inkscape:connector-curvature="0" />
473 <path
474 d="m 46.872485,35.321668 c -0.295587,-0.574676 -0.59117,-1.149351 -0.887179,-1.724024 -0.411284,-0.79946 -2.442377,-0.780135 -2.853662,-1.579594 -0.640154,-1.243435 0.339923,-3.306671 -0.300232,-4.550104 -0.487293,-0.94745 -2.164949,-1.469746 -2.652242,-2.417196 -0.272784,-0.53043 -0.355546,-1.274964 -0.330633,-1.912193 0.05237,-1.364979 0.09627,-2.14664 -0.825104,-0.815224 -1.463147,2.115108 -2.790324,4.459071 -4.019957,7.001881 0.08403,0.130191 0.166794,0.262928 0.248715,0.39617 1.867674,-0.780645 3.579534,-1.925924 5.084062,-3.359053 -1.390517,1.582138 -3.033126,2.860154 -4.860686,3.733354 0.119078,0.203934 0.236469,0.410917 0.350057,0.620953 -0.87662,-1.47788 -1.904834,-2.797597 -3.043681,-3.931183 l -0.220844,0.510597 1.016812,-2.721313 -1.72115,1.539922 0.100502,-0.101717 c -0.426911,-0.375317 -0.869023,-0.727243 -1.324646,-1.05679 l -0.259691,1.287172 0.928137,-6.116986 -3.276349,4.782515 0.695047,-1.149347 C 27.064907,22.874104 25.27366,22.28112 23.39754,22.038534 l 0.05785,0.790309 -0.581035,-4.788622 -1.425989,4.509928 0.165107,-0.635193 c -0.02449,0 -0.04899,-9.74e-4 -0.07348,-9.74e-4 -2.69658,-0.0122 -5.297306,0.706904 -7.628628,2.005263 l 0.994011,1.003896 -3.222299,-2.891682 1.639229,4.403639 -0.736427,-1.695038 c -0.777812,0.531955 -1.518886,1.130533 -2.214777,1.791154 -0.5865257,0.556877 -1.1460249,1.161557 -1.6734311,1.809973 l 0.3800423,0.25581 -2.2287093,-1.303955 1.2275217,2.117143 -0.091631,-0.139345 c -0.260959,0.36159 -0.5122061,0.73538 -0.7533194,1.120363 0,0 4.226e-4,0 4.226e-4,0 0.058698,-0.0046 0.1178119,-0.0076 0.1769282,-0.0097 0.4197311,-0.01322 0.848329,0.04476 1.274816,0.182576 0.9543158,0.307679 1.753238,0.965757 2.327517,1.82777 1.042571,-3.636727 4.259803,-5.735561 7.393005,-4.724541 3.275504,1.057303 5.220032,5.114101 4.342567,9.059015 -0.238157,1.070014 -0.659578,2.022044 -1.212743,2.819977 0.07093,0.03205 0.14188,0.06509 0.212399,0.100705 0.08361,0.04223 0.165949,0.08645 0.247024,0.132733 -2.976541,-1.313107 -6.314119,0.418546 -7.548398,3.975938 -1.2347,3.558409 0.08783,7.634533 2.955006,9.262947 -0.08446,-0.03713 -0.168483,-0.07627 -0.252515,-0.118496 -3.038191,-1.529246 -4.4722,-5.736577 -3.202452,-9.39619 0.218733,-0.629601 0.502918,-1.20224 0.839884,-1.711309 -1.472858,-0.618921 -2.639575,-1.861338 -3.348979,-3.411436 -0.588214,1.277509 -1.5788438,2.193938 -2.71769,2.574851 0.033789,0.06461 0.067143,0.129174 0.099654,0.195797 1.344911,2.750302 0.9285586,6.379401 -0.9298248,8.103932 -0.051515,0.04782 -0.1038771,0.09407 -0.1566596,0.137821 h 0 c 0.026184,-0.02694 0.05236,-0.05442 0.078121,-0.08188 8.773e-4,-0.0014 0.00167,-0.0026 0.00296,-0.0036 0.024916,-0.02694 0.049402,-0.05442 0.073895,-0.08239 0.00128,-0.0021 0.00296,-0.0036 0.00462,-0.005 0.024071,-0.02795 0.047713,-0.05545 0.070937,-0.08341 0.00167,-0.0026 0.00384,-0.0046 0.0055,-0.0071 0.023227,-0.02796 0.045607,-0.05543 0.067989,-0.08391 0.00216,-0.003 0.00423,-0.0061 0.00675,-0.0086 0.021955,-0.02847 0.043919,-0.05646 0.065029,-0.08542 0.00251,-0.003 0.00512,-0.0066 0.0072,-0.0097 0.021109,-0.02847 0.042228,-0.05696 0.062493,-0.08645 0.00251,-0.0036 0.00512,-0.0072 0.00755,-0.01071 0.020265,-0.0295 0.040538,-0.05799 0.060379,-0.08797 0.00251,-0.004 0.00512,-0.0076 0.008,-0.01121 0.01942,-0.0295 0.038848,-0.05898 0.058277,-0.08899 0.00251,-0.0046 0.00549,-0.0086 0.008,-0.0122 0.018997,-0.03002 0.037589,-0.06 0.055741,-0.09052 0.00251,-0.0046 0.00549,-0.0086 0.008,-0.01272 0.018152,-0.03052 0.036322,-0.06103 0.054051,-0.09204 0.00251,-0.0046 0.00512,-0.009 0.008,-0.01322 0.017729,-0.03153 0.035054,-0.06204 0.052361,-0.09357 0.00251,-0.005 0.00513,-0.0097 0.00755,-0.01373 0.017306,-0.03153 0.033789,-0.06306 0.050253,-0.09508 0.00251,-0.005 0.00513,-0.0097 0.00755,-0.01423 0.016464,-0.03153 0.032521,-0.06407 0.048559,-0.09613 0.00213,-0.005 0.00455,-0.0097 0.00716,-0.01425 0.015622,-0.03253 0.031254,-0.06509 0.046458,-0.09816 0.00213,-0.0046 0.00426,-0.0097 0.00677,-0.01373 0.015206,-0.03304 0.030402,-0.06713 0.045191,-0.100694 0.00213,-0.004 0.00387,-0.009 0.0059,-0.01272 0.01478,-0.03409 0.029559,-0.06865 0.043913,-0.102733 0.00175,-0.0046 0.00329,-0.0086 0.00513,-0.0122 0.014354,-0.03508 0.028291,-0.07019 0.042229,-0.105275 0.00126,-0.004 0.003,-0.0082 0.00426,-0.0112 0.013937,-0.0356 0.027449,-0.07222 0.040961,-0.108333 8.768e-4,-0.003 0.00213,-0.0061 0.00329,-0.0097 0.013511,-0.03662 0.026607,-0.07425 0.039693,-0.111368 8.769e-4,-0.0026 0.00175,-0.005 0.00251,-0.0076 0.013085,-0.03815 0.026181,-0.07627 0.038425,-0.115439 0,-9.73e-4 4.229e-4,-0.0021 8.769e-4,-0.0026 0.1570825,-0.485678 0.2630703,-1.002882 0.3166975,-1.535857 4.228e-4,-0.004 8.777e-4,-0.0082 0.00124,-0.01118 0.00383,-0.03762 0.00713,-0.07528 0.010132,-0.113404 4.219e-4,-0.0082 0.00124,-0.01576 0.00217,-0.02389 0.003,-0.03458 0.00548,-0.06968 0.00755,-0.104238 8.767e-4,-0.01071 0.00176,-0.02238 0.00248,-0.03305 0.00217,-0.03253 0.00383,-0.06561 0.00548,-0.09816 4.218e-4,-0.01322 0.00124,-0.02644 0.00217,-0.03917 0.00176,-0.03153 0.00248,-0.06306 0.00383,-0.09459 4.229e-4,-0.01474 8.778e-4,-0.03002 0.00176,-0.04425 8.777e-4,-0.03052 0.00124,-0.06053 0.00217,-0.09052 4.228e-4,-0.01627 8.777e-4,-0.03253 8.777e-4,-0.04883 4.229e-4,-0.0295 4.229e-4,-0.05799 4.229e-4,-0.08747 0,-0.01728 0,-0.03459 0,-0.05239 0,-0.02847 -4.229e-4,-0.05644 -8.778e-4,-0.08492 0,-0.01831 -4.228e-4,-0.03611 -4.228e-4,-0.05441 -4.208e-4,-0.02796 -0.00124,-0.05544 -0.00217,-0.08339 -4.229e-4,-0.0188 -8.767e-4,-0.03763 -0.00176,-0.05645 -8.767e-4,-0.02694 -0.00217,-0.0534 -0.00331,-0.08086 -8.768e-4,-0.01984 -0.00176,-0.03918 -0.003,-0.05899 -0.00124,-0.02694 -0.003,-0.0529 -0.00455,-0.07935 -0.00124,-0.02032 -0.00248,-0.04068 -0.00383,-0.06053 -0.00176,-0.02644 -0.00383,-0.05238 -0.00589,-0.07832 -0.00176,-0.02085 -0.00331,-0.04119 -0.00517,-0.06204 -0.00217,-0.02594 -0.00455,-0.05138 -0.00713,-0.0768 -0.00176,-0.02136 -0.00424,-0.04222 -0.00631,-0.06307 -0.00248,-0.02543 -0.00548,-0.05086 -0.00842,-0.07577 -0.00251,-0.02185 -0.00513,-0.04323 -0.00755,-0.06461 -0.003,-0.02492 -0.0059,-0.04985 -0.00929,-0.07425 -0.003,-0.02185 -0.0059,-0.04375 -0.0089,-0.06561 -0.00329,-0.02492 -0.00677,-0.04934 -0.01056,-0.07425 -0.00329,-0.02185 -0.00677,-0.04425 -0.010132,-0.06612 -0.00387,-0.02439 -0.00755,-0.04883 -0.011401,-0.07322 -0.00387,-0.02237 -0.00755,-0.04476 -0.011401,-0.06661 -0.00426,-0.02441 -0.00842,-0.04831 -0.01267,-0.07221 -0.00426,-0.02288 -0.00842,-0.04526 -0.01267,-0.06765 -0.00455,-0.02389 -0.0089,-0.04782 -0.013937,-0.07119 -0.00455,-0.02288 -0.00929,-0.04526 -0.013938,-0.06815 -0.00513,-0.0234 -0.00971,-0.04729 -0.015206,-0.07069 -0.00513,-0.02288 -0.010132,-0.04576 -0.015206,-0.06866 -0.00513,-0.02288 -0.010549,-0.04629 -0.016047,-0.06915 -0.00552,-0.02339 -0.010976,-0.04629 -0.01688,-0.06915 -0.00552,-0.02288 -0.010975,-0.04576 -0.01688,-0.06814 -0.0059,-0.02339 -0.011827,-0.04678 -0.018148,-0.06968 -0.0059,-0.02288 -0.011818,-0.04527 -0.018148,-0.06765 -0.0063,-0.0234 -0.01267,-0.04628 -0.019416,-0.06968 -0.0063,-0.02238 -0.01267,-0.04425 -0.018999,-0.06661 -0.00677,-0.0234 -0.013937,-0.04678 -0.021109,-0.07019 -0.00677,-0.02185 -0.013086,-0.04374 -0.019842,-0.0656 -0.00755,-0.02389 -0.015206,-0.0473 -0.022804,-0.0707 -0.00677,-0.02136 -0.013937,-0.0427 -0.020683,-0.0646 -0.00803,-0.02339 -0.016038,-0.04679 -0.024071,-0.07069 -0.00755,-0.02085 -0.014354,-0.04222 -0.021952,-0.06306 -0.00842,-0.0244 -0.017306,-0.04831 -0.026181,-0.07221 -0.00755,-0.02031 -0.01478,-0.04069 -0.022378,-0.06103 -0.0089,-0.02441 -0.018574,-0.04883 -0.027875,-0.07272 -0.00755,-0.02032 -0.015206,-0.04018 -0.022804,-0.05949 -0.00971,-0.02492 -0.019842,-0.04933 -0.029985,-0.07425 -0.00803,-0.01865 -0.015622,-0.03799 -0.023645,-0.05732 -0.010975,-0.02594 -0.021952,-0.05188 -0.033363,-0.0768 -0.00755,-0.0178 -0.015206,-0.0351 -0.022804,-0.0529 -0.01267,-0.0295 -0.026182,-0.05799 -0.039267,-0.08696 -0.00677,-0.0137 -0.01267,-0.02845 -0.019416,-0.04219 C 8.552808,41.518875 8.532531,41.476167 8.511847,41.433436 7.1669757,38.683133 4.5692051,37.851124 2.7108196,39.57515 0.85243366,41.299176 0.436081,44.928276 1.7809934,47.678578 c 0.023225,0.04782 0.046871,0.0951 0.07094,0.140872 0.0076,0.01474 0.015624,0.0295 0.023225,0.04425 0.01689,0.03153 0.033358,0.06307 0.05025,0.09459 0.00887,0.01626 0.018158,0.03307 0.027448,0.04985 0.016468,0.0295 0.032514,0.05799 0.048982,0.08645 0.00929,0.01627 0.018578,0.03253 0.028291,0.04883 0.017735,0.03002 0.035048,0.0595 0.053205,0.0885 0.00844,0.01373 0.01689,0.02795 0.025336,0.04172 0.024491,0.03917 0.048983,0.07729 0.073473,0.115944 0.00211,0.0036 0.00423,0.0072 0.00633,0.01012 0.027025,0.0417 0.054894,0.0824 0.082765,0.123071 0.00802,0.01121 0.015624,0.02237 0.023646,0.03305 0.020269,0.02896 0.040538,0.05746 0.061228,0.08595 0.00971,0.01322 0.019424,0.02694 0.029136,0.03966 0.019423,0.02644 0.038848,0.05239 0.058271,0.07729 0.00971,0.01271 0.019847,0.02594 0.029981,0.03865 0.020692,0.02694 0.041381,0.0529 0.062496,0.0783 0.00887,0.01071 0.017735,0.02185 0.026181,0.03255 0.027025,0.03305 0.054473,0.06561 0.082342,0.09764 0.00253,0.003 0.00464,0.0061 0.00718,0.0086 0.031248,0.03611 0.062496,0.07119 0.094165,0.105779 0.00591,0.0066 0.011823,0.0122 0.017735,0.0188 0.025337,0.02747 0.050671,0.05392 0.076429,0.08086 0.00887,0.0097 0.018158,0.0183 0.027448,0.02796 0.023226,0.02339 0.046027,0.0468 0.069674,0.06969 0.00929,0.0097 0.019001,0.0183 0.028292,0.02796 0.024491,0.02339 0.048982,0.04678 0.073473,0.06915 0.00802,0.0076 0.016046,0.01474 0.024069,0.02238 0.031247,0.02847 0.062496,0.05645 0.094587,0.08391 0.00127,9.74e-4 0.00253,0.0021 0.00338,0.003 0.035048,0.03002 0.070097,0.05898 0.1051438,0.08747 0.0017,0.0014 0.00338,0.003 0.00508,0.0046 0.032091,0.02594 0.064184,0.05086 0.096698,0.07527 0.00718,0.0056 0.014357,0.01073 0.021535,0.01578 0.027448,0.02085 0.055317,0.04069 0.083186,0.0605 0.00802,0.0061 0.016046,0.01121 0.024069,0.01678 0.028293,0.02032 0.057006,0.03967 0.08572,0.059 0.00633,0.004 0.012668,0.0086 0.019424,0.0122 0.1072551,0.07119 0.2166217,0.135784 0.3268326,0.193761 0.00423,0.0021 0.00887,0.0046 0.01309,0.0066 0.032515,0.01678 0.064607,0.03307 0.097121,0.04883 0.0059,0.003 0.012246,0.0061 0.018158,0.009 0.032092,0.01524 0.064607,0.03052 0.096698,0.04425 0.00464,0.0021 0.00929,0.0046 0.014356,0.0066 0.1135892,0.04933 0.2284449,0.09256 0.3433009,0.128156 0.0017,5.1e-4 0.00338,9.74e-4 0.00549,0.0014 0.035892,0.0112 0.071785,0.02187 0.1076773,0.03154 0.00464,9.73e-4 0.00929,0.0026 0.013934,0.0036 0.034626,0.0097 0.068829,0.0178 0.1034547,0.02594 0.00379,9.74e-4 0.00802,0.0021 0.011824,0.003 0.1169673,0.02694 0.2343567,0.04679 0.3517462,0.05951 l 0,0 c 0.6481757,1.849131 1.52733,3.584344 2.6163505,5.151733 3.2493206,4.67828 8.2075476,7.650825 13.8810926,7.526736 5.62076,-0.12256 10.470044,-3.267511 13.60958,-7.987475 2.711782,-4.077649 4.055427,-9.202937 3.667366,-14.468077 l -0.625796,0.397186 3.441877,-2.497548 -4.004333,0.160197 0.94925,-0.107311 c -0.220421,-1.378712 -0.556544,-2.696396 -0.990631,-3.942371 0.168484,0.428718 0.325565,0.867097 0.469134,1.315141 2.798347,-0.571116 5.565447,-0.68554 8.28863,-0.151043 0.771477,0.153076 0.933204,0.41702 0.464491,-0.493815 z m -12.799679,3.703349 c -0.150327,4.243438 -1.599116,6.202419 -3.283952,6.35143 -0.291784,0.02594 -0.581036,-0.003 -0.882953,-0.08339 0.127101,0.01169 0.25378,0.01373 0.380461,0.005 0.947982,-0.0656 1.826292,-0.718089 2.438574,-2.048996 -1.654432,-1.002882 -3.38487,-1.607564 -5.059992,-1.826755 1.684833,0.07272 3.4651,0.599086 5.159647,1.598919 0.215777,-0.520259 0.393129,-1.134093 0.522342,-1.846589 -1.866407,-0.63926 -3.746752,-0.830988 -5.497882,-0.626039 1.72875,-0.355486 3.641185,-0.255806 5.541374,0.37074 0.08615,-0.535514 0.146526,-1.122905 0.176508,-1.764709 0.0114,-0.238514 -0.003,-0.451602 -0.03927,-0.641804 -2.009135,-0.114427 -3.941838,0.243602 -5.656652,0.971863 1.643451,-0.864048 3.568132,-1.320736 5.586133,-1.236826 -0.412129,-1.186475 -1.895967,-1.250044 -3.554621,-0.903205 2.210554,-0.579759 4.250091,-0.552808 4.170283,1.68029 z m 2.44111,-7.055789 c 1.92468,-0.563996 3.721414,-1.511446 5.334888,-2.770136 -1.510441,1.419396 -3.24806,2.506191 -5.138958,3.16783 -0.06418,-0.133245 -0.129212,-0.265977 -0.19593,-0.397694 z m 0.825526,1.842519 c -0.05574,-0.141379 -0.112746,-0.282252 -0.171017,-0.421598 1.999844,-0.298525 3.997577,-0.112402 5.887635,0.505511 -1.862188,-0.401765 -3.791937,-0.442449 -5.716618,-0.08392 z"
475 id="path14"
476 style="fill:#f0a513;fill-opacity:1"
477 inkscape:connector-curvature="0" />
478 <path
479 d="m 17.971864,28.383357 c 3.029325,0.977457 4.82775,4.729117 4.016157,8.37805 -0.214087,0.963215 -0.589481,1.823193 -1.080996,2.549419 -2.202109,-0.672827 -4.51105,0.238008 -5.964907,2.257001 -2.974852,-1.022212 -4.729782,-4.734713 -3.926214,-8.347029 0.811593,-3.648933 3.926636,-5.815407 6.95596,-4.837441 z"
480 id="path16"
481 inkscape:connector-curvature="0"
482 style="fill:#ffffff" />
483 <path
484 d="m 21.46948,31.675787 c 0.688291,1.496188 0.915048,3.303109 0.518541,5.08562 -0.214087,0.963215 -0.589481,1.823193 -1.080996,2.549419 -2.202532,-0.672827 -4.511474,0.238008 -5.965329,2.257001 -1.217389,-0.418038 -2.2304,-1.28768 -2.947405,-2.415671 0.307831,0.161723 0.630018,0.298527 0.964451,0.406343 3.605716,1.163589 7.313197,-1.414313 8.279337,-5.756922 0.157927,-0.710463 0.232246,-1.423974 0.231401,-2.12579 z"
485 id="path18"
486 inkscape:connector-curvature="0"
487 style="fill:#eeeeee" />
488 <path
489 d="m 11.148494,37.665629 c -0.473779,-1.361928 -0.61397,-2.903379 -0.33232,-4.44127 -0.52952,-1.020176 -1.3685584,-1.810482 -2.4090152,-2.146133 -2.1826849,-0.704357 -4.4270197,0.856418 -5.0118558,3.484667 -0.3242991,1.457031 -0.070517,2.936437 0.5915924,4.085786 1.0683288,-0.4694 2.2489802,-0.271571 3.2581915,0.503477 0.4619579,0.354468 0.8876005,0.829465 1.2503252,1.416854 1.1793816,-0.417022 2.1776139,-1.463641 2.6530819,-2.903381 z"
490 id="path20"
491 inkscape:connector-curvature="0"
492 style="fill:#ffffff" />
493 <path
494 d="m 31.2411,51.394259 1.26637,0.637229 -2.465178,-0.01373 c -4.530473,2.179698 -9.426207,2.60994 -12.629927,1.007461 -0.08825,-0.03864 -0.176507,-0.07984 -0.264338,-0.124092 -3.038191,-1.529243 -4.472201,-5.736578 -3.202453,-9.39619 0.218732,-0.6296 0.503339,-1.202239 0.840306,-1.710803 l 0,-5.07e-4 c -1.472857,-0.618925 -2.639574,-1.861849 -3.348978,-3.411437 -0.588215,1.277507 -1.5788467,2.193936 -2.7176907,2.574848 0.033779,0.06461 0.067143,0.129175 0.099655,0.195796 1.3449097,2.750303 0.9285573,6.379402 -0.9298254,8.103935 -0.051515,0.04782 -0.1038771,0.09408 -0.1566605,0.137821 l 0,0 c -0.048979,0.05034 -0.098387,0.09866 -0.1494812,0.145956 -0.7486746,0.694696 -1.6176949,0.974406 -2.4761587,0.880322 l 0,5.08e-4 c 0.6477536,1.848622 1.5273307,3.584344 2.6159279,5.151732 3.2493226,4.678262 8.2075486,7.650298 13.8810926,7.526717 5.620762,-0.12256 10.470046,-3.268018 13.609581,-7.987982 2.123568,-3.192243 3.407673,-7.028327 3.678768,-11.070884 -1.87021,3.185631 -4.634352,5.665888 -7.651009,7.353296 z"
495 id="path183"
496 style="fill:#fdd99b"
497 inkscape:connector-curvature="0" />
498 <path
499 d="m 11.261241,44.175223 c -0.158773,-0.250722 -0.250827,-0.566539 -0.243648,-0.906768 0.01224,-0.584846 0.312898,-1.079675 0.733895,-1.291745 -0.616928,0.507545 -0.839039,1.75098 -0.173129,2.336839 0.277429,0.243604 0.439579,0.574168 0.370749,1.028824 -0.05363,0.355991 -0.262648,0.802509 -0.591168,1.144265 -0.374972,0.389558 -0.833129,0.599593 -1.228791,0.541109 0.37835,-0.112404 0.757541,-0.387016 1.06284,-0.752165 0.26307,-0.314291 0.444644,-0.675369 0.519384,-0.97542 0.14906,-0.596542 -0.181995,-0.701818 -0.450132,-1.124939 l 0,0 z m 1.895122,4.408723 c -0.233935,0.931683 -0.952208,1.610106 -1.802226,1.610106 -0.765564,0 -1.4251397,-0.551279 -1.7190352,-1.342094 0.3783472,0.632143 0.9944302,1.044078 1.6907442,1.044078 0.790057,0 1.477502,-0.530939 1.830517,-1.31209 z"
500 id="path185"
501 inkscape:connector-curvature="0" />
502 <g
503 id="g187"
504 transform="matrix(0.42226435,0,0,0.50856192,-47.726977,-111.72952)">
505 <radialGradient
506 id="radialGradient3241"
507 cx="163.4902"
508 cy="274.86621"
509 r="2.8801"
510 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
511 gradientUnits="userSpaceOnUse">
512 <stop
513 offset="0.0112"
514 style="stop-color:#FAF0BB"
515 id="stop3243" />
516 <stop
517 offset="0.4917"
518 style="stop-color:#FAF0BD"
519 id="stop3245" />
520 <stop
521 offset="0.6648"
522 style="stop-color:#FBF2C5"
523 id="stop3247" />
524 <stop
525 offset="0.7882"
526 style="stop-color:#FCF6D0"
527 id="stop3249" />
528 <stop
529 offset="0.8879"
530 style="stop-color:#FCF8E1"
531 id="stop3251" />
532 <stop
533 offset="0.9723"
534 style="stop-color:#FFFDF7"
535 id="stop3253" />
536 <stop
537 offset="1"
538 style="stop-color:#FFFFFF"
539 id="stop3255" />
540 </radialGradient>
541 <path
542 d="m 189.806,311.298 c -0.681,-0.478 -1.432,-0.68 -2.1,-0.645 -0.633,0.034 -1.217,0.284 -1.625,0.739 -0.408,0.454 -0.59,1.052 -0.559,1.676 0.034,0.653 0.305,1.364 0.834,1.98 0.577,0.671 1.35,1.108 2.143,1.244 0.845,0.145 1.679,-0.06 2.247,-0.657 0.573,-0.604 0.725,-1.448 0.515,-2.282 -0.199,-0.789 -0.713,-1.534 -1.455,-2.055 z"
543 id="path204"
544 style="fill:url(#radialGradient3305)"
545 inkscape:connector-curvature="0" />
546 <radialGradient
547 id="radialGradient3258"
548 cx="155.3242"
549 cy="310.6777"
550 r="4.4867001"
551 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
552 gradientUnits="userSpaceOnUse">
553 <stop
554 offset="0.0112"
555 style="stop-color:#FAF0BB"
556 id="stop3260" />
557 <stop
558 offset="0.4917"
559 style="stop-color:#FAF0BD"
560 id="stop3262" />
561 <stop
562 offset="0.6648"
563 style="stop-color:#FBF2C5"
564 id="stop3264" />
565 <stop
566 offset="0.7882"
567 style="stop-color:#FCF6D0"
568 id="stop3266" />
569 <stop
570 offset="0.8879"
571 style="stop-color:#FCF8E1"
572 id="stop3268" />
573 <stop
574 offset="0.9723"
575 style="stop-color:#FFFDF7"
576 id="stop3270" />
577 <stop
578 offset="1"
579 style="stop-color:#FFFFFF"
580 id="stop3272" />
581 </radialGradient>
582 <path
583 d="m 183.164,274.256 c -0.777,-0.621 -1.774,-0.996 -2.853,-1 -1.077,-0.004 -2.096,0.366 -2.89,0.992 -0.839,0.661 -1.465,1.633 -1.646,2.791 -0.197,1.263 0.167,2.499 0.961,3.449 0.841,1.005 2.124,1.644 3.592,1.617 1.455,-0.026 2.71,-0.702 3.522,-1.716 0.762,-0.951 1.106,-2.168 0.913,-3.4 -0.179,-1.131 -0.786,-2.082 -1.599,-2.733 z"
584 id="path221"
585 style="fill:url(#radialGradient3307)"
586 inkscape:connector-curvature="0" />
587 <radialGradient
588 id="radialGradient3275"
589 cx="170.3125"
590 cy="302.00781"
591 r="5.0811"
592 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
593 gradientUnits="userSpaceOnUse">
594 <stop
595 offset="0.0112"
596 style="stop-color:#FAF0BB"
597 id="stop3277" />
598 <stop
599 offset="0.4917"
600 style="stop-color:#FAF0BD"
601 id="stop3279" />
602 <stop
603 offset="0.6648"
604 style="stop-color:#FBF2C5"
605 id="stop3281" />
606 <stop
607 offset="0.7882"
608 style="stop-color:#FCF6D0"
609 id="stop3283" />
610 <stop
611 offset="0.8879"
612 style="stop-color:#FCF8E1"
613 id="stop3285" />
614 <stop
615 offset="0.9723"
616 style="stop-color:#FFFDF7"
617 id="stop3287" />
618 <stop
619 offset="1"
620 style="stop-color:#FFFFFF"
621 id="stop3289" />
622 </radialGradient>
623 <path
624 d="m 197.254,290.925 c 1.482,-0.322 2.697,-1.225 3.201,-2.604 0.5,-1.367 0.166,-2.845 -0.726,-4.066 -0.835,-1.146 -2.134,-2.023 -3.647,-2.408 -1.389,-0.352 -2.723,-0.223 -3.781,0.238 -1.011,0.439 -1.812,1.196 -2.21,2.198 -0.397,1.001 -0.335,2.12 0.108,3.146 0.468,1.083 1.377,2.112 2.666,2.812 1.407,0.762 2.987,0.989 4.389,0.684 z"
625 id="path238"
626 style="fill:url(#radialGradient3310)"
627 inkscape:connector-curvature="0" />
628 <radialGradient
629 id="radialGradient3292"
630 cx="173.2812"
631 cy="283.68359"
632 r="2.8803999"
633 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
634 gradientUnits="userSpaceOnUse">
635 <stop
636 offset="0.0112"
637 style="stop-color:#FAF0BB"
638 id="stop3294" />
639 <stop
640 offset="0.4917"
641 style="stop-color:#FAF0BD"
642 id="stop3296" />
643 <stop
644 offset="0.6648"
645 style="stop-color:#FBF2C5"
646 id="stop3298" />
647 <stop
648 offset="0.7882"
649 style="stop-color:#FCF6D0"
650 id="stop3300" />
651 <stop
652 offset="0.8879"
653 style="stop-color:#FCF8E1"
654 id="stop3302" />
655 <stop
656 offset="0.9723"
657 style="stop-color:#FFFDF7"
658 id="stop3304" />
659 <stop
660 offset="1"
661 style="stop-color:#FFFFFF"
662 id="stop3306" />
663 </radialGradient>
664 <path
665 d="m 200.538,302.533 c -0.568,-0.598 -1.402,-0.802 -2.248,-0.657 -0.792,0.136 -1.565,0.573 -2.143,1.244 -0.529,0.616 -0.8,1.327 -0.833,1.98 -0.032,0.624 0.15,1.222 0.559,1.676 0.408,0.455 0.991,0.705 1.624,0.739 0.668,0.035 1.42,-0.167 2.101,-0.645 0.741,-0.521 1.256,-1.267 1.454,-2.056 0.21,-0.833 0.058,-1.677 -0.514,-2.281 z"
666 id="path255"
667 style="fill:url(#radialGradient3312)"
668 inkscape:connector-curvature="0" />
669 <radialGradient
670 id="radialGradient3309"
671 cx="148.9492"
672 cy="270.04489"
673 r="2.8799"
674 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
675 gradientUnits="userSpaceOnUse">
676 <stop
677 offset="0.0112"
678 style="stop-color:#FAF0BB"
679 id="stop3311" />
680 <stop
681 offset="0.4917"
682 style="stop-color:#FAF0BD"
683 id="stop3313" />
684 <stop
685 offset="0.6648"
686 style="stop-color:#FBF2C5"
687 id="stop3315" />
688 <stop
689 offset="0.7882"
690 style="stop-color:#FCF6D0"
691 id="stop3317" />
692 <stop
693 offset="0.8879"
694 style="stop-color:#FCF8E1"
695 id="stop3319" />
696 <stop
697 offset="0.9723"
698 style="stop-color:#FFFDF7"
699 id="stop3321" />
700 <stop
701 offset="1"
702 style="stop-color:#FFFFFF"
703 id="stop3323" />
704 </radialGradient>
705 <path
706 d="m 173.958,315.516 c -0.793,0.136 -1.566,0.573 -2.143,1.244 -0.529,0.616 -0.801,1.327 -0.834,1.98 -0.031,0.623 0.15,1.222 0.559,1.676 0.408,0.455 0.991,0.705 1.624,0.738 0.669,0.036 1.42,-0.166 2.101,-0.645 0.741,-0.521 1.256,-1.266 1.454,-2.055 0.211,-0.834 0.06,-1.679 -0.514,-2.282 -0.568,-0.598 -1.402,-0.801 -2.247,-0.656 z"
707 id="path272"
708 style="fill:url(#radialGradient3314)"
709 inkscape:connector-curvature="0" />
710 <radialGradient
711 id="radialGradient3326"
712 cx="148.0723"
713 cy="319.09381"
714 r="3.9265001"
715 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
716 gradientUnits="userSpaceOnUse">
717 <stop
718 offset="0.0112"
719 style="stop-color:#FAF0BB"
720 id="stop3328" />
721 <stop
722 offset="0.4917"
723 style="stop-color:#FAF0BD"
724 id="stop3330" />
725 <stop
726 offset="0.6648"
727 style="stop-color:#FBF2C5"
728 id="stop3332" />
729 <stop
730 offset="0.7882"
731 style="stop-color:#FCF6D0"
732 id="stop3334" />
733 <stop
734 offset="0.8879"
735 style="stop-color:#FCF8E1"
736 id="stop3336" />
737 <stop
738 offset="0.9723"
739 style="stop-color:#FFFDF7"
740 id="stop3338" />
741 <stop
742 offset="1"
743 style="stop-color:#FFFFFF"
744 id="stop3340" />
745 </radialGradient>
746 <path
747 d="m 171.282,272.336 c 1.106,0.549 2.333,0.68 3.407,0.405 1.136,-0.291 2.049,-1.022 2.398,-2.102 0.347,-1.069 0.048,-2.201 -0.675,-3.119 -0.678,-0.861 -1.706,-1.502 -2.885,-1.756 -1.083,-0.233 -2.109,-0.095 -2.914,0.291 -0.768,0.368 -1.365,0.975 -1.645,1.76 -0.278,0.785 -0.198,1.646 0.173,2.426 0.394,0.822 1.125,1.592 2.141,2.095 z"
748 id="path289"
749 style="fill:url(#radialGradient3316)"
750 inkscape:connector-curvature="0" />
751 <radialGradient
752 id="radialGradient3343"
753 cx="112.9551"
754 cy="315.56049"
755 r="3.0683999"
756 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
757 gradientUnits="userSpaceOnUse">
758 <stop
759 offset="0.0112"
760 style="stop-color:#FAF0BB"
761 id="stop3345" />
762 <stop
763 offset="0.4917"
764 style="stop-color:#FAF0BD"
765 id="stop3347" />
766 <stop
767 offset="0.6648"
768 style="stop-color:#FBF2C5"
769 id="stop3349" />
770 <stop
771 offset="0.7882"
772 style="stop-color:#FCF6D0"
773 id="stop3351" />
774 <stop
775 offset="0.8879"
776 style="stop-color:#FCF8E1"
777 id="stop3353" />
778 <stop
779 offset="0.9723"
780 style="stop-color:#FFFDF7"
781 id="stop3355" />
782 <stop
783 offset="1"
784 style="stop-color:#FFFFFF"
785 id="stop3357" />
786 </radialGradient>
787 <path
788 d="m 140.776,270.8 c -0.132,-0.306 -0.298,-0.603 -0.496,-0.884 0,0 -0.001,-10e-4 -0.001,-10e-4 -0.031,0.02 -0.061,0.042 -0.091,0.062 -0.1,0.067 -0.199,0.135 -0.298,0.203 -0.12,0.082 -0.24,0.163 -0.358,0.246 -0.123,0.085 -0.245,0.173 -0.366,0.26 -0.096,0.068 -0.193,0.136 -0.289,0.206 -0.146,0.106 -0.29,0.213 -0.434,0.321 -0.072,0.054 -0.145,0.106 -0.216,0.161 -0.215,0.163 -0.429,0.328 -0.641,0.495 -0.223,0.175 -0.443,0.354 -0.663,0.535 -0.064,0.053 -0.129,0.107 -0.194,0.161 -0.171,0.143 -0.341,0.287 -0.51,0.432 -0.054,0.046 -0.108,0.092 -0.162,0.139 -0.193,0.167 -0.384,0.337 -0.574,0.509 -0.098,0.088 -0.196,0.178 -0.293,0.268 -0.099,0.09 -0.196,0.182 -0.294,0.274 -0.079,0.074 -0.16,0.146 -0.238,0.222 0,0 0.001,0.001 0.001,0.001 0.177,0.156 0.363,0.299 0.555,0.429 0.596,0.402 1.257,0.671 1.927,0.786 1.185,0.202 2.356,-0.083 3.152,-0.922 0.804,-0.847 1.017,-2.032 0.722,-3.202 -0.06,-0.24 -0.14,-0.473 -0.239,-0.701 z"
789 id="path306"
790 style="fill:url(#radialGradient3318)"
791 inkscape:connector-curvature="0" />
792 <radialGradient
793 id="radialGradient3360"
794 cx="132.0938"
795 cy="320.1113"
796 r="4.1712999"
797 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
798 gradientUnits="userSpaceOnUse">
799 <stop
800 offset="0.0112"
801 style="stop-color:#FAF0BB"
802 id="stop3362" />
803 <stop
804 offset="0.4917"
805 style="stop-color:#FAF0BD"
806 id="stop3364" />
807 <stop
808 offset="0.6648"
809 style="stop-color:#FBF2C5"
810 id="stop3366" />
811 <stop
812 offset="0.7882"
813 style="stop-color:#FCF6D0"
814 id="stop3368" />
815 <stop
816 offset="0.8879"
817 style="stop-color:#FCF8E1"
818 id="stop3370" />
819 <stop
820 offset="0.9723"
821 style="stop-color:#FFFDF7"
822 id="stop3372" />
823 <stop
824 offset="1"
825 style="stop-color:#FFFFFF"
826 id="stop3374" />
827 </radialGradient>
828 <path
829 d="m 160.2,265.6 c -0.85,-0.392 -1.938,-0.592 -3.115,-0.521 -1.177,0.07 -2.29,0.405 -3.157,0.906 -0.916,0.53 -1.6,1.269 -1.798,2.11 -0.216,0.917 0.182,1.777 1.05,2.403 0.918,0.663 2.32,1.032 3.923,0.914 1.588,-0.118 2.959,-0.687 3.847,-1.468 0.833,-0.732 1.209,-1.627 0.998,-2.496 -0.195,-0.799 -0.859,-1.438 -1.748,-1.848 z"
830 id="path323"
831 style="fill:url(#radialGradient3320)"
832 inkscape:connector-curvature="0" />
833 <radialGradient
834 id="radialGradient3377"
835 cx="147.44189"
836 cy="301.21091"
837 r="2.5313001"
838 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
839 gradientUnits="userSpaceOnUse">
840 <stop
841 offset="0.0112"
842 style="stop-color:#FAF0BB"
843 id="stop3379" />
844 <stop
845 offset="0.4917"
846 style="stop-color:#FAF0BD"
847 id="stop3381" />
848 <stop
849 offset="0.6648"
850 style="stop-color:#FBF2C5"
851 id="stop3383" />
852 <stop
853 offset="0.7882"
854 style="stop-color:#FCF6D0"
855 id="stop3385" />
856 <stop
857 offset="0.8879"
858 style="stop-color:#FCF8E1"
859 id="stop3387" />
860 <stop
861 offset="0.9723"
862 style="stop-color:#FFFDF7"
863 id="stop3389" />
864 <stop
865 offset="1"
866 style="stop-color:#FFFFFF"
867 id="stop3391" />
868 </radialGradient>
869 <path
870 d="m 173.961,289.2 c 0.657,-0.143 1.12,-0.506 1.265,-1.029 0.133,-0.48 -0.03,-1.015 -0.381,-1.495 -0.335,-0.458 -0.853,-0.886 -1.498,-1.196 -0.645,-0.31 -1.333,-0.461 -1.94,-0.451 -0.643,0.011 -1.223,0.2 -1.576,0.587 -0.385,0.422 -0.428,0.996 -0.152,1.584 0.291,0.622 0.925,1.231 1.811,1.642 0.876,0.408 1.77,0.51 2.471,0.358 z"
871 id="path340"
872 style="fill:url(#radialGradient3322)"
873 inkscape:connector-curvature="0" />
874 </g>
875 <path
876 d="m 32.300561,46.79686 c -0.244913,-0.207495 -0.516006,-0.294969 -0.756275,-0.27971 -0.2276,0.01425 -0.437888,0.12307 -0.584836,0.320395 -0.147371,0.197321 -0.212822,0.456181 -0.201419,0.726735 0.01182,0.283777 0.109788,0.591457 0.300228,0.85845 0.207332,0.290901 0.486027,0.480592 0.771056,0.539586 0.304451,0.06256 0.605105,-0.02543 0.809057,-0.284794 0.206488,-0.26191 0.260961,-0.628075 0.185374,-0.989662 -0.07136,-0.342262 -0.256312,-0.665199 -0.523185,-0.891 z"
877 id="path347"
878 style="fill:#000000"
879 inkscape:connector-curvature="0" />
880 <g
881 id="g349"
882 transform="matrix(0.42226435,0,0,0.50856192,-47.726977,-111.72952)">
883 <path
884 d="m 168.559,264.427 c 4.145,0.407 8.127,1.382 11.858,2.845 l 0.623,-0.856 c -3.919,-1.741 -8.161,-2.906 -12.604,-3.384 l 0.123,1.395 z"
885 id="path351"
886 inkscape:connector-curvature="0"
887 style="fill:#ffffff" />
888 <path
889 d="m 145.971,266.73 1.059,0.888 c 5.193,-2.147 10.87,-3.351 16.738,-3.403 l 0.009,-0.038 0.435,-1.388 c -0.059,0 -0.116,-0.002 -0.175,-0.002 -6.387,-0.024 -12.545,1.39 -18.066,3.943 z"
890 id="path353"
891 inkscape:connector-curvature="0"
892 style="fill:#ffffff" />
893 <path
894 d="m 185.374,269.579 c 0.97,0.527 1.917,1.087 2.84,1.683 l 0.494,-0.416 c -1.011,-0.738 -2.058,-1.431 -3.138,-2.078 l -0.196,0.811 z"
895 id="path355"
896 inkscape:connector-curvature="0"
897 style="fill:#ffffff" />
898 <path
899 d="m 190.66,272.366 -0.224,0.429 c 0.458,0.338 0.91,0.683 1.354,1.038 1.494,1.193 2.916,2.493 4.25,3.889 -1.633,-1.962 -3.44,-3.752 -5.38,-5.356 z"
900 id="path357"
901 inkscape:connector-curvature="0"
902 style="fill:#ffffff" />
903 <path
904 d="m 140.28,269.916 c 0.198,0.281 0.363,0.578 0.496,0.884 0.84,-0.514 1.699,-1.002 2.575,-1.462 l -0.52,-0.994 c -0.871,0.494 -1.721,1.019 -2.551,1.572 z"
905 id="path359"
906 inkscape:connector-curvature="0"
907 style="fill:#ffffff" />
908 <path
909 d="m 133.625,275.426 0.562,0.314 c 0.338,-0.307 0.681,-0.608 1.028,-0.904 -0.192,-0.129 -0.378,-0.272 -0.555,-0.429 -0.35,0.333 -0.696,0.673 -1.035,1.019 z"
910 id="path361"
911 inkscape:connector-curvature="0"
912 style="fill:#ffffff" />
913 <path
914 d="m 130.152,279.456 c 0.139,-0.009 0.279,-0.015 0.419,-0.019 0.538,-0.62 1.091,-1.224 1.66,-1.81 l -0.295,-0.374 c -0.618,0.713 -1.212,1.447 -1.784,2.203 z"
915 id="path363"
916 inkscape:connector-curvature="0"
917 style="fill:#ffffff" />
918 </g>
919 <path
920 d="m 11.717707,25.989048 c -0.05574,-0.15562 -0.125834,-0.306666 -0.209444,-0.44957 -0.01309,0.01012 -0.02618,0.02032 -0.03885,0.03052 -0.04223,0.03408 -0.08403,0.06866 -0.125835,0.10324 -0.05067,0.0417 -0.101339,0.08289 -0.151171,0.125104 -0.05194,0.04324 -0.103455,0.08798 -0.154549,0.132228 -0.04054,0.03459 -0.0815,0.06916 -0.122034,0.104767 -0.06165,0.0534 -0.122457,0.108333 -0.183263,0.16325 -0.03041,0.02747 -0.06122,0.05392 -0.09122,0.08188 -0.09078,0.08288 -0.181151,0.166809 -0.27067,0.251737 -0.09416,0.0895 -0.187063,0.180031 -0.279961,0.272083 -0.02703,0.02695 -0.05447,0.05442 -0.08192,0.08188 -0.07221,0.07272 -0.1439917,0.145958 -0.2153547,0.219699 -0.02281,0.02339 -0.0456,0.04679 -0.068411,0.07019 -0.081499,0.08492 -0.1621494,0.171895 -0.24238,0.258858 -0.041385,0.04477 -0.08276,0.09052 -0.1237229,0.136294 -0.041799,0.04628 -0.08276,0.09308 -0.1241459,0.139347 -0.033364,0.03762 -0.066717,0.07527 -0.1000776,0.113908 0.074741,0.07935 0.1532821,0.152062 0.2343573,0.218175 C 9.5506288,27.855494 9.7347353,27.672921 9.9217999,27.495432 10.4927,26.95178 11.092737,26.44983 11.717689,25.989072 z"
921 id="path365"
922 inkscape:connector-curvature="0"
923 style="fill:#eeeeee" />
924 <path
925 d="m 28.381526,27.537111 c 0.388483,0.0014 0.747409,0.164265 1.026947,0.433802 0.293051,0.282252 0.512205,0.694697 0.575969,1.184949 0.06968,0.534499 -0.05447,1.061878 -0.328523,1.474322 -0.292629,0.439906 -0.744451,0.732838 -1.26806,0.744027 -0.528674,0.01119 -0.990631,-0.26547 -1.292973,-0.70131 -0.286295,-0.411932 -0.417197,-0.947959 -0.345834,-1.495681 0.06503,-0.501949 0.290517,-0.923546 0.592437,-1.209867 0.28545,-0.271063 0.652399,-0.431769 1.040037,-0.430242 z"
926 id="path372"
927 style="fill:#000000"
928 inkscape:connector-curvature="0" />
929 <path
930 d="m 13.466305,55.28374 c 0.178195,0.09256 0.329787,0.214614 0.43662,0.342772 0.111901,0.134768 0.178619,0.281236 0.168063,0.408885 -0.0114,0.139346 -0.111902,0.231394 -0.271518,0.261399 -0.170172,0.03153 -0.401994,-0.0082 -0.64353,-0.129175 -0.244069,-0.12256 -0.433666,-0.295472 -0.53712,-0.467367 -0.09797,-0.162232 -0.114433,-0.316834 -0.03674,-0.425668 0.07093,-0.100193 0.209021,-0.143413 0.37117,-0.13782 0.152859,0.005 0.334856,0.05491 0.513051,0.146974 l 0,0 z m -2.368059,-0.261399 c 0.05025,0.0122 0.09585,0.04017 0.130479,0.0768 0.03588,0.03815 0.06165,0.08797 0.06671,0.140364 0.0055,0.05696 -0.01435,0.10731 -0.05278,0.141381 -0.04097,0.0356 -0.101763,0.05188 -0.169749,0.03611 -0.06883,-0.01525 -0.127102,-0.05848 -0.163417,-0.113404 -0.03463,-0.05139 -0.04772,-0.110861 -0.03463,-0.164774 0.01183,-0.04984 0.04392,-0.08594 0.0853,-0.10578 0.03885,-0.01831 0.08741,-0.02339 0.138081,-0.01071 l 0,0 z m 3.807979,2.368373 c 0.09627,0.02389 0.183263,0.07728 0.248714,0.147481 0.06925,0.07322 0.117813,0.167318 0.127101,0.267506 0.01013,0.109332 -0.02745,0.204948 -0.100915,0.270045 -0.07854,0.06866 -0.194242,0.09866 -0.324299,0.06968 -0.131324,-0.03002 -0.24238,-0.111886 -0.311631,-0.216139 -0.06545,-0.09816 -0.09122,-0.21156 -0.0663,-0.314799 0.02281,-0.09459 0.08446,-0.163757 0.162995,-0.2019 0.07515,-0.03611 0.16806,-0.04576 0.264336,-0.02185 l 0,0 z m -2.357501,-1.035942 c -0.09333,-0.04831 -0.188754,-0.07425 -0.269405,-0.0768 -0.08487,-0.003 -0.157504,0.01983 -0.194242,0.07222 -0.04054,0.05696 -0.03209,0.137821 0.01942,0.222749 0.05405,0.09052 0.153704,0.18054 0.281651,0.245128 0.126679,0.06356 0.247869,0.08391 0.337388,0.06765 0.08362,-0.01576 0.136392,-0.06407 0.142304,-0.137313 0.0055,-0.06713 -0.02956,-0.143414 -0.08783,-0.214102 -0.05658,-0.06714 -0.135969,-0.13121 -0.22929,-0.179526 z"
931 id="path374"
932 inkscape:connector-curvature="0"
933 style="fill:#d9bb7a" />
934 <path
935 d="m 32.89722,32.895826 c 0.143148,-0.434312 0.431555,-0.762333 0.795547,-0.953043 0.380884,-0.199865 0.861841,-0.255808 1.361803,-0.10325 0.544721,0.166808 1.012166,0.547722 1.313242,1.044079 0.320921,0.529412 0.440844,1.170201 0.26096,1.762675 -0.181574,0.59807 -0.618618,0.989661 -1.15236,1.129517 -0.504607,0.132224 -1.073818,0.03356 -1.579691,-0.297003 -0.464491,-0.303099 -0.791747,-0.749617 -0.960229,-1.219019 -0.160039,-0.444994 -0.182419,-0.929651 -0.03927,-1.363962 z"
936 id="path381"
937 style="fill:#000000"
938 inkscape:connector-curvature="0" />
939 <path
940 d="m 35.093418,44.08063 c -0.146948,-0.197323 -0.212399,-0.456178 -0.200998,-0.726732 0.01182,-0.28378 0.109367,-0.591461 0.299807,-0.858457 0.207754,-0.290895 0.486028,-0.480589 0.771477,-0.540093 0.304453,-0.06256 0.604685,0.02594 0.809059,0.285306 0.206487,0.261909 0.26096,0.628075 0.184952,0.989659 -0.07137,0.342262 -0.256313,0.6652 -0.523607,0.891001 -0.244913,0.207492 -0.515586,0.294965 -0.755853,0.27971 -0.227601,-0.01423 -0.437466,-0.123072 -0.584837,-0.320394 z"
941 id="path388"
942 style="fill:#000000"
943 inkscape:connector-curvature="0" />
944 <path
945 d="m 24.819304,51.017414 c -0.147371,-0.197322 -0.212821,-0.456179 -0.201421,-0.727243 0.01183,-0.283269 0.10979,-0.590948 0.30023,-0.858455 0.207333,-0.290896 0.485604,-0.481098 0.771055,-0.540089 0.304453,-0.06256 0.605106,0.02594 0.809059,0.285303 0.206487,0.261908 0.260959,0.628074 0.184952,0.989661 -0.07136,0.342263 -0.256314,0.6652 -0.523608,0.891002 -0.24449,0.207493 -0.515584,0.294964 -0.755854,0.279709 -0.2276,-0.01425 -0.437465,-0.123071 -0.584413,-0.319888 z"
946 id="path395"
947 style="fill:#000000"
948 inkscape:connector-curvature="0" />
949 <path
950 d="m 23.786446,24.445052 c 0.102186,-0.347855 0.322609,-0.616885 0.605104,-0.779624 0.296007,-0.170876 0.673933,-0.232414 1.072129,-0.128666 0.433667,0.112897 0.812438,0.396678 1.061996,0.778609 0.266026,0.406849 0.376235,0.908289 0.24829,1.382269 -0.12879,0.47805 -0.464913,0.802512 -0.882532,0.931685 -0.395661,0.12205 -0.84664,0.06357 -1.254126,-0.17952 -0.374125,-0.222751 -0.642686,-0.563996 -0.787099,-0.928635 -0.137237,-0.346331 -0.166373,-0.728261 -0.06377,-1.076118 z"
951 id="path402"
952 style="fill:#000000"
953 inkscape:connector-curvature="0" />
954 <path
955 d="m 9.3572511,27.571182 c 0.2537814,0.256316 0.5518992,0.424651 0.8555069,0.487204 0.426486,0.08747 0.848329,-0.03611 1.135047,-0.399731 0.28925,-0.367181 0.366103,-0.880828 0.259692,-1.388372 -0.0456,-0.217666 -0.123723,-0.429227 -0.230557,-0.625532 -0.344568,0.281745 -0.680268,0.577726 -1.006255,0.886932 -0.347524,0.330057 -0.6857564,0.676897 -1.0134339,1.039499 z"
956 id="path409"
957 style="fill:#000000"
958 inkscape:connector-curvature="0" />
959 <path
960 d="m 9.3572511,27.571182 c 0.081923,0.08289 0.1684839,0.15664 0.2584255,0.220208 0.1013389,-0.100194 0.2031087,-0.199865 0.3061417,-0.296999 0.5244517,-0.497883 1.0733947,-0.962708 1.6434517,-1.391936 -0.04604,-0.15867 -0.109367,-0.312257 -0.188752,-0.457195 l 0,0 c -0.02997,0.02442 -0.05996,0.04933 -0.08995,0.07425 -0.01942,0.01628 -0.03927,0.03255 -0.05869,0.04883 -0.03336,0.02747 -0.0663,0.05545 -0.09923,0.08341 l -0.04519,0.03865 c -0.03758,0.03205 -0.07474,0.06407 -0.111899,0.09613 l -0.02997,0.02594 c -0.04139,0.03611 -0.08235,0.07221 -0.123301,0.108332 l -0.02026,0.01832 c -0.04392,0.03918 -0.08741,0.07781 -0.130901,0.117485 l -0.01309,0.01169 c -0.04603,0.04223 -0.09206,0.08442 -0.13808,0.12714 l -0.0018,0.0014 c -0.04815,0.04476 -0.09585,0.0895 -0.143569,0.134769 -0.07685,0.07322 -0.15286,0.146467 -0.228867,0.221226 l -0.01098,0.01072 c -0.02026,0.02032 -0.04097,0.04018 -0.06123,0.06051 l -0.01858,0.01882 -0.05236,0.05238 -0.02956,0.03002 -0.04307,0.04376 -0.03801,0.03865 -0.01605,0.01627 -0.01562,0.01627 -0.04771,0.04883 -0.01562,0.01627 C 9.6459492,27.256383 9.50069,27.412511 9.3571211,27.571183 z"
961 id="path411"
962 inkscape:connector-curvature="0"
963 style="fill:#888678" />
964 <path
965 d="m 18.571057,23.295194 c 0.423955,-0.03051 0.815816,0.05645 1.121534,0.226311 0.320077,0.177997 0.559079,0.455163 0.629176,0.800985 0.07601,0.376844 -0.05954,0.764369 -0.359348,1.082221 -0.319232,0.338701 -0.812859,0.585354 -1.385028,0.636719 -0.577235,0.05138 -1.081841,-0.108827 -1.412472,-0.39617 -0.312477,-0.271573 -0.456047,-0.644349 -0.378351,-1.042043 0.07136,-0.364639 0.317965,-0.685034 0.647333,-0.914395 0.312897,-0.217665 0.713204,-0.363114 1.137156,-0.393628 z"
966 id="path418"
967 style="fill:#000000"
968 inkscape:connector-curvature="0" />
969 <path
970 d="m 25.268593,33.539157 c 0.209865,0.121549 0.37835,0.289372 0.487716,0.468895 0.11401,0.188169 0.167216,0.397695 0.123723,0.585864 -0.04687,0.20495 -0.198043,0.347856 -0.412131,0.403289 -0.228021,0.05951 -0.519383,0.01933 -0.804835,-0.139854 -0.288406,-0.160707 -0.494471,-0.399731 -0.589482,-0.643842 -0.08995,-0.230376 -0.07601,-0.455669 0.04941,-0.620952 0.114856,-0.152061 0.304451,-0.226311 0.51305,-0.230379 0.198043,-0.0036 0.422688,0.05543 0.632553,0.176979 z"
971 id="path425"
972 style="fill:#000000"
973 inkscape:connector-curvature="0" />
974 <polygon
975 points="188.385,321.662 183.827,319.426 190.01,322.008 182.526,321.973 "
976 id="polygon427"
977 transform="matrix(0.42226435,0,0,0.50856192,-47.726977,-111.72952)" />
978 <polygon
979 points="181.161,310.218 176.159,311.094 182.677,309.541 176.606,313.919 "
980 id="polygon429"
981 transform="matrix(0.42226435,0,0,0.50856192,-47.726977,-111.72952)" />
982 <polygon
983 points="188.996,281.271 183.955,287.956 191.129,279.553 180.144,285.178 "
984 id="polygon431"
985 transform="matrix(0.42226435,0,0,0.50856192,-47.726977,-111.72952)" />
986 <path
987 d="m 35.589578,54.524966 c -0.122034,0.197832 -0.247447,0.39312 -0.376237,0.586373 -3.139958,4.719964 -7.989242,7.864909 -13.609581,7.987982 C 15.929794,63.222902 10.97199,60.250356 7.7226683,55.572603 7.5229375,55.285266 7.3303849,54.991318 7.1445881,54.693299 c 3.5503959,4.555698 8.6741509,7.392458 14.4832419,7.265826 5.617804,-0.123069 10.532541,-3.002548 13.961748,-7.434159 z"
988 id="path440"
989 style="fill:#d9bb7a"
990 inkscape:connector-curvature="0" />
991 <path
992 d="m 16.345302,52.251694 c -2.117655,-1.929991 -2.971052,-5.408047 -1.900189,-8.495019 1.184029,-3.41245 4.302452,-5.144614 7.182295,-4.121385 -2.791167,-0.695713 -5.69128,1.060859 -6.831394,4.34617 -1.023146,2.94966 -0.321343,6.249209 1.549288,8.270234 z"
993 id="path442"
994 inkscape:connector-curvature="0"
995 style="fill:#ffffff" />
996 <path
997 d="m 7.9004418,49.211004 c 1.5839109,-1.826246 1.8765395,-5.188352 0.611861,-7.774387 -0.9606515,-1.964067 -2.560189,-2.949661 -4.0731622,-2.724366 1.4428771,-0.03307 2.911513,0.974913 3.8219146,2.837267 1.2266751,2.507718 1.0299008,5.725391 -0.3606134,7.661486 z"
998 id="path444"
999 inkscape:connector-curvature="0"
1000 style="fill:#ffffff" />
1001 <path
1002 d="m 46.744961,35.073491 -0.497006,-0.879306 c -0.446333,-0.789288 -2.616772,-1.271403 -3.063106,-2.060692 -0.04897,-0.08645 -0.08995,-0.178504 -0.124145,-0.273607 0.02111,0.05392 0.04434,0.106285 0.07093,0.157655 0.411286,0.799459 2.442378,0.780134 2.853664,1.579592 l 0.759653,1.476358 0,0 z m -3.840919,-4.235306 c -0.02154,-1.142737 0.276584,-2.476187 -0.211554,-3.339725 -0.684068,-1.210379 -3.109133,-1.708769 -3.070285,-3.678937 0.02618,-1.300901 0.05531,-2.044928 -0.877888,-0.830484 -0.474202,0.616888 -0.933204,1.256658 -1.378271,1.918806 0.532898,-0.895579 1.084376,-1.758098 1.656966,-2.58553 0.921382,-1.331414 0.877043,-0.549754 0.825104,0.815225 -0.02492,0.63723 0.05786,1.381764 0.330634,1.912701 0.487293,0.947452 2.164949,1.469236 2.652243,2.416687 0.464492,0.901679 0.07769,2.233605 0.07305,3.371257 z"
1003 id="path446"
1004 inkscape:connector-curvature="0"
1005 style="fill:#ffffff" />
1006 <path
1007 d="m 16.756588,33.897186 c 0.357235,-0.248687 0.77781,-0.246145 1.121111,-0.03865 -0.09501,0.0122 -0.189596,0.04832 -0.27785,0.109346 -0.338655,0.235464 -0.455199,0.757757 -0.25927,1.165625 0.19551,0.408372 0.629174,0.548229 0.96783,0.312255 0.08783,-0.06155 0.160883,-0.14189 0.217467,-0.234955 -0.02237,0.461773 -0.230979,0.901679 -0.588638,1.150367 -0.564566,0.39261 -1.287061,0.15918 -1.613471,-0.520769 -0.325145,-0.680454 -0.131747,-1.550096 0.432821,-1.943214 l 0,0 z m -8.4625961,1.183931 c 0.2575811,-0.179014 0.5603435,-0.177488 0.8077901,-0.02795 -0.068836,0.009 -0.1368128,0.03458 -0.2001525,0.07882 -0.2440687,0.169354 -0.327677,0.545687 -0.1866399,0.839639 0.1406128,0.293947 0.453088,0.394643 0.6971553,0.224782 0.063334,-0.04425 0.1161241,-0.102217 0.1570835,-0.16935 C 9.5527694,36.35966 9.4024339,36.676495 9.1452751,36.855507 8.7386349,37.138248 8.2179844,36.970431 7.983206,36.480169 7.7475821,35.990933 7.887351,35.363875 8.2939919,35.081114 z"
1008 id="path448"
1009 inkscape:connector-curvature="0" />
1010 <path
1011 d="m 11.148494,37.665629 c -0.260113,-0.748095 -0.420152,-1.550096 -0.46449,-2.376002 -0.533741,1.967118 -1.8647168,3.382956 -3.4389171,3.862529 0.4619579,0.354468 0.8876005,0.829465 1.2503252,1.416854 1.1793816,-0.417022 2.1776139,-1.463641 2.6530819,-2.903381 z"
1012 id="path450"
1013 inkscape:connector-curvature="0"
1014 style="fill:#eeeeee" />
1015 <path
1016 d="m 3.5654754,33.263516 c -0.2884063,0.139348 -0.5160068,0.432279 -0.656621,0.92355 -0.6697112,2.341929 -0.5459877,4.035438 0.033358,5.072397 C 3.09465,39.150129 3.25131,39.055528 3.4109259,38.975177 3.537183,38.886186 3.6659737,38.807859 3.7972979,38.739713 3.1153408,37.498312 2.8611376,35.923805 3.2065499,34.3732 3.2935369,33.980083 3.4151486,33.609339 3.5654746,33.263516 z"
1017 id="path457"
1018 style="fill:#f0a513"
1019 inkscape:connector-curvature="0" />
1020 <path
1021 d="m 9.6346789,48.851958 c 0.7959681,1.053234 2.8688621,0.917445 3.5212611,-0.268012 -0.352592,0.781151 -1.04046,1.31209 -1.830517,1.31209 -0.695891,0 -1.312395,-0.411935 -1.6907441,-1.044078 z"
1022 id="path459"
1023 inkscape:connector-curvature="0"
1024 style="fill:#ffffff" />
1025 </g>
1026 </g>
1027 </svg>
0 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
1 <!-- Created with Inkscape (http://www.inkscape.org/) -->
2
3 <svg
4 xmlns:dc="http://purl.org/dc/elements/1.1/"
5 xmlns:cc="http://creativecommons.org/ns#"
6 xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
7 xmlns:svg="http://www.w3.org/2000/svg"
8 xmlns="http://www.w3.org/2000/svg"
9 xmlns:xlink="http://www.w3.org/1999/xlink"
10 xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
11 xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
12 width="22"
13 height="22"
14 id="svg3720"
15 version="1.1"
16 inkscape:version="0.48.3.1 r9886"
17 sodipodi:docname="diodon-panel.svg">
18 <defs
19 id="defs3722">
20 <radialGradient
21 inkscape:collect="always"
22 xlink:href="#SVGID_3_"
23 id="radialGradient3305"
24 gradientUnits="userSpaceOnUse"
25 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
26 cx="163.4902"
27 cy="274.86621"
28 r="2.8801" />
29 <radialGradient
30 gradientUnits="userSpaceOnUse"
31 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
32 r="2.8801"
33 cy="274.86621"
34 cx="163.4902"
35 id="SVGID_3_">
36 <stop
37 id="stop190"
38 style="stop-color:#FAF0BB"
39 offset="0.0112" />
40 <stop
41 id="stop192"
42 style="stop-color:#FAF0BD"
43 offset="0.4917" />
44 <stop
45 id="stop194"
46 style="stop-color:#FBF2C5"
47 offset="0.6648" />
48 <stop
49 id="stop196"
50 style="stop-color:#FCF6D0"
51 offset="0.7882" />
52 <stop
53 id="stop198"
54 style="stop-color:#FCF8E1"
55 offset="0.8879" />
56 <stop
57 id="stop200"
58 style="stop-color:#FFFDF7"
59 offset="0.9723" />
60 <stop
61 id="stop202"
62 style="stop-color:#FFFFFF"
63 offset="1" />
64 </radialGradient>
65 <radialGradient
66 inkscape:collect="always"
67 xlink:href="#SVGID_4_"
68 id="radialGradient3307"
69 gradientUnits="userSpaceOnUse"
70 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
71 cx="155.3242"
72 cy="310.6777"
73 r="4.4867001" />
74 <radialGradient
75 gradientUnits="userSpaceOnUse"
76 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
77 r="4.4867001"
78 cy="310.6777"
79 cx="155.3242"
80 id="SVGID_4_">
81 <stop
82 id="stop207"
83 style="stop-color:#FAF0BB"
84 offset="0.0112" />
85 <stop
86 id="stop209"
87 style="stop-color:#FAF0BD"
88 offset="0.4917" />
89 <stop
90 id="stop211"
91 style="stop-color:#FBF2C5"
92 offset="0.6648" />
93 <stop
94 id="stop213"
95 style="stop-color:#FCF6D0"
96 offset="0.7882" />
97 <stop
98 id="stop215"
99 style="stop-color:#FCF8E1"
100 offset="0.8879" />
101 <stop
102 id="stop217"
103 style="stop-color:#FFFDF7"
104 offset="0.9723" />
105 <stop
106 id="stop219"
107 style="stop-color:#FFFFFF"
108 offset="1" />
109 </radialGradient>
110 <radialGradient
111 inkscape:collect="always"
112 xlink:href="#SVGID_5_"
113 id="radialGradient3310"
114 gradientUnits="userSpaceOnUse"
115 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
116 cx="170.3125"
117 cy="302.00781"
118 r="5.0811" />
119 <radialGradient
120 gradientUnits="userSpaceOnUse"
121 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
122 r="5.0811"
123 cy="302.00781"
124 cx="170.3125"
125 id="SVGID_5_">
126 <stop
127 id="stop224"
128 style="stop-color:#FAF0BB"
129 offset="0.0112" />
130 <stop
131 id="stop226"
132 style="stop-color:#FAF0BD"
133 offset="0.4917" />
134 <stop
135 id="stop228"
136 style="stop-color:#FBF2C5"
137 offset="0.6648" />
138 <stop
139 id="stop230"
140 style="stop-color:#FCF6D0"
141 offset="0.7882" />
142 <stop
143 id="stop232"
144 style="stop-color:#FCF8E1"
145 offset="0.8879" />
146 <stop
147 id="stop234"
148 style="stop-color:#FFFDF7"
149 offset="0.9723" />
150 <stop
151 id="stop236"
152 style="stop-color:#FFFFFF"
153 offset="1" />
154 </radialGradient>
155 <radialGradient
156 inkscape:collect="always"
157 xlink:href="#SVGID_6_"
158 id="radialGradient3312"
159 gradientUnits="userSpaceOnUse"
160 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
161 cx="173.2812"
162 cy="283.68359"
163 r="2.8803999" />
164 <radialGradient
165 gradientUnits="userSpaceOnUse"
166 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
167 r="2.8803999"
168 cy="283.68359"
169 cx="173.2812"
170 id="SVGID_6_">
171 <stop
172 id="stop241"
173 style="stop-color:#FAF0BB"
174 offset="0.0112" />
175 <stop
176 id="stop243"
177 style="stop-color:#FAF0BD"
178 offset="0.4917" />
179 <stop
180 id="stop245"
181 style="stop-color:#FBF2C5"
182 offset="0.6648" />
183 <stop
184 id="stop247"
185 style="stop-color:#FCF6D0"
186 offset="0.7882" />
187 <stop
188 id="stop249"
189 style="stop-color:#FCF8E1"
190 offset="0.8879" />
191 <stop
192 id="stop251"
193 style="stop-color:#FFFDF7"
194 offset="0.9723" />
195 <stop
196 id="stop253"
197 style="stop-color:#FFFFFF"
198 offset="1" />
199 </radialGradient>
200 <radialGradient
201 inkscape:collect="always"
202 xlink:href="#SVGID_7_"
203 id="radialGradient3314"
204 gradientUnits="userSpaceOnUse"
205 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
206 cx="148.9492"
207 cy="270.04489"
208 r="2.8799" />
209 <radialGradient
210 gradientUnits="userSpaceOnUse"
211 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
212 r="2.8799"
213 cy="270.04489"
214 cx="148.9492"
215 id="SVGID_7_">
216 <stop
217 id="stop258"
218 style="stop-color:#FAF0BB"
219 offset="0.0112" />
220 <stop
221 id="stop260"
222 style="stop-color:#FAF0BD"
223 offset="0.4917" />
224 <stop
225 id="stop262"
226 style="stop-color:#FBF2C5"
227 offset="0.6648" />
228 <stop
229 id="stop264"
230 style="stop-color:#FCF6D0"
231 offset="0.7882" />
232 <stop
233 id="stop266"
234 style="stop-color:#FCF8E1"
235 offset="0.8879" />
236 <stop
237 id="stop268"
238 style="stop-color:#FFFDF7"
239 offset="0.9723" />
240 <stop
241 id="stop270"
242 style="stop-color:#FFFFFF"
243 offset="1" />
244 </radialGradient>
245 <radialGradient
246 inkscape:collect="always"
247 xlink:href="#SVGID_8_"
248 id="radialGradient3316"
249 gradientUnits="userSpaceOnUse"
250 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
251 cx="148.0723"
252 cy="319.09381"
253 r="3.9265001" />
254 <radialGradient
255 gradientUnits="userSpaceOnUse"
256 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
257 r="3.9265001"
258 cy="319.09381"
259 cx="148.0723"
260 id="SVGID_8_">
261 <stop
262 id="stop275"
263 style="stop-color:#FAF0BB"
264 offset="0.0112" />
265 <stop
266 id="stop277"
267 style="stop-color:#FAF0BD"
268 offset="0.4917" />
269 <stop
270 id="stop279"
271 style="stop-color:#FBF2C5"
272 offset="0.6648" />
273 <stop
274 id="stop281"
275 style="stop-color:#FCF6D0"
276 offset="0.7882" />
277 <stop
278 id="stop283"
279 style="stop-color:#FCF8E1"
280 offset="0.8879" />
281 <stop
282 id="stop285"
283 style="stop-color:#FFFDF7"
284 offset="0.9723" />
285 <stop
286 id="stop287"
287 style="stop-color:#FFFFFF"
288 offset="1" />
289 </radialGradient>
290 <radialGradient
291 inkscape:collect="always"
292 xlink:href="#SVGID_9_"
293 id="radialGradient3318"
294 gradientUnits="userSpaceOnUse"
295 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
296 cx="112.9551"
297 cy="315.56049"
298 r="3.0683999" />
299 <radialGradient
300 gradientUnits="userSpaceOnUse"
301 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
302 r="3.0683999"
303 cy="315.56049"
304 cx="112.9551"
305 id="SVGID_9_">
306 <stop
307 id="stop292"
308 style="stop-color:#FAF0BB"
309 offset="0.0112" />
310 <stop
311 id="stop294"
312 style="stop-color:#FAF0BD"
313 offset="0.4917" />
314 <stop
315 id="stop296"
316 style="stop-color:#FBF2C5"
317 offset="0.6648" />
318 <stop
319 id="stop298"
320 style="stop-color:#FCF6D0"
321 offset="0.7882" />
322 <stop
323 id="stop300"
324 style="stop-color:#FCF8E1"
325 offset="0.8879" />
326 <stop
327 id="stop302"
328 style="stop-color:#FFFDF7"
329 offset="0.9723" />
330 <stop
331 id="stop304"
332 style="stop-color:#FFFFFF"
333 offset="1" />
334 </radialGradient>
335 <radialGradient
336 inkscape:collect="always"
337 xlink:href="#SVGID_10_"
338 id="radialGradient3320"
339 gradientUnits="userSpaceOnUse"
340 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
341 cx="132.0938"
342 cy="320.1113"
343 r="4.1712999" />
344 <radialGradient
345 gradientUnits="userSpaceOnUse"
346 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
347 r="4.1712999"
348 cy="320.1113"
349 cx="132.0938"
350 id="SVGID_10_">
351 <stop
352 id="stop309"
353 style="stop-color:#FAF0BB"
354 offset="0.0112" />
355 <stop
356 id="stop311"
357 style="stop-color:#FAF0BD"
358 offset="0.4917" />
359 <stop
360 id="stop313"
361 style="stop-color:#FBF2C5"
362 offset="0.6648" />
363 <stop
364 id="stop315"
365 style="stop-color:#FCF6D0"
366 offset="0.7882" />
367 <stop
368 id="stop317"
369 style="stop-color:#FCF8E1"
370 offset="0.8879" />
371 <stop
372 id="stop319"
373 style="stop-color:#FFFDF7"
374 offset="0.9723" />
375 <stop
376 id="stop321"
377 style="stop-color:#FFFFFF"
378 offset="1" />
379 </radialGradient>
380 <radialGradient
381 inkscape:collect="always"
382 xlink:href="#SVGID_11_"
383 id="radialGradient3322"
384 gradientUnits="userSpaceOnUse"
385 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
386 cx="147.44189"
387 cy="301.21091"
388 r="2.5313001" />
389 <radialGradient
390 gradientUnits="userSpaceOnUse"
391 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
392 r="2.5313001"
393 cy="301.21091"
394 cx="147.44189"
395 id="SVGID_11_">
396 <stop
397 id="stop326"
398 style="stop-color:#FAF0BB"
399 offset="0.0112" />
400 <stop
401 id="stop328"
402 style="stop-color:#FAF0BD"
403 offset="0.4917" />
404 <stop
405 id="stop330"
406 style="stop-color:#FBF2C5"
407 offset="0.6648" />
408 <stop
409 id="stop332"
410 style="stop-color:#FCF6D0"
411 offset="0.7882" />
412 <stop
413 id="stop334"
414 style="stop-color:#FCF8E1"
415 offset="0.8879" />
416 <stop
417 id="stop336"
418 style="stop-color:#FFFDF7"
419 offset="0.9723" />
420 <stop
421 id="stop338"
422 style="stop-color:#FFFFFF"
423 offset="1" />
424 </radialGradient>
425 </defs>
426 <sodipodi:namedview
427 id="base"
428 pagecolor="#ffffff"
429 bordercolor="#666666"
430 borderopacity="1.0"
431 inkscape:pageopacity="0.0"
432 inkscape:pageshadow="2"
433 inkscape:zoom="22.395604"
434 inkscape:cx="1.9698115"
435 inkscape:cy="13.030678"
436 inkscape:current-layer="layer1"
437 showgrid="true"
438 inkscape:grid-bbox="true"
439 inkscape:document-units="px"
440 showborder="true"
441 borderlayer="false"
442 inkscape:window-width="1600"
443 inkscape:window-height="876"
444 inkscape:window-x="0"
445 inkscape:window-y="24"
446 inkscape:window-maximized="1"
447 gridtolerance="10"
448 objecttolerance="10"
449 guidetolerance="10">
450 <inkscape:grid
451 type="xygrid"
452 id="grid4738"
453 empspacing="5"
454 visible="true"
455 enabled="true"
456 snapvisiblegridlinesonly="true" />
457 </sodipodi:namedview>
458 <metadata
459 id="metadata3725">
460 <rdf:RDF>
461 <cc:Work
462 rdf:about="">
463 <dc:format>image/svg+xml</dc:format>
464 <dc:type
465 rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
466 <dc:title />
467 </cc:Work>
468 </rdf:RDF>
469 </metadata>
470 <g
471 id="layer1"
472 inkscape:label="Layer 1"
473 inkscape:groupmode="layer"
474 transform="translate(0,-10)">
475 <g
476 id="g3183"
477 transform="matrix(0.42456013,0,0,0.36190187,0.67263132,6.4999834)">
478 <path
479 d="m 47.748262,36.240641 c -0.304876,-0.669777 -0.939962,-2.526029 -1.264261,-3.180039 -0.499962,-1.005938 -2.409862,-0.340737 -2.850285,-1.402107 -0.615238,-1.481949 0.402841,-3.075783 -0.26687,-4.517046 -0.51052,-1.098494 -2.320767,-1.749962 -2.830861,-2.848458 -0.374128,-0.804542 0.05785,-5.080024 -0.915894,-3.703855 -1.643875,2.32362 -3.133623,4.929999 -4.51865,7.769812 -0.227178,-0.299544 -0.460268,-0.590441 -0.699692,-0.872694 l 1.273972,-2.395837 -1.94875,1.641638 C 33.517528,26.509306 33.303862,26.293167 33.085974,26.08364 l 0.936581,-2.162914 -1.564066,1.585187 C 31.923058,25.034986 31.365246,24.598131 30.785899,24.1984 l 1.168829,-5.78896 -2.873088,4.753021 C 28.796189,23.01091 28.507361,22.866987 28.213887,22.732727 l 0.283762,-3.540102 -1.360114,3.093074 C 25.924369,21.832064 24.65631,21.526925 23.350669,21.385545 l -0.349636,-4.806419 -1.226255,4.716403 c -0.0033,0 -0.0071,0 -0.01056,0 -1.422186,-0.0066 -2.818193,0.185117 -4.164371,0.553823 l -1.190787,-2.856081 0.196351,3.163762 c -0.403261,0.139347 -0.801035,0.294459 -1.193319,0.465334 l -0.676466,-1.193086 0.243647,1.388883 c -0.482226,0.226309 -0.954317,0.47703 -1.416273,0.750127 l -2.649288,-2.676561 1.488058,3.425166 c -0.733893,0.515174 -1.434852,1.088322 -2.09654,1.715887 -0.09374,0.089 -0.187063,0.180031 -0.279538,0.271064 l -2.6176137,-1.775898 1.7557735,2.685206 c -0.2643372,0.297002 -0.5214955,0.60519 -0.7718972,0.922533 l -2.0728961,-1.396004 1.4580788,2.215805 c -0.340767,0.479065 -0.6650662,0.978474 -0.9716305,1.49568 -1.2705932,0.251233 -2.4081735,1.157486 -3.0905527,2.497041 0.00253,-0.005 0.00508,-0.01071 0.00802,-0.01578 -0.5079841,0.01071 -0.9074462,0.311242 -1.1177337,1.046115 -0.7347402,2.568744 -0.5366981,4.375156 0.1689057,5.408554 -0.1199231,0.09664 -0.2373126,0.202409 -0.3517463,0.317854 -1.90145688,1.925922 -2.20548742,5.78845 -0.6790012,8.625208 0.8470624,1.574001 2.0796522,2.501617 3.3341996,2.686733 0.6452198,1.719448 1.4880601,3.337183 2.5116286,4.809977 3.3333522,4.799809 8.4203702,7.849148 14.2412852,7.722516 5.766442,-0.126125 10.741561,-3.352949 13.962593,-8.195477 2.268826,-3.410417 3.604027,-7.536378 3.803758,-11.87187 L 41.77997,42.904823 39.623044,42.4461 c 0.003,-0.734364 -0.02618,-1.473813 -0.08952,-2.215806 l 3.332089,-2.112565 -3.537731,0.400746 C 39.264542,38.110618 39.19107,37.708348 39.108306,37.31116 l 0.959807,-0.628583 -1.067483,0.13782 c -0.02618,-0.113909 -0.05278,-0.226818 -0.08023,-0.33972 2.756541,-0.434818 5.473393,-0.393116 8.225288,0.328024 0.699694,0.183591 0.893512,0.07272 0.602574,-0.568064 z M 3.2551113,34.170284 c -0.017313,0.06662 -0.033782,0.134262 -0.04856,0.202916 -0.0114,0.05139 -0.022381,0.102733 -0.032514,0.154602 0.010132,-0.05188 0.020692,-0.10325 0.032514,-0.154602 0.01478,-0.06866 0.031247,-0.136294 0.04856,-0.202916 z m 0.4049515,-1.11121 c -0.010132,0.02085 -0.020269,0.04223 -0.030404,0.06306 0.010132,-0.02085 0.02027,-0.04222 0.030404,-0.06306 z m -0.079808,0.172404 c -0.010557,0.02339 -0.020692,0.0473 -0.030825,0.07119 0.010132,-0.02389 0.02027,-0.04782 0.030825,-0.07119 z m -0.075164,0.177488 c -0.010557,0.02644 -0.021113,0.0529 -0.031248,0.07984 0.010132,-0.02694 0.020692,-0.0534 0.031248,-0.07984 z m -0.070097,0.182573 c -0.010979,0.03002 -0.021535,0.06 -0.032092,0.09001 0.010557,-0.03002 0.021113,-0.06002 0.032092,-0.09001 z m -0.06545,0.187661 c -0.01098,0.03407 -0.021535,0.06866 -0.032515,0.103238 0.010979,-0.03458 0.021113,-0.06866 0.032515,-0.103238 z m -0.059962,0.193252 c -0.011823,0.04119 -0.023225,0.08289 -0.034626,0.124599 0.0114,-0.04172 0.022381,-0.08342 0.034626,-0.124599 z m -0.2558905,1.703683 c -8.452e-4,0.05034 -8.452e-4,0.100695 -4.223e-4,0.150535 -4.223e-4,-0.05034 -4.223e-4,-0.100705 4.223e-4,-0.150535 z m 0.1106333,-1.097477 c -0.00633,0.03458 -0.012668,0.06866 -0.018578,0.103239 0.00591,-0.03407 0.012245,-0.06866 0.018578,-0.103239 z m -0.028713,0.164775 c -0.00507,0.03153 -0.010132,0.06256 -0.01478,0.09357 0.00464,-0.03101 0.00971,-0.06204 0.01478,-0.09357 z m -0.023646,0.15867 c -0.00423,0.03053 -0.00802,0.06053 -0.011823,0.09052 0.00379,-0.03052 0.0076,-0.06054 0.011823,-0.09052 z m -0.019423,0.156131 c -0.00338,0.03002 -0.00633,0.05949 -0.00929,0.0895 0.00296,-0.03002 0.00591,-0.05951 0.00929,-0.0895 z m -0.015624,0.155617 c -0.00253,0.03002 -0.00464,0.06001 -0.00717,0.09001 0.00253,-0.03002 0.00508,-0.06001 0.00717,-0.09001 z m -0.0114,0.154604 c -0.0017,0.03154 -0.00338,0.06256 -0.00507,0.09408 0.0017,-0.03153 0.00338,-0.06256 0.00507,-0.09408 z m -0.0076,0.154095 c -0.00127,0.03662 -0.00211,0.07322 -0.00296,0.109332 4.221e-4,-0.03662 0.00127,-0.07272 0.00296,-0.109332 z m 0.1634162,1.705207 c -0.0076,-0.03203 -0.01478,-0.06407 -0.021535,-0.09611 0.00718,0.03205 0.013934,0.06407 0.021535,0.09611 z m -0.037161,-0.168331 c -0.00802,-0.03865 -0.015624,-0.07728 -0.023225,-0.115944 0.0076,0.03865 0.015624,0.07729 0.023225,0.115944 z m -0.033785,-0.176983 c -0.00507,-0.02847 -0.010132,-0.05696 -0.01478,-0.08543 0.00464,0.02795 0.010132,0.05696 0.01478,0.08543 z m -0.024491,-0.152059 c -0.00423,-0.02694 -0.00844,-0.05392 -0.012245,-0.08138 0.00379,0.02694 0.0076,0.05442 0.012245,0.08138 z m -0.021113,-0.150025 c -0.00338,-0.02694 -0.00675,-0.0534 -0.00971,-0.08086 0.00296,0.02747 0.00633,0.05442 0.00971,0.08086 z m -0.017313,-0.149518 c -0.00296,-0.02694 -0.00549,-0.05392 -0.00802,-0.08137 0.00253,0.02747 0.00508,0.05441 0.00802,0.08137 z m -0.013934,-0.150024 c -0.00211,-0.02795 -0.00423,-0.05546 -0.00591,-0.08341 0.0017,0.02747 0.00379,0.05544 0.00591,0.08341 z m -0.010132,-0.150536 c -0.0017,-0.0295 -0.00296,-0.059 -0.00423,-0.0885 0.00127,0.0295 0.00253,0.05898 0.00423,0.0885 z m -0.00675,-0.15206 c -0.00127,-0.03356 -0.0017,-0.06765 -0.00211,-0.101717 0,0.03407 8.451e-4,0.06814 0.00211,0.101717 z m 0.180307,1.313616 c 0.00633,0.02644 0.012668,0.0529 0.019424,0.07882 -0.00633,-0.02644 -0.012668,-0.05239 -0.019424,-0.07882 z m 0.1811488,1.679273 c -0.00211,9.74e-4 -0.00423,0.0021 -0.00633,0.003 0,0 0,0 4.224e-4,0 0.015624,-0.01072 0.031247,-0.02137 0.046871,-0.03205 -0.013511,0.0097 -0.027025,0.01933 -0.04096,0.02896 z M 3.2745435,37.437285 c 0.00675,0.02492 0.013511,0.04984 0.020692,0.07476 -0.00717,-0.02492 -0.013934,-0.04984 -0.020692,-0.07476 z m 0.040537,0.141888 c 0.00717,0.0244 0.014357,0.04883 0.021957,0.07272 -0.00717,-0.0244 -0.014779,-0.04832 -0.021957,-0.07272 z m 0.043072,0.139347 c 0.00802,0.02389 0.015624,0.04782 0.023646,0.0717 -0.0076,-0.02389 -0.015624,-0.04728 -0.023646,-0.0717 z m 0.046449,0.137819 c 0.00844,0.02389 0.016891,0.04782 0.025758,0.07171 -0.00844,-0.02389 -0.017313,-0.0473 -0.025758,-0.07171 z m 0.049405,0.135789 c 0.00929,0.0244 0.019001,0.04883 0.028292,0.07322 -0.00929,-0.02441 -0.019001,-0.04831 -0.028292,-0.07322 z m 0.052361,0.134256 c 0.010979,0.02747 0.022803,0.05442 0.034203,0.08188 -0.0114,-0.02747 -0.023225,-0.05442 -0.034203,-0.08188 z m 0.055317,0.13223 c 0.018158,0.04223 0.037159,0.08491 0.056584,0.12663 -0.019001,-0.04223 -0.038005,-0.0844 -0.056584,-0.12663 z m 0.081498,0.178505 c 0.012245,0.02543 0.024491,0.05086 0.036737,0.07627 -0.012668,-0.02543 -0.024491,-0.05086 -0.036737,-0.07627 z m 0.065028,0.132734 c 0.011824,0.02339 0.023646,0.04678 0.035893,0.07019 -0.012246,-0.02339 -0.024069,-0.04678 -0.035893,-0.07019 z m 0.066295,0.12714 c 0.00802,0.01423 0.015624,0.029 0.023646,0.04272 -0.012668,0.0066 -0.025336,0.01272 -0.037582,0.01933 0.012246,-0.0066 0.02449,-0.01373 0.036737,-0.01983 -0.00802,-0.01373 -0.015202,-0.02797 -0.022803,-0.04223 z"
480 id="path5"
481 inkscape:connector-curvature="0" />
482 <path
483 d="m 46.872485,35.321668 c -0.295587,-0.574676 -0.59117,-1.149351 -0.887179,-1.724024 -0.411284,-0.79946 -2.442377,-0.780135 -2.853662,-1.579594 -0.640154,-1.243435 0.339923,-3.306671 -0.300232,-4.550104 -0.487293,-0.94745 -2.164949,-1.469746 -2.652242,-2.417196 -0.272784,-0.53043 -0.355546,-1.274964 -0.330633,-1.912193 0.05237,-1.364979 0.09627,-2.14664 -0.825104,-0.815224 -1.463147,2.115108 -2.790324,4.459071 -4.019957,7.001881 0.08403,0.130191 0.166794,0.262928 0.248715,0.39617 1.867674,-0.780645 3.579534,-1.925924 5.084062,-3.359053 -1.390517,1.582138 -3.033126,2.860154 -4.860686,3.733354 0.119078,0.203934 0.236469,0.410917 0.350057,0.620953 -0.87662,-1.47788 -1.904834,-2.797597 -3.043681,-3.931183 l -0.220844,0.510597 1.016812,-2.721313 -1.72115,1.539922 0.100502,-0.101717 c -0.426911,-0.375317 -0.869023,-0.727243 -1.324646,-1.05679 l -0.259691,1.287172 0.928137,-6.116986 -3.276349,4.782515 0.695047,-1.149347 C 27.064907,22.874104 25.27366,22.28112 23.39754,22.038534 l 0.05785,0.790309 -0.581035,-4.788622 -1.425989,4.509928 0.165107,-0.635193 c -0.02449,0 -0.04899,-9.74e-4 -0.07348,-9.74e-4 -2.69658,-0.0122 -5.297306,0.706904 -7.628628,2.005263 l 0.994011,1.003896 -3.222299,-2.891682 1.639229,4.403639 -0.736427,-1.695038 c -0.777812,0.531955 -1.518886,1.130533 -2.214777,1.791154 -0.5865257,0.556877 -1.1460249,1.161557 -1.6734311,1.809973 l 0.3800423,0.25581 -2.2287093,-1.303955 1.2275217,2.117143 -0.091631,-0.139345 c -0.260959,0.36159 -0.5122061,0.73538 -0.7533194,1.120363 0,0 4.226e-4,0 4.226e-4,0 0.058698,-0.0046 0.1178119,-0.0076 0.1769282,-0.0097 0.4197311,-0.01322 0.848329,0.04476 1.274816,0.182576 0.9543158,0.307679 1.753238,0.965757 2.327517,1.82777 1.042571,-3.636727 4.259803,-5.735561 7.393005,-4.724541 3.275504,1.057303 5.220032,5.114101 4.342567,9.059015 -0.238157,1.070014 -0.659578,2.022044 -1.212743,2.819977 0.07093,0.03205 0.14188,0.06509 0.212399,0.100705 0.08361,0.04223 0.165949,0.08645 0.247024,0.132733 -2.976541,-1.313107 -6.314119,0.418546 -7.548398,3.975938 -1.2347,3.558409 0.08783,7.634533 2.955006,9.262947 -0.08446,-0.03713 -0.168483,-0.07627 -0.252515,-0.118496 -3.038191,-1.529246 -4.4722,-5.736577 -3.202452,-9.39619 0.218733,-0.629601 0.502918,-1.20224 0.839884,-1.711309 -1.472858,-0.618921 -2.639575,-1.861338 -3.348979,-3.411436 -0.588214,1.277509 -1.5788438,2.193938 -2.71769,2.574851 0.033789,0.06461 0.067143,0.129174 0.099654,0.195797 1.344911,2.750302 0.9285586,6.379401 -0.9298248,8.103932 -0.051515,0.04782 -0.1038771,0.09407 -0.1566596,0.137821 h 0 c 0.026184,-0.02694 0.05236,-0.05442 0.078121,-0.08188 8.773e-4,-0.0014 0.00167,-0.0026 0.00296,-0.0036 0.024916,-0.02694 0.049402,-0.05442 0.073895,-0.08239 0.00128,-0.0021 0.00296,-0.0036 0.00462,-0.005 0.024071,-0.02795 0.047713,-0.05545 0.070937,-0.08341 0.00167,-0.0026 0.00384,-0.0046 0.0055,-0.0071 0.023227,-0.02796 0.045607,-0.05543 0.067989,-0.08391 0.00216,-0.003 0.00423,-0.0061 0.00675,-0.0086 0.021955,-0.02847 0.043919,-0.05646 0.065029,-0.08542 0.00251,-0.003 0.00512,-0.0066 0.0072,-0.0097 0.021109,-0.02847 0.042228,-0.05696 0.062493,-0.08645 0.00251,-0.0036 0.00512,-0.0072 0.00755,-0.01071 0.020265,-0.0295 0.040538,-0.05799 0.060379,-0.08797 0.00251,-0.004 0.00512,-0.0076 0.008,-0.01121 0.01942,-0.0295 0.038848,-0.05898 0.058277,-0.08899 0.00251,-0.0046 0.00549,-0.0086 0.008,-0.0122 0.018997,-0.03002 0.037589,-0.06 0.055741,-0.09052 0.00251,-0.0046 0.00549,-0.0086 0.008,-0.01272 0.018152,-0.03052 0.036322,-0.06103 0.054051,-0.09204 0.00251,-0.0046 0.00512,-0.009 0.008,-0.01322 0.017729,-0.03153 0.035054,-0.06204 0.052361,-0.09357 0.00251,-0.005 0.00513,-0.0097 0.00755,-0.01373 0.017306,-0.03153 0.033789,-0.06306 0.050253,-0.09508 0.00251,-0.005 0.00513,-0.0097 0.00755,-0.01423 0.016464,-0.03153 0.032521,-0.06407 0.048559,-0.09613 0.00213,-0.005 0.00455,-0.0097 0.00716,-0.01425 0.015622,-0.03253 0.031254,-0.06509 0.046458,-0.09816 0.00213,-0.0046 0.00426,-0.0097 0.00677,-0.01373 0.015206,-0.03304 0.030402,-0.06713 0.045191,-0.100694 0.00213,-0.004 0.00387,-0.009 0.0059,-0.01272 0.01478,-0.03409 0.029559,-0.06865 0.043913,-0.102733 0.00175,-0.0046 0.00329,-0.0086 0.00513,-0.0122 0.014354,-0.03508 0.028291,-0.07019 0.042229,-0.105275 0.00126,-0.004 0.003,-0.0082 0.00426,-0.0112 0.013937,-0.0356 0.027449,-0.07222 0.040961,-0.108333 8.768e-4,-0.003 0.00213,-0.0061 0.00329,-0.0097 0.013511,-0.03662 0.026607,-0.07425 0.039693,-0.111368 8.769e-4,-0.0026 0.00175,-0.005 0.00251,-0.0076 0.013085,-0.03815 0.026181,-0.07627 0.038425,-0.115439 0,-9.73e-4 4.229e-4,-0.0021 8.769e-4,-0.0026 0.1570825,-0.485678 0.2630703,-1.002882 0.3166975,-1.535857 4.228e-4,-0.004 8.777e-4,-0.0082 0.00124,-0.01118 0.00383,-0.03762 0.00713,-0.07528 0.010132,-0.113404 4.219e-4,-0.0082 0.00124,-0.01576 0.00217,-0.02389 0.003,-0.03458 0.00548,-0.06968 0.00755,-0.104238 8.767e-4,-0.01071 0.00176,-0.02238 0.00248,-0.03305 0.00217,-0.03253 0.00383,-0.06561 0.00548,-0.09816 4.218e-4,-0.01322 0.00124,-0.02644 0.00217,-0.03917 0.00176,-0.03153 0.00248,-0.06306 0.00383,-0.09459 4.229e-4,-0.01474 8.778e-4,-0.03002 0.00176,-0.04425 8.777e-4,-0.03052 0.00124,-0.06053 0.00217,-0.09052 4.228e-4,-0.01627 8.777e-4,-0.03253 8.777e-4,-0.04883 4.229e-4,-0.0295 4.229e-4,-0.05799 4.229e-4,-0.08747 0,-0.01728 0,-0.03459 0,-0.05239 0,-0.02847 -4.229e-4,-0.05644 -8.778e-4,-0.08492 0,-0.01831 -4.228e-4,-0.03611 -4.228e-4,-0.05441 -4.208e-4,-0.02796 -0.00124,-0.05544 -0.00217,-0.08339 -4.229e-4,-0.0188 -8.767e-4,-0.03763 -0.00176,-0.05645 -8.767e-4,-0.02694 -0.00217,-0.0534 -0.00331,-0.08086 -8.768e-4,-0.01984 -0.00176,-0.03918 -0.003,-0.05899 -0.00124,-0.02694 -0.003,-0.0529 -0.00455,-0.07935 -0.00124,-0.02032 -0.00248,-0.04068 -0.00383,-0.06053 -0.00176,-0.02644 -0.00383,-0.05238 -0.00589,-0.07832 -0.00176,-0.02085 -0.00331,-0.04119 -0.00517,-0.06204 -0.00217,-0.02594 -0.00455,-0.05138 -0.00713,-0.0768 -0.00176,-0.02136 -0.00424,-0.04222 -0.00631,-0.06307 -0.00248,-0.02543 -0.00548,-0.05086 -0.00842,-0.07577 -0.00251,-0.02185 -0.00513,-0.04323 -0.00755,-0.06461 -0.003,-0.02492 -0.0059,-0.04985 -0.00929,-0.07425 -0.003,-0.02185 -0.0059,-0.04375 -0.0089,-0.06561 -0.00329,-0.02492 -0.00677,-0.04934 -0.01056,-0.07425 -0.00329,-0.02185 -0.00677,-0.04425 -0.010132,-0.06612 -0.00387,-0.02439 -0.00755,-0.04883 -0.011401,-0.07322 -0.00387,-0.02237 -0.00755,-0.04476 -0.011401,-0.06661 -0.00426,-0.02441 -0.00842,-0.04831 -0.01267,-0.07221 -0.00426,-0.02288 -0.00842,-0.04526 -0.01267,-0.06765 -0.00455,-0.02389 -0.0089,-0.04782 -0.013937,-0.07119 -0.00455,-0.02288 -0.00929,-0.04526 -0.013938,-0.06815 -0.00513,-0.0234 -0.00971,-0.04729 -0.015206,-0.07069 -0.00513,-0.02288 -0.010132,-0.04576 -0.015206,-0.06866 -0.00513,-0.02288 -0.010549,-0.04629 -0.016047,-0.06915 -0.00552,-0.02339 -0.010976,-0.04629 -0.01688,-0.06915 -0.00552,-0.02288 -0.010975,-0.04576 -0.01688,-0.06814 -0.0059,-0.02339 -0.011827,-0.04678 -0.018148,-0.06968 -0.0059,-0.02288 -0.011818,-0.04527 -0.018148,-0.06765 -0.0063,-0.0234 -0.01267,-0.04628 -0.019416,-0.06968 -0.0063,-0.02238 -0.01267,-0.04425 -0.018999,-0.06661 -0.00677,-0.0234 -0.013937,-0.04678 -0.021109,-0.07019 -0.00677,-0.02185 -0.013086,-0.04374 -0.019842,-0.0656 -0.00755,-0.02389 -0.015206,-0.0473 -0.022804,-0.0707 -0.00677,-0.02136 -0.013937,-0.0427 -0.020683,-0.0646 -0.00803,-0.02339 -0.016038,-0.04679 -0.024071,-0.07069 -0.00755,-0.02085 -0.014354,-0.04222 -0.021952,-0.06306 -0.00842,-0.0244 -0.017306,-0.04831 -0.026181,-0.07221 -0.00755,-0.02031 -0.01478,-0.04069 -0.022378,-0.06103 -0.0089,-0.02441 -0.018574,-0.04883 -0.027875,-0.07272 -0.00755,-0.02032 -0.015206,-0.04018 -0.022804,-0.05949 -0.00971,-0.02492 -0.019842,-0.04933 -0.029985,-0.07425 -0.00803,-0.01865 -0.015622,-0.03799 -0.023645,-0.05732 -0.010975,-0.02594 -0.021952,-0.05188 -0.033363,-0.0768 -0.00755,-0.0178 -0.015206,-0.0351 -0.022804,-0.0529 -0.01267,-0.0295 -0.026182,-0.05799 -0.039267,-0.08696 -0.00677,-0.0137 -0.01267,-0.02845 -0.019416,-0.04219 C 8.552808,41.518875 8.532531,41.476167 8.511847,41.433436 7.1669757,38.683133 4.5692051,37.851124 2.7108196,39.57515 0.85243366,41.299176 0.436081,44.928276 1.7809934,47.678578 c 0.023225,0.04782 0.046871,0.0951 0.07094,0.140872 0.0076,0.01474 0.015624,0.0295 0.023225,0.04425 0.01689,0.03153 0.033358,0.06307 0.05025,0.09459 0.00887,0.01626 0.018158,0.03307 0.027448,0.04985 0.016468,0.0295 0.032514,0.05799 0.048982,0.08645 0.00929,0.01627 0.018578,0.03253 0.028291,0.04883 0.017735,0.03002 0.035048,0.0595 0.053205,0.0885 0.00844,0.01373 0.01689,0.02795 0.025336,0.04172 0.024491,0.03917 0.048983,0.07729 0.073473,0.115944 0.00211,0.0036 0.00423,0.0072 0.00633,0.01012 0.027025,0.0417 0.054894,0.0824 0.082765,0.123071 0.00802,0.01121 0.015624,0.02237 0.023646,0.03305 0.020269,0.02896 0.040538,0.05746 0.061228,0.08595 0.00971,0.01322 0.019424,0.02694 0.029136,0.03966 0.019423,0.02644 0.038848,0.05239 0.058271,0.07729 0.00971,0.01271 0.019847,0.02594 0.029981,0.03865 0.020692,0.02694 0.041381,0.0529 0.062496,0.0783 0.00887,0.01071 0.017735,0.02185 0.026181,0.03255 0.027025,0.03305 0.054473,0.06561 0.082342,0.09764 0.00253,0.003 0.00464,0.0061 0.00718,0.0086 0.031248,0.03611 0.062496,0.07119 0.094165,0.105779 0.00591,0.0066 0.011823,0.0122 0.017735,0.0188 0.025337,0.02747 0.050671,0.05392 0.076429,0.08086 0.00887,0.0097 0.018158,0.0183 0.027448,0.02796 0.023226,0.02339 0.046027,0.0468 0.069674,0.06969 0.00929,0.0097 0.019001,0.0183 0.028292,0.02796 0.024491,0.02339 0.048982,0.04678 0.073473,0.06915 0.00802,0.0076 0.016046,0.01474 0.024069,0.02238 0.031247,0.02847 0.062496,0.05645 0.094587,0.08391 0.00127,9.74e-4 0.00253,0.0021 0.00338,0.003 0.035048,0.03002 0.070097,0.05898 0.1051438,0.08747 0.0017,0.0014 0.00338,0.003 0.00508,0.0046 0.032091,0.02594 0.064184,0.05086 0.096698,0.07527 0.00718,0.0056 0.014357,0.01073 0.021535,0.01578 0.027448,0.02085 0.055317,0.04069 0.083186,0.0605 0.00802,0.0061 0.016046,0.01121 0.024069,0.01678 0.028293,0.02032 0.057006,0.03967 0.08572,0.059 0.00633,0.004 0.012668,0.0086 0.019424,0.0122 0.1072551,0.07119 0.2166217,0.135784 0.3268326,0.193761 0.00423,0.0021 0.00887,0.0046 0.01309,0.0066 0.032515,0.01678 0.064607,0.03307 0.097121,0.04883 0.0059,0.003 0.012246,0.0061 0.018158,0.009 0.032092,0.01524 0.064607,0.03052 0.096698,0.04425 0.00464,0.0021 0.00929,0.0046 0.014356,0.0066 0.1135892,0.04933 0.2284449,0.09256 0.3433009,0.128156 0.0017,5.1e-4 0.00338,9.74e-4 0.00549,0.0014 0.035892,0.0112 0.071785,0.02187 0.1076773,0.03154 0.00464,9.73e-4 0.00929,0.0026 0.013934,0.0036 0.034626,0.0097 0.068829,0.0178 0.1034547,0.02594 0.00379,9.74e-4 0.00802,0.0021 0.011824,0.003 0.1169673,0.02694 0.2343567,0.04679 0.3517462,0.05951 l 0,0 c 0.6481757,1.849131 1.52733,3.584344 2.6163505,5.151733 3.2493206,4.67828 8.2075476,7.650825 13.8810926,7.526736 5.62076,-0.12256 10.470044,-3.267511 13.60958,-7.987475 2.711782,-4.077649 4.055427,-9.202937 3.667366,-14.468077 l -0.625796,0.397186 3.441877,-2.497548 -4.004333,0.160197 0.94925,-0.107311 c -0.220421,-1.378712 -0.556544,-2.696396 -0.990631,-3.942371 0.168484,0.428718 0.325565,0.867097 0.469134,1.315141 2.798347,-0.571116 5.565447,-0.68554 8.28863,-0.151043 0.771477,0.153076 0.933204,0.41702 0.464491,-0.493815 z m -12.799679,3.703349 c -0.150327,4.243438 -1.599116,6.202419 -3.283952,6.35143 -0.291784,0.02594 -0.581036,-0.003 -0.882953,-0.08339 0.127101,0.01169 0.25378,0.01373 0.380461,0.005 0.947982,-0.0656 1.826292,-0.718089 2.438574,-2.048996 -1.654432,-1.002882 -3.38487,-1.607564 -5.059992,-1.826755 1.684833,0.07272 3.4651,0.599086 5.159647,1.598919 0.215777,-0.520259 0.393129,-1.134093 0.522342,-1.846589 -1.866407,-0.63926 -3.746752,-0.830988 -5.497882,-0.626039 1.72875,-0.355486 3.641185,-0.255806 5.541374,0.37074 0.08615,-0.535514 0.146526,-1.122905 0.176508,-1.764709 0.0114,-0.238514 -0.003,-0.451602 -0.03927,-0.641804 -2.009135,-0.114427 -3.941838,0.243602 -5.656652,0.971863 1.643451,-0.864048 3.568132,-1.320736 5.586133,-1.236826 -0.412129,-1.186475 -1.895967,-1.250044 -3.554621,-0.903205 2.210554,-0.579759 4.250091,-0.552808 4.170283,1.68029 z m 2.44111,-7.055789 c 1.92468,-0.563996 3.721414,-1.511446 5.334888,-2.770136 -1.510441,1.419396 -3.24806,2.506191 -5.138958,3.16783 -0.06418,-0.133245 -0.129212,-0.265977 -0.19593,-0.397694 z m 0.825526,1.842519 c -0.05574,-0.141379 -0.112746,-0.282252 -0.171017,-0.421598 1.999844,-0.298525 3.997577,-0.112402 5.887635,0.505511 -1.862188,-0.401765 -3.791937,-0.442449 -5.716618,-0.08392 z"
484 id="path14"
485 style="fill:#f0a513;fill-opacity:1"
486 inkscape:connector-curvature="0" />
487 <path
488 d="m 17.971864,28.383357 c 3.029325,0.977457 4.82775,4.729117 4.016157,8.37805 -0.214087,0.963215 -0.589481,1.823193 -1.080996,2.549419 -2.202109,-0.672827 -4.51105,0.238008 -5.964907,2.257001 -2.974852,-1.022212 -4.729782,-4.734713 -3.926214,-8.347029 0.811593,-3.648933 3.926636,-5.815407 6.95596,-4.837441 z"
489 id="path16"
490 inkscape:connector-curvature="0"
491 style="fill:#ffffff" />
492 <path
493 d="m 21.46948,31.675787 c 0.688291,1.496188 0.915048,3.303109 0.518541,5.08562 -0.214087,0.963215 -0.589481,1.823193 -1.080996,2.549419 -2.202532,-0.672827 -4.511474,0.238008 -5.965329,2.257001 -1.217389,-0.418038 -2.2304,-1.28768 -2.947405,-2.415671 0.307831,0.161723 0.630018,0.298527 0.964451,0.406343 3.605716,1.163589 7.313197,-1.414313 8.279337,-5.756922 0.157927,-0.710463 0.232246,-1.423974 0.231401,-2.12579 z"
494 id="path18"
495 inkscape:connector-curvature="0"
496 style="fill:#eeeeee" />
497 <path
498 d="m 11.148494,37.665629 c -0.473779,-1.361928 -0.61397,-2.903379 -0.33232,-4.44127 -0.52952,-1.020176 -1.3685584,-1.810482 -2.4090152,-2.146133 -2.1826849,-0.704357 -4.4270197,0.856418 -5.0118558,3.484667 -0.3242991,1.457031 -0.070517,2.936437 0.5915924,4.085786 1.0683288,-0.4694 2.2489802,-0.271571 3.2581915,0.503477 0.4619579,0.354468 0.8876005,0.829465 1.2503252,1.416854 1.1793816,-0.417022 2.1776139,-1.463641 2.6530819,-2.903381 z"
499 id="path20"
500 inkscape:connector-curvature="0"
501 style="fill:#ffffff" />
502 <path
503 d="m 31.2411,51.394259 1.26637,0.637229 -2.465178,-0.01373 c -4.530473,2.179698 -9.426207,2.60994 -12.629927,1.007461 -0.08825,-0.03864 -0.176507,-0.07984 -0.264338,-0.124092 -3.038191,-1.529243 -4.472201,-5.736578 -3.202453,-9.39619 0.218732,-0.6296 0.503339,-1.202239 0.840306,-1.710803 l 0,-5.07e-4 c -1.472857,-0.618925 -2.639574,-1.861849 -3.348978,-3.411437 -0.588215,1.277507 -1.5788467,2.193936 -2.7176907,2.574848 0.033779,0.06461 0.067143,0.129175 0.099655,0.195796 1.3449097,2.750303 0.9285573,6.379402 -0.9298254,8.103935 -0.051515,0.04782 -0.1038771,0.09408 -0.1566605,0.137821 l 0,0 c -0.048979,0.05034 -0.098387,0.09866 -0.1494812,0.145956 -0.7486746,0.694696 -1.6176949,0.974406 -2.4761587,0.880322 l 0,5.08e-4 c 0.6477536,1.848622 1.5273307,3.584344 2.6159279,5.151732 3.2493226,4.678262 8.2075486,7.650298 13.8810926,7.526717 5.620762,-0.12256 10.470046,-3.268018 13.609581,-7.987982 2.123568,-3.192243 3.407673,-7.028327 3.678768,-11.070884 -1.87021,3.185631 -4.634352,5.665888 -7.651009,7.353296 z"
504 id="path183"
505 style="fill:#fdd99b"
506 inkscape:connector-curvature="0" />
507 <path
508 d="m 11.261241,44.175223 c -0.158773,-0.250722 -0.250827,-0.566539 -0.243648,-0.906768 0.01224,-0.584846 0.312898,-1.079675 0.733895,-1.291745 -0.616928,0.507545 -0.839039,1.75098 -0.173129,2.336839 0.277429,0.243604 0.439579,0.574168 0.370749,1.028824 -0.05363,0.355991 -0.262648,0.802509 -0.591168,1.144265 -0.374972,0.389558 -0.833129,0.599593 -1.228791,0.541109 0.37835,-0.112404 0.757541,-0.387016 1.06284,-0.752165 0.26307,-0.314291 0.444644,-0.675369 0.519384,-0.97542 0.14906,-0.596542 -0.181995,-0.701818 -0.450132,-1.124939 l 0,0 z m 1.895122,4.408723 c -0.233935,0.931683 -0.952208,1.610106 -1.802226,1.610106 -0.765564,0 -1.4251397,-0.551279 -1.7190352,-1.342094 0.3783472,0.632143 0.9944302,1.044078 1.6907442,1.044078 0.790057,0 1.477502,-0.530939 1.830517,-1.31209 z"
509 id="path185"
510 inkscape:connector-curvature="0" />
511 <g
512 id="g187"
513 transform="matrix(0.42226435,0,0,0.50856192,-47.726977,-111.72952)">
514 <radialGradient
515 id="radialGradient3241"
516 cx="163.4902"
517 cy="274.86621"
518 r="2.8801"
519 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
520 gradientUnits="userSpaceOnUse">
521 <stop
522 offset="0.0112"
523 style="stop-color:#FAF0BB"
524 id="stop3243" />
525 <stop
526 offset="0.4917"
527 style="stop-color:#FAF0BD"
528 id="stop3245" />
529 <stop
530 offset="0.6648"
531 style="stop-color:#FBF2C5"
532 id="stop3247" />
533 <stop
534 offset="0.7882"
535 style="stop-color:#FCF6D0"
536 id="stop3249" />
537 <stop
538 offset="0.8879"
539 style="stop-color:#FCF8E1"
540 id="stop3251" />
541 <stop
542 offset="0.9723"
543 style="stop-color:#FFFDF7"
544 id="stop3253" />
545 <stop
546 offset="1"
547 style="stop-color:#FFFFFF"
548 id="stop3255" />
549 </radialGradient>
550 <path
551 d="m 189.806,311.298 c -0.681,-0.478 -1.432,-0.68 -2.1,-0.645 -0.633,0.034 -1.217,0.284 -1.625,0.739 -0.408,0.454 -0.59,1.052 -0.559,1.676 0.034,0.653 0.305,1.364 0.834,1.98 0.577,0.671 1.35,1.108 2.143,1.244 0.845,0.145 1.679,-0.06 2.247,-0.657 0.573,-0.604 0.725,-1.448 0.515,-2.282 -0.199,-0.789 -0.713,-1.534 -1.455,-2.055 z"
552 id="path204"
553 style="fill:url(#radialGradient3305)"
554 inkscape:connector-curvature="0" />
555 <radialGradient
556 id="radialGradient3258"
557 cx="155.3242"
558 cy="310.6777"
559 r="4.4867001"
560 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
561 gradientUnits="userSpaceOnUse">
562 <stop
563 offset="0.0112"
564 style="stop-color:#FAF0BB"
565 id="stop3260" />
566 <stop
567 offset="0.4917"
568 style="stop-color:#FAF0BD"
569 id="stop3262" />
570 <stop
571 offset="0.6648"
572 style="stop-color:#FBF2C5"
573 id="stop3264" />
574 <stop
575 offset="0.7882"
576 style="stop-color:#FCF6D0"
577 id="stop3266" />
578 <stop
579 offset="0.8879"
580 style="stop-color:#FCF8E1"
581 id="stop3268" />
582 <stop
583 offset="0.9723"
584 style="stop-color:#FFFDF7"
585 id="stop3270" />
586 <stop
587 offset="1"
588 style="stop-color:#FFFFFF"
589 id="stop3272" />
590 </radialGradient>
591 <path
592 d="m 183.164,274.256 c -0.777,-0.621 -1.774,-0.996 -2.853,-1 -1.077,-0.004 -2.096,0.366 -2.89,0.992 -0.839,0.661 -1.465,1.633 -1.646,2.791 -0.197,1.263 0.167,2.499 0.961,3.449 0.841,1.005 2.124,1.644 3.592,1.617 1.455,-0.026 2.71,-0.702 3.522,-1.716 0.762,-0.951 1.106,-2.168 0.913,-3.4 -0.179,-1.131 -0.786,-2.082 -1.599,-2.733 z"
593 id="path221"
594 style="fill:url(#radialGradient3307)"
595 inkscape:connector-curvature="0" />
596 <radialGradient
597 id="radialGradient3275"
598 cx="170.3125"
599 cy="302.00781"
600 r="5.0811"
601 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
602 gradientUnits="userSpaceOnUse">
603 <stop
604 offset="0.0112"
605 style="stop-color:#FAF0BB"
606 id="stop3277" />
607 <stop
608 offset="0.4917"
609 style="stop-color:#FAF0BD"
610 id="stop3279" />
611 <stop
612 offset="0.6648"
613 style="stop-color:#FBF2C5"
614 id="stop3281" />
615 <stop
616 offset="0.7882"
617 style="stop-color:#FCF6D0"
618 id="stop3283" />
619 <stop
620 offset="0.8879"
621 style="stop-color:#FCF8E1"
622 id="stop3285" />
623 <stop
624 offset="0.9723"
625 style="stop-color:#FFFDF7"
626 id="stop3287" />
627 <stop
628 offset="1"
629 style="stop-color:#FFFFFF"
630 id="stop3289" />
631 </radialGradient>
632 <path
633 d="m 197.254,290.925 c 1.482,-0.322 2.697,-1.225 3.201,-2.604 0.5,-1.367 0.166,-2.845 -0.726,-4.066 -0.835,-1.146 -2.134,-2.023 -3.647,-2.408 -1.389,-0.352 -2.723,-0.223 -3.781,0.238 -1.011,0.439 -1.812,1.196 -2.21,2.198 -0.397,1.001 -0.335,2.12 0.108,3.146 0.468,1.083 1.377,2.112 2.666,2.812 1.407,0.762 2.987,0.989 4.389,0.684 z"
634 id="path238"
635 style="fill:url(#radialGradient3310)"
636 inkscape:connector-curvature="0" />
637 <radialGradient
638 id="radialGradient3292"
639 cx="173.2812"
640 cy="283.68359"
641 r="2.8803999"
642 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
643 gradientUnits="userSpaceOnUse">
644 <stop
645 offset="0.0112"
646 style="stop-color:#FAF0BB"
647 id="stop3294" />
648 <stop
649 offset="0.4917"
650 style="stop-color:#FAF0BD"
651 id="stop3296" />
652 <stop
653 offset="0.6648"
654 style="stop-color:#FBF2C5"
655 id="stop3298" />
656 <stop
657 offset="0.7882"
658 style="stop-color:#FCF6D0"
659 id="stop3300" />
660 <stop
661 offset="0.8879"
662 style="stop-color:#FCF8E1"
663 id="stop3302" />
664 <stop
665 offset="0.9723"
666 style="stop-color:#FFFDF7"
667 id="stop3304" />
668 <stop
669 offset="1"
670 style="stop-color:#FFFFFF"
671 id="stop3306" />
672 </radialGradient>
673 <path
674 d="m 200.538,302.533 c -0.568,-0.598 -1.402,-0.802 -2.248,-0.657 -0.792,0.136 -1.565,0.573 -2.143,1.244 -0.529,0.616 -0.8,1.327 -0.833,1.98 -0.032,0.624 0.15,1.222 0.559,1.676 0.408,0.455 0.991,0.705 1.624,0.739 0.668,0.035 1.42,-0.167 2.101,-0.645 0.741,-0.521 1.256,-1.267 1.454,-2.056 0.21,-0.833 0.058,-1.677 -0.514,-2.281 z"
675 id="path255"
676 style="fill:url(#radialGradient3312)"
677 inkscape:connector-curvature="0" />
678 <radialGradient
679 id="radialGradient3309"
680 cx="148.9492"
681 cy="270.04489"
682 r="2.8799"
683 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
684 gradientUnits="userSpaceOnUse">
685 <stop
686 offset="0.0112"
687 style="stop-color:#FAF0BB"
688 id="stop3311" />
689 <stop
690 offset="0.4917"
691 style="stop-color:#FAF0BD"
692 id="stop3313" />
693 <stop
694 offset="0.6648"
695 style="stop-color:#FBF2C5"
696 id="stop3315" />
697 <stop
698 offset="0.7882"
699 style="stop-color:#FCF6D0"
700 id="stop3317" />
701 <stop
702 offset="0.8879"
703 style="stop-color:#FCF8E1"
704 id="stop3319" />
705 <stop
706 offset="0.9723"
707 style="stop-color:#FFFDF7"
708 id="stop3321" />
709 <stop
710 offset="1"
711 style="stop-color:#FFFFFF"
712 id="stop3323" />
713 </radialGradient>
714 <path
715 d="m 173.958,315.516 c -0.793,0.136 -1.566,0.573 -2.143,1.244 -0.529,0.616 -0.801,1.327 -0.834,1.98 -0.031,0.623 0.15,1.222 0.559,1.676 0.408,0.455 0.991,0.705 1.624,0.738 0.669,0.036 1.42,-0.166 2.101,-0.645 0.741,-0.521 1.256,-1.266 1.454,-2.055 0.211,-0.834 0.06,-1.679 -0.514,-2.282 -0.568,-0.598 -1.402,-0.801 -2.247,-0.656 z"
716 id="path272"
717 style="fill:url(#radialGradient3314)"
718 inkscape:connector-curvature="0" />
719 <radialGradient
720 id="radialGradient3326"
721 cx="148.0723"
722 cy="319.09381"
723 r="3.9265001"
724 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
725 gradientUnits="userSpaceOnUse">
726 <stop
727 offset="0.0112"
728 style="stop-color:#FAF0BB"
729 id="stop3328" />
730 <stop
731 offset="0.4917"
732 style="stop-color:#FAF0BD"
733 id="stop3330" />
734 <stop
735 offset="0.6648"
736 style="stop-color:#FBF2C5"
737 id="stop3332" />
738 <stop
739 offset="0.7882"
740 style="stop-color:#FCF6D0"
741 id="stop3334" />
742 <stop
743 offset="0.8879"
744 style="stop-color:#FCF8E1"
745 id="stop3336" />
746 <stop
747 offset="0.9723"
748 style="stop-color:#FFFDF7"
749 id="stop3338" />
750 <stop
751 offset="1"
752 style="stop-color:#FFFFFF"
753 id="stop3340" />
754 </radialGradient>
755 <path
756 d="m 171.282,272.336 c 1.106,0.549 2.333,0.68 3.407,0.405 1.136,-0.291 2.049,-1.022 2.398,-2.102 0.347,-1.069 0.048,-2.201 -0.675,-3.119 -0.678,-0.861 -1.706,-1.502 -2.885,-1.756 -1.083,-0.233 -2.109,-0.095 -2.914,0.291 -0.768,0.368 -1.365,0.975 -1.645,1.76 -0.278,0.785 -0.198,1.646 0.173,2.426 0.394,0.822 1.125,1.592 2.141,2.095 z"
757 id="path289"
758 style="fill:url(#radialGradient3316)"
759 inkscape:connector-curvature="0" />
760 <radialGradient
761 id="radialGradient3343"
762 cx="112.9551"
763 cy="315.56049"
764 r="3.0683999"
765 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
766 gradientUnits="userSpaceOnUse">
767 <stop
768 offset="0.0112"
769 style="stop-color:#FAF0BB"
770 id="stop3345" />
771 <stop
772 offset="0.4917"
773 style="stop-color:#FAF0BD"
774 id="stop3347" />
775 <stop
776 offset="0.6648"
777 style="stop-color:#FBF2C5"
778 id="stop3349" />
779 <stop
780 offset="0.7882"
781 style="stop-color:#FCF6D0"
782 id="stop3351" />
783 <stop
784 offset="0.8879"
785 style="stop-color:#FCF8E1"
786 id="stop3353" />
787 <stop
788 offset="0.9723"
789 style="stop-color:#FFFDF7"
790 id="stop3355" />
791 <stop
792 offset="1"
793 style="stop-color:#FFFFFF"
794 id="stop3357" />
795 </radialGradient>
796 <path
797 d="m 140.776,270.8 c -0.132,-0.306 -0.298,-0.603 -0.496,-0.884 0,0 -0.001,-10e-4 -0.001,-10e-4 -0.031,0.02 -0.061,0.042 -0.091,0.062 -0.1,0.067 -0.199,0.135 -0.298,0.203 -0.12,0.082 -0.24,0.163 -0.358,0.246 -0.123,0.085 -0.245,0.173 -0.366,0.26 -0.096,0.068 -0.193,0.136 -0.289,0.206 -0.146,0.106 -0.29,0.213 -0.434,0.321 -0.072,0.054 -0.145,0.106 -0.216,0.161 -0.215,0.163 -0.429,0.328 -0.641,0.495 -0.223,0.175 -0.443,0.354 -0.663,0.535 -0.064,0.053 -0.129,0.107 -0.194,0.161 -0.171,0.143 -0.341,0.287 -0.51,0.432 -0.054,0.046 -0.108,0.092 -0.162,0.139 -0.193,0.167 -0.384,0.337 -0.574,0.509 -0.098,0.088 -0.196,0.178 -0.293,0.268 -0.099,0.09 -0.196,0.182 -0.294,0.274 -0.079,0.074 -0.16,0.146 -0.238,0.222 0,0 0.001,0.001 0.001,0.001 0.177,0.156 0.363,0.299 0.555,0.429 0.596,0.402 1.257,0.671 1.927,0.786 1.185,0.202 2.356,-0.083 3.152,-0.922 0.804,-0.847 1.017,-2.032 0.722,-3.202 -0.06,-0.24 -0.14,-0.473 -0.239,-0.701 z"
798 id="path306"
799 style="fill:url(#radialGradient3318)"
800 inkscape:connector-curvature="0" />
801 <radialGradient
802 id="radialGradient3360"
803 cx="132.0938"
804 cy="320.1113"
805 r="4.1712999"
806 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
807 gradientUnits="userSpaceOnUse">
808 <stop
809 offset="0.0112"
810 style="stop-color:#FAF0BB"
811 id="stop3362" />
812 <stop
813 offset="0.4917"
814 style="stop-color:#FAF0BD"
815 id="stop3364" />
816 <stop
817 offset="0.6648"
818 style="stop-color:#FBF2C5"
819 id="stop3366" />
820 <stop
821 offset="0.7882"
822 style="stop-color:#FCF6D0"
823 id="stop3368" />
824 <stop
825 offset="0.8879"
826 style="stop-color:#FCF8E1"
827 id="stop3370" />
828 <stop
829 offset="0.9723"
830 style="stop-color:#FFFDF7"
831 id="stop3372" />
832 <stop
833 offset="1"
834 style="stop-color:#FFFFFF"
835 id="stop3374" />
836 </radialGradient>
837 <path
838 d="m 160.2,265.6 c -0.85,-0.392 -1.938,-0.592 -3.115,-0.521 -1.177,0.07 -2.29,0.405 -3.157,0.906 -0.916,0.53 -1.6,1.269 -1.798,2.11 -0.216,0.917 0.182,1.777 1.05,2.403 0.918,0.663 2.32,1.032 3.923,0.914 1.588,-0.118 2.959,-0.687 3.847,-1.468 0.833,-0.732 1.209,-1.627 0.998,-2.496 -0.195,-0.799 -0.859,-1.438 -1.748,-1.848 z"
839 id="path323"
840 style="fill:url(#radialGradient3320)"
841 inkscape:connector-curvature="0" />
842 <radialGradient
843 id="radialGradient3377"
844 cx="147.44189"
845 cy="301.21091"
846 r="2.5313001"
847 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
848 gradientUnits="userSpaceOnUse">
849 <stop
850 offset="0.0112"
851 style="stop-color:#FAF0BB"
852 id="stop3379" />
853 <stop
854 offset="0.4917"
855 style="stop-color:#FAF0BD"
856 id="stop3381" />
857 <stop
858 offset="0.6648"
859 style="stop-color:#FBF2C5"
860 id="stop3383" />
861 <stop
862 offset="0.7882"
863 style="stop-color:#FCF6D0"
864 id="stop3385" />
865 <stop
866 offset="0.8879"
867 style="stop-color:#FCF8E1"
868 id="stop3387" />
869 <stop
870 offset="0.9723"
871 style="stop-color:#FFFDF7"
872 id="stop3389" />
873 <stop
874 offset="1"
875 style="stop-color:#FFFFFF"
876 id="stop3391" />
877 </radialGradient>
878 <path
879 d="m 173.961,289.2 c 0.657,-0.143 1.12,-0.506 1.265,-1.029 0.133,-0.48 -0.03,-1.015 -0.381,-1.495 -0.335,-0.458 -0.853,-0.886 -1.498,-1.196 -0.645,-0.31 -1.333,-0.461 -1.94,-0.451 -0.643,0.011 -1.223,0.2 -1.576,0.587 -0.385,0.422 -0.428,0.996 -0.152,1.584 0.291,0.622 0.925,1.231 1.811,1.642 0.876,0.408 1.77,0.51 2.471,0.358 z"
880 id="path340"
881 style="fill:url(#radialGradient3322)"
882 inkscape:connector-curvature="0" />
883 </g>
884 <path
885 d="m 32.300561,46.79686 c -0.244913,-0.207495 -0.516006,-0.294969 -0.756275,-0.27971 -0.2276,0.01425 -0.437888,0.12307 -0.584836,0.320395 -0.147371,0.197321 -0.212822,0.456181 -0.201419,0.726735 0.01182,0.283777 0.109788,0.591457 0.300228,0.85845 0.207332,0.290901 0.486027,0.480592 0.771056,0.539586 0.304451,0.06256 0.605105,-0.02543 0.809057,-0.284794 0.206488,-0.26191 0.260961,-0.628075 0.185374,-0.989662 -0.07136,-0.342262 -0.256312,-0.665199 -0.523185,-0.891 z"
886 id="path347"
887 style="fill:#000000"
888 inkscape:connector-curvature="0" />
889 <g
890 id="g349"
891 transform="matrix(0.42226435,0,0,0.50856192,-47.726977,-111.72952)">
892 <path
893 d="m 168.559,264.427 c 4.145,0.407 8.127,1.382 11.858,2.845 l 0.623,-0.856 c -3.919,-1.741 -8.161,-2.906 -12.604,-3.384 l 0.123,1.395 z"
894 id="path351"
895 inkscape:connector-curvature="0"
896 style="fill:#ffffff" />
897 <path
898 d="m 145.971,266.73 1.059,0.888 c 5.193,-2.147 10.87,-3.351 16.738,-3.403 l 0.009,-0.038 0.435,-1.388 c -0.059,0 -0.116,-0.002 -0.175,-0.002 -6.387,-0.024 -12.545,1.39 -18.066,3.943 z"
899 id="path353"
900 inkscape:connector-curvature="0"
901 style="fill:#ffffff" />
902 <path
903 d="m 185.374,269.579 c 0.97,0.527 1.917,1.087 2.84,1.683 l 0.494,-0.416 c -1.011,-0.738 -2.058,-1.431 -3.138,-2.078 l -0.196,0.811 z"
904 id="path355"
905 inkscape:connector-curvature="0"
906 style="fill:#ffffff" />
907 <path
908 d="m 190.66,272.366 -0.224,0.429 c 0.458,0.338 0.91,0.683 1.354,1.038 1.494,1.193 2.916,2.493 4.25,3.889 -1.633,-1.962 -3.44,-3.752 -5.38,-5.356 z"
909 id="path357"
910 inkscape:connector-curvature="0"
911 style="fill:#ffffff" />
912 <path
913 d="m 140.28,269.916 c 0.198,0.281 0.363,0.578 0.496,0.884 0.84,-0.514 1.699,-1.002 2.575,-1.462 l -0.52,-0.994 c -0.871,0.494 -1.721,1.019 -2.551,1.572 z"
914 id="path359"
915 inkscape:connector-curvature="0"
916 style="fill:#ffffff" />
917 <path
918 d="m 133.625,275.426 0.562,0.314 c 0.338,-0.307 0.681,-0.608 1.028,-0.904 -0.192,-0.129 -0.378,-0.272 -0.555,-0.429 -0.35,0.333 -0.696,0.673 -1.035,1.019 z"
919 id="path361"
920 inkscape:connector-curvature="0"
921 style="fill:#ffffff" />
922 <path
923 d="m 130.152,279.456 c 0.139,-0.009 0.279,-0.015 0.419,-0.019 0.538,-0.62 1.091,-1.224 1.66,-1.81 l -0.295,-0.374 c -0.618,0.713 -1.212,1.447 -1.784,2.203 z"
924 id="path363"
925 inkscape:connector-curvature="0"
926 style="fill:#ffffff" />
927 </g>
928 <path
929 d="m 11.717707,25.989048 c -0.05574,-0.15562 -0.125834,-0.306666 -0.209444,-0.44957 -0.01309,0.01012 -0.02618,0.02032 -0.03885,0.03052 -0.04223,0.03408 -0.08403,0.06866 -0.125835,0.10324 -0.05067,0.0417 -0.101339,0.08289 -0.151171,0.125104 -0.05194,0.04324 -0.103455,0.08798 -0.154549,0.132228 -0.04054,0.03459 -0.0815,0.06916 -0.122034,0.104767 -0.06165,0.0534 -0.122457,0.108333 -0.183263,0.16325 -0.03041,0.02747 -0.06122,0.05392 -0.09122,0.08188 -0.09078,0.08288 -0.181151,0.166809 -0.27067,0.251737 -0.09416,0.0895 -0.187063,0.180031 -0.279961,0.272083 -0.02703,0.02695 -0.05447,0.05442 -0.08192,0.08188 -0.07221,0.07272 -0.1439917,0.145958 -0.2153547,0.219699 -0.02281,0.02339 -0.0456,0.04679 -0.068411,0.07019 -0.081499,0.08492 -0.1621494,0.171895 -0.24238,0.258858 -0.041385,0.04477 -0.08276,0.09052 -0.1237229,0.136294 -0.041799,0.04628 -0.08276,0.09308 -0.1241459,0.139347 -0.033364,0.03762 -0.066717,0.07527 -0.1000776,0.113908 0.074741,0.07935 0.1532821,0.152062 0.2343573,0.218175 C 9.5506288,27.855494 9.7347353,27.672921 9.9217999,27.495432 10.4927,26.95178 11.092737,26.44983 11.717689,25.989072 z"
930 id="path365"
931 inkscape:connector-curvature="0"
932 style="fill:#eeeeee" />
933 <path
934 d="m 28.381526,27.537111 c 0.388483,0.0014 0.747409,0.164265 1.026947,0.433802 0.293051,0.282252 0.512205,0.694697 0.575969,1.184949 0.06968,0.534499 -0.05447,1.061878 -0.328523,1.474322 -0.292629,0.439906 -0.744451,0.732838 -1.26806,0.744027 -0.528674,0.01119 -0.990631,-0.26547 -1.292973,-0.70131 -0.286295,-0.411932 -0.417197,-0.947959 -0.345834,-1.495681 0.06503,-0.501949 0.290517,-0.923546 0.592437,-1.209867 0.28545,-0.271063 0.652399,-0.431769 1.040037,-0.430242 z"
935 id="path372"
936 style="fill:#000000"
937 inkscape:connector-curvature="0" />
938 <path
939 d="m 13.466305,55.28374 c 0.178195,0.09256 0.329787,0.214614 0.43662,0.342772 0.111901,0.134768 0.178619,0.281236 0.168063,0.408885 -0.0114,0.139346 -0.111902,0.231394 -0.271518,0.261399 -0.170172,0.03153 -0.401994,-0.0082 -0.64353,-0.129175 -0.244069,-0.12256 -0.433666,-0.295472 -0.53712,-0.467367 -0.09797,-0.162232 -0.114433,-0.316834 -0.03674,-0.425668 0.07093,-0.100193 0.209021,-0.143413 0.37117,-0.13782 0.152859,0.005 0.334856,0.05491 0.513051,0.146974 l 0,0 z m -2.368059,-0.261399 c 0.05025,0.0122 0.09585,0.04017 0.130479,0.0768 0.03588,0.03815 0.06165,0.08797 0.06671,0.140364 0.0055,0.05696 -0.01435,0.10731 -0.05278,0.141381 -0.04097,0.0356 -0.101763,0.05188 -0.169749,0.03611 -0.06883,-0.01525 -0.127102,-0.05848 -0.163417,-0.113404 -0.03463,-0.05139 -0.04772,-0.110861 -0.03463,-0.164774 0.01183,-0.04984 0.04392,-0.08594 0.0853,-0.10578 0.03885,-0.01831 0.08741,-0.02339 0.138081,-0.01071 l 0,0 z m 3.807979,2.368373 c 0.09627,0.02389 0.183263,0.07728 0.248714,0.147481 0.06925,0.07322 0.117813,0.167318 0.127101,0.267506 0.01013,0.109332 -0.02745,0.204948 -0.100915,0.270045 -0.07854,0.06866 -0.194242,0.09866 -0.324299,0.06968 -0.131324,-0.03002 -0.24238,-0.111886 -0.311631,-0.216139 -0.06545,-0.09816 -0.09122,-0.21156 -0.0663,-0.314799 0.02281,-0.09459 0.08446,-0.163757 0.162995,-0.2019 0.07515,-0.03611 0.16806,-0.04576 0.264336,-0.02185 l 0,0 z m -2.357501,-1.035942 c -0.09333,-0.04831 -0.188754,-0.07425 -0.269405,-0.0768 -0.08487,-0.003 -0.157504,0.01983 -0.194242,0.07222 -0.04054,0.05696 -0.03209,0.137821 0.01942,0.222749 0.05405,0.09052 0.153704,0.18054 0.281651,0.245128 0.126679,0.06356 0.247869,0.08391 0.337388,0.06765 0.08362,-0.01576 0.136392,-0.06407 0.142304,-0.137313 0.0055,-0.06713 -0.02956,-0.143414 -0.08783,-0.214102 -0.05658,-0.06714 -0.135969,-0.13121 -0.22929,-0.179526 z"
940 id="path374"
941 inkscape:connector-curvature="0"
942 style="fill:#d9bb7a" />
943 <path
944 d="m 32.89722,32.895826 c 0.143148,-0.434312 0.431555,-0.762333 0.795547,-0.953043 0.380884,-0.199865 0.861841,-0.255808 1.361803,-0.10325 0.544721,0.166808 1.012166,0.547722 1.313242,1.044079 0.320921,0.529412 0.440844,1.170201 0.26096,1.762675 -0.181574,0.59807 -0.618618,0.989661 -1.15236,1.129517 -0.504607,0.132224 -1.073818,0.03356 -1.579691,-0.297003 -0.464491,-0.303099 -0.791747,-0.749617 -0.960229,-1.219019 -0.160039,-0.444994 -0.182419,-0.929651 -0.03927,-1.363962 z"
945 id="path381"
946 style="fill:#000000"
947 inkscape:connector-curvature="0" />
948 <path
949 d="m 35.093418,44.08063 c -0.146948,-0.197323 -0.212399,-0.456178 -0.200998,-0.726732 0.01182,-0.28378 0.109367,-0.591461 0.299807,-0.858457 0.207754,-0.290895 0.486028,-0.480589 0.771477,-0.540093 0.304453,-0.06256 0.604685,0.02594 0.809059,0.285306 0.206487,0.261909 0.26096,0.628075 0.184952,0.989659 -0.07137,0.342262 -0.256313,0.6652 -0.523607,0.891001 -0.244913,0.207492 -0.515586,0.294965 -0.755853,0.27971 -0.227601,-0.01423 -0.437466,-0.123072 -0.584837,-0.320394 z"
950 id="path388"
951 style="fill:#000000"
952 inkscape:connector-curvature="0" />
953 <path
954 d="m 24.819304,51.017414 c -0.147371,-0.197322 -0.212821,-0.456179 -0.201421,-0.727243 0.01183,-0.283269 0.10979,-0.590948 0.30023,-0.858455 0.207333,-0.290896 0.485604,-0.481098 0.771055,-0.540089 0.304453,-0.06256 0.605106,0.02594 0.809059,0.285303 0.206487,0.261908 0.260959,0.628074 0.184952,0.989661 -0.07136,0.342263 -0.256314,0.6652 -0.523608,0.891002 -0.24449,0.207493 -0.515584,0.294964 -0.755854,0.279709 -0.2276,-0.01425 -0.437465,-0.123071 -0.584413,-0.319888 z"
955 id="path395"
956 style="fill:#000000"
957 inkscape:connector-curvature="0" />
958 <path
959 d="m 23.786446,24.445052 c 0.102186,-0.347855 0.322609,-0.616885 0.605104,-0.779624 0.296007,-0.170876 0.673933,-0.232414 1.072129,-0.128666 0.433667,0.112897 0.812438,0.396678 1.061996,0.778609 0.266026,0.406849 0.376235,0.908289 0.24829,1.382269 -0.12879,0.47805 -0.464913,0.802512 -0.882532,0.931685 -0.395661,0.12205 -0.84664,0.06357 -1.254126,-0.17952 -0.374125,-0.222751 -0.642686,-0.563996 -0.787099,-0.928635 -0.137237,-0.346331 -0.166373,-0.728261 -0.06377,-1.076118 z"
960 id="path402"
961 style="fill:#000000"
962 inkscape:connector-curvature="0" />
963 <path
964 d="m 9.3572511,27.571182 c 0.2537814,0.256316 0.5518992,0.424651 0.8555069,0.487204 0.426486,0.08747 0.848329,-0.03611 1.135047,-0.399731 0.28925,-0.367181 0.366103,-0.880828 0.259692,-1.388372 -0.0456,-0.217666 -0.123723,-0.429227 -0.230557,-0.625532 -0.344568,0.281745 -0.680268,0.577726 -1.006255,0.886932 -0.347524,0.330057 -0.6857564,0.676897 -1.0134339,1.039499 z"
965 id="path409"
966 style="fill:#000000"
967 inkscape:connector-curvature="0" />
968 <path
969 d="m 9.3572511,27.571182 c 0.081923,0.08289 0.1684839,0.15664 0.2584255,0.220208 0.1013389,-0.100194 0.2031087,-0.199865 0.3061417,-0.296999 0.5244517,-0.497883 1.0733947,-0.962708 1.6434517,-1.391936 -0.04604,-0.15867 -0.109367,-0.312257 -0.188752,-0.457195 l 0,0 c -0.02997,0.02442 -0.05996,0.04933 -0.08995,0.07425 -0.01942,0.01628 -0.03927,0.03255 -0.05869,0.04883 -0.03336,0.02747 -0.0663,0.05545 -0.09923,0.08341 l -0.04519,0.03865 c -0.03758,0.03205 -0.07474,0.06407 -0.111899,0.09613 l -0.02997,0.02594 c -0.04139,0.03611 -0.08235,0.07221 -0.123301,0.108332 l -0.02026,0.01832 c -0.04392,0.03918 -0.08741,0.07781 -0.130901,0.117485 l -0.01309,0.01169 c -0.04603,0.04223 -0.09206,0.08442 -0.13808,0.12714 l -0.0018,0.0014 c -0.04815,0.04476 -0.09585,0.0895 -0.143569,0.134769 -0.07685,0.07322 -0.15286,0.146467 -0.228867,0.221226 l -0.01098,0.01072 c -0.02026,0.02032 -0.04097,0.04018 -0.06123,0.06051 l -0.01858,0.01882 -0.05236,0.05238 -0.02956,0.03002 -0.04307,0.04376 -0.03801,0.03865 -0.01605,0.01627 -0.01562,0.01627 -0.04771,0.04883 -0.01562,0.01627 C 9.6459492,27.256383 9.50069,27.412511 9.3571211,27.571183 z"
970 id="path411"
971 inkscape:connector-curvature="0"
972 style="fill:#888678" />
973 <path
974 d="m 18.571057,23.295194 c 0.423955,-0.03051 0.815816,0.05645 1.121534,0.226311 0.320077,0.177997 0.559079,0.455163 0.629176,0.800985 0.07601,0.376844 -0.05954,0.764369 -0.359348,1.082221 -0.319232,0.338701 -0.812859,0.585354 -1.385028,0.636719 -0.577235,0.05138 -1.081841,-0.108827 -1.412472,-0.39617 -0.312477,-0.271573 -0.456047,-0.644349 -0.378351,-1.042043 0.07136,-0.364639 0.317965,-0.685034 0.647333,-0.914395 0.312897,-0.217665 0.713204,-0.363114 1.137156,-0.393628 z"
975 id="path418"
976 style="fill:#000000"
977 inkscape:connector-curvature="0" />
978 <path
979 d="m 25.268593,33.539157 c 0.209865,0.121549 0.37835,0.289372 0.487716,0.468895 0.11401,0.188169 0.167216,0.397695 0.123723,0.585864 -0.04687,0.20495 -0.198043,0.347856 -0.412131,0.403289 -0.228021,0.05951 -0.519383,0.01933 -0.804835,-0.139854 -0.288406,-0.160707 -0.494471,-0.399731 -0.589482,-0.643842 -0.08995,-0.230376 -0.07601,-0.455669 0.04941,-0.620952 0.114856,-0.152061 0.304451,-0.226311 0.51305,-0.230379 0.198043,-0.0036 0.422688,0.05543 0.632553,0.176979 z"
980 id="path425"
981 style="fill:#000000"
982 inkscape:connector-curvature="0" />
983 <polygon
984 points="190.01,322.008 182.526,321.973 188.385,321.662 183.827,319.426 "
985 id="polygon427"
986 transform="matrix(0.42226435,0,0,0.50856192,-47.726977,-111.72952)" />
987 <polygon
988 points="182.677,309.541 176.606,313.919 181.161,310.218 176.159,311.094 "
989 id="polygon429"
990 transform="matrix(0.42226435,0,0,0.50856192,-47.726977,-111.72952)" />
991 <polygon
992 points="191.129,279.553 180.144,285.178 188.996,281.271 183.955,287.956 "
993 id="polygon431"
994 transform="matrix(0.42226435,0,0,0.50856192,-47.726977,-111.72952)" />
995 <path
996 d="m 35.589578,54.524966 c -0.122034,0.197832 -0.247447,0.39312 -0.376237,0.586373 -3.139958,4.719964 -7.989242,7.864909 -13.609581,7.987982 C 15.929794,63.222902 10.97199,60.250356 7.7226683,55.572603 7.5229375,55.285266 7.3303849,54.991318 7.1445881,54.693299 c 3.5503959,4.555698 8.6741509,7.392458 14.4832419,7.265826 5.617804,-0.123069 10.532541,-3.002548 13.961748,-7.434159 z"
997 id="path440"
998 style="fill:#d9bb7a"
999 inkscape:connector-curvature="0" />
1000 <path
1001 d="m 16.345302,52.251694 c -2.117655,-1.929991 -2.971052,-5.408047 -1.900189,-8.495019 1.184029,-3.41245 4.302452,-5.144614 7.182295,-4.121385 -2.791167,-0.695713 -5.69128,1.060859 -6.831394,4.34617 -1.023146,2.94966 -0.321343,6.249209 1.549288,8.270234 z"
1002 id="path442"
1003 inkscape:connector-curvature="0"
1004 style="fill:#ffffff" />
1005 <path
1006 d="m 7.9004418,49.211004 c 1.5839109,-1.826246 1.8765395,-5.188352 0.611861,-7.774387 -0.9606515,-1.964067 -2.560189,-2.949661 -4.0731622,-2.724366 1.4428771,-0.03307 2.911513,0.974913 3.8219146,2.837267 1.2266751,2.507718 1.0299008,5.725391 -0.3606134,7.661486 z"
1007 id="path444"
1008 inkscape:connector-curvature="0"
1009 style="fill:#ffffff" />
1010 <path
1011 d="m 46.744961,35.073491 -0.497006,-0.879306 c -0.446333,-0.789288 -2.616772,-1.271403 -3.063106,-2.060692 -0.04897,-0.08645 -0.08995,-0.178504 -0.124145,-0.273607 0.02111,0.05392 0.04434,0.106285 0.07093,0.157655 0.411286,0.799459 2.442378,0.780134 2.853664,1.579592 l 0.759653,1.476358 0,0 z m -3.840919,-4.235306 c -0.02154,-1.142737 0.276584,-2.476187 -0.211554,-3.339725 -0.684068,-1.210379 -3.109133,-1.708769 -3.070285,-3.678937 0.02618,-1.300901 0.05531,-2.044928 -0.877888,-0.830484 -0.474202,0.616888 -0.933204,1.256658 -1.378271,1.918806 0.532898,-0.895579 1.084376,-1.758098 1.656966,-2.58553 0.921382,-1.331414 0.877043,-0.549754 0.825104,0.815225 -0.02492,0.63723 0.05786,1.381764 0.330634,1.912701 0.487293,0.947452 2.164949,1.469236 2.652243,2.416687 0.464492,0.901679 0.07769,2.233605 0.07305,3.371257 z"
1012 id="path446"
1013 inkscape:connector-curvature="0"
1014 style="fill:#ffffff" />
1015 <path
1016 d="m 16.756588,33.897186 c 0.357235,-0.248687 0.77781,-0.246145 1.121111,-0.03865 -0.09501,0.0122 -0.189596,0.04832 -0.27785,0.109346 -0.338655,0.235464 -0.455199,0.757757 -0.25927,1.165625 0.19551,0.408372 0.629174,0.548229 0.96783,0.312255 0.08783,-0.06155 0.160883,-0.14189 0.217467,-0.234955 -0.02237,0.461773 -0.230979,0.901679 -0.588638,1.150367 -0.564566,0.39261 -1.287061,0.15918 -1.613471,-0.520769 -0.325145,-0.680454 -0.131747,-1.550096 0.432821,-1.943214 l 0,0 z m -8.4625961,1.183931 c 0.2575811,-0.179014 0.5603435,-0.177488 0.8077901,-0.02795 -0.068836,0.009 -0.1368128,0.03458 -0.2001525,0.07882 -0.2440687,0.169354 -0.327677,0.545687 -0.1866399,0.839639 0.1406128,0.293947 0.453088,0.394643 0.6971553,0.224782 0.063334,-0.04425 0.1161241,-0.102217 0.1570835,-0.16935 C 9.5527694,36.35966 9.4024339,36.676495 9.1452751,36.855507 8.7386349,37.138248 8.2179844,36.970431 7.983206,36.480169 7.7475821,35.990933 7.887351,35.363875 8.2939919,35.081114 z"
1017 id="path448"
1018 inkscape:connector-curvature="0" />
1019 <path
1020 d="m 11.148494,37.665629 c -0.260113,-0.748095 -0.420152,-1.550096 -0.46449,-2.376002 -0.533741,1.967118 -1.8647168,3.382956 -3.4389171,3.862529 0.4619579,0.354468 0.8876005,0.829465 1.2503252,1.416854 1.1793816,-0.417022 2.1776139,-1.463641 2.6530819,-2.903381 z"
1021 id="path450"
1022 inkscape:connector-curvature="0"
1023 style="fill:#eeeeee" />
1024 <path
1025 d="m 3.5654754,33.263516 c -0.2884063,0.139348 -0.5160068,0.432279 -0.656621,0.92355 -0.6697112,2.341929 -0.5459877,4.035438 0.033358,5.072397 C 3.09465,39.150129 3.25131,39.055528 3.4109259,38.975177 3.537183,38.886186 3.6659737,38.807859 3.7972979,38.739713 3.1153408,37.498312 2.8611376,35.923805 3.2065499,34.3732 3.2935369,33.980083 3.4151486,33.609339 3.5654746,33.263516 z"
1026 id="path457"
1027 style="fill:#f0a513"
1028 inkscape:connector-curvature="0" />
1029 <path
1030 d="m 9.6346789,48.851958 c 0.7959681,1.053234 2.8688621,0.917445 3.5212611,-0.268012 -0.352592,0.781151 -1.04046,1.31209 -1.830517,1.31209 -0.695891,0 -1.312395,-0.411935 -1.6907441,-1.044078 z"
1031 id="path459"
1032 inkscape:connector-curvature="0"
1033 style="fill:#ffffff" />
1034 </g>
1035 </g>
1036 </svg>
0 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
1 <!-- Created with Inkscape (http://www.inkscape.org/) -->
2
3 <svg
4 xmlns:dc="http://purl.org/dc/elements/1.1/"
5 xmlns:cc="http://creativecommons.org/ns#"
6 xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
7 xmlns:svg="http://www.w3.org/2000/svg"
8 xmlns="http://www.w3.org/2000/svg"
9 xmlns:xlink="http://www.w3.org/1999/xlink"
10 xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
11 xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
12 width="22"
13 height="22"
14 id="svg3720"
15 version="1.1"
16 inkscape:version="0.48.3.1 r9886"
17 sodipodi:docname="diodon.svg">
18 <defs
19 id="defs3722">
20 <radialGradient
21 inkscape:collect="always"
22 xlink:href="#SVGID_3_"
23 id="radialGradient3305"
24 gradientUnits="userSpaceOnUse"
25 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
26 cx="163.4902"
27 cy="274.86621"
28 r="2.8801" />
29 <radialGradient
30 gradientUnits="userSpaceOnUse"
31 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
32 r="2.8801"
33 cy="274.86621"
34 cx="163.4902"
35 id="SVGID_3_">
36 <stop
37 id="stop190"
38 style="stop-color:#FAF0BB"
39 offset="0.0112" />
40 <stop
41 id="stop192"
42 style="stop-color:#FAF0BD"
43 offset="0.4917" />
44 <stop
45 id="stop194"
46 style="stop-color:#FBF2C5"
47 offset="0.6648" />
48 <stop
49 id="stop196"
50 style="stop-color:#FCF6D0"
51 offset="0.7882" />
52 <stop
53 id="stop198"
54 style="stop-color:#FCF8E1"
55 offset="0.8879" />
56 <stop
57 id="stop200"
58 style="stop-color:#FFFDF7"
59 offset="0.9723" />
60 <stop
61 id="stop202"
62 style="stop-color:#FFFFFF"
63 offset="1" />
64 </radialGradient>
65 <radialGradient
66 inkscape:collect="always"
67 xlink:href="#SVGID_4_"
68 id="radialGradient3307"
69 gradientUnits="userSpaceOnUse"
70 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
71 cx="155.3242"
72 cy="310.6777"
73 r="4.4867001" />
74 <radialGradient
75 gradientUnits="userSpaceOnUse"
76 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
77 r="4.4867001"
78 cy="310.6777"
79 cx="155.3242"
80 id="SVGID_4_">
81 <stop
82 id="stop207"
83 style="stop-color:#FAF0BB"
84 offset="0.0112" />
85 <stop
86 id="stop209"
87 style="stop-color:#FAF0BD"
88 offset="0.4917" />
89 <stop
90 id="stop211"
91 style="stop-color:#FBF2C5"
92 offset="0.6648" />
93 <stop
94 id="stop213"
95 style="stop-color:#FCF6D0"
96 offset="0.7882" />
97 <stop
98 id="stop215"
99 style="stop-color:#FCF8E1"
100 offset="0.8879" />
101 <stop
102 id="stop217"
103 style="stop-color:#FFFDF7"
104 offset="0.9723" />
105 <stop
106 id="stop219"
107 style="stop-color:#FFFFFF"
108 offset="1" />
109 </radialGradient>
110 <radialGradient
111 inkscape:collect="always"
112 xlink:href="#SVGID_5_"
113 id="radialGradient3310"
114 gradientUnits="userSpaceOnUse"
115 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
116 cx="170.3125"
117 cy="302.00781"
118 r="5.0811" />
119 <radialGradient
120 gradientUnits="userSpaceOnUse"
121 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
122 r="5.0811"
123 cy="302.00781"
124 cx="170.3125"
125 id="SVGID_5_">
126 <stop
127 id="stop224"
128 style="stop-color:#FAF0BB"
129 offset="0.0112" />
130 <stop
131 id="stop226"
132 style="stop-color:#FAF0BD"
133 offset="0.4917" />
134 <stop
135 id="stop228"
136 style="stop-color:#FBF2C5"
137 offset="0.6648" />
138 <stop
139 id="stop230"
140 style="stop-color:#FCF6D0"
141 offset="0.7882" />
142 <stop
143 id="stop232"
144 style="stop-color:#FCF8E1"
145 offset="0.8879" />
146 <stop
147 id="stop234"
148 style="stop-color:#FFFDF7"
149 offset="0.9723" />
150 <stop
151 id="stop236"
152 style="stop-color:#FFFFFF"
153 offset="1" />
154 </radialGradient>
155 <radialGradient
156 inkscape:collect="always"
157 xlink:href="#SVGID_6_"
158 id="radialGradient3312"
159 gradientUnits="userSpaceOnUse"
160 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
161 cx="173.2812"
162 cy="283.68359"
163 r="2.8803999" />
164 <radialGradient
165 gradientUnits="userSpaceOnUse"
166 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
167 r="2.8803999"
168 cy="283.68359"
169 cx="173.2812"
170 id="SVGID_6_">
171 <stop
172 id="stop241"
173 style="stop-color:#FAF0BB"
174 offset="0.0112" />
175 <stop
176 id="stop243"
177 style="stop-color:#FAF0BD"
178 offset="0.4917" />
179 <stop
180 id="stop245"
181 style="stop-color:#FBF2C5"
182 offset="0.6648" />
183 <stop
184 id="stop247"
185 style="stop-color:#FCF6D0"
186 offset="0.7882" />
187 <stop
188 id="stop249"
189 style="stop-color:#FCF8E1"
190 offset="0.8879" />
191 <stop
192 id="stop251"
193 style="stop-color:#FFFDF7"
194 offset="0.9723" />
195 <stop
196 id="stop253"
197 style="stop-color:#FFFFFF"
198 offset="1" />
199 </radialGradient>
200 <radialGradient
201 inkscape:collect="always"
202 xlink:href="#SVGID_7_"
203 id="radialGradient3314"
204 gradientUnits="userSpaceOnUse"
205 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
206 cx="148.9492"
207 cy="270.04489"
208 r="2.8799" />
209 <radialGradient
210 gradientUnits="userSpaceOnUse"
211 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
212 r="2.8799"
213 cy="270.04489"
214 cx="148.9492"
215 id="SVGID_7_">
216 <stop
217 id="stop258"
218 style="stop-color:#FAF0BB"
219 offset="0.0112" />
220 <stop
221 id="stop260"
222 style="stop-color:#FAF0BD"
223 offset="0.4917" />
224 <stop
225 id="stop262"
226 style="stop-color:#FBF2C5"
227 offset="0.6648" />
228 <stop
229 id="stop264"
230 style="stop-color:#FCF6D0"
231 offset="0.7882" />
232 <stop
233 id="stop266"
234 style="stop-color:#FCF8E1"
235 offset="0.8879" />
236 <stop
237 id="stop268"
238 style="stop-color:#FFFDF7"
239 offset="0.9723" />
240 <stop
241 id="stop270"
242 style="stop-color:#FFFFFF"
243 offset="1" />
244 </radialGradient>
245 <radialGradient
246 inkscape:collect="always"
247 xlink:href="#SVGID_8_"
248 id="radialGradient3316"
249 gradientUnits="userSpaceOnUse"
250 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
251 cx="148.0723"
252 cy="319.09381"
253 r="3.9265001" />
254 <radialGradient
255 gradientUnits="userSpaceOnUse"
256 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
257 r="3.9265001"
258 cy="319.09381"
259 cx="148.0723"
260 id="SVGID_8_">
261 <stop
262 id="stop275"
263 style="stop-color:#FAF0BB"
264 offset="0.0112" />
265 <stop
266 id="stop277"
267 style="stop-color:#FAF0BD"
268 offset="0.4917" />
269 <stop
270 id="stop279"
271 style="stop-color:#FBF2C5"
272 offset="0.6648" />
273 <stop
274 id="stop281"
275 style="stop-color:#FCF6D0"
276 offset="0.7882" />
277 <stop
278 id="stop283"
279 style="stop-color:#FCF8E1"
280 offset="0.8879" />
281 <stop
282 id="stop285"
283 style="stop-color:#FFFDF7"
284 offset="0.9723" />
285 <stop
286 id="stop287"
287 style="stop-color:#FFFFFF"
288 offset="1" />
289 </radialGradient>
290 <radialGradient
291 inkscape:collect="always"
292 xlink:href="#SVGID_9_"
293 id="radialGradient3318"
294 gradientUnits="userSpaceOnUse"
295 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
296 cx="112.9551"
297 cy="315.56049"
298 r="3.0683999" />
299 <radialGradient
300 gradientUnits="userSpaceOnUse"
301 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
302 r="3.0683999"
303 cy="315.56049"
304 cx="112.9551"
305 id="SVGID_9_">
306 <stop
307 id="stop292"
308 style="stop-color:#FAF0BB"
309 offset="0.0112" />
310 <stop
311 id="stop294"
312 style="stop-color:#FAF0BD"
313 offset="0.4917" />
314 <stop
315 id="stop296"
316 style="stop-color:#FBF2C5"
317 offset="0.6648" />
318 <stop
319 id="stop298"
320 style="stop-color:#FCF6D0"
321 offset="0.7882" />
322 <stop
323 id="stop300"
324 style="stop-color:#FCF8E1"
325 offset="0.8879" />
326 <stop
327 id="stop302"
328 style="stop-color:#FFFDF7"
329 offset="0.9723" />
330 <stop
331 id="stop304"
332 style="stop-color:#FFFFFF"
333 offset="1" />
334 </radialGradient>
335 <radialGradient
336 inkscape:collect="always"
337 xlink:href="#SVGID_10_"
338 id="radialGradient3320"
339 gradientUnits="userSpaceOnUse"
340 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
341 cx="132.0938"
342 cy="320.1113"
343 r="4.1712999" />
344 <radialGradient
345 gradientUnits="userSpaceOnUse"
346 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
347 r="4.1712999"
348 cy="320.1113"
349 cx="132.0938"
350 id="SVGID_10_">
351 <stop
352 id="stop309"
353 style="stop-color:#FAF0BB"
354 offset="0.0112" />
355 <stop
356 id="stop311"
357 style="stop-color:#FAF0BD"
358 offset="0.4917" />
359 <stop
360 id="stop313"
361 style="stop-color:#FBF2C5"
362 offset="0.6648" />
363 <stop
364 id="stop315"
365 style="stop-color:#FCF6D0"
366 offset="0.7882" />
367 <stop
368 id="stop317"
369 style="stop-color:#FCF8E1"
370 offset="0.8879" />
371 <stop
372 id="stop319"
373 style="stop-color:#FFFDF7"
374 offset="0.9723" />
375 <stop
376 id="stop321"
377 style="stop-color:#FFFFFF"
378 offset="1" />
379 </radialGradient>
380 <radialGradient
381 inkscape:collect="always"
382 xlink:href="#SVGID_11_"
383 id="radialGradient3322"
384 gradientUnits="userSpaceOnUse"
385 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
386 cx="147.44189"
387 cy="301.21091"
388 r="2.5313001" />
389 <radialGradient
390 gradientUnits="userSpaceOnUse"
391 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
392 r="2.5313001"
393 cy="301.21091"
394 cx="147.44189"
395 id="SVGID_11_">
396 <stop
397 id="stop326"
398 style="stop-color:#FAF0BB"
399 offset="0.0112" />
400 <stop
401 id="stop328"
402 style="stop-color:#FAF0BD"
403 offset="0.4917" />
404 <stop
405 id="stop330"
406 style="stop-color:#FBF2C5"
407 offset="0.6648" />
408 <stop
409 id="stop332"
410 style="stop-color:#FCF6D0"
411 offset="0.7882" />
412 <stop
413 id="stop334"
414 style="stop-color:#FCF8E1"
415 offset="0.8879" />
416 <stop
417 id="stop336"
418 style="stop-color:#FFFDF7"
419 offset="0.9723" />
420 <stop
421 id="stop338"
422 style="stop-color:#FFFFFF"
423 offset="1" />
424 </radialGradient>
425 </defs>
426 <sodipodi:namedview
427 id="base"
428 pagecolor="#ffffff"
429 bordercolor="#666666"
430 borderopacity="1.0"
431 inkscape:pageopacity="0.0"
432 inkscape:pageshadow="2"
433 inkscape:zoom="22.395604"
434 inkscape:cx="1.9698115"
435 inkscape:cy="13.030678"
436 inkscape:current-layer="layer1"
437 showgrid="true"
438 inkscape:grid-bbox="true"
439 inkscape:document-units="px"
440 showborder="true"
441 borderlayer="false"
442 inkscape:window-width="1600"
443 inkscape:window-height="876"
444 inkscape:window-x="0"
445 inkscape:window-y="24"
446 inkscape:window-maximized="1"
447 gridtolerance="10"
448 objecttolerance="10"
449 guidetolerance="10">
450 <inkscape:grid
451 type="xygrid"
452 id="grid4738"
453 empspacing="5"
454 visible="true"
455 enabled="true"
456 snapvisiblegridlinesonly="true" />
457 </sodipodi:namedview>
458 <metadata
459 id="metadata3725">
460 <rdf:RDF>
461 <cc:Work
462 rdf:about="">
463 <dc:format>image/svg+xml</dc:format>
464 <dc:type
465 rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
466 <dc:title />
467 </cc:Work>
468 </rdf:RDF>
469 </metadata>
470 <g
471 id="layer1"
472 inkscape:label="Layer 1"
473 inkscape:groupmode="layer"
474 transform="translate(0,-10)">
475 <g
476 id="g3183"
477 transform="matrix(0.42456013,0,0,0.36190187,0.67263132,6.4999834)">
478 <path
479 d="m 47.748262,36.240641 c -0.304876,-0.669777 -0.939962,-2.526029 -1.264261,-3.180039 -0.499962,-1.005938 -2.409862,-0.340737 -2.850285,-1.402107 -0.615238,-1.481949 0.402841,-3.075783 -0.26687,-4.517046 -0.51052,-1.098494 -2.320767,-1.749962 -2.830861,-2.848458 -0.374128,-0.804542 0.05785,-5.080024 -0.915894,-3.703855 -1.643875,2.32362 -3.133623,4.929999 -4.51865,7.769812 -0.227178,-0.299544 -0.460268,-0.590441 -0.699692,-0.872694 l 1.273972,-2.395837 -1.94875,1.641638 C 33.517528,26.509306 33.303862,26.293167 33.085974,26.08364 l 0.936581,-2.162914 -1.564066,1.585187 C 31.923058,25.034986 31.365246,24.598131 30.785899,24.1984 l 1.168829,-5.78896 -2.873088,4.753021 C 28.796189,23.01091 28.507361,22.866987 28.213887,22.732727 l 0.283762,-3.540102 -1.360114,3.093074 C 25.924369,21.832064 24.65631,21.526925 23.350669,21.385545 l -0.349636,-4.806419 -1.226255,4.716403 c -0.0033,0 -0.0071,0 -0.01056,0 -1.422186,-0.0066 -2.818193,0.185117 -4.164371,0.553823 l -1.190787,-2.856081 0.196351,3.163762 c -0.403261,0.139347 -0.801035,0.294459 -1.193319,0.465334 l -0.676466,-1.193086 0.243647,1.388883 c -0.482226,0.226309 -0.954317,0.47703 -1.416273,0.750127 l -2.649288,-2.676561 1.488058,3.425166 c -0.733893,0.515174 -1.434852,1.088322 -2.09654,1.715887 -0.09374,0.089 -0.187063,0.180031 -0.279538,0.271064 l -2.6176137,-1.775898 1.7557735,2.685206 c -0.2643372,0.297002 -0.5214955,0.60519 -0.7718972,0.922533 l -2.0728961,-1.396004 1.4580788,2.215805 c -0.340767,0.479065 -0.6650662,0.978474 -0.9716305,1.49568 -1.2705932,0.251233 -2.4081735,1.157486 -3.0905527,2.497041 0.00253,-0.005 0.00508,-0.01071 0.00802,-0.01578 -0.5079841,0.01071 -0.9074462,0.311242 -1.1177337,1.046115 -0.7347402,2.568744 -0.5366981,4.375156 0.1689057,5.408554 -0.1199231,0.09664 -0.2373126,0.202409 -0.3517463,0.317854 -1.90145688,1.925922 -2.20548742,5.78845 -0.6790012,8.625208 0.8470624,1.574001 2.0796522,2.501617 3.3341996,2.686733 0.6452198,1.719448 1.4880601,3.337183 2.5116286,4.809977 3.3333522,4.799809 8.4203702,7.849148 14.2412852,7.722516 5.766442,-0.126125 10.741561,-3.352949 13.962593,-8.195477 2.268826,-3.410417 3.604027,-7.536378 3.803758,-11.87187 L 41.77997,42.904823 39.623044,42.4461 c 0.003,-0.734364 -0.02618,-1.473813 -0.08952,-2.215806 l 3.332089,-2.112565 -3.537731,0.400746 C 39.264542,38.110618 39.19107,37.708348 39.108306,37.31116 l 0.959807,-0.628583 -1.067483,0.13782 c -0.02618,-0.113909 -0.05278,-0.226818 -0.08023,-0.33972 2.756541,-0.434818 5.473393,-0.393116 8.225288,0.328024 0.699694,0.183591 0.893512,0.07272 0.602574,-0.568064 z M 3.2551113,34.170284 c -0.017313,0.06662 -0.033782,0.134262 -0.04856,0.202916 -0.0114,0.05139 -0.022381,0.102733 -0.032514,0.154602 0.010132,-0.05188 0.020692,-0.10325 0.032514,-0.154602 0.01478,-0.06866 0.031247,-0.136294 0.04856,-0.202916 z m 0.4049515,-1.11121 c -0.010132,0.02085 -0.020269,0.04223 -0.030404,0.06306 0.010132,-0.02085 0.02027,-0.04222 0.030404,-0.06306 z m -0.079808,0.172404 c -0.010557,0.02339 -0.020692,0.0473 -0.030825,0.07119 0.010132,-0.02389 0.02027,-0.04782 0.030825,-0.07119 z m -0.075164,0.177488 c -0.010557,0.02644 -0.021113,0.0529 -0.031248,0.07984 0.010132,-0.02694 0.020692,-0.0534 0.031248,-0.07984 z m -0.070097,0.182573 c -0.010979,0.03002 -0.021535,0.06 -0.032092,0.09001 0.010557,-0.03002 0.021113,-0.06002 0.032092,-0.09001 z m -0.06545,0.187661 c -0.01098,0.03407 -0.021535,0.06866 -0.032515,0.103238 0.010979,-0.03458 0.021113,-0.06866 0.032515,-0.103238 z m -0.059962,0.193252 c -0.011823,0.04119 -0.023225,0.08289 -0.034626,0.124599 0.0114,-0.04172 0.022381,-0.08342 0.034626,-0.124599 z m -0.2558905,1.703683 c -8.452e-4,0.05034 -8.452e-4,0.100695 -4.223e-4,0.150535 -4.223e-4,-0.05034 -4.223e-4,-0.100705 4.223e-4,-0.150535 z m 0.1106333,-1.097477 c -0.00633,0.03458 -0.012668,0.06866 -0.018578,0.103239 0.00591,-0.03407 0.012245,-0.06866 0.018578,-0.103239 z m -0.028713,0.164775 c -0.00507,0.03153 -0.010132,0.06256 -0.01478,0.09357 0.00464,-0.03101 0.00971,-0.06204 0.01478,-0.09357 z m -0.023646,0.15867 c -0.00423,0.03053 -0.00802,0.06053 -0.011823,0.09052 0.00379,-0.03052 0.0076,-0.06054 0.011823,-0.09052 z m -0.019423,0.156131 c -0.00338,0.03002 -0.00633,0.05949 -0.00929,0.0895 0.00296,-0.03002 0.00591,-0.05951 0.00929,-0.0895 z m -0.015624,0.155617 c -0.00253,0.03002 -0.00464,0.06001 -0.00717,0.09001 0.00253,-0.03002 0.00508,-0.06001 0.00717,-0.09001 z m -0.0114,0.154604 c -0.0017,0.03154 -0.00338,0.06256 -0.00507,0.09408 0.0017,-0.03153 0.00338,-0.06256 0.00507,-0.09408 z m -0.0076,0.154095 c -0.00127,0.03662 -0.00211,0.07322 -0.00296,0.109332 4.221e-4,-0.03662 0.00127,-0.07272 0.00296,-0.109332 z m 0.1634162,1.705207 c -0.0076,-0.03203 -0.01478,-0.06407 -0.021535,-0.09611 0.00718,0.03205 0.013934,0.06407 0.021535,0.09611 z m -0.037161,-0.168331 c -0.00802,-0.03865 -0.015624,-0.07728 -0.023225,-0.115944 0.0076,0.03865 0.015624,0.07729 0.023225,0.115944 z m -0.033785,-0.176983 c -0.00507,-0.02847 -0.010132,-0.05696 -0.01478,-0.08543 0.00464,0.02795 0.010132,0.05696 0.01478,0.08543 z m -0.024491,-0.152059 c -0.00423,-0.02694 -0.00844,-0.05392 -0.012245,-0.08138 0.00379,0.02694 0.0076,0.05442 0.012245,0.08138 z m -0.021113,-0.150025 c -0.00338,-0.02694 -0.00675,-0.0534 -0.00971,-0.08086 0.00296,0.02747 0.00633,0.05442 0.00971,0.08086 z m -0.017313,-0.149518 c -0.00296,-0.02694 -0.00549,-0.05392 -0.00802,-0.08137 0.00253,0.02747 0.00508,0.05441 0.00802,0.08137 z m -0.013934,-0.150024 c -0.00211,-0.02795 -0.00423,-0.05546 -0.00591,-0.08341 0.0017,0.02747 0.00379,0.05544 0.00591,0.08341 z m -0.010132,-0.150536 c -0.0017,-0.0295 -0.00296,-0.059 -0.00423,-0.0885 0.00127,0.0295 0.00253,0.05898 0.00423,0.0885 z m -0.00675,-0.15206 c -0.00127,-0.03356 -0.0017,-0.06765 -0.00211,-0.101717 0,0.03407 8.451e-4,0.06814 0.00211,0.101717 z m 0.180307,1.313616 c 0.00633,0.02644 0.012668,0.0529 0.019424,0.07882 -0.00633,-0.02644 -0.012668,-0.05239 -0.019424,-0.07882 z m 0.1811488,1.679273 c -0.00211,9.74e-4 -0.00423,0.0021 -0.00633,0.003 0,0 0,0 4.224e-4,0 0.015624,-0.01072 0.031247,-0.02137 0.046871,-0.03205 -0.013511,0.0097 -0.027025,0.01933 -0.04096,0.02896 z M 3.2745435,37.437285 c 0.00675,0.02492 0.013511,0.04984 0.020692,0.07476 -0.00717,-0.02492 -0.013934,-0.04984 -0.020692,-0.07476 z m 0.040537,0.141888 c 0.00717,0.0244 0.014357,0.04883 0.021957,0.07272 -0.00717,-0.0244 -0.014779,-0.04832 -0.021957,-0.07272 z m 0.043072,0.139347 c 0.00802,0.02389 0.015624,0.04782 0.023646,0.0717 -0.0076,-0.02389 -0.015624,-0.04728 -0.023646,-0.0717 z m 0.046449,0.137819 c 0.00844,0.02389 0.016891,0.04782 0.025758,0.07171 -0.00844,-0.02389 -0.017313,-0.0473 -0.025758,-0.07171 z m 0.049405,0.135789 c 0.00929,0.0244 0.019001,0.04883 0.028292,0.07322 -0.00929,-0.02441 -0.019001,-0.04831 -0.028292,-0.07322 z m 0.052361,0.134256 c 0.010979,0.02747 0.022803,0.05442 0.034203,0.08188 -0.0114,-0.02747 -0.023225,-0.05442 -0.034203,-0.08188 z m 0.055317,0.13223 c 0.018158,0.04223 0.037159,0.08491 0.056584,0.12663 -0.019001,-0.04223 -0.038005,-0.0844 -0.056584,-0.12663 z m 0.081498,0.178505 c 0.012245,0.02543 0.024491,0.05086 0.036737,0.07627 -0.012668,-0.02543 -0.024491,-0.05086 -0.036737,-0.07627 z m 0.065028,0.132734 c 0.011824,0.02339 0.023646,0.04678 0.035893,0.07019 -0.012246,-0.02339 -0.024069,-0.04678 -0.035893,-0.07019 z m 0.066295,0.12714 c 0.00802,0.01423 0.015624,0.029 0.023646,0.04272 -0.012668,0.0066 -0.025336,0.01272 -0.037582,0.01933 0.012246,-0.0066 0.02449,-0.01373 0.036737,-0.01983 -0.00802,-0.01373 -0.015202,-0.02797 -0.022803,-0.04223 z"
480 id="path5"
481 inkscape:connector-curvature="0" />
482 <path
483 d="m 46.872485,35.321668 c -0.295587,-0.574676 -0.59117,-1.149351 -0.887179,-1.724024 -0.411284,-0.79946 -2.442377,-0.780135 -2.853662,-1.579594 -0.640154,-1.243435 0.339923,-3.306671 -0.300232,-4.550104 -0.487293,-0.94745 -2.164949,-1.469746 -2.652242,-2.417196 -0.272784,-0.53043 -0.355546,-1.274964 -0.330633,-1.912193 0.05237,-1.364979 0.09627,-2.14664 -0.825104,-0.815224 -1.463147,2.115108 -2.790324,4.459071 -4.019957,7.001881 0.08403,0.130191 0.166794,0.262928 0.248715,0.39617 1.867674,-0.780645 3.579534,-1.925924 5.084062,-3.359053 -1.390517,1.582138 -3.033126,2.860154 -4.860686,3.733354 0.119078,0.203934 0.236469,0.410917 0.350057,0.620953 -0.87662,-1.47788 -1.904834,-2.797597 -3.043681,-3.931183 l -0.220844,0.510597 1.016812,-2.721313 -1.72115,1.539922 0.100502,-0.101717 c -0.426911,-0.375317 -0.869023,-0.727243 -1.324646,-1.05679 l -0.259691,1.287172 0.928137,-6.116986 -3.276349,4.782515 0.695047,-1.149347 C 27.064907,22.874104 25.27366,22.28112 23.39754,22.038534 l 0.05785,0.790309 -0.581035,-4.788622 -1.425989,4.509928 0.165107,-0.635193 c -0.02449,0 -0.04899,-9.74e-4 -0.07348,-9.74e-4 -2.69658,-0.0122 -5.297306,0.706904 -7.628628,2.005263 l 0.994011,1.003896 -3.222299,-2.891682 1.639229,4.403639 -0.736427,-1.695038 c -0.777812,0.531955 -1.518886,1.130533 -2.214777,1.791154 -0.5865257,0.556877 -1.1460249,1.161557 -1.6734311,1.809973 l 0.3800423,0.25581 -2.2287093,-1.303955 1.2275217,2.117143 -0.091631,-0.139345 c -0.260959,0.36159 -0.5122061,0.73538 -0.7533194,1.120363 0,0 4.226e-4,0 4.226e-4,0 0.058698,-0.0046 0.1178119,-0.0076 0.1769282,-0.0097 0.4197311,-0.01322 0.848329,0.04476 1.274816,0.182576 0.9543158,0.307679 1.753238,0.965757 2.327517,1.82777 1.042571,-3.636727 4.259803,-5.735561 7.393005,-4.724541 3.275504,1.057303 5.220032,5.114101 4.342567,9.059015 -0.238157,1.070014 -0.659578,2.022044 -1.212743,2.819977 0.07093,0.03205 0.14188,0.06509 0.212399,0.100705 0.08361,0.04223 0.165949,0.08645 0.247024,0.132733 -2.976541,-1.313107 -6.314119,0.418546 -7.548398,3.975938 -1.2347,3.558409 0.08783,7.634533 2.955006,9.262947 -0.08446,-0.03713 -0.168483,-0.07627 -0.252515,-0.118496 -3.038191,-1.529246 -4.4722,-5.736577 -3.202452,-9.39619 0.218733,-0.629601 0.502918,-1.20224 0.839884,-1.711309 -1.472858,-0.618921 -2.639575,-1.861338 -3.348979,-3.411436 -0.588214,1.277509 -1.5788438,2.193938 -2.71769,2.574851 0.033789,0.06461 0.067143,0.129174 0.099654,0.195797 1.344911,2.750302 0.9285586,6.379401 -0.9298248,8.103932 -0.051515,0.04782 -0.1038771,0.09407 -0.1566596,0.137821 h 0 c 0.026184,-0.02694 0.05236,-0.05442 0.078121,-0.08188 8.773e-4,-0.0014 0.00167,-0.0026 0.00296,-0.0036 0.024916,-0.02694 0.049402,-0.05442 0.073895,-0.08239 0.00128,-0.0021 0.00296,-0.0036 0.00462,-0.005 0.024071,-0.02795 0.047713,-0.05545 0.070937,-0.08341 0.00167,-0.0026 0.00384,-0.0046 0.0055,-0.0071 0.023227,-0.02796 0.045607,-0.05543 0.067989,-0.08391 0.00216,-0.003 0.00423,-0.0061 0.00675,-0.0086 0.021955,-0.02847 0.043919,-0.05646 0.065029,-0.08542 0.00251,-0.003 0.00512,-0.0066 0.0072,-0.0097 0.021109,-0.02847 0.042228,-0.05696 0.062493,-0.08645 0.00251,-0.0036 0.00512,-0.0072 0.00755,-0.01071 0.020265,-0.0295 0.040538,-0.05799 0.060379,-0.08797 0.00251,-0.004 0.00512,-0.0076 0.008,-0.01121 0.01942,-0.0295 0.038848,-0.05898 0.058277,-0.08899 0.00251,-0.0046 0.00549,-0.0086 0.008,-0.0122 0.018997,-0.03002 0.037589,-0.06 0.055741,-0.09052 0.00251,-0.0046 0.00549,-0.0086 0.008,-0.01272 0.018152,-0.03052 0.036322,-0.06103 0.054051,-0.09204 0.00251,-0.0046 0.00512,-0.009 0.008,-0.01322 0.017729,-0.03153 0.035054,-0.06204 0.052361,-0.09357 0.00251,-0.005 0.00513,-0.0097 0.00755,-0.01373 0.017306,-0.03153 0.033789,-0.06306 0.050253,-0.09508 0.00251,-0.005 0.00513,-0.0097 0.00755,-0.01423 0.016464,-0.03153 0.032521,-0.06407 0.048559,-0.09613 0.00213,-0.005 0.00455,-0.0097 0.00716,-0.01425 0.015622,-0.03253 0.031254,-0.06509 0.046458,-0.09816 0.00213,-0.0046 0.00426,-0.0097 0.00677,-0.01373 0.015206,-0.03304 0.030402,-0.06713 0.045191,-0.100694 0.00213,-0.004 0.00387,-0.009 0.0059,-0.01272 0.01478,-0.03409 0.029559,-0.06865 0.043913,-0.102733 0.00175,-0.0046 0.00329,-0.0086 0.00513,-0.0122 0.014354,-0.03508 0.028291,-0.07019 0.042229,-0.105275 0.00126,-0.004 0.003,-0.0082 0.00426,-0.0112 0.013937,-0.0356 0.027449,-0.07222 0.040961,-0.108333 8.768e-4,-0.003 0.00213,-0.0061 0.00329,-0.0097 0.013511,-0.03662 0.026607,-0.07425 0.039693,-0.111368 8.769e-4,-0.0026 0.00175,-0.005 0.00251,-0.0076 0.013085,-0.03815 0.026181,-0.07627 0.038425,-0.115439 0,-9.73e-4 4.229e-4,-0.0021 8.769e-4,-0.0026 0.1570825,-0.485678 0.2630703,-1.002882 0.3166975,-1.535857 4.228e-4,-0.004 8.777e-4,-0.0082 0.00124,-0.01118 0.00383,-0.03762 0.00713,-0.07528 0.010132,-0.113404 4.219e-4,-0.0082 0.00124,-0.01576 0.00217,-0.02389 0.003,-0.03458 0.00548,-0.06968 0.00755,-0.104238 8.767e-4,-0.01071 0.00176,-0.02238 0.00248,-0.03305 0.00217,-0.03253 0.00383,-0.06561 0.00548,-0.09816 4.218e-4,-0.01322 0.00124,-0.02644 0.00217,-0.03917 0.00176,-0.03153 0.00248,-0.06306 0.00383,-0.09459 4.229e-4,-0.01474 8.778e-4,-0.03002 0.00176,-0.04425 8.777e-4,-0.03052 0.00124,-0.06053 0.00217,-0.09052 4.228e-4,-0.01627 8.777e-4,-0.03253 8.777e-4,-0.04883 4.229e-4,-0.0295 4.229e-4,-0.05799 4.229e-4,-0.08747 0,-0.01728 0,-0.03459 0,-0.05239 0,-0.02847 -4.229e-4,-0.05644 -8.778e-4,-0.08492 0,-0.01831 -4.228e-4,-0.03611 -4.228e-4,-0.05441 -4.208e-4,-0.02796 -0.00124,-0.05544 -0.00217,-0.08339 -4.229e-4,-0.0188 -8.767e-4,-0.03763 -0.00176,-0.05645 -8.767e-4,-0.02694 -0.00217,-0.0534 -0.00331,-0.08086 -8.768e-4,-0.01984 -0.00176,-0.03918 -0.003,-0.05899 -0.00124,-0.02694 -0.003,-0.0529 -0.00455,-0.07935 -0.00124,-0.02032 -0.00248,-0.04068 -0.00383,-0.06053 -0.00176,-0.02644 -0.00383,-0.05238 -0.00589,-0.07832 -0.00176,-0.02085 -0.00331,-0.04119 -0.00517,-0.06204 -0.00217,-0.02594 -0.00455,-0.05138 -0.00713,-0.0768 -0.00176,-0.02136 -0.00424,-0.04222 -0.00631,-0.06307 -0.00248,-0.02543 -0.00548,-0.05086 -0.00842,-0.07577 -0.00251,-0.02185 -0.00513,-0.04323 -0.00755,-0.06461 -0.003,-0.02492 -0.0059,-0.04985 -0.00929,-0.07425 -0.003,-0.02185 -0.0059,-0.04375 -0.0089,-0.06561 -0.00329,-0.02492 -0.00677,-0.04934 -0.01056,-0.07425 -0.00329,-0.02185 -0.00677,-0.04425 -0.010132,-0.06612 -0.00387,-0.02439 -0.00755,-0.04883 -0.011401,-0.07322 -0.00387,-0.02237 -0.00755,-0.04476 -0.011401,-0.06661 -0.00426,-0.02441 -0.00842,-0.04831 -0.01267,-0.07221 -0.00426,-0.02288 -0.00842,-0.04526 -0.01267,-0.06765 -0.00455,-0.02389 -0.0089,-0.04782 -0.013937,-0.07119 -0.00455,-0.02288 -0.00929,-0.04526 -0.013938,-0.06815 -0.00513,-0.0234 -0.00971,-0.04729 -0.015206,-0.07069 -0.00513,-0.02288 -0.010132,-0.04576 -0.015206,-0.06866 -0.00513,-0.02288 -0.010549,-0.04629 -0.016047,-0.06915 -0.00552,-0.02339 -0.010976,-0.04629 -0.01688,-0.06915 -0.00552,-0.02288 -0.010975,-0.04576 -0.01688,-0.06814 -0.0059,-0.02339 -0.011827,-0.04678 -0.018148,-0.06968 -0.0059,-0.02288 -0.011818,-0.04527 -0.018148,-0.06765 -0.0063,-0.0234 -0.01267,-0.04628 -0.019416,-0.06968 -0.0063,-0.02238 -0.01267,-0.04425 -0.018999,-0.06661 -0.00677,-0.0234 -0.013937,-0.04678 -0.021109,-0.07019 -0.00677,-0.02185 -0.013086,-0.04374 -0.019842,-0.0656 -0.00755,-0.02389 -0.015206,-0.0473 -0.022804,-0.0707 -0.00677,-0.02136 -0.013937,-0.0427 -0.020683,-0.0646 -0.00803,-0.02339 -0.016038,-0.04679 -0.024071,-0.07069 -0.00755,-0.02085 -0.014354,-0.04222 -0.021952,-0.06306 -0.00842,-0.0244 -0.017306,-0.04831 -0.026181,-0.07221 -0.00755,-0.02031 -0.01478,-0.04069 -0.022378,-0.06103 -0.0089,-0.02441 -0.018574,-0.04883 -0.027875,-0.07272 -0.00755,-0.02032 -0.015206,-0.04018 -0.022804,-0.05949 -0.00971,-0.02492 -0.019842,-0.04933 -0.029985,-0.07425 -0.00803,-0.01865 -0.015622,-0.03799 -0.023645,-0.05732 -0.010975,-0.02594 -0.021952,-0.05188 -0.033363,-0.0768 -0.00755,-0.0178 -0.015206,-0.0351 -0.022804,-0.0529 -0.01267,-0.0295 -0.026182,-0.05799 -0.039267,-0.08696 -0.00677,-0.0137 -0.01267,-0.02845 -0.019416,-0.04219 C 8.552808,41.518875 8.532531,41.476167 8.511847,41.433436 7.1669757,38.683133 4.5692051,37.851124 2.7108196,39.57515 0.85243366,41.299176 0.436081,44.928276 1.7809934,47.678578 c 0.023225,0.04782 0.046871,0.0951 0.07094,0.140872 0.0076,0.01474 0.015624,0.0295 0.023225,0.04425 0.01689,0.03153 0.033358,0.06307 0.05025,0.09459 0.00887,0.01626 0.018158,0.03307 0.027448,0.04985 0.016468,0.0295 0.032514,0.05799 0.048982,0.08645 0.00929,0.01627 0.018578,0.03253 0.028291,0.04883 0.017735,0.03002 0.035048,0.0595 0.053205,0.0885 0.00844,0.01373 0.01689,0.02795 0.025336,0.04172 0.024491,0.03917 0.048983,0.07729 0.073473,0.115944 0.00211,0.0036 0.00423,0.0072 0.00633,0.01012 0.027025,0.0417 0.054894,0.0824 0.082765,0.123071 0.00802,0.01121 0.015624,0.02237 0.023646,0.03305 0.020269,0.02896 0.040538,0.05746 0.061228,0.08595 0.00971,0.01322 0.019424,0.02694 0.029136,0.03966 0.019423,0.02644 0.038848,0.05239 0.058271,0.07729 0.00971,0.01271 0.019847,0.02594 0.029981,0.03865 0.020692,0.02694 0.041381,0.0529 0.062496,0.0783 0.00887,0.01071 0.017735,0.02185 0.026181,0.03255 0.027025,0.03305 0.054473,0.06561 0.082342,0.09764 0.00253,0.003 0.00464,0.0061 0.00718,0.0086 0.031248,0.03611 0.062496,0.07119 0.094165,0.105779 0.00591,0.0066 0.011823,0.0122 0.017735,0.0188 0.025337,0.02747 0.050671,0.05392 0.076429,0.08086 0.00887,0.0097 0.018158,0.0183 0.027448,0.02796 0.023226,0.02339 0.046027,0.0468 0.069674,0.06969 0.00929,0.0097 0.019001,0.0183 0.028292,0.02796 0.024491,0.02339 0.048982,0.04678 0.073473,0.06915 0.00802,0.0076 0.016046,0.01474 0.024069,0.02238 0.031247,0.02847 0.062496,0.05645 0.094587,0.08391 0.00127,9.74e-4 0.00253,0.0021 0.00338,0.003 0.035048,0.03002 0.070097,0.05898 0.1051438,0.08747 0.0017,0.0014 0.00338,0.003 0.00508,0.0046 0.032091,0.02594 0.064184,0.05086 0.096698,0.07527 0.00718,0.0056 0.014357,0.01073 0.021535,0.01578 0.027448,0.02085 0.055317,0.04069 0.083186,0.0605 0.00802,0.0061 0.016046,0.01121 0.024069,0.01678 0.028293,0.02032 0.057006,0.03967 0.08572,0.059 0.00633,0.004 0.012668,0.0086 0.019424,0.0122 0.1072551,0.07119 0.2166217,0.135784 0.3268326,0.193761 0.00423,0.0021 0.00887,0.0046 0.01309,0.0066 0.032515,0.01678 0.064607,0.03307 0.097121,0.04883 0.0059,0.003 0.012246,0.0061 0.018158,0.009 0.032092,0.01524 0.064607,0.03052 0.096698,0.04425 0.00464,0.0021 0.00929,0.0046 0.014356,0.0066 0.1135892,0.04933 0.2284449,0.09256 0.3433009,0.128156 0.0017,5.1e-4 0.00338,9.74e-4 0.00549,0.0014 0.035892,0.0112 0.071785,0.02187 0.1076773,0.03154 0.00464,9.73e-4 0.00929,0.0026 0.013934,0.0036 0.034626,0.0097 0.068829,0.0178 0.1034547,0.02594 0.00379,9.74e-4 0.00802,0.0021 0.011824,0.003 0.1169673,0.02694 0.2343567,0.04679 0.3517462,0.05951 l 0,0 c 0.6481757,1.849131 1.52733,3.584344 2.6163505,5.151733 3.2493206,4.67828 8.2075476,7.650825 13.8810926,7.526736 5.62076,-0.12256 10.470044,-3.267511 13.60958,-7.987475 2.711782,-4.077649 4.055427,-9.202937 3.667366,-14.468077 l -0.625796,0.397186 3.441877,-2.497548 -4.004333,0.160197 0.94925,-0.107311 c -0.220421,-1.378712 -0.556544,-2.696396 -0.990631,-3.942371 0.168484,0.428718 0.325565,0.867097 0.469134,1.315141 2.798347,-0.571116 5.565447,-0.68554 8.28863,-0.151043 0.771477,0.153076 0.933204,0.41702 0.464491,-0.493815 z m -12.799679,3.703349 c -0.150327,4.243438 -1.599116,6.202419 -3.283952,6.35143 -0.291784,0.02594 -0.581036,-0.003 -0.882953,-0.08339 0.127101,0.01169 0.25378,0.01373 0.380461,0.005 0.947982,-0.0656 1.826292,-0.718089 2.438574,-2.048996 -1.654432,-1.002882 -3.38487,-1.607564 -5.059992,-1.826755 1.684833,0.07272 3.4651,0.599086 5.159647,1.598919 0.215777,-0.520259 0.393129,-1.134093 0.522342,-1.846589 -1.866407,-0.63926 -3.746752,-0.830988 -5.497882,-0.626039 1.72875,-0.355486 3.641185,-0.255806 5.541374,0.37074 0.08615,-0.535514 0.146526,-1.122905 0.176508,-1.764709 0.0114,-0.238514 -0.003,-0.451602 -0.03927,-0.641804 -2.009135,-0.114427 -3.941838,0.243602 -5.656652,0.971863 1.643451,-0.864048 3.568132,-1.320736 5.586133,-1.236826 -0.412129,-1.186475 -1.895967,-1.250044 -3.554621,-0.903205 2.210554,-0.579759 4.250091,-0.552808 4.170283,1.68029 z m 2.44111,-7.055789 c 1.92468,-0.563996 3.721414,-1.511446 5.334888,-2.770136 -1.510441,1.419396 -3.24806,2.506191 -5.138958,3.16783 -0.06418,-0.133245 -0.129212,-0.265977 -0.19593,-0.397694 z m 0.825526,1.842519 c -0.05574,-0.141379 -0.112746,-0.282252 -0.171017,-0.421598 1.999844,-0.298525 3.997577,-0.112402 5.887635,0.505511 -1.862188,-0.401765 -3.791937,-0.442449 -5.716618,-0.08392 z"
484 id="path14"
485 style="fill:#f0a513;fill-opacity:1"
486 inkscape:connector-curvature="0" />
487 <path
488 d="m 17.971864,28.383357 c 3.029325,0.977457 4.82775,4.729117 4.016157,8.37805 -0.214087,0.963215 -0.589481,1.823193 -1.080996,2.549419 -2.202109,-0.672827 -4.51105,0.238008 -5.964907,2.257001 -2.974852,-1.022212 -4.729782,-4.734713 -3.926214,-8.347029 0.811593,-3.648933 3.926636,-5.815407 6.95596,-4.837441 z"
489 id="path16"
490 inkscape:connector-curvature="0"
491 style="fill:#ffffff" />
492 <path
493 d="m 21.46948,31.675787 c 0.688291,1.496188 0.915048,3.303109 0.518541,5.08562 -0.214087,0.963215 -0.589481,1.823193 -1.080996,2.549419 -2.202532,-0.672827 -4.511474,0.238008 -5.965329,2.257001 -1.217389,-0.418038 -2.2304,-1.28768 -2.947405,-2.415671 0.307831,0.161723 0.630018,0.298527 0.964451,0.406343 3.605716,1.163589 7.313197,-1.414313 8.279337,-5.756922 0.157927,-0.710463 0.232246,-1.423974 0.231401,-2.12579 z"
494 id="path18"
495 inkscape:connector-curvature="0"
496 style="fill:#eeeeee" />
497 <path
498 d="m 11.148494,37.665629 c -0.473779,-1.361928 -0.61397,-2.903379 -0.33232,-4.44127 -0.52952,-1.020176 -1.3685584,-1.810482 -2.4090152,-2.146133 -2.1826849,-0.704357 -4.4270197,0.856418 -5.0118558,3.484667 -0.3242991,1.457031 -0.070517,2.936437 0.5915924,4.085786 1.0683288,-0.4694 2.2489802,-0.271571 3.2581915,0.503477 0.4619579,0.354468 0.8876005,0.829465 1.2503252,1.416854 1.1793816,-0.417022 2.1776139,-1.463641 2.6530819,-2.903381 z"
499 id="path20"
500 inkscape:connector-curvature="0"
501 style="fill:#ffffff" />
502 <path
503 d="m 31.2411,51.394259 1.26637,0.637229 -2.465178,-0.01373 c -4.530473,2.179698 -9.426207,2.60994 -12.629927,1.007461 -0.08825,-0.03864 -0.176507,-0.07984 -0.264338,-0.124092 -3.038191,-1.529243 -4.472201,-5.736578 -3.202453,-9.39619 0.218732,-0.6296 0.503339,-1.202239 0.840306,-1.710803 l 0,-5.07e-4 c -1.472857,-0.618925 -2.639574,-1.861849 -3.348978,-3.411437 -0.588215,1.277507 -1.5788467,2.193936 -2.7176907,2.574848 0.033779,0.06461 0.067143,0.129175 0.099655,0.195796 1.3449097,2.750303 0.9285573,6.379402 -0.9298254,8.103935 -0.051515,0.04782 -0.1038771,0.09408 -0.1566605,0.137821 l 0,0 c -0.048979,0.05034 -0.098387,0.09866 -0.1494812,0.145956 -0.7486746,0.694696 -1.6176949,0.974406 -2.4761587,0.880322 l 0,5.08e-4 c 0.6477536,1.848622 1.5273307,3.584344 2.6159279,5.151732 3.2493226,4.678262 8.2075486,7.650298 13.8810926,7.526717 5.620762,-0.12256 10.470046,-3.268018 13.609581,-7.987982 2.123568,-3.192243 3.407673,-7.028327 3.678768,-11.070884 -1.87021,3.185631 -4.634352,5.665888 -7.651009,7.353296 z"
504 id="path183"
505 style="fill:#fdd99b"
506 inkscape:connector-curvature="0" />
507 <path
508 d="m 11.261241,44.175223 c -0.158773,-0.250722 -0.250827,-0.566539 -0.243648,-0.906768 0.01224,-0.584846 0.312898,-1.079675 0.733895,-1.291745 -0.616928,0.507545 -0.839039,1.75098 -0.173129,2.336839 0.277429,0.243604 0.439579,0.574168 0.370749,1.028824 -0.05363,0.355991 -0.262648,0.802509 -0.591168,1.144265 -0.374972,0.389558 -0.833129,0.599593 -1.228791,0.541109 0.37835,-0.112404 0.757541,-0.387016 1.06284,-0.752165 0.26307,-0.314291 0.444644,-0.675369 0.519384,-0.97542 0.14906,-0.596542 -0.181995,-0.701818 -0.450132,-1.124939 l 0,0 z m 1.895122,4.408723 c -0.233935,0.931683 -0.952208,1.610106 -1.802226,1.610106 -0.765564,0 -1.4251397,-0.551279 -1.7190352,-1.342094 0.3783472,0.632143 0.9944302,1.044078 1.6907442,1.044078 0.790057,0 1.477502,-0.530939 1.830517,-1.31209 z"
509 id="path185"
510 inkscape:connector-curvature="0" />
511 <g
512 id="g187"
513 transform="matrix(0.42226435,0,0,0.50856192,-47.726977,-111.72952)">
514 <radialGradient
515 id="radialGradient3241"
516 cx="163.4902"
517 cy="274.86621"
518 r="2.8801"
519 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
520 gradientUnits="userSpaceOnUse">
521 <stop
522 offset="0.0112"
523 style="stop-color:#FAF0BB"
524 id="stop3243" />
525 <stop
526 offset="0.4917"
527 style="stop-color:#FAF0BD"
528 id="stop3245" />
529 <stop
530 offset="0.6648"
531 style="stop-color:#FBF2C5"
532 id="stop3247" />
533 <stop
534 offset="0.7882"
535 style="stop-color:#FCF6D0"
536 id="stop3249" />
537 <stop
538 offset="0.8879"
539 style="stop-color:#FCF8E1"
540 id="stop3251" />
541 <stop
542 offset="0.9723"
543 style="stop-color:#FFFDF7"
544 id="stop3253" />
545 <stop
546 offset="1"
547 style="stop-color:#FFFFFF"
548 id="stop3255" />
549 </radialGradient>
550 <path
551 d="m 189.806,311.298 c -0.681,-0.478 -1.432,-0.68 -2.1,-0.645 -0.633,0.034 -1.217,0.284 -1.625,0.739 -0.408,0.454 -0.59,1.052 -0.559,1.676 0.034,0.653 0.305,1.364 0.834,1.98 0.577,0.671 1.35,1.108 2.143,1.244 0.845,0.145 1.679,-0.06 2.247,-0.657 0.573,-0.604 0.725,-1.448 0.515,-2.282 -0.199,-0.789 -0.713,-1.534 -1.455,-2.055 z"
552 id="path204"
553 style="fill:url(#radialGradient3305)"
554 inkscape:connector-curvature="0" />
555 <radialGradient
556 id="radialGradient3258"
557 cx="155.3242"
558 cy="310.6777"
559 r="4.4867001"
560 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
561 gradientUnits="userSpaceOnUse">
562 <stop
563 offset="0.0112"
564 style="stop-color:#FAF0BB"
565 id="stop3260" />
566 <stop
567 offset="0.4917"
568 style="stop-color:#FAF0BD"
569 id="stop3262" />
570 <stop
571 offset="0.6648"
572 style="stop-color:#FBF2C5"
573 id="stop3264" />
574 <stop
575 offset="0.7882"
576 style="stop-color:#FCF6D0"
577 id="stop3266" />
578 <stop
579 offset="0.8879"
580 style="stop-color:#FCF8E1"
581 id="stop3268" />
582 <stop
583 offset="0.9723"
584 style="stop-color:#FFFDF7"
585 id="stop3270" />
586 <stop
587 offset="1"
588 style="stop-color:#FFFFFF"
589 id="stop3272" />
590 </radialGradient>
591 <path
592 d="m 183.164,274.256 c -0.777,-0.621 -1.774,-0.996 -2.853,-1 -1.077,-0.004 -2.096,0.366 -2.89,0.992 -0.839,0.661 -1.465,1.633 -1.646,2.791 -0.197,1.263 0.167,2.499 0.961,3.449 0.841,1.005 2.124,1.644 3.592,1.617 1.455,-0.026 2.71,-0.702 3.522,-1.716 0.762,-0.951 1.106,-2.168 0.913,-3.4 -0.179,-1.131 -0.786,-2.082 -1.599,-2.733 z"
593 id="path221"
594 style="fill:url(#radialGradient3307)"
595 inkscape:connector-curvature="0" />
596 <radialGradient
597 id="radialGradient3275"
598 cx="170.3125"
599 cy="302.00781"
600 r="5.0811"
601 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
602 gradientUnits="userSpaceOnUse">
603 <stop
604 offset="0.0112"
605 style="stop-color:#FAF0BB"
606 id="stop3277" />
607 <stop
608 offset="0.4917"
609 style="stop-color:#FAF0BD"
610 id="stop3279" />
611 <stop
612 offset="0.6648"
613 style="stop-color:#FBF2C5"
614 id="stop3281" />
615 <stop
616 offset="0.7882"
617 style="stop-color:#FCF6D0"
618 id="stop3283" />
619 <stop
620 offset="0.8879"
621 style="stop-color:#FCF8E1"
622 id="stop3285" />
623 <stop
624 offset="0.9723"
625 style="stop-color:#FFFDF7"
626 id="stop3287" />
627 <stop
628 offset="1"
629 style="stop-color:#FFFFFF"
630 id="stop3289" />
631 </radialGradient>
632 <path
633 d="m 197.254,290.925 c 1.482,-0.322 2.697,-1.225 3.201,-2.604 0.5,-1.367 0.166,-2.845 -0.726,-4.066 -0.835,-1.146 -2.134,-2.023 -3.647,-2.408 -1.389,-0.352 -2.723,-0.223 -3.781,0.238 -1.011,0.439 -1.812,1.196 -2.21,2.198 -0.397,1.001 -0.335,2.12 0.108,3.146 0.468,1.083 1.377,2.112 2.666,2.812 1.407,0.762 2.987,0.989 4.389,0.684 z"
634 id="path238"
635 style="fill:url(#radialGradient3310)"
636 inkscape:connector-curvature="0" />
637 <radialGradient
638 id="radialGradient3292"
639 cx="173.2812"
640 cy="283.68359"
641 r="2.8803999"
642 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
643 gradientUnits="userSpaceOnUse">
644 <stop
645 offset="0.0112"
646 style="stop-color:#FAF0BB"
647 id="stop3294" />
648 <stop
649 offset="0.4917"
650 style="stop-color:#FAF0BD"
651 id="stop3296" />
652 <stop
653 offset="0.6648"
654 style="stop-color:#FBF2C5"
655 id="stop3298" />
656 <stop
657 offset="0.7882"
658 style="stop-color:#FCF6D0"
659 id="stop3300" />
660 <stop
661 offset="0.8879"
662 style="stop-color:#FCF8E1"
663 id="stop3302" />
664 <stop
665 offset="0.9723"
666 style="stop-color:#FFFDF7"
667 id="stop3304" />
668 <stop
669 offset="1"
670 style="stop-color:#FFFFFF"
671 id="stop3306" />
672 </radialGradient>
673 <path
674 d="m 200.538,302.533 c -0.568,-0.598 -1.402,-0.802 -2.248,-0.657 -0.792,0.136 -1.565,0.573 -2.143,1.244 -0.529,0.616 -0.8,1.327 -0.833,1.98 -0.032,0.624 0.15,1.222 0.559,1.676 0.408,0.455 0.991,0.705 1.624,0.739 0.668,0.035 1.42,-0.167 2.101,-0.645 0.741,-0.521 1.256,-1.267 1.454,-2.056 0.21,-0.833 0.058,-1.677 -0.514,-2.281 z"
675 id="path255"
676 style="fill:url(#radialGradient3312)"
677 inkscape:connector-curvature="0" />
678 <radialGradient
679 id="radialGradient3309"
680 cx="148.9492"
681 cy="270.04489"
682 r="2.8799"
683 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
684 gradientUnits="userSpaceOnUse">
685 <stop
686 offset="0.0112"
687 style="stop-color:#FAF0BB"
688 id="stop3311" />
689 <stop
690 offset="0.4917"
691 style="stop-color:#FAF0BD"
692 id="stop3313" />
693 <stop
694 offset="0.6648"
695 style="stop-color:#FBF2C5"
696 id="stop3315" />
697 <stop
698 offset="0.7882"
699 style="stop-color:#FCF6D0"
700 id="stop3317" />
701 <stop
702 offset="0.8879"
703 style="stop-color:#FCF8E1"
704 id="stop3319" />
705 <stop
706 offset="0.9723"
707 style="stop-color:#FFFDF7"
708 id="stop3321" />
709 <stop
710 offset="1"
711 style="stop-color:#FFFFFF"
712 id="stop3323" />
713 </radialGradient>
714 <path
715 d="m 173.958,315.516 c -0.793,0.136 -1.566,0.573 -2.143,1.244 -0.529,0.616 -0.801,1.327 -0.834,1.98 -0.031,0.623 0.15,1.222 0.559,1.676 0.408,0.455 0.991,0.705 1.624,0.738 0.669,0.036 1.42,-0.166 2.101,-0.645 0.741,-0.521 1.256,-1.266 1.454,-2.055 0.211,-0.834 0.06,-1.679 -0.514,-2.282 -0.568,-0.598 -1.402,-0.801 -2.247,-0.656 z"
716 id="path272"
717 style="fill:url(#radialGradient3314)"
718 inkscape:connector-curvature="0" />
719 <radialGradient
720 id="radialGradient3326"
721 cx="148.0723"
722 cy="319.09381"
723 r="3.9265001"
724 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
725 gradientUnits="userSpaceOnUse">
726 <stop
727 offset="0.0112"
728 style="stop-color:#FAF0BB"
729 id="stop3328" />
730 <stop
731 offset="0.4917"
732 style="stop-color:#FAF0BD"
733 id="stop3330" />
734 <stop
735 offset="0.6648"
736 style="stop-color:#FBF2C5"
737 id="stop3332" />
738 <stop
739 offset="0.7882"
740 style="stop-color:#FCF6D0"
741 id="stop3334" />
742 <stop
743 offset="0.8879"
744 style="stop-color:#FCF8E1"
745 id="stop3336" />
746 <stop
747 offset="0.9723"
748 style="stop-color:#FFFDF7"
749 id="stop3338" />
750 <stop
751 offset="1"
752 style="stop-color:#FFFFFF"
753 id="stop3340" />
754 </radialGradient>
755 <path
756 d="m 171.282,272.336 c 1.106,0.549 2.333,0.68 3.407,0.405 1.136,-0.291 2.049,-1.022 2.398,-2.102 0.347,-1.069 0.048,-2.201 -0.675,-3.119 -0.678,-0.861 -1.706,-1.502 -2.885,-1.756 -1.083,-0.233 -2.109,-0.095 -2.914,0.291 -0.768,0.368 -1.365,0.975 -1.645,1.76 -0.278,0.785 -0.198,1.646 0.173,2.426 0.394,0.822 1.125,1.592 2.141,2.095 z"
757 id="path289"
758 style="fill:url(#radialGradient3316)"
759 inkscape:connector-curvature="0" />
760 <radialGradient
761 id="radialGradient3343"
762 cx="112.9551"
763 cy="315.56049"
764 r="3.0683999"
765 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
766 gradientUnits="userSpaceOnUse">
767 <stop
768 offset="0.0112"
769 style="stop-color:#FAF0BB"
770 id="stop3345" />
771 <stop
772 offset="0.4917"
773 style="stop-color:#FAF0BD"
774 id="stop3347" />
775 <stop
776 offset="0.6648"
777 style="stop-color:#FBF2C5"
778 id="stop3349" />
779 <stop
780 offset="0.7882"
781 style="stop-color:#FCF6D0"
782 id="stop3351" />
783 <stop
784 offset="0.8879"
785 style="stop-color:#FCF8E1"
786 id="stop3353" />
787 <stop
788 offset="0.9723"
789 style="stop-color:#FFFDF7"
790 id="stop3355" />
791 <stop
792 offset="1"
793 style="stop-color:#FFFFFF"
794 id="stop3357" />
795 </radialGradient>
796 <path
797 d="m 140.776,270.8 c -0.132,-0.306 -0.298,-0.603 -0.496,-0.884 0,0 -0.001,-10e-4 -0.001,-10e-4 -0.031,0.02 -0.061,0.042 -0.091,0.062 -0.1,0.067 -0.199,0.135 -0.298,0.203 -0.12,0.082 -0.24,0.163 -0.358,0.246 -0.123,0.085 -0.245,0.173 -0.366,0.26 -0.096,0.068 -0.193,0.136 -0.289,0.206 -0.146,0.106 -0.29,0.213 -0.434,0.321 -0.072,0.054 -0.145,0.106 -0.216,0.161 -0.215,0.163 -0.429,0.328 -0.641,0.495 -0.223,0.175 -0.443,0.354 -0.663,0.535 -0.064,0.053 -0.129,0.107 -0.194,0.161 -0.171,0.143 -0.341,0.287 -0.51,0.432 -0.054,0.046 -0.108,0.092 -0.162,0.139 -0.193,0.167 -0.384,0.337 -0.574,0.509 -0.098,0.088 -0.196,0.178 -0.293,0.268 -0.099,0.09 -0.196,0.182 -0.294,0.274 -0.079,0.074 -0.16,0.146 -0.238,0.222 0,0 0.001,0.001 0.001,0.001 0.177,0.156 0.363,0.299 0.555,0.429 0.596,0.402 1.257,0.671 1.927,0.786 1.185,0.202 2.356,-0.083 3.152,-0.922 0.804,-0.847 1.017,-2.032 0.722,-3.202 -0.06,-0.24 -0.14,-0.473 -0.239,-0.701 z"
798 id="path306"
799 style="fill:url(#radialGradient3318)"
800 inkscape:connector-curvature="0" />
801 <radialGradient
802 id="radialGradient3360"
803 cx="132.0938"
804 cy="320.1113"
805 r="4.1712999"
806 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
807 gradientUnits="userSpaceOnUse">
808 <stop
809 offset="0.0112"
810 style="stop-color:#FAF0BB"
811 id="stop3362" />
812 <stop
813 offset="0.4917"
814 style="stop-color:#FAF0BD"
815 id="stop3364" />
816 <stop
817 offset="0.6648"
818 style="stop-color:#FBF2C5"
819 id="stop3366" />
820 <stop
821 offset="0.7882"
822 style="stop-color:#FCF6D0"
823 id="stop3368" />
824 <stop
825 offset="0.8879"
826 style="stop-color:#FCF8E1"
827 id="stop3370" />
828 <stop
829 offset="0.9723"
830 style="stop-color:#FFFDF7"
831 id="stop3372" />
832 <stop
833 offset="1"
834 style="stop-color:#FFFFFF"
835 id="stop3374" />
836 </radialGradient>
837 <path
838 d="m 160.2,265.6 c -0.85,-0.392 -1.938,-0.592 -3.115,-0.521 -1.177,0.07 -2.29,0.405 -3.157,0.906 -0.916,0.53 -1.6,1.269 -1.798,2.11 -0.216,0.917 0.182,1.777 1.05,2.403 0.918,0.663 2.32,1.032 3.923,0.914 1.588,-0.118 2.959,-0.687 3.847,-1.468 0.833,-0.732 1.209,-1.627 0.998,-2.496 -0.195,-0.799 -0.859,-1.438 -1.748,-1.848 z"
839 id="path323"
840 style="fill:url(#radialGradient3320)"
841 inkscape:connector-curvature="0" />
842 <radialGradient
843 id="radialGradient3377"
844 cx="147.44189"
845 cy="301.21091"
846 r="2.5313001"
847 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
848 gradientUnits="userSpaceOnUse">
849 <stop
850 offset="0.0112"
851 style="stop-color:#FAF0BB"
852 id="stop3379" />
853 <stop
854 offset="0.4917"
855 style="stop-color:#FAF0BD"
856 id="stop3381" />
857 <stop
858 offset="0.6648"
859 style="stop-color:#FBF2C5"
860 id="stop3383" />
861 <stop
862 offset="0.7882"
863 style="stop-color:#FCF6D0"
864 id="stop3385" />
865 <stop
866 offset="0.8879"
867 style="stop-color:#FCF8E1"
868 id="stop3387" />
869 <stop
870 offset="0.9723"
871 style="stop-color:#FFFDF7"
872 id="stop3389" />
873 <stop
874 offset="1"
875 style="stop-color:#FFFFFF"
876 id="stop3391" />
877 </radialGradient>
878 <path
879 d="m 173.961,289.2 c 0.657,-0.143 1.12,-0.506 1.265,-1.029 0.133,-0.48 -0.03,-1.015 -0.381,-1.495 -0.335,-0.458 -0.853,-0.886 -1.498,-1.196 -0.645,-0.31 -1.333,-0.461 -1.94,-0.451 -0.643,0.011 -1.223,0.2 -1.576,0.587 -0.385,0.422 -0.428,0.996 -0.152,1.584 0.291,0.622 0.925,1.231 1.811,1.642 0.876,0.408 1.77,0.51 2.471,0.358 z"
880 id="path340"
881 style="fill:url(#radialGradient3322)"
882 inkscape:connector-curvature="0" />
883 </g>
884 <path
885 d="m 32.300561,46.79686 c -0.244913,-0.207495 -0.516006,-0.294969 -0.756275,-0.27971 -0.2276,0.01425 -0.437888,0.12307 -0.584836,0.320395 -0.147371,0.197321 -0.212822,0.456181 -0.201419,0.726735 0.01182,0.283777 0.109788,0.591457 0.300228,0.85845 0.207332,0.290901 0.486027,0.480592 0.771056,0.539586 0.304451,0.06256 0.605105,-0.02543 0.809057,-0.284794 0.206488,-0.26191 0.260961,-0.628075 0.185374,-0.989662 -0.07136,-0.342262 -0.256312,-0.665199 -0.523185,-0.891 z"
886 id="path347"
887 style="fill:#000000"
888 inkscape:connector-curvature="0" />
889 <g
890 id="g349"
891 transform="matrix(0.42226435,0,0,0.50856192,-47.726977,-111.72952)">
892 <path
893 d="m 168.559,264.427 c 4.145,0.407 8.127,1.382 11.858,2.845 l 0.623,-0.856 c -3.919,-1.741 -8.161,-2.906 -12.604,-3.384 l 0.123,1.395 z"
894 id="path351"
895 inkscape:connector-curvature="0"
896 style="fill:#ffffff" />
897 <path
898 d="m 145.971,266.73 1.059,0.888 c 5.193,-2.147 10.87,-3.351 16.738,-3.403 l 0.009,-0.038 0.435,-1.388 c -0.059,0 -0.116,-0.002 -0.175,-0.002 -6.387,-0.024 -12.545,1.39 -18.066,3.943 z"
899 id="path353"
900 inkscape:connector-curvature="0"
901 style="fill:#ffffff" />
902 <path
903 d="m 185.374,269.579 c 0.97,0.527 1.917,1.087 2.84,1.683 l 0.494,-0.416 c -1.011,-0.738 -2.058,-1.431 -3.138,-2.078 l -0.196,0.811 z"
904 id="path355"
905 inkscape:connector-curvature="0"
906 style="fill:#ffffff" />
907 <path
908 d="m 190.66,272.366 -0.224,0.429 c 0.458,0.338 0.91,0.683 1.354,1.038 1.494,1.193 2.916,2.493 4.25,3.889 -1.633,-1.962 -3.44,-3.752 -5.38,-5.356 z"
909 id="path357"
910 inkscape:connector-curvature="0"
911 style="fill:#ffffff" />
912 <path
913 d="m 140.28,269.916 c 0.198,0.281 0.363,0.578 0.496,0.884 0.84,-0.514 1.699,-1.002 2.575,-1.462 l -0.52,-0.994 c -0.871,0.494 -1.721,1.019 -2.551,1.572 z"
914 id="path359"
915 inkscape:connector-curvature="0"
916 style="fill:#ffffff" />
917 <path
918 d="m 133.625,275.426 0.562,0.314 c 0.338,-0.307 0.681,-0.608 1.028,-0.904 -0.192,-0.129 -0.378,-0.272 -0.555,-0.429 -0.35,0.333 -0.696,0.673 -1.035,1.019 z"
919 id="path361"
920 inkscape:connector-curvature="0"
921 style="fill:#ffffff" />
922 <path
923 d="m 130.152,279.456 c 0.139,-0.009 0.279,-0.015 0.419,-0.019 0.538,-0.62 1.091,-1.224 1.66,-1.81 l -0.295,-0.374 c -0.618,0.713 -1.212,1.447 -1.784,2.203 z"
924 id="path363"
925 inkscape:connector-curvature="0"
926 style="fill:#ffffff" />
927 </g>
928 <path
929 d="m 11.717707,25.989048 c -0.05574,-0.15562 -0.125834,-0.306666 -0.209444,-0.44957 -0.01309,0.01012 -0.02618,0.02032 -0.03885,0.03052 -0.04223,0.03408 -0.08403,0.06866 -0.125835,0.10324 -0.05067,0.0417 -0.101339,0.08289 -0.151171,0.125104 -0.05194,0.04324 -0.103455,0.08798 -0.154549,0.132228 -0.04054,0.03459 -0.0815,0.06916 -0.122034,0.104767 -0.06165,0.0534 -0.122457,0.108333 -0.183263,0.16325 -0.03041,0.02747 -0.06122,0.05392 -0.09122,0.08188 -0.09078,0.08288 -0.181151,0.166809 -0.27067,0.251737 -0.09416,0.0895 -0.187063,0.180031 -0.279961,0.272083 -0.02703,0.02695 -0.05447,0.05442 -0.08192,0.08188 -0.07221,0.07272 -0.1439917,0.145958 -0.2153547,0.219699 -0.02281,0.02339 -0.0456,0.04679 -0.068411,0.07019 -0.081499,0.08492 -0.1621494,0.171895 -0.24238,0.258858 -0.041385,0.04477 -0.08276,0.09052 -0.1237229,0.136294 -0.041799,0.04628 -0.08276,0.09308 -0.1241459,0.139347 -0.033364,0.03762 -0.066717,0.07527 -0.1000776,0.113908 0.074741,0.07935 0.1532821,0.152062 0.2343573,0.218175 C 9.5506288,27.855494 9.7347353,27.672921 9.9217999,27.495432 10.4927,26.95178 11.092737,26.44983 11.717689,25.989072 z"
930 id="path365"
931 inkscape:connector-curvature="0"
932 style="fill:#eeeeee" />
933 <path
934 d="m 28.381526,27.537111 c 0.388483,0.0014 0.747409,0.164265 1.026947,0.433802 0.293051,0.282252 0.512205,0.694697 0.575969,1.184949 0.06968,0.534499 -0.05447,1.061878 -0.328523,1.474322 -0.292629,0.439906 -0.744451,0.732838 -1.26806,0.744027 -0.528674,0.01119 -0.990631,-0.26547 -1.292973,-0.70131 -0.286295,-0.411932 -0.417197,-0.947959 -0.345834,-1.495681 0.06503,-0.501949 0.290517,-0.923546 0.592437,-1.209867 0.28545,-0.271063 0.652399,-0.431769 1.040037,-0.430242 z"
935 id="path372"
936 style="fill:#000000"
937 inkscape:connector-curvature="0" />
938 <path
939 d="m 13.466305,55.28374 c 0.178195,0.09256 0.329787,0.214614 0.43662,0.342772 0.111901,0.134768 0.178619,0.281236 0.168063,0.408885 -0.0114,0.139346 -0.111902,0.231394 -0.271518,0.261399 -0.170172,0.03153 -0.401994,-0.0082 -0.64353,-0.129175 -0.244069,-0.12256 -0.433666,-0.295472 -0.53712,-0.467367 -0.09797,-0.162232 -0.114433,-0.316834 -0.03674,-0.425668 0.07093,-0.100193 0.209021,-0.143413 0.37117,-0.13782 0.152859,0.005 0.334856,0.05491 0.513051,0.146974 l 0,0 z m -2.368059,-0.261399 c 0.05025,0.0122 0.09585,0.04017 0.130479,0.0768 0.03588,0.03815 0.06165,0.08797 0.06671,0.140364 0.0055,0.05696 -0.01435,0.10731 -0.05278,0.141381 -0.04097,0.0356 -0.101763,0.05188 -0.169749,0.03611 -0.06883,-0.01525 -0.127102,-0.05848 -0.163417,-0.113404 -0.03463,-0.05139 -0.04772,-0.110861 -0.03463,-0.164774 0.01183,-0.04984 0.04392,-0.08594 0.0853,-0.10578 0.03885,-0.01831 0.08741,-0.02339 0.138081,-0.01071 l 0,0 z m 3.807979,2.368373 c 0.09627,0.02389 0.183263,0.07728 0.248714,0.147481 0.06925,0.07322 0.117813,0.167318 0.127101,0.267506 0.01013,0.109332 -0.02745,0.204948 -0.100915,0.270045 -0.07854,0.06866 -0.194242,0.09866 -0.324299,0.06968 -0.131324,-0.03002 -0.24238,-0.111886 -0.311631,-0.216139 -0.06545,-0.09816 -0.09122,-0.21156 -0.0663,-0.314799 0.02281,-0.09459 0.08446,-0.163757 0.162995,-0.2019 0.07515,-0.03611 0.16806,-0.04576 0.264336,-0.02185 l 0,0 z m -2.357501,-1.035942 c -0.09333,-0.04831 -0.188754,-0.07425 -0.269405,-0.0768 -0.08487,-0.003 -0.157504,0.01983 -0.194242,0.07222 -0.04054,0.05696 -0.03209,0.137821 0.01942,0.222749 0.05405,0.09052 0.153704,0.18054 0.281651,0.245128 0.126679,0.06356 0.247869,0.08391 0.337388,0.06765 0.08362,-0.01576 0.136392,-0.06407 0.142304,-0.137313 0.0055,-0.06713 -0.02956,-0.143414 -0.08783,-0.214102 -0.05658,-0.06714 -0.135969,-0.13121 -0.22929,-0.179526 z"
940 id="path374"
941 inkscape:connector-curvature="0"
942 style="fill:#d9bb7a" />
943 <path
944 d="m 32.89722,32.895826 c 0.143148,-0.434312 0.431555,-0.762333 0.795547,-0.953043 0.380884,-0.199865 0.861841,-0.255808 1.361803,-0.10325 0.544721,0.166808 1.012166,0.547722 1.313242,1.044079 0.320921,0.529412 0.440844,1.170201 0.26096,1.762675 -0.181574,0.59807 -0.618618,0.989661 -1.15236,1.129517 -0.504607,0.132224 -1.073818,0.03356 -1.579691,-0.297003 -0.464491,-0.303099 -0.791747,-0.749617 -0.960229,-1.219019 -0.160039,-0.444994 -0.182419,-0.929651 -0.03927,-1.363962 z"
945 id="path381"
946 style="fill:#000000"
947 inkscape:connector-curvature="0" />
948 <path
949 d="m 35.093418,44.08063 c -0.146948,-0.197323 -0.212399,-0.456178 -0.200998,-0.726732 0.01182,-0.28378 0.109367,-0.591461 0.299807,-0.858457 0.207754,-0.290895 0.486028,-0.480589 0.771477,-0.540093 0.304453,-0.06256 0.604685,0.02594 0.809059,0.285306 0.206487,0.261909 0.26096,0.628075 0.184952,0.989659 -0.07137,0.342262 -0.256313,0.6652 -0.523607,0.891001 -0.244913,0.207492 -0.515586,0.294965 -0.755853,0.27971 -0.227601,-0.01423 -0.437466,-0.123072 -0.584837,-0.320394 z"
950 id="path388"
951 style="fill:#000000"
952 inkscape:connector-curvature="0" />
953 <path
954 d="m 24.819304,51.017414 c -0.147371,-0.197322 -0.212821,-0.456179 -0.201421,-0.727243 0.01183,-0.283269 0.10979,-0.590948 0.30023,-0.858455 0.207333,-0.290896 0.485604,-0.481098 0.771055,-0.540089 0.304453,-0.06256 0.605106,0.02594 0.809059,0.285303 0.206487,0.261908 0.260959,0.628074 0.184952,0.989661 -0.07136,0.342263 -0.256314,0.6652 -0.523608,0.891002 -0.24449,0.207493 -0.515584,0.294964 -0.755854,0.279709 -0.2276,-0.01425 -0.437465,-0.123071 -0.584413,-0.319888 z"
955 id="path395"
956 style="fill:#000000"
957 inkscape:connector-curvature="0" />
958 <path
959 d="m 23.786446,24.445052 c 0.102186,-0.347855 0.322609,-0.616885 0.605104,-0.779624 0.296007,-0.170876 0.673933,-0.232414 1.072129,-0.128666 0.433667,0.112897 0.812438,0.396678 1.061996,0.778609 0.266026,0.406849 0.376235,0.908289 0.24829,1.382269 -0.12879,0.47805 -0.464913,0.802512 -0.882532,0.931685 -0.395661,0.12205 -0.84664,0.06357 -1.254126,-0.17952 -0.374125,-0.222751 -0.642686,-0.563996 -0.787099,-0.928635 -0.137237,-0.346331 -0.166373,-0.728261 -0.06377,-1.076118 z"
960 id="path402"
961 style="fill:#000000"
962 inkscape:connector-curvature="0" />
963 <path
964 d="m 9.3572511,27.571182 c 0.2537814,0.256316 0.5518992,0.424651 0.8555069,0.487204 0.426486,0.08747 0.848329,-0.03611 1.135047,-0.399731 0.28925,-0.367181 0.366103,-0.880828 0.259692,-1.388372 -0.0456,-0.217666 -0.123723,-0.429227 -0.230557,-0.625532 -0.344568,0.281745 -0.680268,0.577726 -1.006255,0.886932 -0.347524,0.330057 -0.6857564,0.676897 -1.0134339,1.039499 z"
965 id="path409"
966 style="fill:#000000"
967 inkscape:connector-curvature="0" />
968 <path
969 d="m 9.3572511,27.571182 c 0.081923,0.08289 0.1684839,0.15664 0.2584255,0.220208 0.1013389,-0.100194 0.2031087,-0.199865 0.3061417,-0.296999 0.5244517,-0.497883 1.0733947,-0.962708 1.6434517,-1.391936 -0.04604,-0.15867 -0.109367,-0.312257 -0.188752,-0.457195 l 0,0 c -0.02997,0.02442 -0.05996,0.04933 -0.08995,0.07425 -0.01942,0.01628 -0.03927,0.03255 -0.05869,0.04883 -0.03336,0.02747 -0.0663,0.05545 -0.09923,0.08341 l -0.04519,0.03865 c -0.03758,0.03205 -0.07474,0.06407 -0.111899,0.09613 l -0.02997,0.02594 c -0.04139,0.03611 -0.08235,0.07221 -0.123301,0.108332 l -0.02026,0.01832 c -0.04392,0.03918 -0.08741,0.07781 -0.130901,0.117485 l -0.01309,0.01169 c -0.04603,0.04223 -0.09206,0.08442 -0.13808,0.12714 l -0.0018,0.0014 c -0.04815,0.04476 -0.09585,0.0895 -0.143569,0.134769 -0.07685,0.07322 -0.15286,0.146467 -0.228867,0.221226 l -0.01098,0.01072 c -0.02026,0.02032 -0.04097,0.04018 -0.06123,0.06051 l -0.01858,0.01882 -0.05236,0.05238 -0.02956,0.03002 -0.04307,0.04376 -0.03801,0.03865 -0.01605,0.01627 -0.01562,0.01627 -0.04771,0.04883 -0.01562,0.01627 C 9.6459492,27.256383 9.50069,27.412511 9.3571211,27.571183 z"
970 id="path411"
971 inkscape:connector-curvature="0"
972 style="fill:#888678" />
973 <path
974 d="m 18.571057,23.295194 c 0.423955,-0.03051 0.815816,0.05645 1.121534,0.226311 0.320077,0.177997 0.559079,0.455163 0.629176,0.800985 0.07601,0.376844 -0.05954,0.764369 -0.359348,1.082221 -0.319232,0.338701 -0.812859,0.585354 -1.385028,0.636719 -0.577235,0.05138 -1.081841,-0.108827 -1.412472,-0.39617 -0.312477,-0.271573 -0.456047,-0.644349 -0.378351,-1.042043 0.07136,-0.364639 0.317965,-0.685034 0.647333,-0.914395 0.312897,-0.217665 0.713204,-0.363114 1.137156,-0.393628 z"
975 id="path418"
976 style="fill:#000000"
977 inkscape:connector-curvature="0" />
978 <path
979 d="m 25.268593,33.539157 c 0.209865,0.121549 0.37835,0.289372 0.487716,0.468895 0.11401,0.188169 0.167216,0.397695 0.123723,0.585864 -0.04687,0.20495 -0.198043,0.347856 -0.412131,0.403289 -0.228021,0.05951 -0.519383,0.01933 -0.804835,-0.139854 -0.288406,-0.160707 -0.494471,-0.399731 -0.589482,-0.643842 -0.08995,-0.230376 -0.07601,-0.455669 0.04941,-0.620952 0.114856,-0.152061 0.304451,-0.226311 0.51305,-0.230379 0.198043,-0.0036 0.422688,0.05543 0.632553,0.176979 z"
980 id="path425"
981 style="fill:#000000"
982 inkscape:connector-curvature="0" />
983 <polygon
984 points="182.526,321.973 188.385,321.662 183.827,319.426 190.01,322.008 "
985 id="polygon427"
986 transform="matrix(0.42226435,0,0,0.50856192,-47.726977,-111.72952)" />
987 <polygon
988 points="176.606,313.919 181.161,310.218 176.159,311.094 182.677,309.541 "
989 id="polygon429"
990 transform="matrix(0.42226435,0,0,0.50856192,-47.726977,-111.72952)" />
991 <polygon
992 points="180.144,285.178 188.996,281.271 183.955,287.956 191.129,279.553 "
993 id="polygon431"
994 transform="matrix(0.42226435,0,0,0.50856192,-47.726977,-111.72952)" />
995 <path
996 d="m 35.589578,54.524966 c -0.122034,0.197832 -0.247447,0.39312 -0.376237,0.586373 -3.139958,4.719964 -7.989242,7.864909 -13.609581,7.987982 C 15.929794,63.222902 10.97199,60.250356 7.7226683,55.572603 7.5229375,55.285266 7.3303849,54.991318 7.1445881,54.693299 c 3.5503959,4.555698 8.6741509,7.392458 14.4832419,7.265826 5.617804,-0.123069 10.532541,-3.002548 13.961748,-7.434159 z"
997 id="path440"
998 style="fill:#d9bb7a"
999 inkscape:connector-curvature="0" />
1000 <path
1001 d="m 16.345302,52.251694 c -2.117655,-1.929991 -2.971052,-5.408047 -1.900189,-8.495019 1.184029,-3.41245 4.302452,-5.144614 7.182295,-4.121385 -2.791167,-0.695713 -5.69128,1.060859 -6.831394,4.34617 -1.023146,2.94966 -0.321343,6.249209 1.549288,8.270234 z"
1002 id="path442"
1003 inkscape:connector-curvature="0"
1004 style="fill:#ffffff" />
1005 <path
1006 d="m 7.9004418,49.211004 c 1.5839109,-1.826246 1.8765395,-5.188352 0.611861,-7.774387 -0.9606515,-1.964067 -2.560189,-2.949661 -4.0731622,-2.724366 1.4428771,-0.03307 2.911513,0.974913 3.8219146,2.837267 1.2266751,2.507718 1.0299008,5.725391 -0.3606134,7.661486 z"
1007 id="path444"
1008 inkscape:connector-curvature="0"
1009 style="fill:#ffffff" />
1010 <path
1011 d="m 46.744961,35.073491 -0.497006,-0.879306 c -0.446333,-0.789288 -2.616772,-1.271403 -3.063106,-2.060692 -0.04897,-0.08645 -0.08995,-0.178504 -0.124145,-0.273607 0.02111,0.05392 0.04434,0.106285 0.07093,0.157655 0.411286,0.799459 2.442378,0.780134 2.853664,1.579592 l 0.759653,1.476358 0,0 z m -3.840919,-4.235306 c -0.02154,-1.142737 0.276584,-2.476187 -0.211554,-3.339725 -0.684068,-1.210379 -3.109133,-1.708769 -3.070285,-3.678937 0.02618,-1.300901 0.05531,-2.044928 -0.877888,-0.830484 -0.474202,0.616888 -0.933204,1.256658 -1.378271,1.918806 0.532898,-0.895579 1.084376,-1.758098 1.656966,-2.58553 0.921382,-1.331414 0.877043,-0.549754 0.825104,0.815225 -0.02492,0.63723 0.05786,1.381764 0.330634,1.912701 0.487293,0.947452 2.164949,1.469236 2.652243,2.416687 0.464492,0.901679 0.07769,2.233605 0.07305,3.371257 z"
1012 id="path446"
1013 inkscape:connector-curvature="0"
1014 style="fill:#ffffff" />
1015 <path
1016 d="m 16.756588,33.897186 c 0.357235,-0.248687 0.77781,-0.246145 1.121111,-0.03865 -0.09501,0.0122 -0.189596,0.04832 -0.27785,0.109346 -0.338655,0.235464 -0.455199,0.757757 -0.25927,1.165625 0.19551,0.408372 0.629174,0.548229 0.96783,0.312255 0.08783,-0.06155 0.160883,-0.14189 0.217467,-0.234955 -0.02237,0.461773 -0.230979,0.901679 -0.588638,1.150367 -0.564566,0.39261 -1.287061,0.15918 -1.613471,-0.520769 -0.325145,-0.680454 -0.131747,-1.550096 0.432821,-1.943214 l 0,0 z m -8.4625961,1.183931 c 0.2575811,-0.179014 0.5603435,-0.177488 0.8077901,-0.02795 -0.068836,0.009 -0.1368128,0.03458 -0.2001525,0.07882 -0.2440687,0.169354 -0.327677,0.545687 -0.1866399,0.839639 0.1406128,0.293947 0.453088,0.394643 0.6971553,0.224782 0.063334,-0.04425 0.1161241,-0.102217 0.1570835,-0.16935 C 9.5527694,36.35966 9.4024339,36.676495 9.1452751,36.855507 8.7386349,37.138248 8.2179844,36.970431 7.983206,36.480169 7.7475821,35.990933 7.887351,35.363875 8.2939919,35.081114 z"
1017 id="path448"
1018 inkscape:connector-curvature="0" />
1019 <path
1020 d="m 11.148494,37.665629 c -0.260113,-0.748095 -0.420152,-1.550096 -0.46449,-2.376002 -0.533741,1.967118 -1.8647168,3.382956 -3.4389171,3.862529 0.4619579,0.354468 0.8876005,0.829465 1.2503252,1.416854 1.1793816,-0.417022 2.1776139,-1.463641 2.6530819,-2.903381 z"
1021 id="path450"
1022 inkscape:connector-curvature="0"
1023 style="fill:#eeeeee" />
1024 <path
1025 d="m 3.5654754,33.263516 c -0.2884063,0.139348 -0.5160068,0.432279 -0.656621,0.92355 -0.6697112,2.341929 -0.5459877,4.035438 0.033358,5.072397 C 3.09465,39.150129 3.25131,39.055528 3.4109259,38.975177 3.537183,38.886186 3.6659737,38.807859 3.7972979,38.739713 3.1153408,37.498312 2.8611376,35.923805 3.2065499,34.3732 3.2935369,33.980083 3.4151486,33.609339 3.5654746,33.263516 z"
1026 id="path457"
1027 style="fill:#f0a513"
1028 inkscape:connector-curvature="0" />
1029 <path
1030 d="m 9.6346789,48.851958 c 0.7959681,1.053234 2.8688621,0.917445 3.5212611,-0.268012 -0.352592,0.781151 -1.04046,1.31209 -1.830517,1.31209 -0.695891,0 -1.312395,-0.411935 -1.6907441,-1.044078 z"
1031 id="path459"
1032 inkscape:connector-curvature="0"
1033 style="fill:#ffffff" />
1034 </g>
1035 </g>
1036 </svg>
0 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
1 <!-- Created with Inkscape (http://www.inkscape.org/) -->
2
3 <svg
4 xmlns:dc="http://purl.org/dc/elements/1.1/"
5 xmlns:cc="http://creativecommons.org/ns#"
6 xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
7 xmlns:svg="http://www.w3.org/2000/svg"
8 xmlns="http://www.w3.org/2000/svg"
9 xmlns:xlink="http://www.w3.org/1999/xlink"
10 xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
11 xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
12 width="24"
13 height="24"
14 id="svg3720"
15 version="1.1"
16 inkscape:version="0.48.3.1 r9886"
17 sodipodi:docname="diodon-panel.svg">
18 <defs
19 id="defs3722">
20 <radialGradient
21 inkscape:collect="always"
22 xlink:href="#SVGID_3_"
23 id="radialGradient3305"
24 gradientUnits="userSpaceOnUse"
25 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
26 cx="163.4902"
27 cy="274.86621"
28 r="2.8801" />
29 <radialGradient
30 gradientUnits="userSpaceOnUse"
31 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
32 r="2.8801"
33 cy="274.86621"
34 cx="163.4902"
35 id="SVGID_3_">
36 <stop
37 id="stop190"
38 style="stop-color:#FAF0BB"
39 offset="0.0112" />
40 <stop
41 id="stop192"
42 style="stop-color:#FAF0BD"
43 offset="0.4917" />
44 <stop
45 id="stop194"
46 style="stop-color:#FBF2C5"
47 offset="0.6648" />
48 <stop
49 id="stop196"
50 style="stop-color:#FCF6D0"
51 offset="0.7882" />
52 <stop
53 id="stop198"
54 style="stop-color:#FCF8E1"
55 offset="0.8879" />
56 <stop
57 id="stop200"
58 style="stop-color:#FFFDF7"
59 offset="0.9723" />
60 <stop
61 id="stop202"
62 style="stop-color:#FFFFFF"
63 offset="1" />
64 </radialGradient>
65 <radialGradient
66 inkscape:collect="always"
67 xlink:href="#SVGID_4_"
68 id="radialGradient3307"
69 gradientUnits="userSpaceOnUse"
70 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
71 cx="155.3242"
72 cy="310.6777"
73 r="4.4867001" />
74 <radialGradient
75 gradientUnits="userSpaceOnUse"
76 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
77 r="4.4867001"
78 cy="310.6777"
79 cx="155.3242"
80 id="SVGID_4_">
81 <stop
82 id="stop207"
83 style="stop-color:#FAF0BB"
84 offset="0.0112" />
85 <stop
86 id="stop209"
87 style="stop-color:#FAF0BD"
88 offset="0.4917" />
89 <stop
90 id="stop211"
91 style="stop-color:#FBF2C5"
92 offset="0.6648" />
93 <stop
94 id="stop213"
95 style="stop-color:#FCF6D0"
96 offset="0.7882" />
97 <stop
98 id="stop215"
99 style="stop-color:#FCF8E1"
100 offset="0.8879" />
101 <stop
102 id="stop217"
103 style="stop-color:#FFFDF7"
104 offset="0.9723" />
105 <stop
106 id="stop219"
107 style="stop-color:#FFFFFF"
108 offset="1" />
109 </radialGradient>
110 <radialGradient
111 inkscape:collect="always"
112 xlink:href="#SVGID_5_"
113 id="radialGradient3310"
114 gradientUnits="userSpaceOnUse"
115 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
116 cx="170.3125"
117 cy="302.00781"
118 r="5.0811" />
119 <radialGradient
120 gradientUnits="userSpaceOnUse"
121 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
122 r="5.0811"
123 cy="302.00781"
124 cx="170.3125"
125 id="SVGID_5_">
126 <stop
127 id="stop224"
128 style="stop-color:#FAF0BB"
129 offset="0.0112" />
130 <stop
131 id="stop226"
132 style="stop-color:#FAF0BD"
133 offset="0.4917" />
134 <stop
135 id="stop228"
136 style="stop-color:#FBF2C5"
137 offset="0.6648" />
138 <stop
139 id="stop230"
140 style="stop-color:#FCF6D0"
141 offset="0.7882" />
142 <stop
143 id="stop232"
144 style="stop-color:#FCF8E1"
145 offset="0.8879" />
146 <stop
147 id="stop234"
148 style="stop-color:#FFFDF7"
149 offset="0.9723" />
150 <stop
151 id="stop236"
152 style="stop-color:#FFFFFF"
153 offset="1" />
154 </radialGradient>
155 <radialGradient
156 inkscape:collect="always"
157 xlink:href="#SVGID_6_"
158 id="radialGradient3312"
159 gradientUnits="userSpaceOnUse"
160 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
161 cx="173.2812"
162 cy="283.68359"
163 r="2.8803999" />
164 <radialGradient
165 gradientUnits="userSpaceOnUse"
166 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
167 r="2.8803999"
168 cy="283.68359"
169 cx="173.2812"
170 id="SVGID_6_">
171 <stop
172 id="stop241"
173 style="stop-color:#FAF0BB"
174 offset="0.0112" />
175 <stop
176 id="stop243"
177 style="stop-color:#FAF0BD"
178 offset="0.4917" />
179 <stop
180 id="stop245"
181 style="stop-color:#FBF2C5"
182 offset="0.6648" />
183 <stop
184 id="stop247"
185 style="stop-color:#FCF6D0"
186 offset="0.7882" />
187 <stop
188 id="stop249"
189 style="stop-color:#FCF8E1"
190 offset="0.8879" />
191 <stop
192 id="stop251"
193 style="stop-color:#FFFDF7"
194 offset="0.9723" />
195 <stop
196 id="stop253"
197 style="stop-color:#FFFFFF"
198 offset="1" />
199 </radialGradient>
200 <radialGradient
201 inkscape:collect="always"
202 xlink:href="#SVGID_7_"
203 id="radialGradient3314"
204 gradientUnits="userSpaceOnUse"
205 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
206 cx="148.9492"
207 cy="270.04489"
208 r="2.8799" />
209 <radialGradient
210 gradientUnits="userSpaceOnUse"
211 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
212 r="2.8799"
213 cy="270.04489"
214 cx="148.9492"
215 id="SVGID_7_">
216 <stop
217 id="stop258"
218 style="stop-color:#FAF0BB"
219 offset="0.0112" />
220 <stop
221 id="stop260"
222 style="stop-color:#FAF0BD"
223 offset="0.4917" />
224 <stop
225 id="stop262"
226 style="stop-color:#FBF2C5"
227 offset="0.6648" />
228 <stop
229 id="stop264"
230 style="stop-color:#FCF6D0"
231 offset="0.7882" />
232 <stop
233 id="stop266"
234 style="stop-color:#FCF8E1"
235 offset="0.8879" />
236 <stop
237 id="stop268"
238 style="stop-color:#FFFDF7"
239 offset="0.9723" />
240 <stop
241 id="stop270"
242 style="stop-color:#FFFFFF"
243 offset="1" />
244 </radialGradient>
245 <radialGradient
246 inkscape:collect="always"
247 xlink:href="#SVGID_8_"
248 id="radialGradient3316"
249 gradientUnits="userSpaceOnUse"
250 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
251 cx="148.0723"
252 cy="319.09381"
253 r="3.9265001" />
254 <radialGradient
255 gradientUnits="userSpaceOnUse"
256 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
257 r="3.9265001"
258 cy="319.09381"
259 cx="148.0723"
260 id="SVGID_8_">
261 <stop
262 id="stop275"
263 style="stop-color:#FAF0BB"
264 offset="0.0112" />
265 <stop
266 id="stop277"
267 style="stop-color:#FAF0BD"
268 offset="0.4917" />
269 <stop
270 id="stop279"
271 style="stop-color:#FBF2C5"
272 offset="0.6648" />
273 <stop
274 id="stop281"
275 style="stop-color:#FCF6D0"
276 offset="0.7882" />
277 <stop
278 id="stop283"
279 style="stop-color:#FCF8E1"
280 offset="0.8879" />
281 <stop
282 id="stop285"
283 style="stop-color:#FFFDF7"
284 offset="0.9723" />
285 <stop
286 id="stop287"
287 style="stop-color:#FFFFFF"
288 offset="1" />
289 </radialGradient>
290 <radialGradient
291 inkscape:collect="always"
292 xlink:href="#SVGID_9_"
293 id="radialGradient3318"
294 gradientUnits="userSpaceOnUse"
295 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
296 cx="112.9551"
297 cy="315.56049"
298 r="3.0683999" />
299 <radialGradient
300 gradientUnits="userSpaceOnUse"
301 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
302 r="3.0683999"
303 cy="315.56049"
304 cx="112.9551"
305 id="SVGID_9_">
306 <stop
307 id="stop292"
308 style="stop-color:#FAF0BB"
309 offset="0.0112" />
310 <stop
311 id="stop294"
312 style="stop-color:#FAF0BD"
313 offset="0.4917" />
314 <stop
315 id="stop296"
316 style="stop-color:#FBF2C5"
317 offset="0.6648" />
318 <stop
319 id="stop298"
320 style="stop-color:#FCF6D0"
321 offset="0.7882" />
322 <stop
323 id="stop300"
324 style="stop-color:#FCF8E1"
325 offset="0.8879" />
326 <stop
327 id="stop302"
328 style="stop-color:#FFFDF7"
329 offset="0.9723" />
330 <stop
331 id="stop304"
332 style="stop-color:#FFFFFF"
333 offset="1" />
334 </radialGradient>
335 <radialGradient
336 inkscape:collect="always"
337 xlink:href="#SVGID_10_"
338 id="radialGradient3320"
339 gradientUnits="userSpaceOnUse"
340 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
341 cx="132.0938"
342 cy="320.1113"
343 r="4.1712999" />
344 <radialGradient
345 gradientUnits="userSpaceOnUse"
346 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
347 r="4.1712999"
348 cy="320.1113"
349 cx="132.0938"
350 id="SVGID_10_">
351 <stop
352 id="stop309"
353 style="stop-color:#FAF0BB"
354 offset="0.0112" />
355 <stop
356 id="stop311"
357 style="stop-color:#FAF0BD"
358 offset="0.4917" />
359 <stop
360 id="stop313"
361 style="stop-color:#FBF2C5"
362 offset="0.6648" />
363 <stop
364 id="stop315"
365 style="stop-color:#FCF6D0"
366 offset="0.7882" />
367 <stop
368 id="stop317"
369 style="stop-color:#FCF8E1"
370 offset="0.8879" />
371 <stop
372 id="stop319"
373 style="stop-color:#FFFDF7"
374 offset="0.9723" />
375 <stop
376 id="stop321"
377 style="stop-color:#FFFFFF"
378 offset="1" />
379 </radialGradient>
380 <radialGradient
381 inkscape:collect="always"
382 xlink:href="#SVGID_11_"
383 id="radialGradient3322"
384 gradientUnits="userSpaceOnUse"
385 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
386 cx="147.44189"
387 cy="301.21091"
388 r="2.5313001" />
389 <radialGradient
390 gradientUnits="userSpaceOnUse"
391 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
392 r="2.5313001"
393 cy="301.21091"
394 cx="147.44189"
395 id="SVGID_11_">
396 <stop
397 id="stop326"
398 style="stop-color:#FAF0BB"
399 offset="0.0112" />
400 <stop
401 id="stop328"
402 style="stop-color:#FAF0BD"
403 offset="0.4917" />
404 <stop
405 id="stop330"
406 style="stop-color:#FBF2C5"
407 offset="0.6648" />
408 <stop
409 id="stop332"
410 style="stop-color:#FCF6D0"
411 offset="0.7882" />
412 <stop
413 id="stop334"
414 style="stop-color:#FCF8E1"
415 offset="0.8879" />
416 <stop
417 id="stop336"
418 style="stop-color:#FFFDF7"
419 offset="0.9723" />
420 <stop
421 id="stop338"
422 style="stop-color:#FFFFFF"
423 offset="1" />
424 </radialGradient>
425 </defs>
426 <sodipodi:namedview
427 id="base"
428 pagecolor="#ffffff"
429 bordercolor="#666666"
430 borderopacity="1.0"
431 inkscape:pageopacity="0.0"
432 inkscape:pageshadow="2"
433 inkscape:zoom="22.395604"
434 inkscape:cx="1.9698115"
435 inkscape:cy="13.030678"
436 inkscape:current-layer="layer1"
437 showgrid="true"
438 inkscape:grid-bbox="true"
439 inkscape:document-units="px"
440 showborder="true"
441 borderlayer="false"
442 inkscape:window-width="1600"
443 inkscape:window-height="876"
444 inkscape:window-x="0"
445 inkscape:window-y="24"
446 inkscape:window-maximized="1"
447 gridtolerance="10"
448 objecttolerance="10"
449 guidetolerance="10">
450 <inkscape:grid
451 type="xygrid"
452 id="grid4738"
453 empspacing="5"
454 visible="true"
455 enabled="true"
456 snapvisiblegridlinesonly="true" />
457 </sodipodi:namedview>
458 <metadata
459 id="metadata3725">
460 <rdf:RDF>
461 <cc:Work
462 rdf:about="">
463 <dc:format>image/svg+xml</dc:format>
464 <dc:type
465 rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
466 <dc:title />
467 </cc:Work>
468 </rdf:RDF>
469 </metadata>
470 <g
471 id="layer1"
472 inkscape:label="Layer 1"
473 inkscape:groupmode="layer"
474 transform="translate(0,-8)">
475 <g
476 id="g3183"
477 transform="matrix(0.46701614,0,0,0.38319022,0.63989446,4.647041)">
478 <path
479 d="m 47.748262,36.240641 c -0.304876,-0.669777 -0.939962,-2.526029 -1.264261,-3.180039 -0.499962,-1.005938 -2.409862,-0.340737 -2.850285,-1.402107 -0.615238,-1.481949 0.402841,-3.075783 -0.26687,-4.517046 -0.51052,-1.098494 -2.320767,-1.749962 -2.830861,-2.848458 -0.374128,-0.804542 0.05785,-5.080024 -0.915894,-3.703855 -1.643875,2.32362 -3.133623,4.929999 -4.51865,7.769812 -0.227178,-0.299544 -0.460268,-0.590441 -0.699692,-0.872694 l 1.273972,-2.395837 -1.94875,1.641638 C 33.517528,26.509306 33.303862,26.293167 33.085974,26.08364 l 0.936581,-2.162914 -1.564066,1.585187 C 31.923058,25.034986 31.365246,24.598131 30.785899,24.1984 l 1.168829,-5.78896 -2.873088,4.753021 C 28.796189,23.01091 28.507361,22.866987 28.213887,22.732727 l 0.283762,-3.540102 -1.360114,3.093074 C 25.924369,21.832064 24.65631,21.526925 23.350669,21.385545 l -0.349636,-4.806419 -1.226255,4.716403 c -0.0033,0 -0.0071,0 -0.01056,0 -1.422186,-0.0066 -2.818193,0.185117 -4.164371,0.553823 l -1.190787,-2.856081 0.196351,3.163762 c -0.403261,0.139347 -0.801035,0.294459 -1.193319,0.465334 l -0.676466,-1.193086 0.243647,1.388883 c -0.482226,0.226309 -0.954317,0.47703 -1.416273,0.750127 l -2.649288,-2.676561 1.488058,3.425166 c -0.733893,0.515174 -1.434852,1.088322 -2.09654,1.715887 -0.09374,0.089 -0.187063,0.180031 -0.279538,0.271064 l -2.6176137,-1.775898 1.7557735,2.685206 c -0.2643372,0.297002 -0.5214955,0.60519 -0.7718972,0.922533 l -2.0728961,-1.396004 1.4580788,2.215805 c -0.340767,0.479065 -0.6650662,0.978474 -0.9716305,1.49568 -1.2705932,0.251233 -2.4081735,1.157486 -3.0905527,2.497041 0.00253,-0.005 0.00508,-0.01071 0.00802,-0.01578 -0.5079841,0.01071 -0.9074462,0.311242 -1.1177337,1.046115 -0.7347402,2.568744 -0.5366981,4.375156 0.1689057,5.408554 -0.1199231,0.09664 -0.2373126,0.202409 -0.3517463,0.317854 -1.90145688,1.925922 -2.20548742,5.78845 -0.6790012,8.625208 0.8470624,1.574001 2.0796522,2.501617 3.3341996,2.686733 0.6452198,1.719448 1.4880601,3.337183 2.5116286,4.809977 3.3333522,4.799809 8.4203702,7.849148 14.2412852,7.722516 5.766442,-0.126125 10.741561,-3.352949 13.962593,-8.195477 2.268826,-3.410417 3.604027,-7.536378 3.803758,-11.87187 L 41.77997,42.904823 39.623044,42.4461 c 0.003,-0.734364 -0.02618,-1.473813 -0.08952,-2.215806 l 3.332089,-2.112565 -3.537731,0.400746 C 39.264542,38.110618 39.19107,37.708348 39.108306,37.31116 l 0.959807,-0.628583 -1.067483,0.13782 c -0.02618,-0.113909 -0.05278,-0.226818 -0.08023,-0.33972 2.756541,-0.434818 5.473393,-0.393116 8.225288,0.328024 0.699694,0.183591 0.893512,0.07272 0.602574,-0.568064 z M 3.2551113,34.170284 c -0.017313,0.06662 -0.033782,0.134262 -0.04856,0.202916 -0.0114,0.05139 -0.022381,0.102733 -0.032514,0.154602 0.010132,-0.05188 0.020692,-0.10325 0.032514,-0.154602 0.01478,-0.06866 0.031247,-0.136294 0.04856,-0.202916 z m 0.4049515,-1.11121 c -0.010132,0.02085 -0.020269,0.04223 -0.030404,0.06306 0.010132,-0.02085 0.02027,-0.04222 0.030404,-0.06306 z m -0.079808,0.172404 c -0.010557,0.02339 -0.020692,0.0473 -0.030825,0.07119 0.010132,-0.02389 0.02027,-0.04782 0.030825,-0.07119 z m -0.075164,0.177488 c -0.010557,0.02644 -0.021113,0.0529 -0.031248,0.07984 0.010132,-0.02694 0.020692,-0.0534 0.031248,-0.07984 z m -0.070097,0.182573 c -0.010979,0.03002 -0.021535,0.06 -0.032092,0.09001 0.010557,-0.03002 0.021113,-0.06002 0.032092,-0.09001 z m -0.06545,0.187661 c -0.01098,0.03407 -0.021535,0.06866 -0.032515,0.103238 0.010979,-0.03458 0.021113,-0.06866 0.032515,-0.103238 z m -0.059962,0.193252 c -0.011823,0.04119 -0.023225,0.08289 -0.034626,0.124599 0.0114,-0.04172 0.022381,-0.08342 0.034626,-0.124599 z m -0.2558905,1.703683 c -8.452e-4,0.05034 -8.452e-4,0.100695 -4.223e-4,0.150535 -4.223e-4,-0.05034 -4.223e-4,-0.100705 4.223e-4,-0.150535 z m 0.1106333,-1.097477 c -0.00633,0.03458 -0.012668,0.06866 -0.018578,0.103239 0.00591,-0.03407 0.012245,-0.06866 0.018578,-0.103239 z m -0.028713,0.164775 c -0.00507,0.03153 -0.010132,0.06256 -0.01478,0.09357 0.00464,-0.03101 0.00971,-0.06204 0.01478,-0.09357 z m -0.023646,0.15867 c -0.00423,0.03053 -0.00802,0.06053 -0.011823,0.09052 0.00379,-0.03052 0.0076,-0.06054 0.011823,-0.09052 z m -0.019423,0.156131 c -0.00338,0.03002 -0.00633,0.05949 -0.00929,0.0895 0.00296,-0.03002 0.00591,-0.05951 0.00929,-0.0895 z m -0.015624,0.155617 c -0.00253,0.03002 -0.00464,0.06001 -0.00717,0.09001 0.00253,-0.03002 0.00508,-0.06001 0.00717,-0.09001 z m -0.0114,0.154604 c -0.0017,0.03154 -0.00338,0.06256 -0.00507,0.09408 0.0017,-0.03153 0.00338,-0.06256 0.00507,-0.09408 z m -0.0076,0.154095 c -0.00127,0.03662 -0.00211,0.07322 -0.00296,0.109332 4.221e-4,-0.03662 0.00127,-0.07272 0.00296,-0.109332 z m 0.1634162,1.705207 c -0.0076,-0.03203 -0.01478,-0.06407 -0.021535,-0.09611 0.00718,0.03205 0.013934,0.06407 0.021535,0.09611 z m -0.037161,-0.168331 c -0.00802,-0.03865 -0.015624,-0.07728 -0.023225,-0.115944 0.0076,0.03865 0.015624,0.07729 0.023225,0.115944 z m -0.033785,-0.176983 c -0.00507,-0.02847 -0.010132,-0.05696 -0.01478,-0.08543 0.00464,0.02795 0.010132,0.05696 0.01478,0.08543 z m -0.024491,-0.152059 c -0.00423,-0.02694 -0.00844,-0.05392 -0.012245,-0.08138 0.00379,0.02694 0.0076,0.05442 0.012245,0.08138 z m -0.021113,-0.150025 c -0.00338,-0.02694 -0.00675,-0.0534 -0.00971,-0.08086 0.00296,0.02747 0.00633,0.05442 0.00971,0.08086 z m -0.017313,-0.149518 c -0.00296,-0.02694 -0.00549,-0.05392 -0.00802,-0.08137 0.00253,0.02747 0.00508,0.05441 0.00802,0.08137 z m -0.013934,-0.150024 c -0.00211,-0.02795 -0.00423,-0.05546 -0.00591,-0.08341 0.0017,0.02747 0.00379,0.05544 0.00591,0.08341 z m -0.010132,-0.150536 c -0.0017,-0.0295 -0.00296,-0.059 -0.00423,-0.0885 0.00127,0.0295 0.00253,0.05898 0.00423,0.0885 z m -0.00675,-0.15206 c -0.00127,-0.03356 -0.0017,-0.06765 -0.00211,-0.101717 0,0.03407 8.451e-4,0.06814 0.00211,0.101717 z m 0.180307,1.313616 c 0.00633,0.02644 0.012668,0.0529 0.019424,0.07882 -0.00633,-0.02644 -0.012668,-0.05239 -0.019424,-0.07882 z m 0.1811488,1.679273 c -0.00211,9.74e-4 -0.00423,0.0021 -0.00633,0.003 0,0 0,0 4.224e-4,0 0.015624,-0.01072 0.031247,-0.02137 0.046871,-0.03205 -0.013511,0.0097 -0.027025,0.01933 -0.04096,0.02896 z M 3.2745435,37.437285 c 0.00675,0.02492 0.013511,0.04984 0.020692,0.07476 -0.00717,-0.02492 -0.013934,-0.04984 -0.020692,-0.07476 z m 0.040537,0.141888 c 0.00717,0.0244 0.014357,0.04883 0.021957,0.07272 -0.00717,-0.0244 -0.014779,-0.04832 -0.021957,-0.07272 z m 0.043072,0.139347 c 0.00802,0.02389 0.015624,0.04782 0.023646,0.0717 -0.0076,-0.02389 -0.015624,-0.04728 -0.023646,-0.0717 z m 0.046449,0.137819 c 0.00844,0.02389 0.016891,0.04782 0.025758,0.07171 -0.00844,-0.02389 -0.017313,-0.0473 -0.025758,-0.07171 z m 0.049405,0.135789 c 0.00929,0.0244 0.019001,0.04883 0.028292,0.07322 -0.00929,-0.02441 -0.019001,-0.04831 -0.028292,-0.07322 z m 0.052361,0.134256 c 0.010979,0.02747 0.022803,0.05442 0.034203,0.08188 -0.0114,-0.02747 -0.023225,-0.05442 -0.034203,-0.08188 z m 0.055317,0.13223 c 0.018158,0.04223 0.037159,0.08491 0.056584,0.12663 -0.019001,-0.04223 -0.038005,-0.0844 -0.056584,-0.12663 z m 0.081498,0.178505 c 0.012245,0.02543 0.024491,0.05086 0.036737,0.07627 -0.012668,-0.02543 -0.024491,-0.05086 -0.036737,-0.07627 z m 0.065028,0.132734 c 0.011824,0.02339 0.023646,0.04678 0.035893,0.07019 -0.012246,-0.02339 -0.024069,-0.04678 -0.035893,-0.07019 z m 0.066295,0.12714 c 0.00802,0.01423 0.015624,0.029 0.023646,0.04272 -0.012668,0.0066 -0.025336,0.01272 -0.037582,0.01933 0.012246,-0.0066 0.02449,-0.01373 0.036737,-0.01983 -0.00802,-0.01373 -0.015202,-0.02797 -0.022803,-0.04223 z"
480 id="path5"
481 inkscape:connector-curvature="0" />
482 <path
483 d="m 46.872485,35.321668 c -0.295587,-0.574676 -0.59117,-1.149351 -0.887179,-1.724024 -0.411284,-0.79946 -2.442377,-0.780135 -2.853662,-1.579594 -0.640154,-1.243435 0.339923,-3.306671 -0.300232,-4.550104 -0.487293,-0.94745 -2.164949,-1.469746 -2.652242,-2.417196 -0.272784,-0.53043 -0.355546,-1.274964 -0.330633,-1.912193 0.05237,-1.364979 0.09627,-2.14664 -0.825104,-0.815224 -1.463147,2.115108 -2.790324,4.459071 -4.019957,7.001881 0.08403,0.130191 0.166794,0.262928 0.248715,0.39617 1.867674,-0.780645 3.579534,-1.925924 5.084062,-3.359053 -1.390517,1.582138 -3.033126,2.860154 -4.860686,3.733354 0.119078,0.203934 0.236469,0.410917 0.350057,0.620953 -0.87662,-1.47788 -1.904834,-2.797597 -3.043681,-3.931183 l -0.220844,0.510597 1.016812,-2.721313 -1.72115,1.539922 0.100502,-0.101717 c -0.426911,-0.375317 -0.869023,-0.727243 -1.324646,-1.05679 l -0.259691,1.287172 0.928137,-6.116986 -3.276349,4.782515 0.695047,-1.149347 C 27.064907,22.874104 25.27366,22.28112 23.39754,22.038534 l 0.05785,0.790309 -0.581035,-4.788622 -1.425989,4.509928 0.165107,-0.635193 c -0.02449,0 -0.04899,-9.74e-4 -0.07348,-9.74e-4 -2.69658,-0.0122 -5.297306,0.706904 -7.628628,2.005263 l 0.994011,1.003896 -3.222299,-2.891682 1.639229,4.403639 -0.736427,-1.695038 c -0.777812,0.531955 -1.518886,1.130533 -2.214777,1.791154 -0.5865257,0.556877 -1.1460249,1.161557 -1.6734311,1.809973 l 0.3800423,0.25581 -2.2287093,-1.303955 1.2275217,2.117143 -0.091631,-0.139345 c -0.260959,0.36159 -0.5122061,0.73538 -0.7533194,1.120363 0,0 4.226e-4,0 4.226e-4,0 0.058698,-0.0046 0.1178119,-0.0076 0.1769282,-0.0097 0.4197311,-0.01322 0.848329,0.04476 1.274816,0.182576 0.9543158,0.307679 1.753238,0.965757 2.327517,1.82777 1.042571,-3.636727 4.259803,-5.735561 7.393005,-4.724541 3.275504,1.057303 5.220032,5.114101 4.342567,9.059015 -0.238157,1.070014 -0.659578,2.022044 -1.212743,2.819977 0.07093,0.03205 0.14188,0.06509 0.212399,0.100705 0.08361,0.04223 0.165949,0.08645 0.247024,0.132733 -2.976541,-1.313107 -6.314119,0.418546 -7.548398,3.975938 -1.2347,3.558409 0.08783,7.634533 2.955006,9.262947 -0.08446,-0.03713 -0.168483,-0.07627 -0.252515,-0.118496 -3.038191,-1.529246 -4.4722,-5.736577 -3.202452,-9.39619 0.218733,-0.629601 0.502918,-1.20224 0.839884,-1.711309 -1.472858,-0.618921 -2.639575,-1.861338 -3.348979,-3.411436 -0.588214,1.277509 -1.5788438,2.193938 -2.71769,2.574851 0.033789,0.06461 0.067143,0.129174 0.099654,0.195797 1.344911,2.750302 0.9285586,6.379401 -0.9298248,8.103932 -0.051515,0.04782 -0.1038771,0.09407 -0.1566596,0.137821 h 0 c 0.026184,-0.02694 0.05236,-0.05442 0.078121,-0.08188 8.773e-4,-0.0014 0.00167,-0.0026 0.00296,-0.0036 0.024916,-0.02694 0.049402,-0.05442 0.073895,-0.08239 0.00128,-0.0021 0.00296,-0.0036 0.00462,-0.005 0.024071,-0.02795 0.047713,-0.05545 0.070937,-0.08341 0.00167,-0.0026 0.00384,-0.0046 0.0055,-0.0071 0.023227,-0.02796 0.045607,-0.05543 0.067989,-0.08391 0.00216,-0.003 0.00423,-0.0061 0.00675,-0.0086 0.021955,-0.02847 0.043919,-0.05646 0.065029,-0.08542 0.00251,-0.003 0.00512,-0.0066 0.0072,-0.0097 0.021109,-0.02847 0.042228,-0.05696 0.062493,-0.08645 0.00251,-0.0036 0.00512,-0.0072 0.00755,-0.01071 0.020265,-0.0295 0.040538,-0.05799 0.060379,-0.08797 0.00251,-0.004 0.00512,-0.0076 0.008,-0.01121 0.01942,-0.0295 0.038848,-0.05898 0.058277,-0.08899 0.00251,-0.0046 0.00549,-0.0086 0.008,-0.0122 0.018997,-0.03002 0.037589,-0.06 0.055741,-0.09052 0.00251,-0.0046 0.00549,-0.0086 0.008,-0.01272 0.018152,-0.03052 0.036322,-0.06103 0.054051,-0.09204 0.00251,-0.0046 0.00512,-0.009 0.008,-0.01322 0.017729,-0.03153 0.035054,-0.06204 0.052361,-0.09357 0.00251,-0.005 0.00513,-0.0097 0.00755,-0.01373 0.017306,-0.03153 0.033789,-0.06306 0.050253,-0.09508 0.00251,-0.005 0.00513,-0.0097 0.00755,-0.01423 0.016464,-0.03153 0.032521,-0.06407 0.048559,-0.09613 0.00213,-0.005 0.00455,-0.0097 0.00716,-0.01425 0.015622,-0.03253 0.031254,-0.06509 0.046458,-0.09816 0.00213,-0.0046 0.00426,-0.0097 0.00677,-0.01373 0.015206,-0.03304 0.030402,-0.06713 0.045191,-0.100694 0.00213,-0.004 0.00387,-0.009 0.0059,-0.01272 0.01478,-0.03409 0.029559,-0.06865 0.043913,-0.102733 0.00175,-0.0046 0.00329,-0.0086 0.00513,-0.0122 0.014354,-0.03508 0.028291,-0.07019 0.042229,-0.105275 0.00126,-0.004 0.003,-0.0082 0.00426,-0.0112 0.013937,-0.0356 0.027449,-0.07222 0.040961,-0.108333 8.768e-4,-0.003 0.00213,-0.0061 0.00329,-0.0097 0.013511,-0.03662 0.026607,-0.07425 0.039693,-0.111368 8.769e-4,-0.0026 0.00175,-0.005 0.00251,-0.0076 0.013085,-0.03815 0.026181,-0.07627 0.038425,-0.115439 0,-9.73e-4 4.229e-4,-0.0021 8.769e-4,-0.0026 0.1570825,-0.485678 0.2630703,-1.002882 0.3166975,-1.535857 4.228e-4,-0.004 8.777e-4,-0.0082 0.00124,-0.01118 0.00383,-0.03762 0.00713,-0.07528 0.010132,-0.113404 4.219e-4,-0.0082 0.00124,-0.01576 0.00217,-0.02389 0.003,-0.03458 0.00548,-0.06968 0.00755,-0.104238 8.767e-4,-0.01071 0.00176,-0.02238 0.00248,-0.03305 0.00217,-0.03253 0.00383,-0.06561 0.00548,-0.09816 4.218e-4,-0.01322 0.00124,-0.02644 0.00217,-0.03917 0.00176,-0.03153 0.00248,-0.06306 0.00383,-0.09459 4.229e-4,-0.01474 8.778e-4,-0.03002 0.00176,-0.04425 8.777e-4,-0.03052 0.00124,-0.06053 0.00217,-0.09052 4.228e-4,-0.01627 8.777e-4,-0.03253 8.777e-4,-0.04883 4.229e-4,-0.0295 4.229e-4,-0.05799 4.229e-4,-0.08747 0,-0.01728 0,-0.03459 0,-0.05239 0,-0.02847 -4.229e-4,-0.05644 -8.778e-4,-0.08492 0,-0.01831 -4.228e-4,-0.03611 -4.228e-4,-0.05441 -4.208e-4,-0.02796 -0.00124,-0.05544 -0.00217,-0.08339 -4.229e-4,-0.0188 -8.767e-4,-0.03763 -0.00176,-0.05645 -8.767e-4,-0.02694 -0.00217,-0.0534 -0.00331,-0.08086 -8.768e-4,-0.01984 -0.00176,-0.03918 -0.003,-0.05899 -0.00124,-0.02694 -0.003,-0.0529 -0.00455,-0.07935 -0.00124,-0.02032 -0.00248,-0.04068 -0.00383,-0.06053 -0.00176,-0.02644 -0.00383,-0.05238 -0.00589,-0.07832 -0.00176,-0.02085 -0.00331,-0.04119 -0.00517,-0.06204 -0.00217,-0.02594 -0.00455,-0.05138 -0.00713,-0.0768 -0.00176,-0.02136 -0.00424,-0.04222 -0.00631,-0.06307 -0.00248,-0.02543 -0.00548,-0.05086 -0.00842,-0.07577 -0.00251,-0.02185 -0.00513,-0.04323 -0.00755,-0.06461 -0.003,-0.02492 -0.0059,-0.04985 -0.00929,-0.07425 -0.003,-0.02185 -0.0059,-0.04375 -0.0089,-0.06561 -0.00329,-0.02492 -0.00677,-0.04934 -0.01056,-0.07425 -0.00329,-0.02185 -0.00677,-0.04425 -0.010132,-0.06612 -0.00387,-0.02439 -0.00755,-0.04883 -0.011401,-0.07322 -0.00387,-0.02237 -0.00755,-0.04476 -0.011401,-0.06661 -0.00426,-0.02441 -0.00842,-0.04831 -0.01267,-0.07221 -0.00426,-0.02288 -0.00842,-0.04526 -0.01267,-0.06765 -0.00455,-0.02389 -0.0089,-0.04782 -0.013937,-0.07119 -0.00455,-0.02288 -0.00929,-0.04526 -0.013938,-0.06815 -0.00513,-0.0234 -0.00971,-0.04729 -0.015206,-0.07069 -0.00513,-0.02288 -0.010132,-0.04576 -0.015206,-0.06866 -0.00513,-0.02288 -0.010549,-0.04629 -0.016047,-0.06915 -0.00552,-0.02339 -0.010976,-0.04629 -0.01688,-0.06915 -0.00552,-0.02288 -0.010975,-0.04576 -0.01688,-0.06814 -0.0059,-0.02339 -0.011827,-0.04678 -0.018148,-0.06968 -0.0059,-0.02288 -0.011818,-0.04527 -0.018148,-0.06765 -0.0063,-0.0234 -0.01267,-0.04628 -0.019416,-0.06968 -0.0063,-0.02238 -0.01267,-0.04425 -0.018999,-0.06661 -0.00677,-0.0234 -0.013937,-0.04678 -0.021109,-0.07019 -0.00677,-0.02185 -0.013086,-0.04374 -0.019842,-0.0656 -0.00755,-0.02389 -0.015206,-0.0473 -0.022804,-0.0707 -0.00677,-0.02136 -0.013937,-0.0427 -0.020683,-0.0646 -0.00803,-0.02339 -0.016038,-0.04679 -0.024071,-0.07069 -0.00755,-0.02085 -0.014354,-0.04222 -0.021952,-0.06306 -0.00842,-0.0244 -0.017306,-0.04831 -0.026181,-0.07221 -0.00755,-0.02031 -0.01478,-0.04069 -0.022378,-0.06103 -0.0089,-0.02441 -0.018574,-0.04883 -0.027875,-0.07272 -0.00755,-0.02032 -0.015206,-0.04018 -0.022804,-0.05949 -0.00971,-0.02492 -0.019842,-0.04933 -0.029985,-0.07425 -0.00803,-0.01865 -0.015622,-0.03799 -0.023645,-0.05732 -0.010975,-0.02594 -0.021952,-0.05188 -0.033363,-0.0768 -0.00755,-0.0178 -0.015206,-0.0351 -0.022804,-0.0529 -0.01267,-0.0295 -0.026182,-0.05799 -0.039267,-0.08696 -0.00677,-0.0137 -0.01267,-0.02845 -0.019416,-0.04219 C 8.552808,41.518875 8.532531,41.476167 8.511847,41.433436 7.1669757,38.683133 4.5692051,37.851124 2.7108196,39.57515 0.85243366,41.299176 0.436081,44.928276 1.7809934,47.678578 c 0.023225,0.04782 0.046871,0.0951 0.07094,0.140872 0.0076,0.01474 0.015624,0.0295 0.023225,0.04425 0.01689,0.03153 0.033358,0.06307 0.05025,0.09459 0.00887,0.01626 0.018158,0.03307 0.027448,0.04985 0.016468,0.0295 0.032514,0.05799 0.048982,0.08645 0.00929,0.01627 0.018578,0.03253 0.028291,0.04883 0.017735,0.03002 0.035048,0.0595 0.053205,0.0885 0.00844,0.01373 0.01689,0.02795 0.025336,0.04172 0.024491,0.03917 0.048983,0.07729 0.073473,0.115944 0.00211,0.0036 0.00423,0.0072 0.00633,0.01012 0.027025,0.0417 0.054894,0.0824 0.082765,0.123071 0.00802,0.01121 0.015624,0.02237 0.023646,0.03305 0.020269,0.02896 0.040538,0.05746 0.061228,0.08595 0.00971,0.01322 0.019424,0.02694 0.029136,0.03966 0.019423,0.02644 0.038848,0.05239 0.058271,0.07729 0.00971,0.01271 0.019847,0.02594 0.029981,0.03865 0.020692,0.02694 0.041381,0.0529 0.062496,0.0783 0.00887,0.01071 0.017735,0.02185 0.026181,0.03255 0.027025,0.03305 0.054473,0.06561 0.082342,0.09764 0.00253,0.003 0.00464,0.0061 0.00718,0.0086 0.031248,0.03611 0.062496,0.07119 0.094165,0.105779 0.00591,0.0066 0.011823,0.0122 0.017735,0.0188 0.025337,0.02747 0.050671,0.05392 0.076429,0.08086 0.00887,0.0097 0.018158,0.0183 0.027448,0.02796 0.023226,0.02339 0.046027,0.0468 0.069674,0.06969 0.00929,0.0097 0.019001,0.0183 0.028292,0.02796 0.024491,0.02339 0.048982,0.04678 0.073473,0.06915 0.00802,0.0076 0.016046,0.01474 0.024069,0.02238 0.031247,0.02847 0.062496,0.05645 0.094587,0.08391 0.00127,9.74e-4 0.00253,0.0021 0.00338,0.003 0.035048,0.03002 0.070097,0.05898 0.1051438,0.08747 0.0017,0.0014 0.00338,0.003 0.00508,0.0046 0.032091,0.02594 0.064184,0.05086 0.096698,0.07527 0.00718,0.0056 0.014357,0.01073 0.021535,0.01578 0.027448,0.02085 0.055317,0.04069 0.083186,0.0605 0.00802,0.0061 0.016046,0.01121 0.024069,0.01678 0.028293,0.02032 0.057006,0.03967 0.08572,0.059 0.00633,0.004 0.012668,0.0086 0.019424,0.0122 0.1072551,0.07119 0.2166217,0.135784 0.3268326,0.193761 0.00423,0.0021 0.00887,0.0046 0.01309,0.0066 0.032515,0.01678 0.064607,0.03307 0.097121,0.04883 0.0059,0.003 0.012246,0.0061 0.018158,0.009 0.032092,0.01524 0.064607,0.03052 0.096698,0.04425 0.00464,0.0021 0.00929,0.0046 0.014356,0.0066 0.1135892,0.04933 0.2284449,0.09256 0.3433009,0.128156 0.0017,5.1e-4 0.00338,9.74e-4 0.00549,0.0014 0.035892,0.0112 0.071785,0.02187 0.1076773,0.03154 0.00464,9.73e-4 0.00929,0.0026 0.013934,0.0036 0.034626,0.0097 0.068829,0.0178 0.1034547,0.02594 0.00379,9.74e-4 0.00802,0.0021 0.011824,0.003 0.1169673,0.02694 0.2343567,0.04679 0.3517462,0.05951 l 0,0 c 0.6481757,1.849131 1.52733,3.584344 2.6163505,5.151733 3.2493206,4.67828 8.2075476,7.650825 13.8810926,7.526736 5.62076,-0.12256 10.470044,-3.267511 13.60958,-7.987475 2.711782,-4.077649 4.055427,-9.202937 3.667366,-14.468077 l -0.625796,0.397186 3.441877,-2.497548 -4.004333,0.160197 0.94925,-0.107311 c -0.220421,-1.378712 -0.556544,-2.696396 -0.990631,-3.942371 0.168484,0.428718 0.325565,0.867097 0.469134,1.315141 2.798347,-0.571116 5.565447,-0.68554 8.28863,-0.151043 0.771477,0.153076 0.933204,0.41702 0.464491,-0.493815 z m -12.799679,3.703349 c -0.150327,4.243438 -1.599116,6.202419 -3.283952,6.35143 -0.291784,0.02594 -0.581036,-0.003 -0.882953,-0.08339 0.127101,0.01169 0.25378,0.01373 0.380461,0.005 0.947982,-0.0656 1.826292,-0.718089 2.438574,-2.048996 -1.654432,-1.002882 -3.38487,-1.607564 -5.059992,-1.826755 1.684833,0.07272 3.4651,0.599086 5.159647,1.598919 0.215777,-0.520259 0.393129,-1.134093 0.522342,-1.846589 -1.866407,-0.63926 -3.746752,-0.830988 -5.497882,-0.626039 1.72875,-0.355486 3.641185,-0.255806 5.541374,0.37074 0.08615,-0.535514 0.146526,-1.122905 0.176508,-1.764709 0.0114,-0.238514 -0.003,-0.451602 -0.03927,-0.641804 -2.009135,-0.114427 -3.941838,0.243602 -5.656652,0.971863 1.643451,-0.864048 3.568132,-1.320736 5.586133,-1.236826 -0.412129,-1.186475 -1.895967,-1.250044 -3.554621,-0.903205 2.210554,-0.579759 4.250091,-0.552808 4.170283,1.68029 z m 2.44111,-7.055789 c 1.92468,-0.563996 3.721414,-1.511446 5.334888,-2.770136 -1.510441,1.419396 -3.24806,2.506191 -5.138958,3.16783 -0.06418,-0.133245 -0.129212,-0.265977 -0.19593,-0.397694 z m 0.825526,1.842519 c -0.05574,-0.141379 -0.112746,-0.282252 -0.171017,-0.421598 1.999844,-0.298525 3.997577,-0.112402 5.887635,0.505511 -1.862188,-0.401765 -3.791937,-0.442449 -5.716618,-0.08392 z"
484 id="path14"
485 style="fill:#f0a513;fill-opacity:1"
486 inkscape:connector-curvature="0" />
487 <path
488 d="m 17.971864,28.383357 c 3.029325,0.977457 4.82775,4.729117 4.016157,8.37805 -0.214087,0.963215 -0.589481,1.823193 -1.080996,2.549419 -2.202109,-0.672827 -4.51105,0.238008 -5.964907,2.257001 -2.974852,-1.022212 -4.729782,-4.734713 -3.926214,-8.347029 0.811593,-3.648933 3.926636,-5.815407 6.95596,-4.837441 z"
489 id="path16"
490 inkscape:connector-curvature="0"
491 style="fill:#ffffff" />
492 <path
493 d="m 21.46948,31.675787 c 0.688291,1.496188 0.915048,3.303109 0.518541,5.08562 -0.214087,0.963215 -0.589481,1.823193 -1.080996,2.549419 -2.202532,-0.672827 -4.511474,0.238008 -5.965329,2.257001 -1.217389,-0.418038 -2.2304,-1.28768 -2.947405,-2.415671 0.307831,0.161723 0.630018,0.298527 0.964451,0.406343 3.605716,1.163589 7.313197,-1.414313 8.279337,-5.756922 0.157927,-0.710463 0.232246,-1.423974 0.231401,-2.12579 z"
494 id="path18"
495 inkscape:connector-curvature="0"
496 style="fill:#eeeeee" />
497 <path
498 d="m 11.148494,37.665629 c -0.473779,-1.361928 -0.61397,-2.903379 -0.33232,-4.44127 -0.52952,-1.020176 -1.3685584,-1.810482 -2.4090152,-2.146133 -2.1826849,-0.704357 -4.4270197,0.856418 -5.0118558,3.484667 -0.3242991,1.457031 -0.070517,2.936437 0.5915924,4.085786 1.0683288,-0.4694 2.2489802,-0.271571 3.2581915,0.503477 0.4619579,0.354468 0.8876005,0.829465 1.2503252,1.416854 1.1793816,-0.417022 2.1776139,-1.463641 2.6530819,-2.903381 z"
499 id="path20"
500 inkscape:connector-curvature="0"
501 style="fill:#ffffff" />
502 <path
503 d="m 31.2411,51.394259 1.26637,0.637229 -2.465178,-0.01373 c -4.530473,2.179698 -9.426207,2.60994 -12.629927,1.007461 -0.08825,-0.03864 -0.176507,-0.07984 -0.264338,-0.124092 -3.038191,-1.529243 -4.472201,-5.736578 -3.202453,-9.39619 0.218732,-0.6296 0.503339,-1.202239 0.840306,-1.710803 l 0,-5.07e-4 c -1.472857,-0.618925 -2.639574,-1.861849 -3.348978,-3.411437 -0.588215,1.277507 -1.5788467,2.193936 -2.7176907,2.574848 0.033779,0.06461 0.067143,0.129175 0.099655,0.195796 1.3449097,2.750303 0.9285573,6.379402 -0.9298254,8.103935 -0.051515,0.04782 -0.1038771,0.09408 -0.1566605,0.137821 l 0,0 c -0.048979,0.05034 -0.098387,0.09866 -0.1494812,0.145956 -0.7486746,0.694696 -1.6176949,0.974406 -2.4761587,0.880322 l 0,5.08e-4 c 0.6477536,1.848622 1.5273307,3.584344 2.6159279,5.151732 3.2493226,4.678262 8.2075486,7.650298 13.8810926,7.526717 5.620762,-0.12256 10.470046,-3.268018 13.609581,-7.987982 2.123568,-3.192243 3.407673,-7.028327 3.678768,-11.070884 -1.87021,3.185631 -4.634352,5.665888 -7.651009,7.353296 z"
504 id="path183"
505 style="fill:#fdd99b"
506 inkscape:connector-curvature="0" />
507 <path
508 d="m 11.261241,44.175223 c -0.158773,-0.250722 -0.250827,-0.566539 -0.243648,-0.906768 0.01224,-0.584846 0.312898,-1.079675 0.733895,-1.291745 -0.616928,0.507545 -0.839039,1.75098 -0.173129,2.336839 0.277429,0.243604 0.439579,0.574168 0.370749,1.028824 -0.05363,0.355991 -0.262648,0.802509 -0.591168,1.144265 -0.374972,0.389558 -0.833129,0.599593 -1.228791,0.541109 0.37835,-0.112404 0.757541,-0.387016 1.06284,-0.752165 0.26307,-0.314291 0.444644,-0.675369 0.519384,-0.97542 0.14906,-0.596542 -0.181995,-0.701818 -0.450132,-1.124939 l 0,0 z m 1.895122,4.408723 c -0.233935,0.931683 -0.952208,1.610106 -1.802226,1.610106 -0.765564,0 -1.4251397,-0.551279 -1.7190352,-1.342094 0.3783472,0.632143 0.9944302,1.044078 1.6907442,1.044078 0.790057,0 1.477502,-0.530939 1.830517,-1.31209 z"
509 id="path185"
510 inkscape:connector-curvature="0" />
511 <g
512 id="g187"
513 transform="matrix(0.42226435,0,0,0.50856192,-47.726977,-111.72952)">
514 <radialGradient
515 id="radialGradient3241"
516 cx="163.4902"
517 cy="274.86621"
518 r="2.8801"
519 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
520 gradientUnits="userSpaceOnUse">
521 <stop
522 offset="0.0112"
523 style="stop-color:#FAF0BB"
524 id="stop3243" />
525 <stop
526 offset="0.4917"
527 style="stop-color:#FAF0BD"
528 id="stop3245" />
529 <stop
530 offset="0.6648"
531 style="stop-color:#FBF2C5"
532 id="stop3247" />
533 <stop
534 offset="0.7882"
535 style="stop-color:#FCF6D0"
536 id="stop3249" />
537 <stop
538 offset="0.8879"
539 style="stop-color:#FCF8E1"
540 id="stop3251" />
541 <stop
542 offset="0.9723"
543 style="stop-color:#FFFDF7"
544 id="stop3253" />
545 <stop
546 offset="1"
547 style="stop-color:#FFFFFF"
548 id="stop3255" />
549 </radialGradient>
550 <path
551 d="m 189.806,311.298 c -0.681,-0.478 -1.432,-0.68 -2.1,-0.645 -0.633,0.034 -1.217,0.284 -1.625,0.739 -0.408,0.454 -0.59,1.052 -0.559,1.676 0.034,0.653 0.305,1.364 0.834,1.98 0.577,0.671 1.35,1.108 2.143,1.244 0.845,0.145 1.679,-0.06 2.247,-0.657 0.573,-0.604 0.725,-1.448 0.515,-2.282 -0.199,-0.789 -0.713,-1.534 -1.455,-2.055 z"
552 id="path204"
553 style="fill:url(#radialGradient3305)"
554 inkscape:connector-curvature="0" />
555 <radialGradient
556 id="radialGradient3258"
557 cx="155.3242"
558 cy="310.6777"
559 r="4.4867001"
560 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
561 gradientUnits="userSpaceOnUse">
562 <stop
563 offset="0.0112"
564 style="stop-color:#FAF0BB"
565 id="stop3260" />
566 <stop
567 offset="0.4917"
568 style="stop-color:#FAF0BD"
569 id="stop3262" />
570 <stop
571 offset="0.6648"
572 style="stop-color:#FBF2C5"
573 id="stop3264" />
574 <stop
575 offset="0.7882"
576 style="stop-color:#FCF6D0"
577 id="stop3266" />
578 <stop
579 offset="0.8879"
580 style="stop-color:#FCF8E1"
581 id="stop3268" />
582 <stop
583 offset="0.9723"
584 style="stop-color:#FFFDF7"
585 id="stop3270" />
586 <stop
587 offset="1"
588 style="stop-color:#FFFFFF"
589 id="stop3272" />
590 </radialGradient>
591 <path
592 d="m 183.164,274.256 c -0.777,-0.621 -1.774,-0.996 -2.853,-1 -1.077,-0.004 -2.096,0.366 -2.89,0.992 -0.839,0.661 -1.465,1.633 -1.646,2.791 -0.197,1.263 0.167,2.499 0.961,3.449 0.841,1.005 2.124,1.644 3.592,1.617 1.455,-0.026 2.71,-0.702 3.522,-1.716 0.762,-0.951 1.106,-2.168 0.913,-3.4 -0.179,-1.131 -0.786,-2.082 -1.599,-2.733 z"
593 id="path221"
594 style="fill:url(#radialGradient3307)"
595 inkscape:connector-curvature="0" />
596 <radialGradient
597 id="radialGradient3275"
598 cx="170.3125"
599 cy="302.00781"
600 r="5.0811"
601 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
602 gradientUnits="userSpaceOnUse">
603 <stop
604 offset="0.0112"
605 style="stop-color:#FAF0BB"
606 id="stop3277" />
607 <stop
608 offset="0.4917"
609 style="stop-color:#FAF0BD"
610 id="stop3279" />
611 <stop
612 offset="0.6648"
613 style="stop-color:#FBF2C5"
614 id="stop3281" />
615 <stop
616 offset="0.7882"
617 style="stop-color:#FCF6D0"
618 id="stop3283" />
619 <stop
620 offset="0.8879"
621 style="stop-color:#FCF8E1"
622 id="stop3285" />
623 <stop
624 offset="0.9723"
625 style="stop-color:#FFFDF7"
626 id="stop3287" />
627 <stop
628 offset="1"
629 style="stop-color:#FFFFFF"
630 id="stop3289" />
631 </radialGradient>
632 <path
633 d="m 197.254,290.925 c 1.482,-0.322 2.697,-1.225 3.201,-2.604 0.5,-1.367 0.166,-2.845 -0.726,-4.066 -0.835,-1.146 -2.134,-2.023 -3.647,-2.408 -1.389,-0.352 -2.723,-0.223 -3.781,0.238 -1.011,0.439 -1.812,1.196 -2.21,2.198 -0.397,1.001 -0.335,2.12 0.108,3.146 0.468,1.083 1.377,2.112 2.666,2.812 1.407,0.762 2.987,0.989 4.389,0.684 z"
634 id="path238"
635 style="fill:url(#radialGradient3310)"
636 inkscape:connector-curvature="0" />
637 <radialGradient
638 id="radialGradient3292"
639 cx="173.2812"
640 cy="283.68359"
641 r="2.8803999"
642 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
643 gradientUnits="userSpaceOnUse">
644 <stop
645 offset="0.0112"
646 style="stop-color:#FAF0BB"
647 id="stop3294" />
648 <stop
649 offset="0.4917"
650 style="stop-color:#FAF0BD"
651 id="stop3296" />
652 <stop
653 offset="0.6648"
654 style="stop-color:#FBF2C5"
655 id="stop3298" />
656 <stop
657 offset="0.7882"
658 style="stop-color:#FCF6D0"
659 id="stop3300" />
660 <stop
661 offset="0.8879"
662 style="stop-color:#FCF8E1"
663 id="stop3302" />
664 <stop
665 offset="0.9723"
666 style="stop-color:#FFFDF7"
667 id="stop3304" />
668 <stop
669 offset="1"
670 style="stop-color:#FFFFFF"
671 id="stop3306" />
672 </radialGradient>
673 <path
674 d="m 200.538,302.533 c -0.568,-0.598 -1.402,-0.802 -2.248,-0.657 -0.792,0.136 -1.565,0.573 -2.143,1.244 -0.529,0.616 -0.8,1.327 -0.833,1.98 -0.032,0.624 0.15,1.222 0.559,1.676 0.408,0.455 0.991,0.705 1.624,0.739 0.668,0.035 1.42,-0.167 2.101,-0.645 0.741,-0.521 1.256,-1.267 1.454,-2.056 0.21,-0.833 0.058,-1.677 -0.514,-2.281 z"
675 id="path255"
676 style="fill:url(#radialGradient3312)"
677 inkscape:connector-curvature="0" />
678 <radialGradient
679 id="radialGradient3309"
680 cx="148.9492"
681 cy="270.04489"
682 r="2.8799"
683 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
684 gradientUnits="userSpaceOnUse">
685 <stop
686 offset="0.0112"
687 style="stop-color:#FAF0BB"
688 id="stop3311" />
689 <stop
690 offset="0.4917"
691 style="stop-color:#FAF0BD"
692 id="stop3313" />
693 <stop
694 offset="0.6648"
695 style="stop-color:#FBF2C5"
696 id="stop3315" />
697 <stop
698 offset="0.7882"
699 style="stop-color:#FCF6D0"
700 id="stop3317" />
701 <stop
702 offset="0.8879"
703 style="stop-color:#FCF8E1"
704 id="stop3319" />
705 <stop
706 offset="0.9723"
707 style="stop-color:#FFFDF7"
708 id="stop3321" />
709 <stop
710 offset="1"
711 style="stop-color:#FFFFFF"
712 id="stop3323" />
713 </radialGradient>
714 <path
715 d="m 173.958,315.516 c -0.793,0.136 -1.566,0.573 -2.143,1.244 -0.529,0.616 -0.801,1.327 -0.834,1.98 -0.031,0.623 0.15,1.222 0.559,1.676 0.408,0.455 0.991,0.705 1.624,0.738 0.669,0.036 1.42,-0.166 2.101,-0.645 0.741,-0.521 1.256,-1.266 1.454,-2.055 0.211,-0.834 0.06,-1.679 -0.514,-2.282 -0.568,-0.598 -1.402,-0.801 -2.247,-0.656 z"
716 id="path272"
717 style="fill:url(#radialGradient3314)"
718 inkscape:connector-curvature="0" />
719 <radialGradient
720 id="radialGradient3326"
721 cx="148.0723"
722 cy="319.09381"
723 r="3.9265001"
724 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
725 gradientUnits="userSpaceOnUse">
726 <stop
727 offset="0.0112"
728 style="stop-color:#FAF0BB"
729 id="stop3328" />
730 <stop
731 offset="0.4917"
732 style="stop-color:#FAF0BD"
733 id="stop3330" />
734 <stop
735 offset="0.6648"
736 style="stop-color:#FBF2C5"
737 id="stop3332" />
738 <stop
739 offset="0.7882"
740 style="stop-color:#FCF6D0"
741 id="stop3334" />
742 <stop
743 offset="0.8879"
744 style="stop-color:#FCF8E1"
745 id="stop3336" />
746 <stop
747 offset="0.9723"
748 style="stop-color:#FFFDF7"
749 id="stop3338" />
750 <stop
751 offset="1"
752 style="stop-color:#FFFFFF"
753 id="stop3340" />
754 </radialGradient>
755 <path
756 d="m 171.282,272.336 c 1.106,0.549 2.333,0.68 3.407,0.405 1.136,-0.291 2.049,-1.022 2.398,-2.102 0.347,-1.069 0.048,-2.201 -0.675,-3.119 -0.678,-0.861 -1.706,-1.502 -2.885,-1.756 -1.083,-0.233 -2.109,-0.095 -2.914,0.291 -0.768,0.368 -1.365,0.975 -1.645,1.76 -0.278,0.785 -0.198,1.646 0.173,2.426 0.394,0.822 1.125,1.592 2.141,2.095 z"
757 id="path289"
758 style="fill:url(#radialGradient3316)"
759 inkscape:connector-curvature="0" />
760 <radialGradient
761 id="radialGradient3343"
762 cx="112.9551"
763 cy="315.56049"
764 r="3.0683999"
765 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
766 gradientUnits="userSpaceOnUse">
767 <stop
768 offset="0.0112"
769 style="stop-color:#FAF0BB"
770 id="stop3345" />
771 <stop
772 offset="0.4917"
773 style="stop-color:#FAF0BD"
774 id="stop3347" />
775 <stop
776 offset="0.6648"
777 style="stop-color:#FBF2C5"
778 id="stop3349" />
779 <stop
780 offset="0.7882"
781 style="stop-color:#FCF6D0"
782 id="stop3351" />
783 <stop
784 offset="0.8879"
785 style="stop-color:#FCF8E1"
786 id="stop3353" />
787 <stop
788 offset="0.9723"
789 style="stop-color:#FFFDF7"
790 id="stop3355" />
791 <stop
792 offset="1"
793 style="stop-color:#FFFFFF"
794 id="stop3357" />
795 </radialGradient>
796 <path
797 d="m 140.776,270.8 c -0.132,-0.306 -0.298,-0.603 -0.496,-0.884 0,0 -0.001,-10e-4 -0.001,-10e-4 -0.031,0.02 -0.061,0.042 -0.091,0.062 -0.1,0.067 -0.199,0.135 -0.298,0.203 -0.12,0.082 -0.24,0.163 -0.358,0.246 -0.123,0.085 -0.245,0.173 -0.366,0.26 -0.096,0.068 -0.193,0.136 -0.289,0.206 -0.146,0.106 -0.29,0.213 -0.434,0.321 -0.072,0.054 -0.145,0.106 -0.216,0.161 -0.215,0.163 -0.429,0.328 -0.641,0.495 -0.223,0.175 -0.443,0.354 -0.663,0.535 -0.064,0.053 -0.129,0.107 -0.194,0.161 -0.171,0.143 -0.341,0.287 -0.51,0.432 -0.054,0.046 -0.108,0.092 -0.162,0.139 -0.193,0.167 -0.384,0.337 -0.574,0.509 -0.098,0.088 -0.196,0.178 -0.293,0.268 -0.099,0.09 -0.196,0.182 -0.294,0.274 -0.079,0.074 -0.16,0.146 -0.238,0.222 0,0 0.001,0.001 0.001,0.001 0.177,0.156 0.363,0.299 0.555,0.429 0.596,0.402 1.257,0.671 1.927,0.786 1.185,0.202 2.356,-0.083 3.152,-0.922 0.804,-0.847 1.017,-2.032 0.722,-3.202 -0.06,-0.24 -0.14,-0.473 -0.239,-0.701 z"
798 id="path306"
799 style="fill:url(#radialGradient3318)"
800 inkscape:connector-curvature="0" />
801 <radialGradient
802 id="radialGradient3360"
803 cx="132.0938"
804 cy="320.1113"
805 r="4.1712999"
806 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
807 gradientUnits="userSpaceOnUse">
808 <stop
809 offset="0.0112"
810 style="stop-color:#FAF0BB"
811 id="stop3362" />
812 <stop
813 offset="0.4917"
814 style="stop-color:#FAF0BD"
815 id="stop3364" />
816 <stop
817 offset="0.6648"
818 style="stop-color:#FBF2C5"
819 id="stop3366" />
820 <stop
821 offset="0.7882"
822 style="stop-color:#FCF6D0"
823 id="stop3368" />
824 <stop
825 offset="0.8879"
826 style="stop-color:#FCF8E1"
827 id="stop3370" />
828 <stop
829 offset="0.9723"
830 style="stop-color:#FFFDF7"
831 id="stop3372" />
832 <stop
833 offset="1"
834 style="stop-color:#FFFFFF"
835 id="stop3374" />
836 </radialGradient>
837 <path
838 d="m 160.2,265.6 c -0.85,-0.392 -1.938,-0.592 -3.115,-0.521 -1.177,0.07 -2.29,0.405 -3.157,0.906 -0.916,0.53 -1.6,1.269 -1.798,2.11 -0.216,0.917 0.182,1.777 1.05,2.403 0.918,0.663 2.32,1.032 3.923,0.914 1.588,-0.118 2.959,-0.687 3.847,-1.468 0.833,-0.732 1.209,-1.627 0.998,-2.496 -0.195,-0.799 -0.859,-1.438 -1.748,-1.848 z"
839 id="path323"
840 style="fill:url(#radialGradient3320)"
841 inkscape:connector-curvature="0" />
842 <radialGradient
843 id="radialGradient3377"
844 cx="147.44189"
845 cy="301.21091"
846 r="2.5313001"
847 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
848 gradientUnits="userSpaceOnUse">
849 <stop
850 offset="0.0112"
851 style="stop-color:#FAF0BB"
852 id="stop3379" />
853 <stop
854 offset="0.4917"
855 style="stop-color:#FAF0BD"
856 id="stop3381" />
857 <stop
858 offset="0.6648"
859 style="stop-color:#FBF2C5"
860 id="stop3383" />
861 <stop
862 offset="0.7882"
863 style="stop-color:#FCF6D0"
864 id="stop3385" />
865 <stop
866 offset="0.8879"
867 style="stop-color:#FCF8E1"
868 id="stop3387" />
869 <stop
870 offset="0.9723"
871 style="stop-color:#FFFDF7"
872 id="stop3389" />
873 <stop
874 offset="1"
875 style="stop-color:#FFFFFF"
876 id="stop3391" />
877 </radialGradient>
878 <path
879 d="m 173.961,289.2 c 0.657,-0.143 1.12,-0.506 1.265,-1.029 0.133,-0.48 -0.03,-1.015 -0.381,-1.495 -0.335,-0.458 -0.853,-0.886 -1.498,-1.196 -0.645,-0.31 -1.333,-0.461 -1.94,-0.451 -0.643,0.011 -1.223,0.2 -1.576,0.587 -0.385,0.422 -0.428,0.996 -0.152,1.584 0.291,0.622 0.925,1.231 1.811,1.642 0.876,0.408 1.77,0.51 2.471,0.358 z"
880 id="path340"
881 style="fill:url(#radialGradient3322)"
882 inkscape:connector-curvature="0" />
883 </g>
884 <path
885 d="m 32.300561,46.79686 c -0.244913,-0.207495 -0.516006,-0.294969 -0.756275,-0.27971 -0.2276,0.01425 -0.437888,0.12307 -0.584836,0.320395 -0.147371,0.197321 -0.212822,0.456181 -0.201419,0.726735 0.01182,0.283777 0.109788,0.591457 0.300228,0.85845 0.207332,0.290901 0.486027,0.480592 0.771056,0.539586 0.304451,0.06256 0.605105,-0.02543 0.809057,-0.284794 0.206488,-0.26191 0.260961,-0.628075 0.185374,-0.989662 -0.07136,-0.342262 -0.256312,-0.665199 -0.523185,-0.891 z"
886 id="path347"
887 style="fill:#000000"
888 inkscape:connector-curvature="0" />
889 <g
890 id="g349"
891 transform="matrix(0.42226435,0,0,0.50856192,-47.726977,-111.72952)">
892 <path
893 d="m 168.559,264.427 c 4.145,0.407 8.127,1.382 11.858,2.845 l 0.623,-0.856 c -3.919,-1.741 -8.161,-2.906 -12.604,-3.384 l 0.123,1.395 z"
894 id="path351"
895 inkscape:connector-curvature="0"
896 style="fill:#ffffff" />
897 <path
898 d="m 145.971,266.73 1.059,0.888 c 5.193,-2.147 10.87,-3.351 16.738,-3.403 l 0.009,-0.038 0.435,-1.388 c -0.059,0 -0.116,-0.002 -0.175,-0.002 -6.387,-0.024 -12.545,1.39 -18.066,3.943 z"
899 id="path353"
900 inkscape:connector-curvature="0"
901 style="fill:#ffffff" />
902 <path
903 d="m 185.374,269.579 c 0.97,0.527 1.917,1.087 2.84,1.683 l 0.494,-0.416 c -1.011,-0.738 -2.058,-1.431 -3.138,-2.078 l -0.196,0.811 z"
904 id="path355"
905 inkscape:connector-curvature="0"
906 style="fill:#ffffff" />
907 <path
908 d="m 190.66,272.366 -0.224,0.429 c 0.458,0.338 0.91,0.683 1.354,1.038 1.494,1.193 2.916,2.493 4.25,3.889 -1.633,-1.962 -3.44,-3.752 -5.38,-5.356 z"
909 id="path357"
910 inkscape:connector-curvature="0"
911 style="fill:#ffffff" />
912 <path
913 d="m 140.28,269.916 c 0.198,0.281 0.363,0.578 0.496,0.884 0.84,-0.514 1.699,-1.002 2.575,-1.462 l -0.52,-0.994 c -0.871,0.494 -1.721,1.019 -2.551,1.572 z"
914 id="path359"
915 inkscape:connector-curvature="0"
916 style="fill:#ffffff" />
917 <path
918 d="m 133.625,275.426 0.562,0.314 c 0.338,-0.307 0.681,-0.608 1.028,-0.904 -0.192,-0.129 -0.378,-0.272 -0.555,-0.429 -0.35,0.333 -0.696,0.673 -1.035,1.019 z"
919 id="path361"
920 inkscape:connector-curvature="0"
921 style="fill:#ffffff" />
922 <path
923 d="m 130.152,279.456 c 0.139,-0.009 0.279,-0.015 0.419,-0.019 0.538,-0.62 1.091,-1.224 1.66,-1.81 l -0.295,-0.374 c -0.618,0.713 -1.212,1.447 -1.784,2.203 z"
924 id="path363"
925 inkscape:connector-curvature="0"
926 style="fill:#ffffff" />
927 </g>
928 <path
929 d="m 11.717707,25.989048 c -0.05574,-0.15562 -0.125834,-0.306666 -0.209444,-0.44957 -0.01309,0.01012 -0.02618,0.02032 -0.03885,0.03052 -0.04223,0.03408 -0.08403,0.06866 -0.125835,0.10324 -0.05067,0.0417 -0.101339,0.08289 -0.151171,0.125104 -0.05194,0.04324 -0.103455,0.08798 -0.154549,0.132228 -0.04054,0.03459 -0.0815,0.06916 -0.122034,0.104767 -0.06165,0.0534 -0.122457,0.108333 -0.183263,0.16325 -0.03041,0.02747 -0.06122,0.05392 -0.09122,0.08188 -0.09078,0.08288 -0.181151,0.166809 -0.27067,0.251737 -0.09416,0.0895 -0.187063,0.180031 -0.279961,0.272083 -0.02703,0.02695 -0.05447,0.05442 -0.08192,0.08188 -0.07221,0.07272 -0.1439917,0.145958 -0.2153547,0.219699 -0.02281,0.02339 -0.0456,0.04679 -0.068411,0.07019 -0.081499,0.08492 -0.1621494,0.171895 -0.24238,0.258858 -0.041385,0.04477 -0.08276,0.09052 -0.1237229,0.136294 -0.041799,0.04628 -0.08276,0.09308 -0.1241459,0.139347 -0.033364,0.03762 -0.066717,0.07527 -0.1000776,0.113908 0.074741,0.07935 0.1532821,0.152062 0.2343573,0.218175 C 9.5506288,27.855494 9.7347353,27.672921 9.9217999,27.495432 10.4927,26.95178 11.092737,26.44983 11.717689,25.989072 z"
930 id="path365"
931 inkscape:connector-curvature="0"
932 style="fill:#eeeeee" />
933 <path
934 d="m 28.381526,27.537111 c 0.388483,0.0014 0.747409,0.164265 1.026947,0.433802 0.293051,0.282252 0.512205,0.694697 0.575969,1.184949 0.06968,0.534499 -0.05447,1.061878 -0.328523,1.474322 -0.292629,0.439906 -0.744451,0.732838 -1.26806,0.744027 -0.528674,0.01119 -0.990631,-0.26547 -1.292973,-0.70131 -0.286295,-0.411932 -0.417197,-0.947959 -0.345834,-1.495681 0.06503,-0.501949 0.290517,-0.923546 0.592437,-1.209867 0.28545,-0.271063 0.652399,-0.431769 1.040037,-0.430242 z"
935 id="path372"
936 style="fill:#000000"
937 inkscape:connector-curvature="0" />
938 <path
939 d="m 13.466305,55.28374 c 0.178195,0.09256 0.329787,0.214614 0.43662,0.342772 0.111901,0.134768 0.178619,0.281236 0.168063,0.408885 -0.0114,0.139346 -0.111902,0.231394 -0.271518,0.261399 -0.170172,0.03153 -0.401994,-0.0082 -0.64353,-0.129175 -0.244069,-0.12256 -0.433666,-0.295472 -0.53712,-0.467367 -0.09797,-0.162232 -0.114433,-0.316834 -0.03674,-0.425668 0.07093,-0.100193 0.209021,-0.143413 0.37117,-0.13782 0.152859,0.005 0.334856,0.05491 0.513051,0.146974 l 0,0 z m -2.368059,-0.261399 c 0.05025,0.0122 0.09585,0.04017 0.130479,0.0768 0.03588,0.03815 0.06165,0.08797 0.06671,0.140364 0.0055,0.05696 -0.01435,0.10731 -0.05278,0.141381 -0.04097,0.0356 -0.101763,0.05188 -0.169749,0.03611 -0.06883,-0.01525 -0.127102,-0.05848 -0.163417,-0.113404 -0.03463,-0.05139 -0.04772,-0.110861 -0.03463,-0.164774 0.01183,-0.04984 0.04392,-0.08594 0.0853,-0.10578 0.03885,-0.01831 0.08741,-0.02339 0.138081,-0.01071 l 0,0 z m 3.807979,2.368373 c 0.09627,0.02389 0.183263,0.07728 0.248714,0.147481 0.06925,0.07322 0.117813,0.167318 0.127101,0.267506 0.01013,0.109332 -0.02745,0.204948 -0.100915,0.270045 -0.07854,0.06866 -0.194242,0.09866 -0.324299,0.06968 -0.131324,-0.03002 -0.24238,-0.111886 -0.311631,-0.216139 -0.06545,-0.09816 -0.09122,-0.21156 -0.0663,-0.314799 0.02281,-0.09459 0.08446,-0.163757 0.162995,-0.2019 0.07515,-0.03611 0.16806,-0.04576 0.264336,-0.02185 l 0,0 z m -2.357501,-1.035942 c -0.09333,-0.04831 -0.188754,-0.07425 -0.269405,-0.0768 -0.08487,-0.003 -0.157504,0.01983 -0.194242,0.07222 -0.04054,0.05696 -0.03209,0.137821 0.01942,0.222749 0.05405,0.09052 0.153704,0.18054 0.281651,0.245128 0.126679,0.06356 0.247869,0.08391 0.337388,0.06765 0.08362,-0.01576 0.136392,-0.06407 0.142304,-0.137313 0.0055,-0.06713 -0.02956,-0.143414 -0.08783,-0.214102 -0.05658,-0.06714 -0.135969,-0.13121 -0.22929,-0.179526 z"
940 id="path374"
941 inkscape:connector-curvature="0"
942 style="fill:#d9bb7a" />
943 <path
944 d="m 32.89722,32.895826 c 0.143148,-0.434312 0.431555,-0.762333 0.795547,-0.953043 0.380884,-0.199865 0.861841,-0.255808 1.361803,-0.10325 0.544721,0.166808 1.012166,0.547722 1.313242,1.044079 0.320921,0.529412 0.440844,1.170201 0.26096,1.762675 -0.181574,0.59807 -0.618618,0.989661 -1.15236,1.129517 -0.504607,0.132224 -1.073818,0.03356 -1.579691,-0.297003 -0.464491,-0.303099 -0.791747,-0.749617 -0.960229,-1.219019 -0.160039,-0.444994 -0.182419,-0.929651 -0.03927,-1.363962 z"
945 id="path381"
946 style="fill:#000000"
947 inkscape:connector-curvature="0" />
948 <path
949 d="m 35.093418,44.08063 c -0.146948,-0.197323 -0.212399,-0.456178 -0.200998,-0.726732 0.01182,-0.28378 0.109367,-0.591461 0.299807,-0.858457 0.207754,-0.290895 0.486028,-0.480589 0.771477,-0.540093 0.304453,-0.06256 0.604685,0.02594 0.809059,0.285306 0.206487,0.261909 0.26096,0.628075 0.184952,0.989659 -0.07137,0.342262 -0.256313,0.6652 -0.523607,0.891001 -0.244913,0.207492 -0.515586,0.294965 -0.755853,0.27971 -0.227601,-0.01423 -0.437466,-0.123072 -0.584837,-0.320394 z"
950 id="path388"
951 style="fill:#000000"
952 inkscape:connector-curvature="0" />
953 <path
954 d="m 24.819304,51.017414 c -0.147371,-0.197322 -0.212821,-0.456179 -0.201421,-0.727243 0.01183,-0.283269 0.10979,-0.590948 0.30023,-0.858455 0.207333,-0.290896 0.485604,-0.481098 0.771055,-0.540089 0.304453,-0.06256 0.605106,0.02594 0.809059,0.285303 0.206487,0.261908 0.260959,0.628074 0.184952,0.989661 -0.07136,0.342263 -0.256314,0.6652 -0.523608,0.891002 -0.24449,0.207493 -0.515584,0.294964 -0.755854,0.279709 -0.2276,-0.01425 -0.437465,-0.123071 -0.584413,-0.319888 z"
955 id="path395"
956 style="fill:#000000"
957 inkscape:connector-curvature="0" />
958 <path
959 d="m 23.786446,24.445052 c 0.102186,-0.347855 0.322609,-0.616885 0.605104,-0.779624 0.296007,-0.170876 0.673933,-0.232414 1.072129,-0.128666 0.433667,0.112897 0.812438,0.396678 1.061996,0.778609 0.266026,0.406849 0.376235,0.908289 0.24829,1.382269 -0.12879,0.47805 -0.464913,0.802512 -0.882532,0.931685 -0.395661,0.12205 -0.84664,0.06357 -1.254126,-0.17952 -0.374125,-0.222751 -0.642686,-0.563996 -0.787099,-0.928635 -0.137237,-0.346331 -0.166373,-0.728261 -0.06377,-1.076118 z"
960 id="path402"
961 style="fill:#000000"
962 inkscape:connector-curvature="0" />
963 <path
964 d="m 9.3572511,27.571182 c 0.2537814,0.256316 0.5518992,0.424651 0.8555069,0.487204 0.426486,0.08747 0.848329,-0.03611 1.135047,-0.399731 0.28925,-0.367181 0.366103,-0.880828 0.259692,-1.388372 -0.0456,-0.217666 -0.123723,-0.429227 -0.230557,-0.625532 -0.344568,0.281745 -0.680268,0.577726 -1.006255,0.886932 -0.347524,0.330057 -0.6857564,0.676897 -1.0134339,1.039499 z"
965 id="path409"
966 style="fill:#000000"
967 inkscape:connector-curvature="0" />
968 <path
969 d="m 9.3572511,27.571182 c 0.081923,0.08289 0.1684839,0.15664 0.2584255,0.220208 0.1013389,-0.100194 0.2031087,-0.199865 0.3061417,-0.296999 0.5244517,-0.497883 1.0733947,-0.962708 1.6434517,-1.391936 -0.04604,-0.15867 -0.109367,-0.312257 -0.188752,-0.457195 l 0,0 c -0.02997,0.02442 -0.05996,0.04933 -0.08995,0.07425 -0.01942,0.01628 -0.03927,0.03255 -0.05869,0.04883 -0.03336,0.02747 -0.0663,0.05545 -0.09923,0.08341 l -0.04519,0.03865 c -0.03758,0.03205 -0.07474,0.06407 -0.111899,0.09613 l -0.02997,0.02594 c -0.04139,0.03611 -0.08235,0.07221 -0.123301,0.108332 l -0.02026,0.01832 c -0.04392,0.03918 -0.08741,0.07781 -0.130901,0.117485 l -0.01309,0.01169 c -0.04603,0.04223 -0.09206,0.08442 -0.13808,0.12714 l -0.0018,0.0014 c -0.04815,0.04476 -0.09585,0.0895 -0.143569,0.134769 -0.07685,0.07322 -0.15286,0.146467 -0.228867,0.221226 l -0.01098,0.01072 c -0.02026,0.02032 -0.04097,0.04018 -0.06123,0.06051 l -0.01858,0.01882 -0.05236,0.05238 -0.02956,0.03002 -0.04307,0.04376 -0.03801,0.03865 -0.01605,0.01627 -0.01562,0.01627 -0.04771,0.04883 -0.01562,0.01627 C 9.6459492,27.256383 9.50069,27.412511 9.3571211,27.571183 z"
970 id="path411"
971 inkscape:connector-curvature="0"
972 style="fill:#888678" />
973 <path
974 d="m 18.571057,23.295194 c 0.423955,-0.03051 0.815816,0.05645 1.121534,0.226311 0.320077,0.177997 0.559079,0.455163 0.629176,0.800985 0.07601,0.376844 -0.05954,0.764369 -0.359348,1.082221 -0.319232,0.338701 -0.812859,0.585354 -1.385028,0.636719 -0.577235,0.05138 -1.081841,-0.108827 -1.412472,-0.39617 -0.312477,-0.271573 -0.456047,-0.644349 -0.378351,-1.042043 0.07136,-0.364639 0.317965,-0.685034 0.647333,-0.914395 0.312897,-0.217665 0.713204,-0.363114 1.137156,-0.393628 z"
975 id="path418"
976 style="fill:#000000"
977 inkscape:connector-curvature="0" />
978 <path
979 d="m 25.268593,33.539157 c 0.209865,0.121549 0.37835,0.289372 0.487716,0.468895 0.11401,0.188169 0.167216,0.397695 0.123723,0.585864 -0.04687,0.20495 -0.198043,0.347856 -0.412131,0.403289 -0.228021,0.05951 -0.519383,0.01933 -0.804835,-0.139854 -0.288406,-0.160707 -0.494471,-0.399731 -0.589482,-0.643842 -0.08995,-0.230376 -0.07601,-0.455669 0.04941,-0.620952 0.114856,-0.152061 0.304451,-0.226311 0.51305,-0.230379 0.198043,-0.0036 0.422688,0.05543 0.632553,0.176979 z"
980 id="path425"
981 style="fill:#000000"
982 inkscape:connector-curvature="0" />
983 <polygon
984 points="190.01,322.008 182.526,321.973 188.385,321.662 183.827,319.426 "
985 id="polygon427"
986 transform="matrix(0.42226435,0,0,0.50856192,-47.726977,-111.72952)" />
987 <polygon
988 points="182.677,309.541 176.606,313.919 181.161,310.218 176.159,311.094 "
989 id="polygon429"
990 transform="matrix(0.42226435,0,0,0.50856192,-47.726977,-111.72952)" />
991 <polygon
992 points="191.129,279.553 180.144,285.178 188.996,281.271 183.955,287.956 "
993 id="polygon431"
994 transform="matrix(0.42226435,0,0,0.50856192,-47.726977,-111.72952)" />
995 <path
996 d="m 35.589578,54.524966 c -0.122034,0.197832 -0.247447,0.39312 -0.376237,0.586373 -3.139958,4.719964 -7.989242,7.864909 -13.609581,7.987982 C 15.929794,63.222902 10.97199,60.250356 7.7226683,55.572603 7.5229375,55.285266 7.3303849,54.991318 7.1445881,54.693299 c 3.5503959,4.555698 8.6741509,7.392458 14.4832419,7.265826 5.617804,-0.123069 10.532541,-3.002548 13.961748,-7.434159 z"
997 id="path440"
998 style="fill:#d9bb7a"
999 inkscape:connector-curvature="0" />
1000 <path
1001 d="m 16.345302,52.251694 c -2.117655,-1.929991 -2.971052,-5.408047 -1.900189,-8.495019 1.184029,-3.41245 4.302452,-5.144614 7.182295,-4.121385 -2.791167,-0.695713 -5.69128,1.060859 -6.831394,4.34617 -1.023146,2.94966 -0.321343,6.249209 1.549288,8.270234 z"
1002 id="path442"
1003 inkscape:connector-curvature="0"
1004 style="fill:#ffffff" />
1005 <path
1006 d="m 7.9004418,49.211004 c 1.5839109,-1.826246 1.8765395,-5.188352 0.611861,-7.774387 -0.9606515,-1.964067 -2.560189,-2.949661 -4.0731622,-2.724366 1.4428771,-0.03307 2.911513,0.974913 3.8219146,2.837267 1.2266751,2.507718 1.0299008,5.725391 -0.3606134,7.661486 z"
1007 id="path444"
1008 inkscape:connector-curvature="0"
1009 style="fill:#ffffff" />
1010 <path
1011 d="m 46.744961,35.073491 -0.497006,-0.879306 c -0.446333,-0.789288 -2.616772,-1.271403 -3.063106,-2.060692 -0.04897,-0.08645 -0.08995,-0.178504 -0.124145,-0.273607 0.02111,0.05392 0.04434,0.106285 0.07093,0.157655 0.411286,0.799459 2.442378,0.780134 2.853664,1.579592 l 0.759653,1.476358 0,0 z m -3.840919,-4.235306 c -0.02154,-1.142737 0.276584,-2.476187 -0.211554,-3.339725 -0.684068,-1.210379 -3.109133,-1.708769 -3.070285,-3.678937 0.02618,-1.300901 0.05531,-2.044928 -0.877888,-0.830484 -0.474202,0.616888 -0.933204,1.256658 -1.378271,1.918806 0.532898,-0.895579 1.084376,-1.758098 1.656966,-2.58553 0.921382,-1.331414 0.877043,-0.549754 0.825104,0.815225 -0.02492,0.63723 0.05786,1.381764 0.330634,1.912701 0.487293,0.947452 2.164949,1.469236 2.652243,2.416687 0.464492,0.901679 0.07769,2.233605 0.07305,3.371257 z"
1012 id="path446"
1013 inkscape:connector-curvature="0"
1014 style="fill:#ffffff" />
1015 <path
1016 d="m 16.756588,33.897186 c 0.357235,-0.248687 0.77781,-0.246145 1.121111,-0.03865 -0.09501,0.0122 -0.189596,0.04832 -0.27785,0.109346 -0.338655,0.235464 -0.455199,0.757757 -0.25927,1.165625 0.19551,0.408372 0.629174,0.548229 0.96783,0.312255 0.08783,-0.06155 0.160883,-0.14189 0.217467,-0.234955 -0.02237,0.461773 -0.230979,0.901679 -0.588638,1.150367 -0.564566,0.39261 -1.287061,0.15918 -1.613471,-0.520769 -0.325145,-0.680454 -0.131747,-1.550096 0.432821,-1.943214 l 0,0 z m -8.4625961,1.183931 c 0.2575811,-0.179014 0.5603435,-0.177488 0.8077901,-0.02795 -0.068836,0.009 -0.1368128,0.03458 -0.2001525,0.07882 -0.2440687,0.169354 -0.327677,0.545687 -0.1866399,0.839639 0.1406128,0.293947 0.453088,0.394643 0.6971553,0.224782 0.063334,-0.04425 0.1161241,-0.102217 0.1570835,-0.16935 C 9.5527694,36.35966 9.4024339,36.676495 9.1452751,36.855507 8.7386349,37.138248 8.2179844,36.970431 7.983206,36.480169 7.7475821,35.990933 7.887351,35.363875 8.2939919,35.081114 z"
1017 id="path448"
1018 inkscape:connector-curvature="0" />
1019 <path
1020 d="m 11.148494,37.665629 c -0.260113,-0.748095 -0.420152,-1.550096 -0.46449,-2.376002 -0.533741,1.967118 -1.8647168,3.382956 -3.4389171,3.862529 0.4619579,0.354468 0.8876005,0.829465 1.2503252,1.416854 1.1793816,-0.417022 2.1776139,-1.463641 2.6530819,-2.903381 z"
1021 id="path450"
1022 inkscape:connector-curvature="0"
1023 style="fill:#eeeeee" />
1024 <path
1025 d="m 3.5654754,33.263516 c -0.2884063,0.139348 -0.5160068,0.432279 -0.656621,0.92355 -0.6697112,2.341929 -0.5459877,4.035438 0.033358,5.072397 C 3.09465,39.150129 3.25131,39.055528 3.4109259,38.975177 3.537183,38.886186 3.6659737,38.807859 3.7972979,38.739713 3.1153408,37.498312 2.8611376,35.923805 3.2065499,34.3732 3.2935369,33.980083 3.4151486,33.609339 3.5654746,33.263516 z"
1026 id="path457"
1027 style="fill:#f0a513"
1028 inkscape:connector-curvature="0" />
1029 <path
1030 d="m 9.6346789,48.851958 c 0.7959681,1.053234 2.8688621,0.917445 3.5212611,-0.268012 -0.352592,0.781151 -1.04046,1.31209 -1.830517,1.31209 -0.695891,0 -1.312395,-0.411935 -1.6907441,-1.044078 z"
1031 id="path459"
1032 inkscape:connector-curvature="0"
1033 style="fill:#ffffff" />
1034 </g>
1035 </g>
1036 </svg>
0 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
1 <!-- Created with Inkscape (http://www.inkscape.org/) -->
2
3 <svg
4 xmlns:dc="http://purl.org/dc/elements/1.1/"
5 xmlns:cc="http://creativecommons.org/ns#"
6 xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
7 xmlns:svg="http://www.w3.org/2000/svg"
8 xmlns="http://www.w3.org/2000/svg"
9 xmlns:xlink="http://www.w3.org/1999/xlink"
10 xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
11 xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
12 width="24"
13 height="24"
14 id="svg3720"
15 version="1.1"
16 inkscape:version="0.48.3.1 r9886"
17 sodipodi:docname="diodon.svg">
18 <defs
19 id="defs3722">
20 <radialGradient
21 inkscape:collect="always"
22 xlink:href="#SVGID_3_"
23 id="radialGradient3305"
24 gradientUnits="userSpaceOnUse"
25 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
26 cx="163.4902"
27 cy="274.86621"
28 r="2.8801" />
29 <radialGradient
30 gradientUnits="userSpaceOnUse"
31 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
32 r="2.8801"
33 cy="274.86621"
34 cx="163.4902"
35 id="SVGID_3_">
36 <stop
37 id="stop190"
38 style="stop-color:#FAF0BB"
39 offset="0.0112" />
40 <stop
41 id="stop192"
42 style="stop-color:#FAF0BD"
43 offset="0.4917" />
44 <stop
45 id="stop194"
46 style="stop-color:#FBF2C5"
47 offset="0.6648" />
48 <stop
49 id="stop196"
50 style="stop-color:#FCF6D0"
51 offset="0.7882" />
52 <stop
53 id="stop198"
54 style="stop-color:#FCF8E1"
55 offset="0.8879" />
56 <stop
57 id="stop200"
58 style="stop-color:#FFFDF7"
59 offset="0.9723" />
60 <stop
61 id="stop202"
62 style="stop-color:#FFFFFF"
63 offset="1" />
64 </radialGradient>
65 <radialGradient
66 inkscape:collect="always"
67 xlink:href="#SVGID_4_"
68 id="radialGradient3307"
69 gradientUnits="userSpaceOnUse"
70 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
71 cx="155.3242"
72 cy="310.6777"
73 r="4.4867001" />
74 <radialGradient
75 gradientUnits="userSpaceOnUse"
76 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
77 r="4.4867001"
78 cy="310.6777"
79 cx="155.3242"
80 id="SVGID_4_">
81 <stop
82 id="stop207"
83 style="stop-color:#FAF0BB"
84 offset="0.0112" />
85 <stop
86 id="stop209"
87 style="stop-color:#FAF0BD"
88 offset="0.4917" />
89 <stop
90 id="stop211"
91 style="stop-color:#FBF2C5"
92 offset="0.6648" />
93 <stop
94 id="stop213"
95 style="stop-color:#FCF6D0"
96 offset="0.7882" />
97 <stop
98 id="stop215"
99 style="stop-color:#FCF8E1"
100 offset="0.8879" />
101 <stop
102 id="stop217"
103 style="stop-color:#FFFDF7"
104 offset="0.9723" />
105 <stop
106 id="stop219"
107 style="stop-color:#FFFFFF"
108 offset="1" />
109 </radialGradient>
110 <radialGradient
111 inkscape:collect="always"
112 xlink:href="#SVGID_5_"
113 id="radialGradient3310"
114 gradientUnits="userSpaceOnUse"
115 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
116 cx="170.3125"
117 cy="302.00781"
118 r="5.0811" />
119 <radialGradient
120 gradientUnits="userSpaceOnUse"
121 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
122 r="5.0811"
123 cy="302.00781"
124 cx="170.3125"
125 id="SVGID_5_">
126 <stop
127 id="stop224"
128 style="stop-color:#FAF0BB"
129 offset="0.0112" />
130 <stop
131 id="stop226"
132 style="stop-color:#FAF0BD"
133 offset="0.4917" />
134 <stop
135 id="stop228"
136 style="stop-color:#FBF2C5"
137 offset="0.6648" />
138 <stop
139 id="stop230"
140 style="stop-color:#FCF6D0"
141 offset="0.7882" />
142 <stop
143 id="stop232"
144 style="stop-color:#FCF8E1"
145 offset="0.8879" />
146 <stop
147 id="stop234"
148 style="stop-color:#FFFDF7"
149 offset="0.9723" />
150 <stop
151 id="stop236"
152 style="stop-color:#FFFFFF"
153 offset="1" />
154 </radialGradient>
155 <radialGradient
156 inkscape:collect="always"
157 xlink:href="#SVGID_6_"
158 id="radialGradient3312"
159 gradientUnits="userSpaceOnUse"
160 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
161 cx="173.2812"
162 cy="283.68359"
163 r="2.8803999" />
164 <radialGradient
165 gradientUnits="userSpaceOnUse"
166 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
167 r="2.8803999"
168 cy="283.68359"
169 cx="173.2812"
170 id="SVGID_6_">
171 <stop
172 id="stop241"
173 style="stop-color:#FAF0BB"
174 offset="0.0112" />
175 <stop
176 id="stop243"
177 style="stop-color:#FAF0BD"
178 offset="0.4917" />
179 <stop
180 id="stop245"
181 style="stop-color:#FBF2C5"
182 offset="0.6648" />
183 <stop
184 id="stop247"
185 style="stop-color:#FCF6D0"
186 offset="0.7882" />
187 <stop
188 id="stop249"
189 style="stop-color:#FCF8E1"
190 offset="0.8879" />
191 <stop
192 id="stop251"
193 style="stop-color:#FFFDF7"
194 offset="0.9723" />
195 <stop
196 id="stop253"
197 style="stop-color:#FFFFFF"
198 offset="1" />
199 </radialGradient>
200 <radialGradient
201 inkscape:collect="always"
202 xlink:href="#SVGID_7_"
203 id="radialGradient3314"
204 gradientUnits="userSpaceOnUse"
205 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
206 cx="148.9492"
207 cy="270.04489"
208 r="2.8799" />
209 <radialGradient
210 gradientUnits="userSpaceOnUse"
211 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
212 r="2.8799"
213 cy="270.04489"
214 cx="148.9492"
215 id="SVGID_7_">
216 <stop
217 id="stop258"
218 style="stop-color:#FAF0BB"
219 offset="0.0112" />
220 <stop
221 id="stop260"
222 style="stop-color:#FAF0BD"
223 offset="0.4917" />
224 <stop
225 id="stop262"
226 style="stop-color:#FBF2C5"
227 offset="0.6648" />
228 <stop
229 id="stop264"
230 style="stop-color:#FCF6D0"
231 offset="0.7882" />
232 <stop
233 id="stop266"
234 style="stop-color:#FCF8E1"
235 offset="0.8879" />
236 <stop
237 id="stop268"
238 style="stop-color:#FFFDF7"
239 offset="0.9723" />
240 <stop
241 id="stop270"
242 style="stop-color:#FFFFFF"
243 offset="1" />
244 </radialGradient>
245 <radialGradient
246 inkscape:collect="always"
247 xlink:href="#SVGID_8_"
248 id="radialGradient3316"
249 gradientUnits="userSpaceOnUse"
250 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
251 cx="148.0723"
252 cy="319.09381"
253 r="3.9265001" />
254 <radialGradient
255 gradientUnits="userSpaceOnUse"
256 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
257 r="3.9265001"
258 cy="319.09381"
259 cx="148.0723"
260 id="SVGID_8_">
261 <stop
262 id="stop275"
263 style="stop-color:#FAF0BB"
264 offset="0.0112" />
265 <stop
266 id="stop277"
267 style="stop-color:#FAF0BD"
268 offset="0.4917" />
269 <stop
270 id="stop279"
271 style="stop-color:#FBF2C5"
272 offset="0.6648" />
273 <stop
274 id="stop281"
275 style="stop-color:#FCF6D0"
276 offset="0.7882" />
277 <stop
278 id="stop283"
279 style="stop-color:#FCF8E1"
280 offset="0.8879" />
281 <stop
282 id="stop285"
283 style="stop-color:#FFFDF7"
284 offset="0.9723" />
285 <stop
286 id="stop287"
287 style="stop-color:#FFFFFF"
288 offset="1" />
289 </radialGradient>
290 <radialGradient
291 inkscape:collect="always"
292 xlink:href="#SVGID_9_"
293 id="radialGradient3318"
294 gradientUnits="userSpaceOnUse"
295 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
296 cx="112.9551"
297 cy="315.56049"
298 r="3.0683999" />
299 <radialGradient
300 gradientUnits="userSpaceOnUse"
301 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
302 r="3.0683999"
303 cy="315.56049"
304 cx="112.9551"
305 id="SVGID_9_">
306 <stop
307 id="stop292"
308 style="stop-color:#FAF0BB"
309 offset="0.0112" />
310 <stop
311 id="stop294"
312 style="stop-color:#FAF0BD"
313 offset="0.4917" />
314 <stop
315 id="stop296"
316 style="stop-color:#FBF2C5"
317 offset="0.6648" />
318 <stop
319 id="stop298"
320 style="stop-color:#FCF6D0"
321 offset="0.7882" />
322 <stop
323 id="stop300"
324 style="stop-color:#FCF8E1"
325 offset="0.8879" />
326 <stop
327 id="stop302"
328 style="stop-color:#FFFDF7"
329 offset="0.9723" />
330 <stop
331 id="stop304"
332 style="stop-color:#FFFFFF"
333 offset="1" />
334 </radialGradient>
335 <radialGradient
336 inkscape:collect="always"
337 xlink:href="#SVGID_10_"
338 id="radialGradient3320"
339 gradientUnits="userSpaceOnUse"
340 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
341 cx="132.0938"
342 cy="320.1113"
343 r="4.1712999" />
344 <radialGradient
345 gradientUnits="userSpaceOnUse"
346 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
347 r="4.1712999"
348 cy="320.1113"
349 cx="132.0938"
350 id="SVGID_10_">
351 <stop
352 id="stop309"
353 style="stop-color:#FAF0BB"
354 offset="0.0112" />
355 <stop
356 id="stop311"
357 style="stop-color:#FAF0BD"
358 offset="0.4917" />
359 <stop
360 id="stop313"
361 style="stop-color:#FBF2C5"
362 offset="0.6648" />
363 <stop
364 id="stop315"
365 style="stop-color:#FCF6D0"
366 offset="0.7882" />
367 <stop
368 id="stop317"
369 style="stop-color:#FCF8E1"
370 offset="0.8879" />
371 <stop
372 id="stop319"
373 style="stop-color:#FFFDF7"
374 offset="0.9723" />
375 <stop
376 id="stop321"
377 style="stop-color:#FFFFFF"
378 offset="1" />
379 </radialGradient>
380 <radialGradient
381 inkscape:collect="always"
382 xlink:href="#SVGID_11_"
383 id="radialGradient3322"
384 gradientUnits="userSpaceOnUse"
385 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
386 cx="147.44189"
387 cy="301.21091"
388 r="2.5313001" />
389 <radialGradient
390 gradientUnits="userSpaceOnUse"
391 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
392 r="2.5313001"
393 cy="301.21091"
394 cx="147.44189"
395 id="SVGID_11_">
396 <stop
397 id="stop326"
398 style="stop-color:#FAF0BB"
399 offset="0.0112" />
400 <stop
401 id="stop328"
402 style="stop-color:#FAF0BD"
403 offset="0.4917" />
404 <stop
405 id="stop330"
406 style="stop-color:#FBF2C5"
407 offset="0.6648" />
408 <stop
409 id="stop332"
410 style="stop-color:#FCF6D0"
411 offset="0.7882" />
412 <stop
413 id="stop334"
414 style="stop-color:#FCF8E1"
415 offset="0.8879" />
416 <stop
417 id="stop336"
418 style="stop-color:#FFFDF7"
419 offset="0.9723" />
420 <stop
421 id="stop338"
422 style="stop-color:#FFFFFF"
423 offset="1" />
424 </radialGradient>
425 </defs>
426 <sodipodi:namedview
427 id="base"
428 pagecolor="#ffffff"
429 bordercolor="#666666"
430 borderopacity="1.0"
431 inkscape:pageopacity="0.0"
432 inkscape:pageshadow="2"
433 inkscape:zoom="22.395604"
434 inkscape:cx="1.9698115"
435 inkscape:cy="13.030678"
436 inkscape:current-layer="layer1"
437 showgrid="true"
438 inkscape:grid-bbox="true"
439 inkscape:document-units="px"
440 showborder="true"
441 borderlayer="false"
442 inkscape:window-width="1600"
443 inkscape:window-height="876"
444 inkscape:window-x="0"
445 inkscape:window-y="24"
446 inkscape:window-maximized="1"
447 gridtolerance="10"
448 objecttolerance="10"
449 guidetolerance="10">
450 <inkscape:grid
451 type="xygrid"
452 id="grid4738"
453 empspacing="5"
454 visible="true"
455 enabled="true"
456 snapvisiblegridlinesonly="true" />
457 </sodipodi:namedview>
458 <metadata
459 id="metadata3725">
460 <rdf:RDF>
461 <cc:Work
462 rdf:about="">
463 <dc:format>image/svg+xml</dc:format>
464 <dc:type
465 rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
466 <dc:title />
467 </cc:Work>
468 </rdf:RDF>
469 </metadata>
470 <g
471 id="layer1"
472 inkscape:label="Layer 1"
473 inkscape:groupmode="layer"
474 transform="translate(0,-8)">
475 <g
476 id="g3183"
477 transform="matrix(0.46701614,0,0,0.38319022,0.63989446,4.647041)">
478 <path
479 d="m 47.748262,36.240641 c -0.304876,-0.669777 -0.939962,-2.526029 -1.264261,-3.180039 -0.499962,-1.005938 -2.409862,-0.340737 -2.850285,-1.402107 -0.615238,-1.481949 0.402841,-3.075783 -0.26687,-4.517046 -0.51052,-1.098494 -2.320767,-1.749962 -2.830861,-2.848458 -0.374128,-0.804542 0.05785,-5.080024 -0.915894,-3.703855 -1.643875,2.32362 -3.133623,4.929999 -4.51865,7.769812 -0.227178,-0.299544 -0.460268,-0.590441 -0.699692,-0.872694 l 1.273972,-2.395837 -1.94875,1.641638 C 33.517528,26.509306 33.303862,26.293167 33.085974,26.08364 l 0.936581,-2.162914 -1.564066,1.585187 C 31.923058,25.034986 31.365246,24.598131 30.785899,24.1984 l 1.168829,-5.78896 -2.873088,4.753021 C 28.796189,23.01091 28.507361,22.866987 28.213887,22.732727 l 0.283762,-3.540102 -1.360114,3.093074 C 25.924369,21.832064 24.65631,21.526925 23.350669,21.385545 l -0.349636,-4.806419 -1.226255,4.716403 c -0.0033,0 -0.0071,0 -0.01056,0 -1.422186,-0.0066 -2.818193,0.185117 -4.164371,0.553823 l -1.190787,-2.856081 0.196351,3.163762 c -0.403261,0.139347 -0.801035,0.294459 -1.193319,0.465334 l -0.676466,-1.193086 0.243647,1.388883 c -0.482226,0.226309 -0.954317,0.47703 -1.416273,0.750127 l -2.649288,-2.676561 1.488058,3.425166 c -0.733893,0.515174 -1.434852,1.088322 -2.09654,1.715887 -0.09374,0.089 -0.187063,0.180031 -0.279538,0.271064 l -2.6176137,-1.775898 1.7557735,2.685206 c -0.2643372,0.297002 -0.5214955,0.60519 -0.7718972,0.922533 l -2.0728961,-1.396004 1.4580788,2.215805 c -0.340767,0.479065 -0.6650662,0.978474 -0.9716305,1.49568 -1.2705932,0.251233 -2.4081735,1.157486 -3.0905527,2.497041 0.00253,-0.005 0.00508,-0.01071 0.00802,-0.01578 -0.5079841,0.01071 -0.9074462,0.311242 -1.1177337,1.046115 -0.7347402,2.568744 -0.5366981,4.375156 0.1689057,5.408554 -0.1199231,0.09664 -0.2373126,0.202409 -0.3517463,0.317854 -1.90145688,1.925922 -2.20548742,5.78845 -0.6790012,8.625208 0.8470624,1.574001 2.0796522,2.501617 3.3341996,2.686733 0.6452198,1.719448 1.4880601,3.337183 2.5116286,4.809977 3.3333522,4.799809 8.4203702,7.849148 14.2412852,7.722516 5.766442,-0.126125 10.741561,-3.352949 13.962593,-8.195477 2.268826,-3.410417 3.604027,-7.536378 3.803758,-11.87187 L 41.77997,42.904823 39.623044,42.4461 c 0.003,-0.734364 -0.02618,-1.473813 -0.08952,-2.215806 l 3.332089,-2.112565 -3.537731,0.400746 C 39.264542,38.110618 39.19107,37.708348 39.108306,37.31116 l 0.959807,-0.628583 -1.067483,0.13782 c -0.02618,-0.113909 -0.05278,-0.226818 -0.08023,-0.33972 2.756541,-0.434818 5.473393,-0.393116 8.225288,0.328024 0.699694,0.183591 0.893512,0.07272 0.602574,-0.568064 z M 3.2551113,34.170284 c -0.017313,0.06662 -0.033782,0.134262 -0.04856,0.202916 -0.0114,0.05139 -0.022381,0.102733 -0.032514,0.154602 0.010132,-0.05188 0.020692,-0.10325 0.032514,-0.154602 0.01478,-0.06866 0.031247,-0.136294 0.04856,-0.202916 z m 0.4049515,-1.11121 c -0.010132,0.02085 -0.020269,0.04223 -0.030404,0.06306 0.010132,-0.02085 0.02027,-0.04222 0.030404,-0.06306 z m -0.079808,0.172404 c -0.010557,0.02339 -0.020692,0.0473 -0.030825,0.07119 0.010132,-0.02389 0.02027,-0.04782 0.030825,-0.07119 z m -0.075164,0.177488 c -0.010557,0.02644 -0.021113,0.0529 -0.031248,0.07984 0.010132,-0.02694 0.020692,-0.0534 0.031248,-0.07984 z m -0.070097,0.182573 c -0.010979,0.03002 -0.021535,0.06 -0.032092,0.09001 0.010557,-0.03002 0.021113,-0.06002 0.032092,-0.09001 z m -0.06545,0.187661 c -0.01098,0.03407 -0.021535,0.06866 -0.032515,0.103238 0.010979,-0.03458 0.021113,-0.06866 0.032515,-0.103238 z m -0.059962,0.193252 c -0.011823,0.04119 -0.023225,0.08289 -0.034626,0.124599 0.0114,-0.04172 0.022381,-0.08342 0.034626,-0.124599 z m -0.2558905,1.703683 c -8.452e-4,0.05034 -8.452e-4,0.100695 -4.223e-4,0.150535 -4.223e-4,-0.05034 -4.223e-4,-0.100705 4.223e-4,-0.150535 z m 0.1106333,-1.097477 c -0.00633,0.03458 -0.012668,0.06866 -0.018578,0.103239 0.00591,-0.03407 0.012245,-0.06866 0.018578,-0.103239 z m -0.028713,0.164775 c -0.00507,0.03153 -0.010132,0.06256 -0.01478,0.09357 0.00464,-0.03101 0.00971,-0.06204 0.01478,-0.09357 z m -0.023646,0.15867 c -0.00423,0.03053 -0.00802,0.06053 -0.011823,0.09052 0.00379,-0.03052 0.0076,-0.06054 0.011823,-0.09052 z m -0.019423,0.156131 c -0.00338,0.03002 -0.00633,0.05949 -0.00929,0.0895 0.00296,-0.03002 0.00591,-0.05951 0.00929,-0.0895 z m -0.015624,0.155617 c -0.00253,0.03002 -0.00464,0.06001 -0.00717,0.09001 0.00253,-0.03002 0.00508,-0.06001 0.00717,-0.09001 z m -0.0114,0.154604 c -0.0017,0.03154 -0.00338,0.06256 -0.00507,0.09408 0.0017,-0.03153 0.00338,-0.06256 0.00507,-0.09408 z m -0.0076,0.154095 c -0.00127,0.03662 -0.00211,0.07322 -0.00296,0.109332 4.221e-4,-0.03662 0.00127,-0.07272 0.00296,-0.109332 z m 0.1634162,1.705207 c -0.0076,-0.03203 -0.01478,-0.06407 -0.021535,-0.09611 0.00718,0.03205 0.013934,0.06407 0.021535,0.09611 z m -0.037161,-0.168331 c -0.00802,-0.03865 -0.015624,-0.07728 -0.023225,-0.115944 0.0076,0.03865 0.015624,0.07729 0.023225,0.115944 z m -0.033785,-0.176983 c -0.00507,-0.02847 -0.010132,-0.05696 -0.01478,-0.08543 0.00464,0.02795 0.010132,0.05696 0.01478,0.08543 z m -0.024491,-0.152059 c -0.00423,-0.02694 -0.00844,-0.05392 -0.012245,-0.08138 0.00379,0.02694 0.0076,0.05442 0.012245,0.08138 z m -0.021113,-0.150025 c -0.00338,-0.02694 -0.00675,-0.0534 -0.00971,-0.08086 0.00296,0.02747 0.00633,0.05442 0.00971,0.08086 z m -0.017313,-0.149518 c -0.00296,-0.02694 -0.00549,-0.05392 -0.00802,-0.08137 0.00253,0.02747 0.00508,0.05441 0.00802,0.08137 z m -0.013934,-0.150024 c -0.00211,-0.02795 -0.00423,-0.05546 -0.00591,-0.08341 0.0017,0.02747 0.00379,0.05544 0.00591,0.08341 z m -0.010132,-0.150536 c -0.0017,-0.0295 -0.00296,-0.059 -0.00423,-0.0885 0.00127,0.0295 0.00253,0.05898 0.00423,0.0885 z m -0.00675,-0.15206 c -0.00127,-0.03356 -0.0017,-0.06765 -0.00211,-0.101717 0,0.03407 8.451e-4,0.06814 0.00211,0.101717 z m 0.180307,1.313616 c 0.00633,0.02644 0.012668,0.0529 0.019424,0.07882 -0.00633,-0.02644 -0.012668,-0.05239 -0.019424,-0.07882 z m 0.1811488,1.679273 c -0.00211,9.74e-4 -0.00423,0.0021 -0.00633,0.003 0,0 0,0 4.224e-4,0 0.015624,-0.01072 0.031247,-0.02137 0.046871,-0.03205 -0.013511,0.0097 -0.027025,0.01933 -0.04096,0.02896 z M 3.2745435,37.437285 c 0.00675,0.02492 0.013511,0.04984 0.020692,0.07476 -0.00717,-0.02492 -0.013934,-0.04984 -0.020692,-0.07476 z m 0.040537,0.141888 c 0.00717,0.0244 0.014357,0.04883 0.021957,0.07272 -0.00717,-0.0244 -0.014779,-0.04832 -0.021957,-0.07272 z m 0.043072,0.139347 c 0.00802,0.02389 0.015624,0.04782 0.023646,0.0717 -0.0076,-0.02389 -0.015624,-0.04728 -0.023646,-0.0717 z m 0.046449,0.137819 c 0.00844,0.02389 0.016891,0.04782 0.025758,0.07171 -0.00844,-0.02389 -0.017313,-0.0473 -0.025758,-0.07171 z m 0.049405,0.135789 c 0.00929,0.0244 0.019001,0.04883 0.028292,0.07322 -0.00929,-0.02441 -0.019001,-0.04831 -0.028292,-0.07322 z m 0.052361,0.134256 c 0.010979,0.02747 0.022803,0.05442 0.034203,0.08188 -0.0114,-0.02747 -0.023225,-0.05442 -0.034203,-0.08188 z m 0.055317,0.13223 c 0.018158,0.04223 0.037159,0.08491 0.056584,0.12663 -0.019001,-0.04223 -0.038005,-0.0844 -0.056584,-0.12663 z m 0.081498,0.178505 c 0.012245,0.02543 0.024491,0.05086 0.036737,0.07627 -0.012668,-0.02543 -0.024491,-0.05086 -0.036737,-0.07627 z m 0.065028,0.132734 c 0.011824,0.02339 0.023646,0.04678 0.035893,0.07019 -0.012246,-0.02339 -0.024069,-0.04678 -0.035893,-0.07019 z m 0.066295,0.12714 c 0.00802,0.01423 0.015624,0.029 0.023646,0.04272 -0.012668,0.0066 -0.025336,0.01272 -0.037582,0.01933 0.012246,-0.0066 0.02449,-0.01373 0.036737,-0.01983 -0.00802,-0.01373 -0.015202,-0.02797 -0.022803,-0.04223 z"
480 id="path5"
481 inkscape:connector-curvature="0" />
482 <path
483 d="m 46.872485,35.321668 c -0.295587,-0.574676 -0.59117,-1.149351 -0.887179,-1.724024 -0.411284,-0.79946 -2.442377,-0.780135 -2.853662,-1.579594 -0.640154,-1.243435 0.339923,-3.306671 -0.300232,-4.550104 -0.487293,-0.94745 -2.164949,-1.469746 -2.652242,-2.417196 -0.272784,-0.53043 -0.355546,-1.274964 -0.330633,-1.912193 0.05237,-1.364979 0.09627,-2.14664 -0.825104,-0.815224 -1.463147,2.115108 -2.790324,4.459071 -4.019957,7.001881 0.08403,0.130191 0.166794,0.262928 0.248715,0.39617 1.867674,-0.780645 3.579534,-1.925924 5.084062,-3.359053 -1.390517,1.582138 -3.033126,2.860154 -4.860686,3.733354 0.119078,0.203934 0.236469,0.410917 0.350057,0.620953 -0.87662,-1.47788 -1.904834,-2.797597 -3.043681,-3.931183 l -0.220844,0.510597 1.016812,-2.721313 -1.72115,1.539922 0.100502,-0.101717 c -0.426911,-0.375317 -0.869023,-0.727243 -1.324646,-1.05679 l -0.259691,1.287172 0.928137,-6.116986 -3.276349,4.782515 0.695047,-1.149347 C 27.064907,22.874104 25.27366,22.28112 23.39754,22.038534 l 0.05785,0.790309 -0.581035,-4.788622 -1.425989,4.509928 0.165107,-0.635193 c -0.02449,0 -0.04899,-9.74e-4 -0.07348,-9.74e-4 -2.69658,-0.0122 -5.297306,0.706904 -7.628628,2.005263 l 0.994011,1.003896 -3.222299,-2.891682 1.639229,4.403639 -0.736427,-1.695038 c -0.777812,0.531955 -1.518886,1.130533 -2.214777,1.791154 -0.5865257,0.556877 -1.1460249,1.161557 -1.6734311,1.809973 l 0.3800423,0.25581 -2.2287093,-1.303955 1.2275217,2.117143 -0.091631,-0.139345 c -0.260959,0.36159 -0.5122061,0.73538 -0.7533194,1.120363 0,0 4.226e-4,0 4.226e-4,0 0.058698,-0.0046 0.1178119,-0.0076 0.1769282,-0.0097 0.4197311,-0.01322 0.848329,0.04476 1.274816,0.182576 0.9543158,0.307679 1.753238,0.965757 2.327517,1.82777 1.042571,-3.636727 4.259803,-5.735561 7.393005,-4.724541 3.275504,1.057303 5.220032,5.114101 4.342567,9.059015 -0.238157,1.070014 -0.659578,2.022044 -1.212743,2.819977 0.07093,0.03205 0.14188,0.06509 0.212399,0.100705 0.08361,0.04223 0.165949,0.08645 0.247024,0.132733 -2.976541,-1.313107 -6.314119,0.418546 -7.548398,3.975938 -1.2347,3.558409 0.08783,7.634533 2.955006,9.262947 -0.08446,-0.03713 -0.168483,-0.07627 -0.252515,-0.118496 -3.038191,-1.529246 -4.4722,-5.736577 -3.202452,-9.39619 0.218733,-0.629601 0.502918,-1.20224 0.839884,-1.711309 -1.472858,-0.618921 -2.639575,-1.861338 -3.348979,-3.411436 -0.588214,1.277509 -1.5788438,2.193938 -2.71769,2.574851 0.033789,0.06461 0.067143,0.129174 0.099654,0.195797 1.344911,2.750302 0.9285586,6.379401 -0.9298248,8.103932 -0.051515,0.04782 -0.1038771,0.09407 -0.1566596,0.137821 h 0 c 0.026184,-0.02694 0.05236,-0.05442 0.078121,-0.08188 8.773e-4,-0.0014 0.00167,-0.0026 0.00296,-0.0036 0.024916,-0.02694 0.049402,-0.05442 0.073895,-0.08239 0.00128,-0.0021 0.00296,-0.0036 0.00462,-0.005 0.024071,-0.02795 0.047713,-0.05545 0.070937,-0.08341 0.00167,-0.0026 0.00384,-0.0046 0.0055,-0.0071 0.023227,-0.02796 0.045607,-0.05543 0.067989,-0.08391 0.00216,-0.003 0.00423,-0.0061 0.00675,-0.0086 0.021955,-0.02847 0.043919,-0.05646 0.065029,-0.08542 0.00251,-0.003 0.00512,-0.0066 0.0072,-0.0097 0.021109,-0.02847 0.042228,-0.05696 0.062493,-0.08645 0.00251,-0.0036 0.00512,-0.0072 0.00755,-0.01071 0.020265,-0.0295 0.040538,-0.05799 0.060379,-0.08797 0.00251,-0.004 0.00512,-0.0076 0.008,-0.01121 0.01942,-0.0295 0.038848,-0.05898 0.058277,-0.08899 0.00251,-0.0046 0.00549,-0.0086 0.008,-0.0122 0.018997,-0.03002 0.037589,-0.06 0.055741,-0.09052 0.00251,-0.0046 0.00549,-0.0086 0.008,-0.01272 0.018152,-0.03052 0.036322,-0.06103 0.054051,-0.09204 0.00251,-0.0046 0.00512,-0.009 0.008,-0.01322 0.017729,-0.03153 0.035054,-0.06204 0.052361,-0.09357 0.00251,-0.005 0.00513,-0.0097 0.00755,-0.01373 0.017306,-0.03153 0.033789,-0.06306 0.050253,-0.09508 0.00251,-0.005 0.00513,-0.0097 0.00755,-0.01423 0.016464,-0.03153 0.032521,-0.06407 0.048559,-0.09613 0.00213,-0.005 0.00455,-0.0097 0.00716,-0.01425 0.015622,-0.03253 0.031254,-0.06509 0.046458,-0.09816 0.00213,-0.0046 0.00426,-0.0097 0.00677,-0.01373 0.015206,-0.03304 0.030402,-0.06713 0.045191,-0.100694 0.00213,-0.004 0.00387,-0.009 0.0059,-0.01272 0.01478,-0.03409 0.029559,-0.06865 0.043913,-0.102733 0.00175,-0.0046 0.00329,-0.0086 0.00513,-0.0122 0.014354,-0.03508 0.028291,-0.07019 0.042229,-0.105275 0.00126,-0.004 0.003,-0.0082 0.00426,-0.0112 0.013937,-0.0356 0.027449,-0.07222 0.040961,-0.108333 8.768e-4,-0.003 0.00213,-0.0061 0.00329,-0.0097 0.013511,-0.03662 0.026607,-0.07425 0.039693,-0.111368 8.769e-4,-0.0026 0.00175,-0.005 0.00251,-0.0076 0.013085,-0.03815 0.026181,-0.07627 0.038425,-0.115439 0,-9.73e-4 4.229e-4,-0.0021 8.769e-4,-0.0026 0.1570825,-0.485678 0.2630703,-1.002882 0.3166975,-1.535857 4.228e-4,-0.004 8.777e-4,-0.0082 0.00124,-0.01118 0.00383,-0.03762 0.00713,-0.07528 0.010132,-0.113404 4.219e-4,-0.0082 0.00124,-0.01576 0.00217,-0.02389 0.003,-0.03458 0.00548,-0.06968 0.00755,-0.104238 8.767e-4,-0.01071 0.00176,-0.02238 0.00248,-0.03305 0.00217,-0.03253 0.00383,-0.06561 0.00548,-0.09816 4.218e-4,-0.01322 0.00124,-0.02644 0.00217,-0.03917 0.00176,-0.03153 0.00248,-0.06306 0.00383,-0.09459 4.229e-4,-0.01474 8.778e-4,-0.03002 0.00176,-0.04425 8.777e-4,-0.03052 0.00124,-0.06053 0.00217,-0.09052 4.228e-4,-0.01627 8.777e-4,-0.03253 8.777e-4,-0.04883 4.229e-4,-0.0295 4.229e-4,-0.05799 4.229e-4,-0.08747 0,-0.01728 0,-0.03459 0,-0.05239 0,-0.02847 -4.229e-4,-0.05644 -8.778e-4,-0.08492 0,-0.01831 -4.228e-4,-0.03611 -4.228e-4,-0.05441 -4.208e-4,-0.02796 -0.00124,-0.05544 -0.00217,-0.08339 -4.229e-4,-0.0188 -8.767e-4,-0.03763 -0.00176,-0.05645 -8.767e-4,-0.02694 -0.00217,-0.0534 -0.00331,-0.08086 -8.768e-4,-0.01984 -0.00176,-0.03918 -0.003,-0.05899 -0.00124,-0.02694 -0.003,-0.0529 -0.00455,-0.07935 -0.00124,-0.02032 -0.00248,-0.04068 -0.00383,-0.06053 -0.00176,-0.02644 -0.00383,-0.05238 -0.00589,-0.07832 -0.00176,-0.02085 -0.00331,-0.04119 -0.00517,-0.06204 -0.00217,-0.02594 -0.00455,-0.05138 -0.00713,-0.0768 -0.00176,-0.02136 -0.00424,-0.04222 -0.00631,-0.06307 -0.00248,-0.02543 -0.00548,-0.05086 -0.00842,-0.07577 -0.00251,-0.02185 -0.00513,-0.04323 -0.00755,-0.06461 -0.003,-0.02492 -0.0059,-0.04985 -0.00929,-0.07425 -0.003,-0.02185 -0.0059,-0.04375 -0.0089,-0.06561 -0.00329,-0.02492 -0.00677,-0.04934 -0.01056,-0.07425 -0.00329,-0.02185 -0.00677,-0.04425 -0.010132,-0.06612 -0.00387,-0.02439 -0.00755,-0.04883 -0.011401,-0.07322 -0.00387,-0.02237 -0.00755,-0.04476 -0.011401,-0.06661 -0.00426,-0.02441 -0.00842,-0.04831 -0.01267,-0.07221 -0.00426,-0.02288 -0.00842,-0.04526 -0.01267,-0.06765 -0.00455,-0.02389 -0.0089,-0.04782 -0.013937,-0.07119 -0.00455,-0.02288 -0.00929,-0.04526 -0.013938,-0.06815 -0.00513,-0.0234 -0.00971,-0.04729 -0.015206,-0.07069 -0.00513,-0.02288 -0.010132,-0.04576 -0.015206,-0.06866 -0.00513,-0.02288 -0.010549,-0.04629 -0.016047,-0.06915 -0.00552,-0.02339 -0.010976,-0.04629 -0.01688,-0.06915 -0.00552,-0.02288 -0.010975,-0.04576 -0.01688,-0.06814 -0.0059,-0.02339 -0.011827,-0.04678 -0.018148,-0.06968 -0.0059,-0.02288 -0.011818,-0.04527 -0.018148,-0.06765 -0.0063,-0.0234 -0.01267,-0.04628 -0.019416,-0.06968 -0.0063,-0.02238 -0.01267,-0.04425 -0.018999,-0.06661 -0.00677,-0.0234 -0.013937,-0.04678 -0.021109,-0.07019 -0.00677,-0.02185 -0.013086,-0.04374 -0.019842,-0.0656 -0.00755,-0.02389 -0.015206,-0.0473 -0.022804,-0.0707 -0.00677,-0.02136 -0.013937,-0.0427 -0.020683,-0.0646 -0.00803,-0.02339 -0.016038,-0.04679 -0.024071,-0.07069 -0.00755,-0.02085 -0.014354,-0.04222 -0.021952,-0.06306 -0.00842,-0.0244 -0.017306,-0.04831 -0.026181,-0.07221 -0.00755,-0.02031 -0.01478,-0.04069 -0.022378,-0.06103 -0.0089,-0.02441 -0.018574,-0.04883 -0.027875,-0.07272 -0.00755,-0.02032 -0.015206,-0.04018 -0.022804,-0.05949 -0.00971,-0.02492 -0.019842,-0.04933 -0.029985,-0.07425 -0.00803,-0.01865 -0.015622,-0.03799 -0.023645,-0.05732 -0.010975,-0.02594 -0.021952,-0.05188 -0.033363,-0.0768 -0.00755,-0.0178 -0.015206,-0.0351 -0.022804,-0.0529 -0.01267,-0.0295 -0.026182,-0.05799 -0.039267,-0.08696 -0.00677,-0.0137 -0.01267,-0.02845 -0.019416,-0.04219 C 8.552808,41.518875 8.532531,41.476167 8.511847,41.433436 7.1669757,38.683133 4.5692051,37.851124 2.7108196,39.57515 0.85243366,41.299176 0.436081,44.928276 1.7809934,47.678578 c 0.023225,0.04782 0.046871,0.0951 0.07094,0.140872 0.0076,0.01474 0.015624,0.0295 0.023225,0.04425 0.01689,0.03153 0.033358,0.06307 0.05025,0.09459 0.00887,0.01626 0.018158,0.03307 0.027448,0.04985 0.016468,0.0295 0.032514,0.05799 0.048982,0.08645 0.00929,0.01627 0.018578,0.03253 0.028291,0.04883 0.017735,0.03002 0.035048,0.0595 0.053205,0.0885 0.00844,0.01373 0.01689,0.02795 0.025336,0.04172 0.024491,0.03917 0.048983,0.07729 0.073473,0.115944 0.00211,0.0036 0.00423,0.0072 0.00633,0.01012 0.027025,0.0417 0.054894,0.0824 0.082765,0.123071 0.00802,0.01121 0.015624,0.02237 0.023646,0.03305 0.020269,0.02896 0.040538,0.05746 0.061228,0.08595 0.00971,0.01322 0.019424,0.02694 0.029136,0.03966 0.019423,0.02644 0.038848,0.05239 0.058271,0.07729 0.00971,0.01271 0.019847,0.02594 0.029981,0.03865 0.020692,0.02694 0.041381,0.0529 0.062496,0.0783 0.00887,0.01071 0.017735,0.02185 0.026181,0.03255 0.027025,0.03305 0.054473,0.06561 0.082342,0.09764 0.00253,0.003 0.00464,0.0061 0.00718,0.0086 0.031248,0.03611 0.062496,0.07119 0.094165,0.105779 0.00591,0.0066 0.011823,0.0122 0.017735,0.0188 0.025337,0.02747 0.050671,0.05392 0.076429,0.08086 0.00887,0.0097 0.018158,0.0183 0.027448,0.02796 0.023226,0.02339 0.046027,0.0468 0.069674,0.06969 0.00929,0.0097 0.019001,0.0183 0.028292,0.02796 0.024491,0.02339 0.048982,0.04678 0.073473,0.06915 0.00802,0.0076 0.016046,0.01474 0.024069,0.02238 0.031247,0.02847 0.062496,0.05645 0.094587,0.08391 0.00127,9.74e-4 0.00253,0.0021 0.00338,0.003 0.035048,0.03002 0.070097,0.05898 0.1051438,0.08747 0.0017,0.0014 0.00338,0.003 0.00508,0.0046 0.032091,0.02594 0.064184,0.05086 0.096698,0.07527 0.00718,0.0056 0.014357,0.01073 0.021535,0.01578 0.027448,0.02085 0.055317,0.04069 0.083186,0.0605 0.00802,0.0061 0.016046,0.01121 0.024069,0.01678 0.028293,0.02032 0.057006,0.03967 0.08572,0.059 0.00633,0.004 0.012668,0.0086 0.019424,0.0122 0.1072551,0.07119 0.2166217,0.135784 0.3268326,0.193761 0.00423,0.0021 0.00887,0.0046 0.01309,0.0066 0.032515,0.01678 0.064607,0.03307 0.097121,0.04883 0.0059,0.003 0.012246,0.0061 0.018158,0.009 0.032092,0.01524 0.064607,0.03052 0.096698,0.04425 0.00464,0.0021 0.00929,0.0046 0.014356,0.0066 0.1135892,0.04933 0.2284449,0.09256 0.3433009,0.128156 0.0017,5.1e-4 0.00338,9.74e-4 0.00549,0.0014 0.035892,0.0112 0.071785,0.02187 0.1076773,0.03154 0.00464,9.73e-4 0.00929,0.0026 0.013934,0.0036 0.034626,0.0097 0.068829,0.0178 0.1034547,0.02594 0.00379,9.74e-4 0.00802,0.0021 0.011824,0.003 0.1169673,0.02694 0.2343567,0.04679 0.3517462,0.05951 l 0,0 c 0.6481757,1.849131 1.52733,3.584344 2.6163505,5.151733 3.2493206,4.67828 8.2075476,7.650825 13.8810926,7.526736 5.62076,-0.12256 10.470044,-3.267511 13.60958,-7.987475 2.711782,-4.077649 4.055427,-9.202937 3.667366,-14.468077 l -0.625796,0.397186 3.441877,-2.497548 -4.004333,0.160197 0.94925,-0.107311 c -0.220421,-1.378712 -0.556544,-2.696396 -0.990631,-3.942371 0.168484,0.428718 0.325565,0.867097 0.469134,1.315141 2.798347,-0.571116 5.565447,-0.68554 8.28863,-0.151043 0.771477,0.153076 0.933204,0.41702 0.464491,-0.493815 z m -12.799679,3.703349 c -0.150327,4.243438 -1.599116,6.202419 -3.283952,6.35143 -0.291784,0.02594 -0.581036,-0.003 -0.882953,-0.08339 0.127101,0.01169 0.25378,0.01373 0.380461,0.005 0.947982,-0.0656 1.826292,-0.718089 2.438574,-2.048996 -1.654432,-1.002882 -3.38487,-1.607564 -5.059992,-1.826755 1.684833,0.07272 3.4651,0.599086 5.159647,1.598919 0.215777,-0.520259 0.393129,-1.134093 0.522342,-1.846589 -1.866407,-0.63926 -3.746752,-0.830988 -5.497882,-0.626039 1.72875,-0.355486 3.641185,-0.255806 5.541374,0.37074 0.08615,-0.535514 0.146526,-1.122905 0.176508,-1.764709 0.0114,-0.238514 -0.003,-0.451602 -0.03927,-0.641804 -2.009135,-0.114427 -3.941838,0.243602 -5.656652,0.971863 1.643451,-0.864048 3.568132,-1.320736 5.586133,-1.236826 -0.412129,-1.186475 -1.895967,-1.250044 -3.554621,-0.903205 2.210554,-0.579759 4.250091,-0.552808 4.170283,1.68029 z m 2.44111,-7.055789 c 1.92468,-0.563996 3.721414,-1.511446 5.334888,-2.770136 -1.510441,1.419396 -3.24806,2.506191 -5.138958,3.16783 -0.06418,-0.133245 -0.129212,-0.265977 -0.19593,-0.397694 z m 0.825526,1.842519 c -0.05574,-0.141379 -0.112746,-0.282252 -0.171017,-0.421598 1.999844,-0.298525 3.997577,-0.112402 5.887635,0.505511 -1.862188,-0.401765 -3.791937,-0.442449 -5.716618,-0.08392 z"
484 id="path14"
485 style="fill:#f0a513;fill-opacity:1"
486 inkscape:connector-curvature="0" />
487 <path
488 d="m 17.971864,28.383357 c 3.029325,0.977457 4.82775,4.729117 4.016157,8.37805 -0.214087,0.963215 -0.589481,1.823193 -1.080996,2.549419 -2.202109,-0.672827 -4.51105,0.238008 -5.964907,2.257001 -2.974852,-1.022212 -4.729782,-4.734713 -3.926214,-8.347029 0.811593,-3.648933 3.926636,-5.815407 6.95596,-4.837441 z"
489 id="path16"
490 inkscape:connector-curvature="0"
491 style="fill:#ffffff" />
492 <path
493 d="m 21.46948,31.675787 c 0.688291,1.496188 0.915048,3.303109 0.518541,5.08562 -0.214087,0.963215 -0.589481,1.823193 -1.080996,2.549419 -2.202532,-0.672827 -4.511474,0.238008 -5.965329,2.257001 -1.217389,-0.418038 -2.2304,-1.28768 -2.947405,-2.415671 0.307831,0.161723 0.630018,0.298527 0.964451,0.406343 3.605716,1.163589 7.313197,-1.414313 8.279337,-5.756922 0.157927,-0.710463 0.232246,-1.423974 0.231401,-2.12579 z"
494 id="path18"
495 inkscape:connector-curvature="0"
496 style="fill:#eeeeee" />
497 <path
498 d="m 11.148494,37.665629 c -0.473779,-1.361928 -0.61397,-2.903379 -0.33232,-4.44127 -0.52952,-1.020176 -1.3685584,-1.810482 -2.4090152,-2.146133 -2.1826849,-0.704357 -4.4270197,0.856418 -5.0118558,3.484667 -0.3242991,1.457031 -0.070517,2.936437 0.5915924,4.085786 1.0683288,-0.4694 2.2489802,-0.271571 3.2581915,0.503477 0.4619579,0.354468 0.8876005,0.829465 1.2503252,1.416854 1.1793816,-0.417022 2.1776139,-1.463641 2.6530819,-2.903381 z"
499 id="path20"
500 inkscape:connector-curvature="0"
501 style="fill:#ffffff" />
502 <path
503 d="m 31.2411,51.394259 1.26637,0.637229 -2.465178,-0.01373 c -4.530473,2.179698 -9.426207,2.60994 -12.629927,1.007461 -0.08825,-0.03864 -0.176507,-0.07984 -0.264338,-0.124092 -3.038191,-1.529243 -4.472201,-5.736578 -3.202453,-9.39619 0.218732,-0.6296 0.503339,-1.202239 0.840306,-1.710803 l 0,-5.07e-4 c -1.472857,-0.618925 -2.639574,-1.861849 -3.348978,-3.411437 -0.588215,1.277507 -1.5788467,2.193936 -2.7176907,2.574848 0.033779,0.06461 0.067143,0.129175 0.099655,0.195796 1.3449097,2.750303 0.9285573,6.379402 -0.9298254,8.103935 -0.051515,0.04782 -0.1038771,0.09408 -0.1566605,0.137821 l 0,0 c -0.048979,0.05034 -0.098387,0.09866 -0.1494812,0.145956 -0.7486746,0.694696 -1.6176949,0.974406 -2.4761587,0.880322 l 0,5.08e-4 c 0.6477536,1.848622 1.5273307,3.584344 2.6159279,5.151732 3.2493226,4.678262 8.2075486,7.650298 13.8810926,7.526717 5.620762,-0.12256 10.470046,-3.268018 13.609581,-7.987982 2.123568,-3.192243 3.407673,-7.028327 3.678768,-11.070884 -1.87021,3.185631 -4.634352,5.665888 -7.651009,7.353296 z"
504 id="path183"
505 style="fill:#fdd99b"
506 inkscape:connector-curvature="0" />
507 <path
508 d="m 11.261241,44.175223 c -0.158773,-0.250722 -0.250827,-0.566539 -0.243648,-0.906768 0.01224,-0.584846 0.312898,-1.079675 0.733895,-1.291745 -0.616928,0.507545 -0.839039,1.75098 -0.173129,2.336839 0.277429,0.243604 0.439579,0.574168 0.370749,1.028824 -0.05363,0.355991 -0.262648,0.802509 -0.591168,1.144265 -0.374972,0.389558 -0.833129,0.599593 -1.228791,0.541109 0.37835,-0.112404 0.757541,-0.387016 1.06284,-0.752165 0.26307,-0.314291 0.444644,-0.675369 0.519384,-0.97542 0.14906,-0.596542 -0.181995,-0.701818 -0.450132,-1.124939 l 0,0 z m 1.895122,4.408723 c -0.233935,0.931683 -0.952208,1.610106 -1.802226,1.610106 -0.765564,0 -1.4251397,-0.551279 -1.7190352,-1.342094 0.3783472,0.632143 0.9944302,1.044078 1.6907442,1.044078 0.790057,0 1.477502,-0.530939 1.830517,-1.31209 z"
509 id="path185"
510 inkscape:connector-curvature="0" />
511 <g
512 id="g187"
513 transform="matrix(0.42226435,0,0,0.50856192,-47.726977,-111.72952)">
514 <radialGradient
515 id="radialGradient3241"
516 cx="163.4902"
517 cy="274.86621"
518 r="2.8801"
519 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
520 gradientUnits="userSpaceOnUse">
521 <stop
522 offset="0.0112"
523 style="stop-color:#FAF0BB"
524 id="stop3243" />
525 <stop
526 offset="0.4917"
527 style="stop-color:#FAF0BD"
528 id="stop3245" />
529 <stop
530 offset="0.6648"
531 style="stop-color:#FBF2C5"
532 id="stop3247" />
533 <stop
534 offset="0.7882"
535 style="stop-color:#FCF6D0"
536 id="stop3249" />
537 <stop
538 offset="0.8879"
539 style="stop-color:#FCF8E1"
540 id="stop3251" />
541 <stop
542 offset="0.9723"
543 style="stop-color:#FFFDF7"
544 id="stop3253" />
545 <stop
546 offset="1"
547 style="stop-color:#FFFFFF"
548 id="stop3255" />
549 </radialGradient>
550 <path
551 d="m 189.806,311.298 c -0.681,-0.478 -1.432,-0.68 -2.1,-0.645 -0.633,0.034 -1.217,0.284 -1.625,0.739 -0.408,0.454 -0.59,1.052 -0.559,1.676 0.034,0.653 0.305,1.364 0.834,1.98 0.577,0.671 1.35,1.108 2.143,1.244 0.845,0.145 1.679,-0.06 2.247,-0.657 0.573,-0.604 0.725,-1.448 0.515,-2.282 -0.199,-0.789 -0.713,-1.534 -1.455,-2.055 z"
552 id="path204"
553 style="fill:url(#radialGradient3305)"
554 inkscape:connector-curvature="0" />
555 <radialGradient
556 id="radialGradient3258"
557 cx="155.3242"
558 cy="310.6777"
559 r="4.4867001"
560 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
561 gradientUnits="userSpaceOnUse">
562 <stop
563 offset="0.0112"
564 style="stop-color:#FAF0BB"
565 id="stop3260" />
566 <stop
567 offset="0.4917"
568 style="stop-color:#FAF0BD"
569 id="stop3262" />
570 <stop
571 offset="0.6648"
572 style="stop-color:#FBF2C5"
573 id="stop3264" />
574 <stop
575 offset="0.7882"
576 style="stop-color:#FCF6D0"
577 id="stop3266" />
578 <stop
579 offset="0.8879"
580 style="stop-color:#FCF8E1"
581 id="stop3268" />
582 <stop
583 offset="0.9723"
584 style="stop-color:#FFFDF7"
585 id="stop3270" />
586 <stop
587 offset="1"
588 style="stop-color:#FFFFFF"
589 id="stop3272" />
590 </radialGradient>
591 <path
592 d="m 183.164,274.256 c -0.777,-0.621 -1.774,-0.996 -2.853,-1 -1.077,-0.004 -2.096,0.366 -2.89,0.992 -0.839,0.661 -1.465,1.633 -1.646,2.791 -0.197,1.263 0.167,2.499 0.961,3.449 0.841,1.005 2.124,1.644 3.592,1.617 1.455,-0.026 2.71,-0.702 3.522,-1.716 0.762,-0.951 1.106,-2.168 0.913,-3.4 -0.179,-1.131 -0.786,-2.082 -1.599,-2.733 z"
593 id="path221"
594 style="fill:url(#radialGradient3307)"
595 inkscape:connector-curvature="0" />
596 <radialGradient
597 id="radialGradient3275"
598 cx="170.3125"
599 cy="302.00781"
600 r="5.0811"
601 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
602 gradientUnits="userSpaceOnUse">
603 <stop
604 offset="0.0112"
605 style="stop-color:#FAF0BB"
606 id="stop3277" />
607 <stop
608 offset="0.4917"
609 style="stop-color:#FAF0BD"
610 id="stop3279" />
611 <stop
612 offset="0.6648"
613 style="stop-color:#FBF2C5"
614 id="stop3281" />
615 <stop
616 offset="0.7882"
617 style="stop-color:#FCF6D0"
618 id="stop3283" />
619 <stop
620 offset="0.8879"
621 style="stop-color:#FCF8E1"
622 id="stop3285" />
623 <stop
624 offset="0.9723"
625 style="stop-color:#FFFDF7"
626 id="stop3287" />
627 <stop
628 offset="1"
629 style="stop-color:#FFFFFF"
630 id="stop3289" />
631 </radialGradient>
632 <path
633 d="m 197.254,290.925 c 1.482,-0.322 2.697,-1.225 3.201,-2.604 0.5,-1.367 0.166,-2.845 -0.726,-4.066 -0.835,-1.146 -2.134,-2.023 -3.647,-2.408 -1.389,-0.352 -2.723,-0.223 -3.781,0.238 -1.011,0.439 -1.812,1.196 -2.21,2.198 -0.397,1.001 -0.335,2.12 0.108,3.146 0.468,1.083 1.377,2.112 2.666,2.812 1.407,0.762 2.987,0.989 4.389,0.684 z"
634 id="path238"
635 style="fill:url(#radialGradient3310)"
636 inkscape:connector-curvature="0" />
637 <radialGradient
638 id="radialGradient3292"
639 cx="173.2812"
640 cy="283.68359"
641 r="2.8803999"
642 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
643 gradientUnits="userSpaceOnUse">
644 <stop
645 offset="0.0112"
646 style="stop-color:#FAF0BB"
647 id="stop3294" />
648 <stop
649 offset="0.4917"
650 style="stop-color:#FAF0BD"
651 id="stop3296" />
652 <stop
653 offset="0.6648"
654 style="stop-color:#FBF2C5"
655 id="stop3298" />
656 <stop
657 offset="0.7882"
658 style="stop-color:#FCF6D0"
659 id="stop3300" />
660 <stop
661 offset="0.8879"
662 style="stop-color:#FCF8E1"
663 id="stop3302" />
664 <stop
665 offset="0.9723"
666 style="stop-color:#FFFDF7"
667 id="stop3304" />
668 <stop
669 offset="1"
670 style="stop-color:#FFFFFF"
671 id="stop3306" />
672 </radialGradient>
673 <path
674 d="m 200.538,302.533 c -0.568,-0.598 -1.402,-0.802 -2.248,-0.657 -0.792,0.136 -1.565,0.573 -2.143,1.244 -0.529,0.616 -0.8,1.327 -0.833,1.98 -0.032,0.624 0.15,1.222 0.559,1.676 0.408,0.455 0.991,0.705 1.624,0.739 0.668,0.035 1.42,-0.167 2.101,-0.645 0.741,-0.521 1.256,-1.267 1.454,-2.056 0.21,-0.833 0.058,-1.677 -0.514,-2.281 z"
675 id="path255"
676 style="fill:url(#radialGradient3312)"
677 inkscape:connector-curvature="0" />
678 <radialGradient
679 id="radialGradient3309"
680 cx="148.9492"
681 cy="270.04489"
682 r="2.8799"
683 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
684 gradientUnits="userSpaceOnUse">
685 <stop
686 offset="0.0112"
687 style="stop-color:#FAF0BB"
688 id="stop3311" />
689 <stop
690 offset="0.4917"
691 style="stop-color:#FAF0BD"
692 id="stop3313" />
693 <stop
694 offset="0.6648"
695 style="stop-color:#FBF2C5"
696 id="stop3315" />
697 <stop
698 offset="0.7882"
699 style="stop-color:#FCF6D0"
700 id="stop3317" />
701 <stop
702 offset="0.8879"
703 style="stop-color:#FCF8E1"
704 id="stop3319" />
705 <stop
706 offset="0.9723"
707 style="stop-color:#FFFDF7"
708 id="stop3321" />
709 <stop
710 offset="1"
711 style="stop-color:#FFFFFF"
712 id="stop3323" />
713 </radialGradient>
714 <path
715 d="m 173.958,315.516 c -0.793,0.136 -1.566,0.573 -2.143,1.244 -0.529,0.616 -0.801,1.327 -0.834,1.98 -0.031,0.623 0.15,1.222 0.559,1.676 0.408,0.455 0.991,0.705 1.624,0.738 0.669,0.036 1.42,-0.166 2.101,-0.645 0.741,-0.521 1.256,-1.266 1.454,-2.055 0.211,-0.834 0.06,-1.679 -0.514,-2.282 -0.568,-0.598 -1.402,-0.801 -2.247,-0.656 z"
716 id="path272"
717 style="fill:url(#radialGradient3314)"
718 inkscape:connector-curvature="0" />
719 <radialGradient
720 id="radialGradient3326"
721 cx="148.0723"
722 cy="319.09381"
723 r="3.9265001"
724 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
725 gradientUnits="userSpaceOnUse">
726 <stop
727 offset="0.0112"
728 style="stop-color:#FAF0BB"
729 id="stop3328" />
730 <stop
731 offset="0.4917"
732 style="stop-color:#FAF0BD"
733 id="stop3330" />
734 <stop
735 offset="0.6648"
736 style="stop-color:#FBF2C5"
737 id="stop3332" />
738 <stop
739 offset="0.7882"
740 style="stop-color:#FCF6D0"
741 id="stop3334" />
742 <stop
743 offset="0.8879"
744 style="stop-color:#FCF8E1"
745 id="stop3336" />
746 <stop
747 offset="0.9723"
748 style="stop-color:#FFFDF7"
749 id="stop3338" />
750 <stop
751 offset="1"
752 style="stop-color:#FFFFFF"
753 id="stop3340" />
754 </radialGradient>
755 <path
756 d="m 171.282,272.336 c 1.106,0.549 2.333,0.68 3.407,0.405 1.136,-0.291 2.049,-1.022 2.398,-2.102 0.347,-1.069 0.048,-2.201 -0.675,-3.119 -0.678,-0.861 -1.706,-1.502 -2.885,-1.756 -1.083,-0.233 -2.109,-0.095 -2.914,0.291 -0.768,0.368 -1.365,0.975 -1.645,1.76 -0.278,0.785 -0.198,1.646 0.173,2.426 0.394,0.822 1.125,1.592 2.141,2.095 z"
757 id="path289"
758 style="fill:url(#radialGradient3316)"
759 inkscape:connector-curvature="0" />
760 <radialGradient
761 id="radialGradient3343"
762 cx="112.9551"
763 cy="315.56049"
764 r="3.0683999"
765 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
766 gradientUnits="userSpaceOnUse">
767 <stop
768 offset="0.0112"
769 style="stop-color:#FAF0BB"
770 id="stop3345" />
771 <stop
772 offset="0.4917"
773 style="stop-color:#FAF0BD"
774 id="stop3347" />
775 <stop
776 offset="0.6648"
777 style="stop-color:#FBF2C5"
778 id="stop3349" />
779 <stop
780 offset="0.7882"
781 style="stop-color:#FCF6D0"
782 id="stop3351" />
783 <stop
784 offset="0.8879"
785 style="stop-color:#FCF8E1"
786 id="stop3353" />
787 <stop
788 offset="0.9723"
789 style="stop-color:#FFFDF7"
790 id="stop3355" />
791 <stop
792 offset="1"
793 style="stop-color:#FFFFFF"
794 id="stop3357" />
795 </radialGradient>
796 <path
797 d="m 140.776,270.8 c -0.132,-0.306 -0.298,-0.603 -0.496,-0.884 0,0 -0.001,-10e-4 -0.001,-10e-4 -0.031,0.02 -0.061,0.042 -0.091,0.062 -0.1,0.067 -0.199,0.135 -0.298,0.203 -0.12,0.082 -0.24,0.163 -0.358,0.246 -0.123,0.085 -0.245,0.173 -0.366,0.26 -0.096,0.068 -0.193,0.136 -0.289,0.206 -0.146,0.106 -0.29,0.213 -0.434,0.321 -0.072,0.054 -0.145,0.106 -0.216,0.161 -0.215,0.163 -0.429,0.328 -0.641,0.495 -0.223,0.175 -0.443,0.354 -0.663,0.535 -0.064,0.053 -0.129,0.107 -0.194,0.161 -0.171,0.143 -0.341,0.287 -0.51,0.432 -0.054,0.046 -0.108,0.092 -0.162,0.139 -0.193,0.167 -0.384,0.337 -0.574,0.509 -0.098,0.088 -0.196,0.178 -0.293,0.268 -0.099,0.09 -0.196,0.182 -0.294,0.274 -0.079,0.074 -0.16,0.146 -0.238,0.222 0,0 0.001,0.001 0.001,0.001 0.177,0.156 0.363,0.299 0.555,0.429 0.596,0.402 1.257,0.671 1.927,0.786 1.185,0.202 2.356,-0.083 3.152,-0.922 0.804,-0.847 1.017,-2.032 0.722,-3.202 -0.06,-0.24 -0.14,-0.473 -0.239,-0.701 z"
798 id="path306"
799 style="fill:url(#radialGradient3318)"
800 inkscape:connector-curvature="0" />
801 <radialGradient
802 id="radialGradient3360"
803 cx="132.0938"
804 cy="320.1113"
805 r="4.1712999"
806 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
807 gradientUnits="userSpaceOnUse">
808 <stop
809 offset="0.0112"
810 style="stop-color:#FAF0BB"
811 id="stop3362" />
812 <stop
813 offset="0.4917"
814 style="stop-color:#FAF0BD"
815 id="stop3364" />
816 <stop
817 offset="0.6648"
818 style="stop-color:#FBF2C5"
819 id="stop3366" />
820 <stop
821 offset="0.7882"
822 style="stop-color:#FCF6D0"
823 id="stop3368" />
824 <stop
825 offset="0.8879"
826 style="stop-color:#FCF8E1"
827 id="stop3370" />
828 <stop
829 offset="0.9723"
830 style="stop-color:#FFFDF7"
831 id="stop3372" />
832 <stop
833 offset="1"
834 style="stop-color:#FFFFFF"
835 id="stop3374" />
836 </radialGradient>
837 <path
838 d="m 160.2,265.6 c -0.85,-0.392 -1.938,-0.592 -3.115,-0.521 -1.177,0.07 -2.29,0.405 -3.157,0.906 -0.916,0.53 -1.6,1.269 -1.798,2.11 -0.216,0.917 0.182,1.777 1.05,2.403 0.918,0.663 2.32,1.032 3.923,0.914 1.588,-0.118 2.959,-0.687 3.847,-1.468 0.833,-0.732 1.209,-1.627 0.998,-2.496 -0.195,-0.799 -0.859,-1.438 -1.748,-1.848 z"
839 id="path323"
840 style="fill:url(#radialGradient3320)"
841 inkscape:connector-curvature="0" />
842 <radialGradient
843 id="radialGradient3377"
844 cx="147.44189"
845 cy="301.21091"
846 r="2.5313001"
847 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
848 gradientUnits="userSpaceOnUse">
849 <stop
850 offset="0.0112"
851 style="stop-color:#FAF0BB"
852 id="stop3379" />
853 <stop
854 offset="0.4917"
855 style="stop-color:#FAF0BD"
856 id="stop3381" />
857 <stop
858 offset="0.6648"
859 style="stop-color:#FBF2C5"
860 id="stop3383" />
861 <stop
862 offset="0.7882"
863 style="stop-color:#FCF6D0"
864 id="stop3385" />
865 <stop
866 offset="0.8879"
867 style="stop-color:#FCF8E1"
868 id="stop3387" />
869 <stop
870 offset="0.9723"
871 style="stop-color:#FFFDF7"
872 id="stop3389" />
873 <stop
874 offset="1"
875 style="stop-color:#FFFFFF"
876 id="stop3391" />
877 </radialGradient>
878 <path
879 d="m 173.961,289.2 c 0.657,-0.143 1.12,-0.506 1.265,-1.029 0.133,-0.48 -0.03,-1.015 -0.381,-1.495 -0.335,-0.458 -0.853,-0.886 -1.498,-1.196 -0.645,-0.31 -1.333,-0.461 -1.94,-0.451 -0.643,0.011 -1.223,0.2 -1.576,0.587 -0.385,0.422 -0.428,0.996 -0.152,1.584 0.291,0.622 0.925,1.231 1.811,1.642 0.876,0.408 1.77,0.51 2.471,0.358 z"
880 id="path340"
881 style="fill:url(#radialGradient3322)"
882 inkscape:connector-curvature="0" />
883 </g>
884 <path
885 d="m 32.300561,46.79686 c -0.244913,-0.207495 -0.516006,-0.294969 -0.756275,-0.27971 -0.2276,0.01425 -0.437888,0.12307 -0.584836,0.320395 -0.147371,0.197321 -0.212822,0.456181 -0.201419,0.726735 0.01182,0.283777 0.109788,0.591457 0.300228,0.85845 0.207332,0.290901 0.486027,0.480592 0.771056,0.539586 0.304451,0.06256 0.605105,-0.02543 0.809057,-0.284794 0.206488,-0.26191 0.260961,-0.628075 0.185374,-0.989662 -0.07136,-0.342262 -0.256312,-0.665199 -0.523185,-0.891 z"
886 id="path347"
887 style="fill:#000000"
888 inkscape:connector-curvature="0" />
889 <g
890 id="g349"
891 transform="matrix(0.42226435,0,0,0.50856192,-47.726977,-111.72952)">
892 <path
893 d="m 168.559,264.427 c 4.145,0.407 8.127,1.382 11.858,2.845 l 0.623,-0.856 c -3.919,-1.741 -8.161,-2.906 -12.604,-3.384 l 0.123,1.395 z"
894 id="path351"
895 inkscape:connector-curvature="0"
896 style="fill:#ffffff" />
897 <path
898 d="m 145.971,266.73 1.059,0.888 c 5.193,-2.147 10.87,-3.351 16.738,-3.403 l 0.009,-0.038 0.435,-1.388 c -0.059,0 -0.116,-0.002 -0.175,-0.002 -6.387,-0.024 -12.545,1.39 -18.066,3.943 z"
899 id="path353"
900 inkscape:connector-curvature="0"
901 style="fill:#ffffff" />
902 <path
903 d="m 185.374,269.579 c 0.97,0.527 1.917,1.087 2.84,1.683 l 0.494,-0.416 c -1.011,-0.738 -2.058,-1.431 -3.138,-2.078 l -0.196,0.811 z"
904 id="path355"
905 inkscape:connector-curvature="0"
906 style="fill:#ffffff" />
907 <path
908 d="m 190.66,272.366 -0.224,0.429 c 0.458,0.338 0.91,0.683 1.354,1.038 1.494,1.193 2.916,2.493 4.25,3.889 -1.633,-1.962 -3.44,-3.752 -5.38,-5.356 z"
909 id="path357"
910 inkscape:connector-curvature="0"
911 style="fill:#ffffff" />
912 <path
913 d="m 140.28,269.916 c 0.198,0.281 0.363,0.578 0.496,0.884 0.84,-0.514 1.699,-1.002 2.575,-1.462 l -0.52,-0.994 c -0.871,0.494 -1.721,1.019 -2.551,1.572 z"
914 id="path359"
915 inkscape:connector-curvature="0"
916 style="fill:#ffffff" />
917 <path
918 d="m 133.625,275.426 0.562,0.314 c 0.338,-0.307 0.681,-0.608 1.028,-0.904 -0.192,-0.129 -0.378,-0.272 -0.555,-0.429 -0.35,0.333 -0.696,0.673 -1.035,1.019 z"
919 id="path361"
920 inkscape:connector-curvature="0"
921 style="fill:#ffffff" />
922 <path
923 d="m 130.152,279.456 c 0.139,-0.009 0.279,-0.015 0.419,-0.019 0.538,-0.62 1.091,-1.224 1.66,-1.81 l -0.295,-0.374 c -0.618,0.713 -1.212,1.447 -1.784,2.203 z"
924 id="path363"
925 inkscape:connector-curvature="0"
926 style="fill:#ffffff" />
927 </g>
928 <path
929 d="m 11.717707,25.989048 c -0.05574,-0.15562 -0.125834,-0.306666 -0.209444,-0.44957 -0.01309,0.01012 -0.02618,0.02032 -0.03885,0.03052 -0.04223,0.03408 -0.08403,0.06866 -0.125835,0.10324 -0.05067,0.0417 -0.101339,0.08289 -0.151171,0.125104 -0.05194,0.04324 -0.103455,0.08798 -0.154549,0.132228 -0.04054,0.03459 -0.0815,0.06916 -0.122034,0.104767 -0.06165,0.0534 -0.122457,0.108333 -0.183263,0.16325 -0.03041,0.02747 -0.06122,0.05392 -0.09122,0.08188 -0.09078,0.08288 -0.181151,0.166809 -0.27067,0.251737 -0.09416,0.0895 -0.187063,0.180031 -0.279961,0.272083 -0.02703,0.02695 -0.05447,0.05442 -0.08192,0.08188 -0.07221,0.07272 -0.1439917,0.145958 -0.2153547,0.219699 -0.02281,0.02339 -0.0456,0.04679 -0.068411,0.07019 -0.081499,0.08492 -0.1621494,0.171895 -0.24238,0.258858 -0.041385,0.04477 -0.08276,0.09052 -0.1237229,0.136294 -0.041799,0.04628 -0.08276,0.09308 -0.1241459,0.139347 -0.033364,0.03762 -0.066717,0.07527 -0.1000776,0.113908 0.074741,0.07935 0.1532821,0.152062 0.2343573,0.218175 C 9.5506288,27.855494 9.7347353,27.672921 9.9217999,27.495432 10.4927,26.95178 11.092737,26.44983 11.717689,25.989072 z"
930 id="path365"
931 inkscape:connector-curvature="0"
932 style="fill:#eeeeee" />
933 <path
934 d="m 28.381526,27.537111 c 0.388483,0.0014 0.747409,0.164265 1.026947,0.433802 0.293051,0.282252 0.512205,0.694697 0.575969,1.184949 0.06968,0.534499 -0.05447,1.061878 -0.328523,1.474322 -0.292629,0.439906 -0.744451,0.732838 -1.26806,0.744027 -0.528674,0.01119 -0.990631,-0.26547 -1.292973,-0.70131 -0.286295,-0.411932 -0.417197,-0.947959 -0.345834,-1.495681 0.06503,-0.501949 0.290517,-0.923546 0.592437,-1.209867 0.28545,-0.271063 0.652399,-0.431769 1.040037,-0.430242 z"
935 id="path372"
936 style="fill:#000000"
937 inkscape:connector-curvature="0" />
938 <path
939 d="m 13.466305,55.28374 c 0.178195,0.09256 0.329787,0.214614 0.43662,0.342772 0.111901,0.134768 0.178619,0.281236 0.168063,0.408885 -0.0114,0.139346 -0.111902,0.231394 -0.271518,0.261399 -0.170172,0.03153 -0.401994,-0.0082 -0.64353,-0.129175 -0.244069,-0.12256 -0.433666,-0.295472 -0.53712,-0.467367 -0.09797,-0.162232 -0.114433,-0.316834 -0.03674,-0.425668 0.07093,-0.100193 0.209021,-0.143413 0.37117,-0.13782 0.152859,0.005 0.334856,0.05491 0.513051,0.146974 l 0,0 z m -2.368059,-0.261399 c 0.05025,0.0122 0.09585,0.04017 0.130479,0.0768 0.03588,0.03815 0.06165,0.08797 0.06671,0.140364 0.0055,0.05696 -0.01435,0.10731 -0.05278,0.141381 -0.04097,0.0356 -0.101763,0.05188 -0.169749,0.03611 -0.06883,-0.01525 -0.127102,-0.05848 -0.163417,-0.113404 -0.03463,-0.05139 -0.04772,-0.110861 -0.03463,-0.164774 0.01183,-0.04984 0.04392,-0.08594 0.0853,-0.10578 0.03885,-0.01831 0.08741,-0.02339 0.138081,-0.01071 l 0,0 z m 3.807979,2.368373 c 0.09627,0.02389 0.183263,0.07728 0.248714,0.147481 0.06925,0.07322 0.117813,0.167318 0.127101,0.267506 0.01013,0.109332 -0.02745,0.204948 -0.100915,0.270045 -0.07854,0.06866 -0.194242,0.09866 -0.324299,0.06968 -0.131324,-0.03002 -0.24238,-0.111886 -0.311631,-0.216139 -0.06545,-0.09816 -0.09122,-0.21156 -0.0663,-0.314799 0.02281,-0.09459 0.08446,-0.163757 0.162995,-0.2019 0.07515,-0.03611 0.16806,-0.04576 0.264336,-0.02185 l 0,0 z m -2.357501,-1.035942 c -0.09333,-0.04831 -0.188754,-0.07425 -0.269405,-0.0768 -0.08487,-0.003 -0.157504,0.01983 -0.194242,0.07222 -0.04054,0.05696 -0.03209,0.137821 0.01942,0.222749 0.05405,0.09052 0.153704,0.18054 0.281651,0.245128 0.126679,0.06356 0.247869,0.08391 0.337388,0.06765 0.08362,-0.01576 0.136392,-0.06407 0.142304,-0.137313 0.0055,-0.06713 -0.02956,-0.143414 -0.08783,-0.214102 -0.05658,-0.06714 -0.135969,-0.13121 -0.22929,-0.179526 z"
940 id="path374"
941 inkscape:connector-curvature="0"
942 style="fill:#d9bb7a" />
943 <path
944 d="m 32.89722,32.895826 c 0.143148,-0.434312 0.431555,-0.762333 0.795547,-0.953043 0.380884,-0.199865 0.861841,-0.255808 1.361803,-0.10325 0.544721,0.166808 1.012166,0.547722 1.313242,1.044079 0.320921,0.529412 0.440844,1.170201 0.26096,1.762675 -0.181574,0.59807 -0.618618,0.989661 -1.15236,1.129517 -0.504607,0.132224 -1.073818,0.03356 -1.579691,-0.297003 -0.464491,-0.303099 -0.791747,-0.749617 -0.960229,-1.219019 -0.160039,-0.444994 -0.182419,-0.929651 -0.03927,-1.363962 z"
945 id="path381"
946 style="fill:#000000"
947 inkscape:connector-curvature="0" />
948 <path
949 d="m 35.093418,44.08063 c -0.146948,-0.197323 -0.212399,-0.456178 -0.200998,-0.726732 0.01182,-0.28378 0.109367,-0.591461 0.299807,-0.858457 0.207754,-0.290895 0.486028,-0.480589 0.771477,-0.540093 0.304453,-0.06256 0.604685,0.02594 0.809059,0.285306 0.206487,0.261909 0.26096,0.628075 0.184952,0.989659 -0.07137,0.342262 -0.256313,0.6652 -0.523607,0.891001 -0.244913,0.207492 -0.515586,0.294965 -0.755853,0.27971 -0.227601,-0.01423 -0.437466,-0.123072 -0.584837,-0.320394 z"
950 id="path388"
951 style="fill:#000000"
952 inkscape:connector-curvature="0" />
953 <path
954 d="m 24.819304,51.017414 c -0.147371,-0.197322 -0.212821,-0.456179 -0.201421,-0.727243 0.01183,-0.283269 0.10979,-0.590948 0.30023,-0.858455 0.207333,-0.290896 0.485604,-0.481098 0.771055,-0.540089 0.304453,-0.06256 0.605106,0.02594 0.809059,0.285303 0.206487,0.261908 0.260959,0.628074 0.184952,0.989661 -0.07136,0.342263 -0.256314,0.6652 -0.523608,0.891002 -0.24449,0.207493 -0.515584,0.294964 -0.755854,0.279709 -0.2276,-0.01425 -0.437465,-0.123071 -0.584413,-0.319888 z"
955 id="path395"
956 style="fill:#000000"
957 inkscape:connector-curvature="0" />
958 <path
959 d="m 23.786446,24.445052 c 0.102186,-0.347855 0.322609,-0.616885 0.605104,-0.779624 0.296007,-0.170876 0.673933,-0.232414 1.072129,-0.128666 0.433667,0.112897 0.812438,0.396678 1.061996,0.778609 0.266026,0.406849 0.376235,0.908289 0.24829,1.382269 -0.12879,0.47805 -0.464913,0.802512 -0.882532,0.931685 -0.395661,0.12205 -0.84664,0.06357 -1.254126,-0.17952 -0.374125,-0.222751 -0.642686,-0.563996 -0.787099,-0.928635 -0.137237,-0.346331 -0.166373,-0.728261 -0.06377,-1.076118 z"
960 id="path402"
961 style="fill:#000000"
962 inkscape:connector-curvature="0" />
963 <path
964 d="m 9.3572511,27.571182 c 0.2537814,0.256316 0.5518992,0.424651 0.8555069,0.487204 0.426486,0.08747 0.848329,-0.03611 1.135047,-0.399731 0.28925,-0.367181 0.366103,-0.880828 0.259692,-1.388372 -0.0456,-0.217666 -0.123723,-0.429227 -0.230557,-0.625532 -0.344568,0.281745 -0.680268,0.577726 -1.006255,0.886932 -0.347524,0.330057 -0.6857564,0.676897 -1.0134339,1.039499 z"
965 id="path409"
966 style="fill:#000000"
967 inkscape:connector-curvature="0" />
968 <path
969 d="m 9.3572511,27.571182 c 0.081923,0.08289 0.1684839,0.15664 0.2584255,0.220208 0.1013389,-0.100194 0.2031087,-0.199865 0.3061417,-0.296999 0.5244517,-0.497883 1.0733947,-0.962708 1.6434517,-1.391936 -0.04604,-0.15867 -0.109367,-0.312257 -0.188752,-0.457195 l 0,0 c -0.02997,0.02442 -0.05996,0.04933 -0.08995,0.07425 -0.01942,0.01628 -0.03927,0.03255 -0.05869,0.04883 -0.03336,0.02747 -0.0663,0.05545 -0.09923,0.08341 l -0.04519,0.03865 c -0.03758,0.03205 -0.07474,0.06407 -0.111899,0.09613 l -0.02997,0.02594 c -0.04139,0.03611 -0.08235,0.07221 -0.123301,0.108332 l -0.02026,0.01832 c -0.04392,0.03918 -0.08741,0.07781 -0.130901,0.117485 l -0.01309,0.01169 c -0.04603,0.04223 -0.09206,0.08442 -0.13808,0.12714 l -0.0018,0.0014 c -0.04815,0.04476 -0.09585,0.0895 -0.143569,0.134769 -0.07685,0.07322 -0.15286,0.146467 -0.228867,0.221226 l -0.01098,0.01072 c -0.02026,0.02032 -0.04097,0.04018 -0.06123,0.06051 l -0.01858,0.01882 -0.05236,0.05238 -0.02956,0.03002 -0.04307,0.04376 -0.03801,0.03865 -0.01605,0.01627 -0.01562,0.01627 -0.04771,0.04883 -0.01562,0.01627 C 9.6459492,27.256383 9.50069,27.412511 9.3571211,27.571183 z"
970 id="path411"
971 inkscape:connector-curvature="0"
972 style="fill:#888678" />
973 <path
974 d="m 18.571057,23.295194 c 0.423955,-0.03051 0.815816,0.05645 1.121534,0.226311 0.320077,0.177997 0.559079,0.455163 0.629176,0.800985 0.07601,0.376844 -0.05954,0.764369 -0.359348,1.082221 -0.319232,0.338701 -0.812859,0.585354 -1.385028,0.636719 -0.577235,0.05138 -1.081841,-0.108827 -1.412472,-0.39617 -0.312477,-0.271573 -0.456047,-0.644349 -0.378351,-1.042043 0.07136,-0.364639 0.317965,-0.685034 0.647333,-0.914395 0.312897,-0.217665 0.713204,-0.363114 1.137156,-0.393628 z"
975 id="path418"
976 style="fill:#000000"
977 inkscape:connector-curvature="0" />
978 <path
979 d="m 25.268593,33.539157 c 0.209865,0.121549 0.37835,0.289372 0.487716,0.468895 0.11401,0.188169 0.167216,0.397695 0.123723,0.585864 -0.04687,0.20495 -0.198043,0.347856 -0.412131,0.403289 -0.228021,0.05951 -0.519383,0.01933 -0.804835,-0.139854 -0.288406,-0.160707 -0.494471,-0.399731 -0.589482,-0.643842 -0.08995,-0.230376 -0.07601,-0.455669 0.04941,-0.620952 0.114856,-0.152061 0.304451,-0.226311 0.51305,-0.230379 0.198043,-0.0036 0.422688,0.05543 0.632553,0.176979 z"
980 id="path425"
981 style="fill:#000000"
982 inkscape:connector-curvature="0" />
983 <polygon
984 points="183.827,319.426 190.01,322.008 182.526,321.973 188.385,321.662 "
985 id="polygon427"
986 transform="matrix(0.42226435,0,0,0.50856192,-47.726977,-111.72952)" />
987 <polygon
988 points="176.159,311.094 182.677,309.541 176.606,313.919 181.161,310.218 "
989 id="polygon429"
990 transform="matrix(0.42226435,0,0,0.50856192,-47.726977,-111.72952)" />
991 <polygon
992 points="183.955,287.956 191.129,279.553 180.144,285.178 188.996,281.271 "
993 id="polygon431"
994 transform="matrix(0.42226435,0,0,0.50856192,-47.726977,-111.72952)" />
995 <path
996 d="m 35.589578,54.524966 c -0.122034,0.197832 -0.247447,0.39312 -0.376237,0.586373 -3.139958,4.719964 -7.989242,7.864909 -13.609581,7.987982 C 15.929794,63.222902 10.97199,60.250356 7.7226683,55.572603 7.5229375,55.285266 7.3303849,54.991318 7.1445881,54.693299 c 3.5503959,4.555698 8.6741509,7.392458 14.4832419,7.265826 5.617804,-0.123069 10.532541,-3.002548 13.961748,-7.434159 z"
997 id="path440"
998 style="fill:#d9bb7a"
999 inkscape:connector-curvature="0" />
1000 <path
1001 d="m 16.345302,52.251694 c -2.117655,-1.929991 -2.971052,-5.408047 -1.900189,-8.495019 1.184029,-3.41245 4.302452,-5.144614 7.182295,-4.121385 -2.791167,-0.695713 -5.69128,1.060859 -6.831394,4.34617 -1.023146,2.94966 -0.321343,6.249209 1.549288,8.270234 z"
1002 id="path442"
1003 inkscape:connector-curvature="0"
1004 style="fill:#ffffff" />
1005 <path
1006 d="m 7.9004418,49.211004 c 1.5839109,-1.826246 1.8765395,-5.188352 0.611861,-7.774387 -0.9606515,-1.964067 -2.560189,-2.949661 -4.0731622,-2.724366 1.4428771,-0.03307 2.911513,0.974913 3.8219146,2.837267 1.2266751,2.507718 1.0299008,5.725391 -0.3606134,7.661486 z"
1007 id="path444"
1008 inkscape:connector-curvature="0"
1009 style="fill:#ffffff" />
1010 <path
1011 d="m 46.744961,35.073491 -0.497006,-0.879306 c -0.446333,-0.789288 -2.616772,-1.271403 -3.063106,-2.060692 -0.04897,-0.08645 -0.08995,-0.178504 -0.124145,-0.273607 0.02111,0.05392 0.04434,0.106285 0.07093,0.157655 0.411286,0.799459 2.442378,0.780134 2.853664,1.579592 l 0.759653,1.476358 0,0 z m -3.840919,-4.235306 c -0.02154,-1.142737 0.276584,-2.476187 -0.211554,-3.339725 -0.684068,-1.210379 -3.109133,-1.708769 -3.070285,-3.678937 0.02618,-1.300901 0.05531,-2.044928 -0.877888,-0.830484 -0.474202,0.616888 -0.933204,1.256658 -1.378271,1.918806 0.532898,-0.895579 1.084376,-1.758098 1.656966,-2.58553 0.921382,-1.331414 0.877043,-0.549754 0.825104,0.815225 -0.02492,0.63723 0.05786,1.381764 0.330634,1.912701 0.487293,0.947452 2.164949,1.469236 2.652243,2.416687 0.464492,0.901679 0.07769,2.233605 0.07305,3.371257 z"
1012 id="path446"
1013 inkscape:connector-curvature="0"
1014 style="fill:#ffffff" />
1015 <path
1016 d="m 16.756588,33.897186 c 0.357235,-0.248687 0.77781,-0.246145 1.121111,-0.03865 -0.09501,0.0122 -0.189596,0.04832 -0.27785,0.109346 -0.338655,0.235464 -0.455199,0.757757 -0.25927,1.165625 0.19551,0.408372 0.629174,0.548229 0.96783,0.312255 0.08783,-0.06155 0.160883,-0.14189 0.217467,-0.234955 -0.02237,0.461773 -0.230979,0.901679 -0.588638,1.150367 -0.564566,0.39261 -1.287061,0.15918 -1.613471,-0.520769 -0.325145,-0.680454 -0.131747,-1.550096 0.432821,-1.943214 l 0,0 z m -8.4625961,1.183931 c 0.2575811,-0.179014 0.5603435,-0.177488 0.8077901,-0.02795 -0.068836,0.009 -0.1368128,0.03458 -0.2001525,0.07882 -0.2440687,0.169354 -0.327677,0.545687 -0.1866399,0.839639 0.1406128,0.293947 0.453088,0.394643 0.6971553,0.224782 0.063334,-0.04425 0.1161241,-0.102217 0.1570835,-0.16935 C 9.5527694,36.35966 9.4024339,36.676495 9.1452751,36.855507 8.7386349,37.138248 8.2179844,36.970431 7.983206,36.480169 7.7475821,35.990933 7.887351,35.363875 8.2939919,35.081114 z"
1017 id="path448"
1018 inkscape:connector-curvature="0" />
1019 <path
1020 d="m 11.148494,37.665629 c -0.260113,-0.748095 -0.420152,-1.550096 -0.46449,-2.376002 -0.533741,1.967118 -1.8647168,3.382956 -3.4389171,3.862529 0.4619579,0.354468 0.8876005,0.829465 1.2503252,1.416854 1.1793816,-0.417022 2.1776139,-1.463641 2.6530819,-2.903381 z"
1021 id="path450"
1022 inkscape:connector-curvature="0"
1023 style="fill:#eeeeee" />
1024 <path
1025 d="m 3.5654754,33.263516 c -0.2884063,0.139348 -0.5160068,0.432279 -0.656621,0.92355 -0.6697112,2.341929 -0.5459877,4.035438 0.033358,5.072397 C 3.09465,39.150129 3.25131,39.055528 3.4109259,38.975177 3.537183,38.886186 3.6659737,38.807859 3.7972979,38.739713 3.1153408,37.498312 2.8611376,35.923805 3.2065499,34.3732 3.2935369,33.980083 3.4151486,33.609339 3.5654746,33.263516 z"
1026 id="path457"
1027 style="fill:#f0a513"
1028 inkscape:connector-curvature="0" />
1029 <path
1030 d="m 9.6346789,48.851958 c 0.7959681,1.053234 2.8688621,0.917445 3.5212611,-0.268012 -0.352592,0.781151 -1.04046,1.31209 -1.830517,1.31209 -0.695891,0 -1.312395,-0.411935 -1.6907441,-1.044078 z"
1031 id="path459"
1032 inkscape:connector-curvature="0"
1033 style="fill:#ffffff" />
1034 </g>
1035 </g>
1036 </svg>
0 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
1 <!-- Created with Inkscape (http://www.inkscape.org/) -->
2
3 <svg
4 xmlns:dc="http://purl.org/dc/elements/1.1/"
5 xmlns:cc="http://creativecommons.org/ns#"
6 xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
7 xmlns:svg="http://www.w3.org/2000/svg"
8 xmlns="http://www.w3.org/2000/svg"
9 xmlns:xlink="http://www.w3.org/1999/xlink"
10 xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
11 xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
12 width="32"
13 height="32"
14 id="svg3720"
15 version="1.1"
16 inkscape:version="0.48.3.1 r9886"
17 sodipodi:docname="diodon.svg">
18 <defs
19 id="defs3722">
20 <radialGradient
21 inkscape:collect="always"
22 xlink:href="#SVGID_3_"
23 id="radialGradient3305"
24 gradientUnits="userSpaceOnUse"
25 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
26 cx="163.4902"
27 cy="274.86621"
28 r="2.8801" />
29 <radialGradient
30 gradientUnits="userSpaceOnUse"
31 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
32 r="2.8801"
33 cy="274.86621"
34 cx="163.4902"
35 id="SVGID_3_">
36 <stop
37 id="stop190"
38 style="stop-color:#FAF0BB"
39 offset="0.0112" />
40 <stop
41 id="stop192"
42 style="stop-color:#FAF0BD"
43 offset="0.4917" />
44 <stop
45 id="stop194"
46 style="stop-color:#FBF2C5"
47 offset="0.6648" />
48 <stop
49 id="stop196"
50 style="stop-color:#FCF6D0"
51 offset="0.7882" />
52 <stop
53 id="stop198"
54 style="stop-color:#FCF8E1"
55 offset="0.8879" />
56 <stop
57 id="stop200"
58 style="stop-color:#FFFDF7"
59 offset="0.9723" />
60 <stop
61 id="stop202"
62 style="stop-color:#FFFFFF"
63 offset="1" />
64 </radialGradient>
65 <radialGradient
66 inkscape:collect="always"
67 xlink:href="#SVGID_4_"
68 id="radialGradient3307"
69 gradientUnits="userSpaceOnUse"
70 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
71 cx="155.3242"
72 cy="310.6777"
73 r="4.4867001" />
74 <radialGradient
75 gradientUnits="userSpaceOnUse"
76 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
77 r="4.4867001"
78 cy="310.6777"
79 cx="155.3242"
80 id="SVGID_4_">
81 <stop
82 id="stop207"
83 style="stop-color:#FAF0BB"
84 offset="0.0112" />
85 <stop
86 id="stop209"
87 style="stop-color:#FAF0BD"
88 offset="0.4917" />
89 <stop
90 id="stop211"
91 style="stop-color:#FBF2C5"
92 offset="0.6648" />
93 <stop
94 id="stop213"
95 style="stop-color:#FCF6D0"
96 offset="0.7882" />
97 <stop
98 id="stop215"
99 style="stop-color:#FCF8E1"
100 offset="0.8879" />
101 <stop
102 id="stop217"
103 style="stop-color:#FFFDF7"
104 offset="0.9723" />
105 <stop
106 id="stop219"
107 style="stop-color:#FFFFFF"
108 offset="1" />
109 </radialGradient>
110 <radialGradient
111 inkscape:collect="always"
112 xlink:href="#SVGID_5_"
113 id="radialGradient3310"
114 gradientUnits="userSpaceOnUse"
115 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
116 cx="170.3125"
117 cy="302.00781"
118 r="5.0811" />
119 <radialGradient
120 gradientUnits="userSpaceOnUse"
121 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
122 r="5.0811"
123 cy="302.00781"
124 cx="170.3125"
125 id="SVGID_5_">
126 <stop
127 id="stop224"
128 style="stop-color:#FAF0BB"
129 offset="0.0112" />
130 <stop
131 id="stop226"
132 style="stop-color:#FAF0BD"
133 offset="0.4917" />
134 <stop
135 id="stop228"
136 style="stop-color:#FBF2C5"
137 offset="0.6648" />
138 <stop
139 id="stop230"
140 style="stop-color:#FCF6D0"
141 offset="0.7882" />
142 <stop
143 id="stop232"
144 style="stop-color:#FCF8E1"
145 offset="0.8879" />
146 <stop
147 id="stop234"
148 style="stop-color:#FFFDF7"
149 offset="0.9723" />
150 <stop
151 id="stop236"
152 style="stop-color:#FFFFFF"
153 offset="1" />
154 </radialGradient>
155 <radialGradient
156 inkscape:collect="always"
157 xlink:href="#SVGID_6_"
158 id="radialGradient3312"
159 gradientUnits="userSpaceOnUse"
160 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
161 cx="173.2812"
162 cy="283.68359"
163 r="2.8803999" />
164 <radialGradient
165 gradientUnits="userSpaceOnUse"
166 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
167 r="2.8803999"
168 cy="283.68359"
169 cx="173.2812"
170 id="SVGID_6_">
171 <stop
172 id="stop241"
173 style="stop-color:#FAF0BB"
174 offset="0.0112" />
175 <stop
176 id="stop243"
177 style="stop-color:#FAF0BD"
178 offset="0.4917" />
179 <stop
180 id="stop245"
181 style="stop-color:#FBF2C5"
182 offset="0.6648" />
183 <stop
184 id="stop247"
185 style="stop-color:#FCF6D0"
186 offset="0.7882" />
187 <stop
188 id="stop249"
189 style="stop-color:#FCF8E1"
190 offset="0.8879" />
191 <stop
192 id="stop251"
193 style="stop-color:#FFFDF7"
194 offset="0.9723" />
195 <stop
196 id="stop253"
197 style="stop-color:#FFFFFF"
198 offset="1" />
199 </radialGradient>
200 <radialGradient
201 inkscape:collect="always"
202 xlink:href="#SVGID_7_"
203 id="radialGradient3314"
204 gradientUnits="userSpaceOnUse"
205 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
206 cx="148.9492"
207 cy="270.04489"
208 r="2.8799" />
209 <radialGradient
210 gradientUnits="userSpaceOnUse"
211 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
212 r="2.8799"
213 cy="270.04489"
214 cx="148.9492"
215 id="SVGID_7_">
216 <stop
217 id="stop258"
218 style="stop-color:#FAF0BB"
219 offset="0.0112" />
220 <stop
221 id="stop260"
222 style="stop-color:#FAF0BD"
223 offset="0.4917" />
224 <stop
225 id="stop262"
226 style="stop-color:#FBF2C5"
227 offset="0.6648" />
228 <stop
229 id="stop264"
230 style="stop-color:#FCF6D0"
231 offset="0.7882" />
232 <stop
233 id="stop266"
234 style="stop-color:#FCF8E1"
235 offset="0.8879" />
236 <stop
237 id="stop268"
238 style="stop-color:#FFFDF7"
239 offset="0.9723" />
240 <stop
241 id="stop270"
242 style="stop-color:#FFFFFF"
243 offset="1" />
244 </radialGradient>
245 <radialGradient
246 inkscape:collect="always"
247 xlink:href="#SVGID_8_"
248 id="radialGradient3316"
249 gradientUnits="userSpaceOnUse"
250 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
251 cx="148.0723"
252 cy="319.09381"
253 r="3.9265001" />
254 <radialGradient
255 gradientUnits="userSpaceOnUse"
256 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
257 r="3.9265001"
258 cy="319.09381"
259 cx="148.0723"
260 id="SVGID_8_">
261 <stop
262 id="stop275"
263 style="stop-color:#FAF0BB"
264 offset="0.0112" />
265 <stop
266 id="stop277"
267 style="stop-color:#FAF0BD"
268 offset="0.4917" />
269 <stop
270 id="stop279"
271 style="stop-color:#FBF2C5"
272 offset="0.6648" />
273 <stop
274 id="stop281"
275 style="stop-color:#FCF6D0"
276 offset="0.7882" />
277 <stop
278 id="stop283"
279 style="stop-color:#FCF8E1"
280 offset="0.8879" />
281 <stop
282 id="stop285"
283 style="stop-color:#FFFDF7"
284 offset="0.9723" />
285 <stop
286 id="stop287"
287 style="stop-color:#FFFFFF"
288 offset="1" />
289 </radialGradient>
290 <radialGradient
291 inkscape:collect="always"
292 xlink:href="#SVGID_9_"
293 id="radialGradient3318"
294 gradientUnits="userSpaceOnUse"
295 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
296 cx="112.9551"
297 cy="315.56049"
298 r="3.0683999" />
299 <radialGradient
300 gradientUnits="userSpaceOnUse"
301 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
302 r="3.0683999"
303 cy="315.56049"
304 cx="112.9551"
305 id="SVGID_9_">
306 <stop
307 id="stop292"
308 style="stop-color:#FAF0BB"
309 offset="0.0112" />
310 <stop
311 id="stop294"
312 style="stop-color:#FAF0BD"
313 offset="0.4917" />
314 <stop
315 id="stop296"
316 style="stop-color:#FBF2C5"
317 offset="0.6648" />
318 <stop
319 id="stop298"
320 style="stop-color:#FCF6D0"
321 offset="0.7882" />
322 <stop
323 id="stop300"
324 style="stop-color:#FCF8E1"
325 offset="0.8879" />
326 <stop
327 id="stop302"
328 style="stop-color:#FFFDF7"
329 offset="0.9723" />
330 <stop
331 id="stop304"
332 style="stop-color:#FFFFFF"
333 offset="1" />
334 </radialGradient>
335 <radialGradient
336 inkscape:collect="always"
337 xlink:href="#SVGID_10_"
338 id="radialGradient3320"
339 gradientUnits="userSpaceOnUse"
340 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
341 cx="132.0938"
342 cy="320.1113"
343 r="4.1712999" />
344 <radialGradient
345 gradientUnits="userSpaceOnUse"
346 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
347 r="4.1712999"
348 cy="320.1113"
349 cx="132.0938"
350 id="SVGID_10_">
351 <stop
352 id="stop309"
353 style="stop-color:#FAF0BB"
354 offset="0.0112" />
355 <stop
356 id="stop311"
357 style="stop-color:#FAF0BD"
358 offset="0.4917" />
359 <stop
360 id="stop313"
361 style="stop-color:#FBF2C5"
362 offset="0.6648" />
363 <stop
364 id="stop315"
365 style="stop-color:#FCF6D0"
366 offset="0.7882" />
367 <stop
368 id="stop317"
369 style="stop-color:#FCF8E1"
370 offset="0.8879" />
371 <stop
372 id="stop319"
373 style="stop-color:#FFFDF7"
374 offset="0.9723" />
375 <stop
376 id="stop321"
377 style="stop-color:#FFFFFF"
378 offset="1" />
379 </radialGradient>
380 <radialGradient
381 inkscape:collect="always"
382 xlink:href="#SVGID_11_"
383 id="radialGradient3322"
384 gradientUnits="userSpaceOnUse"
385 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
386 cx="147.44189"
387 cy="301.21091"
388 r="2.5313001" />
389 <radialGradient
390 gradientUnits="userSpaceOnUse"
391 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
392 r="2.5313001"
393 cy="301.21091"
394 cx="147.44189"
395 id="SVGID_11_">
396 <stop
397 id="stop326"
398 style="stop-color:#FAF0BB"
399 offset="0.0112" />
400 <stop
401 id="stop328"
402 style="stop-color:#FAF0BD"
403 offset="0.4917" />
404 <stop
405 id="stop330"
406 style="stop-color:#FBF2C5"
407 offset="0.6648" />
408 <stop
409 id="stop332"
410 style="stop-color:#FCF6D0"
411 offset="0.7882" />
412 <stop
413 id="stop334"
414 style="stop-color:#FCF8E1"
415 offset="0.8879" />
416 <stop
417 id="stop336"
418 style="stop-color:#FFFDF7"
419 offset="0.9723" />
420 <stop
421 id="stop338"
422 style="stop-color:#FFFFFF"
423 offset="1" />
424 </radialGradient>
425 </defs>
426 <sodipodi:namedview
427 id="base"
428 pagecolor="#ffffff"
429 bordercolor="#666666"
430 borderopacity="1.0"
431 inkscape:pageopacity="0.0"
432 inkscape:pageshadow="2"
433 inkscape:zoom="22.395604"
434 inkscape:cx="1.9698115"
435 inkscape:cy="16.602807"
436 inkscape:current-layer="layer1"
437 showgrid="true"
438 inkscape:grid-bbox="true"
439 inkscape:document-units="px"
440 showborder="true"
441 borderlayer="false"
442 inkscape:window-width="1600"
443 inkscape:window-height="876"
444 inkscape:window-x="0"
445 inkscape:window-y="24"
446 inkscape:window-maximized="1"
447 gridtolerance="10"
448 objecttolerance="10"
449 guidetolerance="10">
450 <inkscape:grid
451 type="xygrid"
452 id="grid4738"
453 empspacing="5"
454 visible="true"
455 enabled="true"
456 snapvisiblegridlinesonly="true" />
457 </sodipodi:namedview>
458 <metadata
459 id="metadata3725">
460 <rdf:RDF>
461 <cc:Work
462 rdf:about="">
463 <dc:format>image/svg+xml</dc:format>
464 <dc:type
465 rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
466 <dc:title />
467 </cc:Work>
468 </rdf:RDF>
469 </metadata>
470 <g
471 id="layer1"
472 inkscape:label="Layer 1"
473 inkscape:groupmode="layer">
474 <g
475 id="g3183"
476 transform="matrix(0.63684019,0,0,0.53220864,0.50894698,-5.3235542)">
477 <path
478 d="m 47.748262,36.240641 c -0.304876,-0.669777 -0.939962,-2.526029 -1.264261,-3.180039 -0.499962,-1.005938 -2.409862,-0.340737 -2.850285,-1.402107 -0.615238,-1.481949 0.402841,-3.075783 -0.26687,-4.517046 -0.51052,-1.098494 -2.320767,-1.749962 -2.830861,-2.848458 -0.374128,-0.804542 0.05785,-5.080024 -0.915894,-3.703855 -1.643875,2.32362 -3.133623,4.929999 -4.51865,7.769812 -0.227178,-0.299544 -0.460268,-0.590441 -0.699692,-0.872694 l 1.273972,-2.395837 -1.94875,1.641638 C 33.517528,26.509306 33.303862,26.293167 33.085974,26.08364 l 0.936581,-2.162914 -1.564066,1.585187 C 31.923058,25.034986 31.365246,24.598131 30.785899,24.1984 l 1.168829,-5.78896 -2.873088,4.753021 C 28.796189,23.01091 28.507361,22.866987 28.213887,22.732727 l 0.283762,-3.540102 -1.360114,3.093074 C 25.924369,21.832064 24.65631,21.526925 23.350669,21.385545 l -0.349636,-4.806419 -1.226255,4.716403 c -0.0033,0 -0.0071,0 -0.01056,0 -1.422186,-0.0066 -2.818193,0.185117 -4.164371,0.553823 l -1.190787,-2.856081 0.196351,3.163762 c -0.403261,0.139347 -0.801035,0.294459 -1.193319,0.465334 l -0.676466,-1.193086 0.243647,1.388883 c -0.482226,0.226309 -0.954317,0.47703 -1.416273,0.750127 l -2.649288,-2.676561 1.488058,3.425166 c -0.733893,0.515174 -1.434852,1.088322 -2.09654,1.715887 -0.09374,0.089 -0.187063,0.180031 -0.279538,0.271064 l -2.6176137,-1.775898 1.7557735,2.685206 c -0.2643372,0.297002 -0.5214955,0.60519 -0.7718972,0.922533 l -2.0728961,-1.396004 1.4580788,2.215805 c -0.340767,0.479065 -0.6650662,0.978474 -0.9716305,1.49568 -1.2705932,0.251233 -2.4081735,1.157486 -3.0905527,2.497041 0.00253,-0.005 0.00508,-0.01071 0.00802,-0.01578 -0.5079841,0.01071 -0.9074462,0.311242 -1.1177337,1.046115 -0.7347402,2.568744 -0.5366981,4.375156 0.1689057,5.408554 -0.1199231,0.09664 -0.2373126,0.202409 -0.3517463,0.317854 -1.90145688,1.925922 -2.20548742,5.78845 -0.6790012,8.625208 0.8470624,1.574001 2.0796522,2.501617 3.3341996,2.686733 0.6452198,1.719448 1.4880601,3.337183 2.5116286,4.809977 3.3333522,4.799809 8.4203702,7.849148 14.2412852,7.722516 5.766442,-0.126125 10.741561,-3.352949 13.962593,-8.195477 2.268826,-3.410417 3.604027,-7.536378 3.803758,-11.87187 L 41.77997,42.904823 39.623044,42.4461 c 0.003,-0.734364 -0.02618,-1.473813 -0.08952,-2.215806 l 3.332089,-2.112565 -3.537731,0.400746 C 39.264542,38.110618 39.19107,37.708348 39.108306,37.31116 l 0.959807,-0.628583 -1.067483,0.13782 c -0.02618,-0.113909 -0.05278,-0.226818 -0.08023,-0.33972 2.756541,-0.434818 5.473393,-0.393116 8.225288,0.328024 0.699694,0.183591 0.893512,0.07272 0.602574,-0.568064 z M 3.2551113,34.170284 c -0.017313,0.06662 -0.033782,0.134262 -0.04856,0.202916 -0.0114,0.05139 -0.022381,0.102733 -0.032514,0.154602 0.010132,-0.05188 0.020692,-0.10325 0.032514,-0.154602 0.01478,-0.06866 0.031247,-0.136294 0.04856,-0.202916 z m 0.4049515,-1.11121 c -0.010132,0.02085 -0.020269,0.04223 -0.030404,0.06306 0.010132,-0.02085 0.02027,-0.04222 0.030404,-0.06306 z m -0.079808,0.172404 c -0.010557,0.02339 -0.020692,0.0473 -0.030825,0.07119 0.010132,-0.02389 0.02027,-0.04782 0.030825,-0.07119 z m -0.075164,0.177488 c -0.010557,0.02644 -0.021113,0.0529 -0.031248,0.07984 0.010132,-0.02694 0.020692,-0.0534 0.031248,-0.07984 z m -0.070097,0.182573 c -0.010979,0.03002 -0.021535,0.06 -0.032092,0.09001 0.010557,-0.03002 0.021113,-0.06002 0.032092,-0.09001 z m -0.06545,0.187661 c -0.01098,0.03407 -0.021535,0.06866 -0.032515,0.103238 0.010979,-0.03458 0.021113,-0.06866 0.032515,-0.103238 z m -0.059962,0.193252 c -0.011823,0.04119 -0.023225,0.08289 -0.034626,0.124599 0.0114,-0.04172 0.022381,-0.08342 0.034626,-0.124599 z m -0.2558905,1.703683 c -8.452e-4,0.05034 -8.452e-4,0.100695 -4.223e-4,0.150535 -4.223e-4,-0.05034 -4.223e-4,-0.100705 4.223e-4,-0.150535 z m 0.1106333,-1.097477 c -0.00633,0.03458 -0.012668,0.06866 -0.018578,0.103239 0.00591,-0.03407 0.012245,-0.06866 0.018578,-0.103239 z m -0.028713,0.164775 c -0.00507,0.03153 -0.010132,0.06256 -0.01478,0.09357 0.00464,-0.03101 0.00971,-0.06204 0.01478,-0.09357 z m -0.023646,0.15867 c -0.00423,0.03053 -0.00802,0.06053 -0.011823,0.09052 0.00379,-0.03052 0.0076,-0.06054 0.011823,-0.09052 z m -0.019423,0.156131 c -0.00338,0.03002 -0.00633,0.05949 -0.00929,0.0895 0.00296,-0.03002 0.00591,-0.05951 0.00929,-0.0895 z m -0.015624,0.155617 c -0.00253,0.03002 -0.00464,0.06001 -0.00717,0.09001 0.00253,-0.03002 0.00508,-0.06001 0.00717,-0.09001 z m -0.0114,0.154604 c -0.0017,0.03154 -0.00338,0.06256 -0.00507,0.09408 0.0017,-0.03153 0.00338,-0.06256 0.00507,-0.09408 z m -0.0076,0.154095 c -0.00127,0.03662 -0.00211,0.07322 -0.00296,0.109332 4.221e-4,-0.03662 0.00127,-0.07272 0.00296,-0.109332 z m 0.1634162,1.705207 c -0.0076,-0.03203 -0.01478,-0.06407 -0.021535,-0.09611 0.00718,0.03205 0.013934,0.06407 0.021535,0.09611 z m -0.037161,-0.168331 c -0.00802,-0.03865 -0.015624,-0.07728 -0.023225,-0.115944 0.0076,0.03865 0.015624,0.07729 0.023225,0.115944 z m -0.033785,-0.176983 c -0.00507,-0.02847 -0.010132,-0.05696 -0.01478,-0.08543 0.00464,0.02795 0.010132,0.05696 0.01478,0.08543 z m -0.024491,-0.152059 c -0.00423,-0.02694 -0.00844,-0.05392 -0.012245,-0.08138 0.00379,0.02694 0.0076,0.05442 0.012245,0.08138 z m -0.021113,-0.150025 c -0.00338,-0.02694 -0.00675,-0.0534 -0.00971,-0.08086 0.00296,0.02747 0.00633,0.05442 0.00971,0.08086 z m -0.017313,-0.149518 c -0.00296,-0.02694 -0.00549,-0.05392 -0.00802,-0.08137 0.00253,0.02747 0.00508,0.05441 0.00802,0.08137 z m -0.013934,-0.150024 c -0.00211,-0.02795 -0.00423,-0.05546 -0.00591,-0.08341 0.0017,0.02747 0.00379,0.05544 0.00591,0.08341 z m -0.010132,-0.150536 c -0.0017,-0.0295 -0.00296,-0.059 -0.00423,-0.0885 0.00127,0.0295 0.00253,0.05898 0.00423,0.0885 z m -0.00675,-0.15206 c -0.00127,-0.03356 -0.0017,-0.06765 -0.00211,-0.101717 0,0.03407 8.451e-4,0.06814 0.00211,0.101717 z m 0.180307,1.313616 c 0.00633,0.02644 0.012668,0.0529 0.019424,0.07882 -0.00633,-0.02644 -0.012668,-0.05239 -0.019424,-0.07882 z m 0.1811488,1.679273 c -0.00211,9.74e-4 -0.00423,0.0021 -0.00633,0.003 0,0 0,0 4.224e-4,0 0.015624,-0.01072 0.031247,-0.02137 0.046871,-0.03205 -0.013511,0.0097 -0.027025,0.01933 -0.04096,0.02896 z M 3.2745435,37.437285 c 0.00675,0.02492 0.013511,0.04984 0.020692,0.07476 -0.00717,-0.02492 -0.013934,-0.04984 -0.020692,-0.07476 z m 0.040537,0.141888 c 0.00717,0.0244 0.014357,0.04883 0.021957,0.07272 -0.00717,-0.0244 -0.014779,-0.04832 -0.021957,-0.07272 z m 0.043072,0.139347 c 0.00802,0.02389 0.015624,0.04782 0.023646,0.0717 -0.0076,-0.02389 -0.015624,-0.04728 -0.023646,-0.0717 z m 0.046449,0.137819 c 0.00844,0.02389 0.016891,0.04782 0.025758,0.07171 -0.00844,-0.02389 -0.017313,-0.0473 -0.025758,-0.07171 z m 0.049405,0.135789 c 0.00929,0.0244 0.019001,0.04883 0.028292,0.07322 -0.00929,-0.02441 -0.019001,-0.04831 -0.028292,-0.07322 z m 0.052361,0.134256 c 0.010979,0.02747 0.022803,0.05442 0.034203,0.08188 -0.0114,-0.02747 -0.023225,-0.05442 -0.034203,-0.08188 z m 0.055317,0.13223 c 0.018158,0.04223 0.037159,0.08491 0.056584,0.12663 -0.019001,-0.04223 -0.038005,-0.0844 -0.056584,-0.12663 z m 0.081498,0.178505 c 0.012245,0.02543 0.024491,0.05086 0.036737,0.07627 -0.012668,-0.02543 -0.024491,-0.05086 -0.036737,-0.07627 z m 0.065028,0.132734 c 0.011824,0.02339 0.023646,0.04678 0.035893,0.07019 -0.012246,-0.02339 -0.024069,-0.04678 -0.035893,-0.07019 z m 0.066295,0.12714 c 0.00802,0.01423 0.015624,0.029 0.023646,0.04272 -0.012668,0.0066 -0.025336,0.01272 -0.037582,0.01933 0.012246,-0.0066 0.02449,-0.01373 0.036737,-0.01983 -0.00802,-0.01373 -0.015202,-0.02797 -0.022803,-0.04223 z"
479 id="path5"
480 inkscape:connector-curvature="0" />
481 <path
482 d="m 46.872485,35.321668 c -0.295587,-0.574676 -0.59117,-1.149351 -0.887179,-1.724024 -0.411284,-0.79946 -2.442377,-0.780135 -2.853662,-1.579594 -0.640154,-1.243435 0.339923,-3.306671 -0.300232,-4.550104 -0.487293,-0.94745 -2.164949,-1.469746 -2.652242,-2.417196 -0.272784,-0.53043 -0.355546,-1.274964 -0.330633,-1.912193 0.05237,-1.364979 0.09627,-2.14664 -0.825104,-0.815224 -1.463147,2.115108 -2.790324,4.459071 -4.019957,7.001881 0.08403,0.130191 0.166794,0.262928 0.248715,0.39617 1.867674,-0.780645 3.579534,-1.925924 5.084062,-3.359053 -1.390517,1.582138 -3.033126,2.860154 -4.860686,3.733354 0.119078,0.203934 0.236469,0.410917 0.350057,0.620953 -0.87662,-1.47788 -1.904834,-2.797597 -3.043681,-3.931183 l -0.220844,0.510597 1.016812,-2.721313 -1.72115,1.539922 0.100502,-0.101717 c -0.426911,-0.375317 -0.869023,-0.727243 -1.324646,-1.05679 l -0.259691,1.287172 0.928137,-6.116986 -3.276349,4.782515 0.695047,-1.149347 C 27.064907,22.874104 25.27366,22.28112 23.39754,22.038534 l 0.05785,0.790309 -0.581035,-4.788622 -1.425989,4.509928 0.165107,-0.635193 c -0.02449,0 -0.04899,-9.74e-4 -0.07348,-9.74e-4 -2.69658,-0.0122 -5.297306,0.706904 -7.628628,2.005263 l 0.994011,1.003896 -3.222299,-2.891682 1.639229,4.403639 -0.736427,-1.695038 c -0.777812,0.531955 -1.518886,1.130533 -2.214777,1.791154 -0.5865257,0.556877 -1.1460249,1.161557 -1.6734311,1.809973 l 0.3800423,0.25581 -2.2287093,-1.303955 1.2275217,2.117143 -0.091631,-0.139345 c -0.260959,0.36159 -0.5122061,0.73538 -0.7533194,1.120363 0,0 4.226e-4,0 4.226e-4,0 0.058698,-0.0046 0.1178119,-0.0076 0.1769282,-0.0097 0.4197311,-0.01322 0.848329,0.04476 1.274816,0.182576 0.9543158,0.307679 1.753238,0.965757 2.327517,1.82777 1.042571,-3.636727 4.259803,-5.735561 7.393005,-4.724541 3.275504,1.057303 5.220032,5.114101 4.342567,9.059015 -0.238157,1.070014 -0.659578,2.022044 -1.212743,2.819977 0.07093,0.03205 0.14188,0.06509 0.212399,0.100705 0.08361,0.04223 0.165949,0.08645 0.247024,0.132733 -2.976541,-1.313107 -6.314119,0.418546 -7.548398,3.975938 -1.2347,3.558409 0.08783,7.634533 2.955006,9.262947 -0.08446,-0.03713 -0.168483,-0.07627 -0.252515,-0.118496 -3.038191,-1.529246 -4.4722,-5.736577 -3.202452,-9.39619 0.218733,-0.629601 0.502918,-1.20224 0.839884,-1.711309 -1.472858,-0.618921 -2.639575,-1.861338 -3.348979,-3.411436 -0.588214,1.277509 -1.5788438,2.193938 -2.71769,2.574851 0.033789,0.06461 0.067143,0.129174 0.099654,0.195797 1.344911,2.750302 0.9285586,6.379401 -0.9298248,8.103932 -0.051515,0.04782 -0.1038771,0.09407 -0.1566596,0.137821 h 0 c 0.026184,-0.02694 0.05236,-0.05442 0.078121,-0.08188 8.773e-4,-0.0014 0.00167,-0.0026 0.00296,-0.0036 0.024916,-0.02694 0.049402,-0.05442 0.073895,-0.08239 0.00128,-0.0021 0.00296,-0.0036 0.00462,-0.005 0.024071,-0.02795 0.047713,-0.05545 0.070937,-0.08341 0.00167,-0.0026 0.00384,-0.0046 0.0055,-0.0071 0.023227,-0.02796 0.045607,-0.05543 0.067989,-0.08391 0.00216,-0.003 0.00423,-0.0061 0.00675,-0.0086 0.021955,-0.02847 0.043919,-0.05646 0.065029,-0.08542 0.00251,-0.003 0.00512,-0.0066 0.0072,-0.0097 0.021109,-0.02847 0.042228,-0.05696 0.062493,-0.08645 0.00251,-0.0036 0.00512,-0.0072 0.00755,-0.01071 0.020265,-0.0295 0.040538,-0.05799 0.060379,-0.08797 0.00251,-0.004 0.00512,-0.0076 0.008,-0.01121 0.01942,-0.0295 0.038848,-0.05898 0.058277,-0.08899 0.00251,-0.0046 0.00549,-0.0086 0.008,-0.0122 0.018997,-0.03002 0.037589,-0.06 0.055741,-0.09052 0.00251,-0.0046 0.00549,-0.0086 0.008,-0.01272 0.018152,-0.03052 0.036322,-0.06103 0.054051,-0.09204 0.00251,-0.0046 0.00512,-0.009 0.008,-0.01322 0.017729,-0.03153 0.035054,-0.06204 0.052361,-0.09357 0.00251,-0.005 0.00513,-0.0097 0.00755,-0.01373 0.017306,-0.03153 0.033789,-0.06306 0.050253,-0.09508 0.00251,-0.005 0.00513,-0.0097 0.00755,-0.01423 0.016464,-0.03153 0.032521,-0.06407 0.048559,-0.09613 0.00213,-0.005 0.00455,-0.0097 0.00716,-0.01425 0.015622,-0.03253 0.031254,-0.06509 0.046458,-0.09816 0.00213,-0.0046 0.00426,-0.0097 0.00677,-0.01373 0.015206,-0.03304 0.030402,-0.06713 0.045191,-0.100694 0.00213,-0.004 0.00387,-0.009 0.0059,-0.01272 0.01478,-0.03409 0.029559,-0.06865 0.043913,-0.102733 0.00175,-0.0046 0.00329,-0.0086 0.00513,-0.0122 0.014354,-0.03508 0.028291,-0.07019 0.042229,-0.105275 0.00126,-0.004 0.003,-0.0082 0.00426,-0.0112 0.013937,-0.0356 0.027449,-0.07222 0.040961,-0.108333 8.768e-4,-0.003 0.00213,-0.0061 0.00329,-0.0097 0.013511,-0.03662 0.026607,-0.07425 0.039693,-0.111368 8.769e-4,-0.0026 0.00175,-0.005 0.00251,-0.0076 0.013085,-0.03815 0.026181,-0.07627 0.038425,-0.115439 0,-9.73e-4 4.229e-4,-0.0021 8.769e-4,-0.0026 0.1570825,-0.485678 0.2630703,-1.002882 0.3166975,-1.535857 4.228e-4,-0.004 8.777e-4,-0.0082 0.00124,-0.01118 0.00383,-0.03762 0.00713,-0.07528 0.010132,-0.113404 4.219e-4,-0.0082 0.00124,-0.01576 0.00217,-0.02389 0.003,-0.03458 0.00548,-0.06968 0.00755,-0.104238 8.767e-4,-0.01071 0.00176,-0.02238 0.00248,-0.03305 0.00217,-0.03253 0.00383,-0.06561 0.00548,-0.09816 4.218e-4,-0.01322 0.00124,-0.02644 0.00217,-0.03917 0.00176,-0.03153 0.00248,-0.06306 0.00383,-0.09459 4.229e-4,-0.01474 8.778e-4,-0.03002 0.00176,-0.04425 8.777e-4,-0.03052 0.00124,-0.06053 0.00217,-0.09052 4.228e-4,-0.01627 8.777e-4,-0.03253 8.777e-4,-0.04883 4.229e-4,-0.0295 4.229e-4,-0.05799 4.229e-4,-0.08747 0,-0.01728 0,-0.03459 0,-0.05239 0,-0.02847 -4.229e-4,-0.05644 -8.778e-4,-0.08492 0,-0.01831 -4.228e-4,-0.03611 -4.228e-4,-0.05441 -4.208e-4,-0.02796 -0.00124,-0.05544 -0.00217,-0.08339 -4.229e-4,-0.0188 -8.767e-4,-0.03763 -0.00176,-0.05645 -8.767e-4,-0.02694 -0.00217,-0.0534 -0.00331,-0.08086 -8.768e-4,-0.01984 -0.00176,-0.03918 -0.003,-0.05899 -0.00124,-0.02694 -0.003,-0.0529 -0.00455,-0.07935 -0.00124,-0.02032 -0.00248,-0.04068 -0.00383,-0.06053 -0.00176,-0.02644 -0.00383,-0.05238 -0.00589,-0.07832 -0.00176,-0.02085 -0.00331,-0.04119 -0.00517,-0.06204 -0.00217,-0.02594 -0.00455,-0.05138 -0.00713,-0.0768 -0.00176,-0.02136 -0.00424,-0.04222 -0.00631,-0.06307 -0.00248,-0.02543 -0.00548,-0.05086 -0.00842,-0.07577 -0.00251,-0.02185 -0.00513,-0.04323 -0.00755,-0.06461 -0.003,-0.02492 -0.0059,-0.04985 -0.00929,-0.07425 -0.003,-0.02185 -0.0059,-0.04375 -0.0089,-0.06561 -0.00329,-0.02492 -0.00677,-0.04934 -0.01056,-0.07425 -0.00329,-0.02185 -0.00677,-0.04425 -0.010132,-0.06612 -0.00387,-0.02439 -0.00755,-0.04883 -0.011401,-0.07322 -0.00387,-0.02237 -0.00755,-0.04476 -0.011401,-0.06661 -0.00426,-0.02441 -0.00842,-0.04831 -0.01267,-0.07221 -0.00426,-0.02288 -0.00842,-0.04526 -0.01267,-0.06765 -0.00455,-0.02389 -0.0089,-0.04782 -0.013937,-0.07119 -0.00455,-0.02288 -0.00929,-0.04526 -0.013938,-0.06815 -0.00513,-0.0234 -0.00971,-0.04729 -0.015206,-0.07069 -0.00513,-0.02288 -0.010132,-0.04576 -0.015206,-0.06866 -0.00513,-0.02288 -0.010549,-0.04629 -0.016047,-0.06915 -0.00552,-0.02339 -0.010976,-0.04629 -0.01688,-0.06915 -0.00552,-0.02288 -0.010975,-0.04576 -0.01688,-0.06814 -0.0059,-0.02339 -0.011827,-0.04678 -0.018148,-0.06968 -0.0059,-0.02288 -0.011818,-0.04527 -0.018148,-0.06765 -0.0063,-0.0234 -0.01267,-0.04628 -0.019416,-0.06968 -0.0063,-0.02238 -0.01267,-0.04425 -0.018999,-0.06661 -0.00677,-0.0234 -0.013937,-0.04678 -0.021109,-0.07019 -0.00677,-0.02185 -0.013086,-0.04374 -0.019842,-0.0656 -0.00755,-0.02389 -0.015206,-0.0473 -0.022804,-0.0707 -0.00677,-0.02136 -0.013937,-0.0427 -0.020683,-0.0646 -0.00803,-0.02339 -0.016038,-0.04679 -0.024071,-0.07069 -0.00755,-0.02085 -0.014354,-0.04222 -0.021952,-0.06306 -0.00842,-0.0244 -0.017306,-0.04831 -0.026181,-0.07221 -0.00755,-0.02031 -0.01478,-0.04069 -0.022378,-0.06103 -0.0089,-0.02441 -0.018574,-0.04883 -0.027875,-0.07272 -0.00755,-0.02032 -0.015206,-0.04018 -0.022804,-0.05949 -0.00971,-0.02492 -0.019842,-0.04933 -0.029985,-0.07425 -0.00803,-0.01865 -0.015622,-0.03799 -0.023645,-0.05732 -0.010975,-0.02594 -0.021952,-0.05188 -0.033363,-0.0768 -0.00755,-0.0178 -0.015206,-0.0351 -0.022804,-0.0529 -0.01267,-0.0295 -0.026182,-0.05799 -0.039267,-0.08696 -0.00677,-0.0137 -0.01267,-0.02845 -0.019416,-0.04219 C 8.552808,41.518875 8.532531,41.476167 8.511847,41.433436 7.1669757,38.683133 4.5692051,37.851124 2.7108196,39.57515 0.85243366,41.299176 0.436081,44.928276 1.7809934,47.678578 c 0.023225,0.04782 0.046871,0.0951 0.07094,0.140872 0.0076,0.01474 0.015624,0.0295 0.023225,0.04425 0.01689,0.03153 0.033358,0.06307 0.05025,0.09459 0.00887,0.01626 0.018158,0.03307 0.027448,0.04985 0.016468,0.0295 0.032514,0.05799 0.048982,0.08645 0.00929,0.01627 0.018578,0.03253 0.028291,0.04883 0.017735,0.03002 0.035048,0.0595 0.053205,0.0885 0.00844,0.01373 0.01689,0.02795 0.025336,0.04172 0.024491,0.03917 0.048983,0.07729 0.073473,0.115944 0.00211,0.0036 0.00423,0.0072 0.00633,0.01012 0.027025,0.0417 0.054894,0.0824 0.082765,0.123071 0.00802,0.01121 0.015624,0.02237 0.023646,0.03305 0.020269,0.02896 0.040538,0.05746 0.061228,0.08595 0.00971,0.01322 0.019424,0.02694 0.029136,0.03966 0.019423,0.02644 0.038848,0.05239 0.058271,0.07729 0.00971,0.01271 0.019847,0.02594 0.029981,0.03865 0.020692,0.02694 0.041381,0.0529 0.062496,0.0783 0.00887,0.01071 0.017735,0.02185 0.026181,0.03255 0.027025,0.03305 0.054473,0.06561 0.082342,0.09764 0.00253,0.003 0.00464,0.0061 0.00718,0.0086 0.031248,0.03611 0.062496,0.07119 0.094165,0.105779 0.00591,0.0066 0.011823,0.0122 0.017735,0.0188 0.025337,0.02747 0.050671,0.05392 0.076429,0.08086 0.00887,0.0097 0.018158,0.0183 0.027448,0.02796 0.023226,0.02339 0.046027,0.0468 0.069674,0.06969 0.00929,0.0097 0.019001,0.0183 0.028292,0.02796 0.024491,0.02339 0.048982,0.04678 0.073473,0.06915 0.00802,0.0076 0.016046,0.01474 0.024069,0.02238 0.031247,0.02847 0.062496,0.05645 0.094587,0.08391 0.00127,9.74e-4 0.00253,0.0021 0.00338,0.003 0.035048,0.03002 0.070097,0.05898 0.1051438,0.08747 0.0017,0.0014 0.00338,0.003 0.00508,0.0046 0.032091,0.02594 0.064184,0.05086 0.096698,0.07527 0.00718,0.0056 0.014357,0.01073 0.021535,0.01578 0.027448,0.02085 0.055317,0.04069 0.083186,0.0605 0.00802,0.0061 0.016046,0.01121 0.024069,0.01678 0.028293,0.02032 0.057006,0.03967 0.08572,0.059 0.00633,0.004 0.012668,0.0086 0.019424,0.0122 0.1072551,0.07119 0.2166217,0.135784 0.3268326,0.193761 0.00423,0.0021 0.00887,0.0046 0.01309,0.0066 0.032515,0.01678 0.064607,0.03307 0.097121,0.04883 0.0059,0.003 0.012246,0.0061 0.018158,0.009 0.032092,0.01524 0.064607,0.03052 0.096698,0.04425 0.00464,0.0021 0.00929,0.0046 0.014356,0.0066 0.1135892,0.04933 0.2284449,0.09256 0.3433009,0.128156 0.0017,5.1e-4 0.00338,9.74e-4 0.00549,0.0014 0.035892,0.0112 0.071785,0.02187 0.1076773,0.03154 0.00464,9.73e-4 0.00929,0.0026 0.013934,0.0036 0.034626,0.0097 0.068829,0.0178 0.1034547,0.02594 0.00379,9.74e-4 0.00802,0.0021 0.011824,0.003 0.1169673,0.02694 0.2343567,0.04679 0.3517462,0.05951 l 0,0 c 0.6481757,1.849131 1.52733,3.584344 2.6163505,5.151733 3.2493206,4.67828 8.2075476,7.650825 13.8810926,7.526736 5.62076,-0.12256 10.470044,-3.267511 13.60958,-7.987475 2.711782,-4.077649 4.055427,-9.202937 3.667366,-14.468077 l -0.625796,0.397186 3.441877,-2.497548 -4.004333,0.160197 0.94925,-0.107311 c -0.220421,-1.378712 -0.556544,-2.696396 -0.990631,-3.942371 0.168484,0.428718 0.325565,0.867097 0.469134,1.315141 2.798347,-0.571116 5.565447,-0.68554 8.28863,-0.151043 0.771477,0.153076 0.933204,0.41702 0.464491,-0.493815 z m -12.799679,3.703349 c -0.150327,4.243438 -1.599116,6.202419 -3.283952,6.35143 -0.291784,0.02594 -0.581036,-0.003 -0.882953,-0.08339 0.127101,0.01169 0.25378,0.01373 0.380461,0.005 0.947982,-0.0656 1.826292,-0.718089 2.438574,-2.048996 -1.654432,-1.002882 -3.38487,-1.607564 -5.059992,-1.826755 1.684833,0.07272 3.4651,0.599086 5.159647,1.598919 0.215777,-0.520259 0.393129,-1.134093 0.522342,-1.846589 -1.866407,-0.63926 -3.746752,-0.830988 -5.497882,-0.626039 1.72875,-0.355486 3.641185,-0.255806 5.541374,0.37074 0.08615,-0.535514 0.146526,-1.122905 0.176508,-1.764709 0.0114,-0.238514 -0.003,-0.451602 -0.03927,-0.641804 -2.009135,-0.114427 -3.941838,0.243602 -5.656652,0.971863 1.643451,-0.864048 3.568132,-1.320736 5.586133,-1.236826 -0.412129,-1.186475 -1.895967,-1.250044 -3.554621,-0.903205 2.210554,-0.579759 4.250091,-0.552808 4.170283,1.68029 z m 2.44111,-7.055789 c 1.92468,-0.563996 3.721414,-1.511446 5.334888,-2.770136 -1.510441,1.419396 -3.24806,2.506191 -5.138958,3.16783 -0.06418,-0.133245 -0.129212,-0.265977 -0.19593,-0.397694 z m 0.825526,1.842519 c -0.05574,-0.141379 -0.112746,-0.282252 -0.171017,-0.421598 1.999844,-0.298525 3.997577,-0.112402 5.887635,0.505511 -1.862188,-0.401765 -3.791937,-0.442449 -5.716618,-0.08392 z"
483 id="path14"
484 style="fill:#f0a513;fill-opacity:1"
485 inkscape:connector-curvature="0" />
486 <path
487 d="m 17.971864,28.383357 c 3.029325,0.977457 4.82775,4.729117 4.016157,8.37805 -0.214087,0.963215 -0.589481,1.823193 -1.080996,2.549419 -2.202109,-0.672827 -4.51105,0.238008 -5.964907,2.257001 -2.974852,-1.022212 -4.729782,-4.734713 -3.926214,-8.347029 0.811593,-3.648933 3.926636,-5.815407 6.95596,-4.837441 z"
488 id="path16"
489 inkscape:connector-curvature="0"
490 style="fill:#ffffff" />
491 <path
492 d="m 21.46948,31.675787 c 0.688291,1.496188 0.915048,3.303109 0.518541,5.08562 -0.214087,0.963215 -0.589481,1.823193 -1.080996,2.549419 -2.202532,-0.672827 -4.511474,0.238008 -5.965329,2.257001 -1.217389,-0.418038 -2.2304,-1.28768 -2.947405,-2.415671 0.307831,0.161723 0.630018,0.298527 0.964451,0.406343 3.605716,1.163589 7.313197,-1.414313 8.279337,-5.756922 0.157927,-0.710463 0.232246,-1.423974 0.231401,-2.12579 z"
493 id="path18"
494 inkscape:connector-curvature="0"
495 style="fill:#eeeeee" />
496 <path
497 d="m 11.148494,37.665629 c -0.473779,-1.361928 -0.61397,-2.903379 -0.33232,-4.44127 -0.52952,-1.020176 -1.3685584,-1.810482 -2.4090152,-2.146133 -2.1826849,-0.704357 -4.4270197,0.856418 -5.0118558,3.484667 -0.3242991,1.457031 -0.070517,2.936437 0.5915924,4.085786 1.0683288,-0.4694 2.2489802,-0.271571 3.2581915,0.503477 0.4619579,0.354468 0.8876005,0.829465 1.2503252,1.416854 1.1793816,-0.417022 2.1776139,-1.463641 2.6530819,-2.903381 z"
498 id="path20"
499 inkscape:connector-curvature="0"
500 style="fill:#ffffff" />
501 <path
502 d="m 31.2411,51.394259 1.26637,0.637229 -2.465178,-0.01373 c -4.530473,2.179698 -9.426207,2.60994 -12.629927,1.007461 -0.08825,-0.03864 -0.176507,-0.07984 -0.264338,-0.124092 -3.038191,-1.529243 -4.472201,-5.736578 -3.202453,-9.39619 0.218732,-0.6296 0.503339,-1.202239 0.840306,-1.710803 l 0,-5.07e-4 c -1.472857,-0.618925 -2.639574,-1.861849 -3.348978,-3.411437 -0.588215,1.277507 -1.5788467,2.193936 -2.7176907,2.574848 0.033779,0.06461 0.067143,0.129175 0.099655,0.195796 1.3449097,2.750303 0.9285573,6.379402 -0.9298254,8.103935 -0.051515,0.04782 -0.1038771,0.09408 -0.1566605,0.137821 l 0,0 c -0.048979,0.05034 -0.098387,0.09866 -0.1494812,0.145956 -0.7486746,0.694696 -1.6176949,0.974406 -2.4761587,0.880322 l 0,5.08e-4 c 0.6477536,1.848622 1.5273307,3.584344 2.6159279,5.151732 3.2493226,4.678262 8.2075486,7.650298 13.8810926,7.526717 5.620762,-0.12256 10.470046,-3.268018 13.609581,-7.987982 2.123568,-3.192243 3.407673,-7.028327 3.678768,-11.070884 -1.87021,3.185631 -4.634352,5.665888 -7.651009,7.353296 z"
503 id="path183"
504 style="fill:#fdd99b"
505 inkscape:connector-curvature="0" />
506 <path
507 d="m 11.261241,44.175223 c -0.158773,-0.250722 -0.250827,-0.566539 -0.243648,-0.906768 0.01224,-0.584846 0.312898,-1.079675 0.733895,-1.291745 -0.616928,0.507545 -0.839039,1.75098 -0.173129,2.336839 0.277429,0.243604 0.439579,0.574168 0.370749,1.028824 -0.05363,0.355991 -0.262648,0.802509 -0.591168,1.144265 -0.374972,0.389558 -0.833129,0.599593 -1.228791,0.541109 0.37835,-0.112404 0.757541,-0.387016 1.06284,-0.752165 0.26307,-0.314291 0.444644,-0.675369 0.519384,-0.97542 0.14906,-0.596542 -0.181995,-0.701818 -0.450132,-1.124939 l 0,0 z m 1.895122,4.408723 c -0.233935,0.931683 -0.952208,1.610106 -1.802226,1.610106 -0.765564,0 -1.4251397,-0.551279 -1.7190352,-1.342094 0.3783472,0.632143 0.9944302,1.044078 1.6907442,1.044078 0.790057,0 1.477502,-0.530939 1.830517,-1.31209 z"
508 id="path185"
509 inkscape:connector-curvature="0" />
510 <g
511 id="g187"
512 transform="matrix(0.42226435,0,0,0.50856192,-47.726977,-111.72952)">
513 <radialGradient
514 id="radialGradient3241"
515 cx="163.4902"
516 cy="274.86621"
517 r="2.8801"
518 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
519 gradientUnits="userSpaceOnUse">
520 <stop
521 offset="0.0112"
522 style="stop-color:#FAF0BB"
523 id="stop3243" />
524 <stop
525 offset="0.4917"
526 style="stop-color:#FAF0BD"
527 id="stop3245" />
528 <stop
529 offset="0.6648"
530 style="stop-color:#FBF2C5"
531 id="stop3247" />
532 <stop
533 offset="0.7882"
534 style="stop-color:#FCF6D0"
535 id="stop3249" />
536 <stop
537 offset="0.8879"
538 style="stop-color:#FCF8E1"
539 id="stop3251" />
540 <stop
541 offset="0.9723"
542 style="stop-color:#FFFDF7"
543 id="stop3253" />
544 <stop
545 offset="1"
546 style="stop-color:#FFFFFF"
547 id="stop3255" />
548 </radialGradient>
549 <path
550 d="m 189.806,311.298 c -0.681,-0.478 -1.432,-0.68 -2.1,-0.645 -0.633,0.034 -1.217,0.284 -1.625,0.739 -0.408,0.454 -0.59,1.052 -0.559,1.676 0.034,0.653 0.305,1.364 0.834,1.98 0.577,0.671 1.35,1.108 2.143,1.244 0.845,0.145 1.679,-0.06 2.247,-0.657 0.573,-0.604 0.725,-1.448 0.515,-2.282 -0.199,-0.789 -0.713,-1.534 -1.455,-2.055 z"
551 id="path204"
552 style="fill:url(#radialGradient3305)"
553 inkscape:connector-curvature="0" />
554 <radialGradient
555 id="radialGradient3258"
556 cx="155.3242"
557 cy="310.6777"
558 r="4.4867001"
559 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
560 gradientUnits="userSpaceOnUse">
561 <stop
562 offset="0.0112"
563 style="stop-color:#FAF0BB"
564 id="stop3260" />
565 <stop
566 offset="0.4917"
567 style="stop-color:#FAF0BD"
568 id="stop3262" />
569 <stop
570 offset="0.6648"
571 style="stop-color:#FBF2C5"
572 id="stop3264" />
573 <stop
574 offset="0.7882"
575 style="stop-color:#FCF6D0"
576 id="stop3266" />
577 <stop
578 offset="0.8879"
579 style="stop-color:#FCF8E1"
580 id="stop3268" />
581 <stop
582 offset="0.9723"
583 style="stop-color:#FFFDF7"
584 id="stop3270" />
585 <stop
586 offset="1"
587 style="stop-color:#FFFFFF"
588 id="stop3272" />
589 </radialGradient>
590 <path
591 d="m 183.164,274.256 c -0.777,-0.621 -1.774,-0.996 -2.853,-1 -1.077,-0.004 -2.096,0.366 -2.89,0.992 -0.839,0.661 -1.465,1.633 -1.646,2.791 -0.197,1.263 0.167,2.499 0.961,3.449 0.841,1.005 2.124,1.644 3.592,1.617 1.455,-0.026 2.71,-0.702 3.522,-1.716 0.762,-0.951 1.106,-2.168 0.913,-3.4 -0.179,-1.131 -0.786,-2.082 -1.599,-2.733 z"
592 id="path221"
593 style="fill:url(#radialGradient3307)"
594 inkscape:connector-curvature="0" />
595 <radialGradient
596 id="radialGradient3275"
597 cx="170.3125"
598 cy="302.00781"
599 r="5.0811"
600 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
601 gradientUnits="userSpaceOnUse">
602 <stop
603 offset="0.0112"
604 style="stop-color:#FAF0BB"
605 id="stop3277" />
606 <stop
607 offset="0.4917"
608 style="stop-color:#FAF0BD"
609 id="stop3279" />
610 <stop
611 offset="0.6648"
612 style="stop-color:#FBF2C5"
613 id="stop3281" />
614 <stop
615 offset="0.7882"
616 style="stop-color:#FCF6D0"
617 id="stop3283" />
618 <stop
619 offset="0.8879"
620 style="stop-color:#FCF8E1"
621 id="stop3285" />
622 <stop
623 offset="0.9723"
624 style="stop-color:#FFFDF7"
625 id="stop3287" />
626 <stop
627 offset="1"
628 style="stop-color:#FFFFFF"
629 id="stop3289" />
630 </radialGradient>
631 <path
632 d="m 197.254,290.925 c 1.482,-0.322 2.697,-1.225 3.201,-2.604 0.5,-1.367 0.166,-2.845 -0.726,-4.066 -0.835,-1.146 -2.134,-2.023 -3.647,-2.408 -1.389,-0.352 -2.723,-0.223 -3.781,0.238 -1.011,0.439 -1.812,1.196 -2.21,2.198 -0.397,1.001 -0.335,2.12 0.108,3.146 0.468,1.083 1.377,2.112 2.666,2.812 1.407,0.762 2.987,0.989 4.389,0.684 z"
633 id="path238"
634 style="fill:url(#radialGradient3310)"
635 inkscape:connector-curvature="0" />
636 <radialGradient
637 id="radialGradient3292"
638 cx="173.2812"
639 cy="283.68359"
640 r="2.8803999"
641 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
642 gradientUnits="userSpaceOnUse">
643 <stop
644 offset="0.0112"
645 style="stop-color:#FAF0BB"
646 id="stop3294" />
647 <stop
648 offset="0.4917"
649 style="stop-color:#FAF0BD"
650 id="stop3296" />
651 <stop
652 offset="0.6648"
653 style="stop-color:#FBF2C5"
654 id="stop3298" />
655 <stop
656 offset="0.7882"
657 style="stop-color:#FCF6D0"
658 id="stop3300" />
659 <stop
660 offset="0.8879"
661 style="stop-color:#FCF8E1"
662 id="stop3302" />
663 <stop
664 offset="0.9723"
665 style="stop-color:#FFFDF7"
666 id="stop3304" />
667 <stop
668 offset="1"
669 style="stop-color:#FFFFFF"
670 id="stop3306" />
671 </radialGradient>
672 <path
673 d="m 200.538,302.533 c -0.568,-0.598 -1.402,-0.802 -2.248,-0.657 -0.792,0.136 -1.565,0.573 -2.143,1.244 -0.529,0.616 -0.8,1.327 -0.833,1.98 -0.032,0.624 0.15,1.222 0.559,1.676 0.408,0.455 0.991,0.705 1.624,0.739 0.668,0.035 1.42,-0.167 2.101,-0.645 0.741,-0.521 1.256,-1.267 1.454,-2.056 0.21,-0.833 0.058,-1.677 -0.514,-2.281 z"
674 id="path255"
675 style="fill:url(#radialGradient3312)"
676 inkscape:connector-curvature="0" />
677 <radialGradient
678 id="radialGradient3309"
679 cx="148.9492"
680 cy="270.04489"
681 r="2.8799"
682 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
683 gradientUnits="userSpaceOnUse">
684 <stop
685 offset="0.0112"
686 style="stop-color:#FAF0BB"
687 id="stop3311" />
688 <stop
689 offset="0.4917"
690 style="stop-color:#FAF0BD"
691 id="stop3313" />
692 <stop
693 offset="0.6648"
694 style="stop-color:#FBF2C5"
695 id="stop3315" />
696 <stop
697 offset="0.7882"
698 style="stop-color:#FCF6D0"
699 id="stop3317" />
700 <stop
701 offset="0.8879"
702 style="stop-color:#FCF8E1"
703 id="stop3319" />
704 <stop
705 offset="0.9723"
706 style="stop-color:#FFFDF7"
707 id="stop3321" />
708 <stop
709 offset="1"
710 style="stop-color:#FFFFFF"
711 id="stop3323" />
712 </radialGradient>
713 <path
714 d="m 173.958,315.516 c -0.793,0.136 -1.566,0.573 -2.143,1.244 -0.529,0.616 -0.801,1.327 -0.834,1.98 -0.031,0.623 0.15,1.222 0.559,1.676 0.408,0.455 0.991,0.705 1.624,0.738 0.669,0.036 1.42,-0.166 2.101,-0.645 0.741,-0.521 1.256,-1.266 1.454,-2.055 0.211,-0.834 0.06,-1.679 -0.514,-2.282 -0.568,-0.598 -1.402,-0.801 -2.247,-0.656 z"
715 id="path272"
716 style="fill:url(#radialGradient3314)"
717 inkscape:connector-curvature="0" />
718 <radialGradient
719 id="radialGradient3326"
720 cx="148.0723"
721 cy="319.09381"
722 r="3.9265001"
723 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
724 gradientUnits="userSpaceOnUse">
725 <stop
726 offset="0.0112"
727 style="stop-color:#FAF0BB"
728 id="stop3328" />
729 <stop
730 offset="0.4917"
731 style="stop-color:#FAF0BD"
732 id="stop3330" />
733 <stop
734 offset="0.6648"
735 style="stop-color:#FBF2C5"
736 id="stop3332" />
737 <stop
738 offset="0.7882"
739 style="stop-color:#FCF6D0"
740 id="stop3334" />
741 <stop
742 offset="0.8879"
743 style="stop-color:#FCF8E1"
744 id="stop3336" />
745 <stop
746 offset="0.9723"
747 style="stop-color:#FFFDF7"
748 id="stop3338" />
749 <stop
750 offset="1"
751 style="stop-color:#FFFFFF"
752 id="stop3340" />
753 </radialGradient>
754 <path
755 d="m 171.282,272.336 c 1.106,0.549 2.333,0.68 3.407,0.405 1.136,-0.291 2.049,-1.022 2.398,-2.102 0.347,-1.069 0.048,-2.201 -0.675,-3.119 -0.678,-0.861 -1.706,-1.502 -2.885,-1.756 -1.083,-0.233 -2.109,-0.095 -2.914,0.291 -0.768,0.368 -1.365,0.975 -1.645,1.76 -0.278,0.785 -0.198,1.646 0.173,2.426 0.394,0.822 1.125,1.592 2.141,2.095 z"
756 id="path289"
757 style="fill:url(#radialGradient3316)"
758 inkscape:connector-curvature="0" />
759 <radialGradient
760 id="radialGradient3343"
761 cx="112.9551"
762 cy="315.56049"
763 r="3.0683999"
764 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
765 gradientUnits="userSpaceOnUse">
766 <stop
767 offset="0.0112"
768 style="stop-color:#FAF0BB"
769 id="stop3345" />
770 <stop
771 offset="0.4917"
772 style="stop-color:#FAF0BD"
773 id="stop3347" />
774 <stop
775 offset="0.6648"
776 style="stop-color:#FBF2C5"
777 id="stop3349" />
778 <stop
779 offset="0.7882"
780 style="stop-color:#FCF6D0"
781 id="stop3351" />
782 <stop
783 offset="0.8879"
784 style="stop-color:#FCF8E1"
785 id="stop3353" />
786 <stop
787 offset="0.9723"
788 style="stop-color:#FFFDF7"
789 id="stop3355" />
790 <stop
791 offset="1"
792 style="stop-color:#FFFFFF"
793 id="stop3357" />
794 </radialGradient>
795 <path
796 d="m 140.776,270.8 c -0.132,-0.306 -0.298,-0.603 -0.496,-0.884 0,0 -0.001,-10e-4 -0.001,-10e-4 -0.031,0.02 -0.061,0.042 -0.091,0.062 -0.1,0.067 -0.199,0.135 -0.298,0.203 -0.12,0.082 -0.24,0.163 -0.358,0.246 -0.123,0.085 -0.245,0.173 -0.366,0.26 -0.096,0.068 -0.193,0.136 -0.289,0.206 -0.146,0.106 -0.29,0.213 -0.434,0.321 -0.072,0.054 -0.145,0.106 -0.216,0.161 -0.215,0.163 -0.429,0.328 -0.641,0.495 -0.223,0.175 -0.443,0.354 -0.663,0.535 -0.064,0.053 -0.129,0.107 -0.194,0.161 -0.171,0.143 -0.341,0.287 -0.51,0.432 -0.054,0.046 -0.108,0.092 -0.162,0.139 -0.193,0.167 -0.384,0.337 -0.574,0.509 -0.098,0.088 -0.196,0.178 -0.293,0.268 -0.099,0.09 -0.196,0.182 -0.294,0.274 -0.079,0.074 -0.16,0.146 -0.238,0.222 0,0 0.001,0.001 0.001,0.001 0.177,0.156 0.363,0.299 0.555,0.429 0.596,0.402 1.257,0.671 1.927,0.786 1.185,0.202 2.356,-0.083 3.152,-0.922 0.804,-0.847 1.017,-2.032 0.722,-3.202 -0.06,-0.24 -0.14,-0.473 -0.239,-0.701 z"
797 id="path306"
798 style="fill:url(#radialGradient3318)"
799 inkscape:connector-curvature="0" />
800 <radialGradient
801 id="radialGradient3360"
802 cx="132.0938"
803 cy="320.1113"
804 r="4.1712999"
805 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
806 gradientUnits="userSpaceOnUse">
807 <stop
808 offset="0.0112"
809 style="stop-color:#FAF0BB"
810 id="stop3362" />
811 <stop
812 offset="0.4917"
813 style="stop-color:#FAF0BD"
814 id="stop3364" />
815 <stop
816 offset="0.6648"
817 style="stop-color:#FBF2C5"
818 id="stop3366" />
819 <stop
820 offset="0.7882"
821 style="stop-color:#FCF6D0"
822 id="stop3368" />
823 <stop
824 offset="0.8879"
825 style="stop-color:#FCF8E1"
826 id="stop3370" />
827 <stop
828 offset="0.9723"
829 style="stop-color:#FFFDF7"
830 id="stop3372" />
831 <stop
832 offset="1"
833 style="stop-color:#FFFFFF"
834 id="stop3374" />
835 </radialGradient>
836 <path
837 d="m 160.2,265.6 c -0.85,-0.392 -1.938,-0.592 -3.115,-0.521 -1.177,0.07 -2.29,0.405 -3.157,0.906 -0.916,0.53 -1.6,1.269 -1.798,2.11 -0.216,0.917 0.182,1.777 1.05,2.403 0.918,0.663 2.32,1.032 3.923,0.914 1.588,-0.118 2.959,-0.687 3.847,-1.468 0.833,-0.732 1.209,-1.627 0.998,-2.496 -0.195,-0.799 -0.859,-1.438 -1.748,-1.848 z"
838 id="path323"
839 style="fill:url(#radialGradient3320)"
840 inkscape:connector-curvature="0" />
841 <radialGradient
842 id="radialGradient3377"
843 cx="147.44189"
844 cy="301.21091"
845 r="2.5313001"
846 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
847 gradientUnits="userSpaceOnUse">
848 <stop
849 offset="0.0112"
850 style="stop-color:#FAF0BB"
851 id="stop3379" />
852 <stop
853 offset="0.4917"
854 style="stop-color:#FAF0BD"
855 id="stop3381" />
856 <stop
857 offset="0.6648"
858 style="stop-color:#FBF2C5"
859 id="stop3383" />
860 <stop
861 offset="0.7882"
862 style="stop-color:#FCF6D0"
863 id="stop3385" />
864 <stop
865 offset="0.8879"
866 style="stop-color:#FCF8E1"
867 id="stop3387" />
868 <stop
869 offset="0.9723"
870 style="stop-color:#FFFDF7"
871 id="stop3389" />
872 <stop
873 offset="1"
874 style="stop-color:#FFFFFF"
875 id="stop3391" />
876 </radialGradient>
877 <path
878 d="m 173.961,289.2 c 0.657,-0.143 1.12,-0.506 1.265,-1.029 0.133,-0.48 -0.03,-1.015 -0.381,-1.495 -0.335,-0.458 -0.853,-0.886 -1.498,-1.196 -0.645,-0.31 -1.333,-0.461 -1.94,-0.451 -0.643,0.011 -1.223,0.2 -1.576,0.587 -0.385,0.422 -0.428,0.996 -0.152,1.584 0.291,0.622 0.925,1.231 1.811,1.642 0.876,0.408 1.77,0.51 2.471,0.358 z"
879 id="path340"
880 style="fill:url(#radialGradient3322)"
881 inkscape:connector-curvature="0" />
882 </g>
883 <path
884 d="m 32.300561,46.79686 c -0.244913,-0.207495 -0.516006,-0.294969 -0.756275,-0.27971 -0.2276,0.01425 -0.437888,0.12307 -0.584836,0.320395 -0.147371,0.197321 -0.212822,0.456181 -0.201419,0.726735 0.01182,0.283777 0.109788,0.591457 0.300228,0.85845 0.207332,0.290901 0.486027,0.480592 0.771056,0.539586 0.304451,0.06256 0.605105,-0.02543 0.809057,-0.284794 0.206488,-0.26191 0.260961,-0.628075 0.185374,-0.989662 -0.07136,-0.342262 -0.256312,-0.665199 -0.523185,-0.891 z"
885 id="path347"
886 style="fill:#000000"
887 inkscape:connector-curvature="0" />
888 <g
889 id="g349"
890 transform="matrix(0.42226435,0,0,0.50856192,-47.726977,-111.72952)">
891 <path
892 d="m 168.559,264.427 c 4.145,0.407 8.127,1.382 11.858,2.845 l 0.623,-0.856 c -3.919,-1.741 -8.161,-2.906 -12.604,-3.384 l 0.123,1.395 z"
893 id="path351"
894 inkscape:connector-curvature="0"
895 style="fill:#ffffff" />
896 <path
897 d="m 145.971,266.73 1.059,0.888 c 5.193,-2.147 10.87,-3.351 16.738,-3.403 l 0.009,-0.038 0.435,-1.388 c -0.059,0 -0.116,-0.002 -0.175,-0.002 -6.387,-0.024 -12.545,1.39 -18.066,3.943 z"
898 id="path353"
899 inkscape:connector-curvature="0"
900 style="fill:#ffffff" />
901 <path
902 d="m 185.374,269.579 c 0.97,0.527 1.917,1.087 2.84,1.683 l 0.494,-0.416 c -1.011,-0.738 -2.058,-1.431 -3.138,-2.078 l -0.196,0.811 z"
903 id="path355"
904 inkscape:connector-curvature="0"
905 style="fill:#ffffff" />
906 <path
907 d="m 190.66,272.366 -0.224,0.429 c 0.458,0.338 0.91,0.683 1.354,1.038 1.494,1.193 2.916,2.493 4.25,3.889 -1.633,-1.962 -3.44,-3.752 -5.38,-5.356 z"
908 id="path357"
909 inkscape:connector-curvature="0"
910 style="fill:#ffffff" />
911 <path
912 d="m 140.28,269.916 c 0.198,0.281 0.363,0.578 0.496,0.884 0.84,-0.514 1.699,-1.002 2.575,-1.462 l -0.52,-0.994 c -0.871,0.494 -1.721,1.019 -2.551,1.572 z"
913 id="path359"
914 inkscape:connector-curvature="0"
915 style="fill:#ffffff" />
916 <path
917 d="m 133.625,275.426 0.562,0.314 c 0.338,-0.307 0.681,-0.608 1.028,-0.904 -0.192,-0.129 -0.378,-0.272 -0.555,-0.429 -0.35,0.333 -0.696,0.673 -1.035,1.019 z"
918 id="path361"
919 inkscape:connector-curvature="0"
920 style="fill:#ffffff" />
921 <path
922 d="m 130.152,279.456 c 0.139,-0.009 0.279,-0.015 0.419,-0.019 0.538,-0.62 1.091,-1.224 1.66,-1.81 l -0.295,-0.374 c -0.618,0.713 -1.212,1.447 -1.784,2.203 z"
923 id="path363"
924 inkscape:connector-curvature="0"
925 style="fill:#ffffff" />
926 </g>
927 <path
928 d="m 11.717707,25.989048 c -0.05574,-0.15562 -0.125834,-0.306666 -0.209444,-0.44957 -0.01309,0.01012 -0.02618,0.02032 -0.03885,0.03052 -0.04223,0.03408 -0.08403,0.06866 -0.125835,0.10324 -0.05067,0.0417 -0.101339,0.08289 -0.151171,0.125104 -0.05194,0.04324 -0.103455,0.08798 -0.154549,0.132228 -0.04054,0.03459 -0.0815,0.06916 -0.122034,0.104767 -0.06165,0.0534 -0.122457,0.108333 -0.183263,0.16325 -0.03041,0.02747 -0.06122,0.05392 -0.09122,0.08188 -0.09078,0.08288 -0.181151,0.166809 -0.27067,0.251737 -0.09416,0.0895 -0.187063,0.180031 -0.279961,0.272083 -0.02703,0.02695 -0.05447,0.05442 -0.08192,0.08188 -0.07221,0.07272 -0.1439917,0.145958 -0.2153547,0.219699 -0.02281,0.02339 -0.0456,0.04679 -0.068411,0.07019 -0.081499,0.08492 -0.1621494,0.171895 -0.24238,0.258858 -0.041385,0.04477 -0.08276,0.09052 -0.1237229,0.136294 -0.041799,0.04628 -0.08276,0.09308 -0.1241459,0.139347 -0.033364,0.03762 -0.066717,0.07527 -0.1000776,0.113908 0.074741,0.07935 0.1532821,0.152062 0.2343573,0.218175 C 9.5506288,27.855494 9.7347353,27.672921 9.9217999,27.495432 10.4927,26.95178 11.092737,26.44983 11.717689,25.989072 z"
929 id="path365"
930 inkscape:connector-curvature="0"
931 style="fill:#eeeeee" />
932 <path
933 d="m 28.381526,27.537111 c 0.388483,0.0014 0.747409,0.164265 1.026947,0.433802 0.293051,0.282252 0.512205,0.694697 0.575969,1.184949 0.06968,0.534499 -0.05447,1.061878 -0.328523,1.474322 -0.292629,0.439906 -0.744451,0.732838 -1.26806,0.744027 -0.528674,0.01119 -0.990631,-0.26547 -1.292973,-0.70131 -0.286295,-0.411932 -0.417197,-0.947959 -0.345834,-1.495681 0.06503,-0.501949 0.290517,-0.923546 0.592437,-1.209867 0.28545,-0.271063 0.652399,-0.431769 1.040037,-0.430242 z"
934 id="path372"
935 style="fill:#000000"
936 inkscape:connector-curvature="0" />
937 <path
938 d="m 13.466305,55.28374 c 0.178195,0.09256 0.329787,0.214614 0.43662,0.342772 0.111901,0.134768 0.178619,0.281236 0.168063,0.408885 -0.0114,0.139346 -0.111902,0.231394 -0.271518,0.261399 -0.170172,0.03153 -0.401994,-0.0082 -0.64353,-0.129175 -0.244069,-0.12256 -0.433666,-0.295472 -0.53712,-0.467367 -0.09797,-0.162232 -0.114433,-0.316834 -0.03674,-0.425668 0.07093,-0.100193 0.209021,-0.143413 0.37117,-0.13782 0.152859,0.005 0.334856,0.05491 0.513051,0.146974 l 0,0 z m -2.368059,-0.261399 c 0.05025,0.0122 0.09585,0.04017 0.130479,0.0768 0.03588,0.03815 0.06165,0.08797 0.06671,0.140364 0.0055,0.05696 -0.01435,0.10731 -0.05278,0.141381 -0.04097,0.0356 -0.101763,0.05188 -0.169749,0.03611 -0.06883,-0.01525 -0.127102,-0.05848 -0.163417,-0.113404 -0.03463,-0.05139 -0.04772,-0.110861 -0.03463,-0.164774 0.01183,-0.04984 0.04392,-0.08594 0.0853,-0.10578 0.03885,-0.01831 0.08741,-0.02339 0.138081,-0.01071 l 0,0 z m 3.807979,2.368373 c 0.09627,0.02389 0.183263,0.07728 0.248714,0.147481 0.06925,0.07322 0.117813,0.167318 0.127101,0.267506 0.01013,0.109332 -0.02745,0.204948 -0.100915,0.270045 -0.07854,0.06866 -0.194242,0.09866 -0.324299,0.06968 -0.131324,-0.03002 -0.24238,-0.111886 -0.311631,-0.216139 -0.06545,-0.09816 -0.09122,-0.21156 -0.0663,-0.314799 0.02281,-0.09459 0.08446,-0.163757 0.162995,-0.2019 0.07515,-0.03611 0.16806,-0.04576 0.264336,-0.02185 l 0,0 z m -2.357501,-1.035942 c -0.09333,-0.04831 -0.188754,-0.07425 -0.269405,-0.0768 -0.08487,-0.003 -0.157504,0.01983 -0.194242,0.07222 -0.04054,0.05696 -0.03209,0.137821 0.01942,0.222749 0.05405,0.09052 0.153704,0.18054 0.281651,0.245128 0.126679,0.06356 0.247869,0.08391 0.337388,0.06765 0.08362,-0.01576 0.136392,-0.06407 0.142304,-0.137313 0.0055,-0.06713 -0.02956,-0.143414 -0.08783,-0.214102 -0.05658,-0.06714 -0.135969,-0.13121 -0.22929,-0.179526 z"
939 id="path374"
940 inkscape:connector-curvature="0"
941 style="fill:#d9bb7a" />
942 <path
943 d="m 32.89722,32.895826 c 0.143148,-0.434312 0.431555,-0.762333 0.795547,-0.953043 0.380884,-0.199865 0.861841,-0.255808 1.361803,-0.10325 0.544721,0.166808 1.012166,0.547722 1.313242,1.044079 0.320921,0.529412 0.440844,1.170201 0.26096,1.762675 -0.181574,0.59807 -0.618618,0.989661 -1.15236,1.129517 -0.504607,0.132224 -1.073818,0.03356 -1.579691,-0.297003 -0.464491,-0.303099 -0.791747,-0.749617 -0.960229,-1.219019 -0.160039,-0.444994 -0.182419,-0.929651 -0.03927,-1.363962 z"
944 id="path381"
945 style="fill:#000000"
946 inkscape:connector-curvature="0" />
947 <path
948 d="m 35.093418,44.08063 c -0.146948,-0.197323 -0.212399,-0.456178 -0.200998,-0.726732 0.01182,-0.28378 0.109367,-0.591461 0.299807,-0.858457 0.207754,-0.290895 0.486028,-0.480589 0.771477,-0.540093 0.304453,-0.06256 0.604685,0.02594 0.809059,0.285306 0.206487,0.261909 0.26096,0.628075 0.184952,0.989659 -0.07137,0.342262 -0.256313,0.6652 -0.523607,0.891001 -0.244913,0.207492 -0.515586,0.294965 -0.755853,0.27971 -0.227601,-0.01423 -0.437466,-0.123072 -0.584837,-0.320394 z"
949 id="path388"
950 style="fill:#000000"
951 inkscape:connector-curvature="0" />
952 <path
953 d="m 24.819304,51.017414 c -0.147371,-0.197322 -0.212821,-0.456179 -0.201421,-0.727243 0.01183,-0.283269 0.10979,-0.590948 0.30023,-0.858455 0.207333,-0.290896 0.485604,-0.481098 0.771055,-0.540089 0.304453,-0.06256 0.605106,0.02594 0.809059,0.285303 0.206487,0.261908 0.260959,0.628074 0.184952,0.989661 -0.07136,0.342263 -0.256314,0.6652 -0.523608,0.891002 -0.24449,0.207493 -0.515584,0.294964 -0.755854,0.279709 -0.2276,-0.01425 -0.437465,-0.123071 -0.584413,-0.319888 z"
954 id="path395"
955 style="fill:#000000"
956 inkscape:connector-curvature="0" />
957 <path
958 d="m 23.786446,24.445052 c 0.102186,-0.347855 0.322609,-0.616885 0.605104,-0.779624 0.296007,-0.170876 0.673933,-0.232414 1.072129,-0.128666 0.433667,0.112897 0.812438,0.396678 1.061996,0.778609 0.266026,0.406849 0.376235,0.908289 0.24829,1.382269 -0.12879,0.47805 -0.464913,0.802512 -0.882532,0.931685 -0.395661,0.12205 -0.84664,0.06357 -1.254126,-0.17952 -0.374125,-0.222751 -0.642686,-0.563996 -0.787099,-0.928635 -0.137237,-0.346331 -0.166373,-0.728261 -0.06377,-1.076118 z"
959 id="path402"
960 style="fill:#000000"
961 inkscape:connector-curvature="0" />
962 <path
963 d="m 9.3572511,27.571182 c 0.2537814,0.256316 0.5518992,0.424651 0.8555069,0.487204 0.426486,0.08747 0.848329,-0.03611 1.135047,-0.399731 0.28925,-0.367181 0.366103,-0.880828 0.259692,-1.388372 -0.0456,-0.217666 -0.123723,-0.429227 -0.230557,-0.625532 -0.344568,0.281745 -0.680268,0.577726 -1.006255,0.886932 -0.347524,0.330057 -0.6857564,0.676897 -1.0134339,1.039499 z"
964 id="path409"
965 style="fill:#000000"
966 inkscape:connector-curvature="0" />
967 <path
968 d="m 9.3572511,27.571182 c 0.081923,0.08289 0.1684839,0.15664 0.2584255,0.220208 0.1013389,-0.100194 0.2031087,-0.199865 0.3061417,-0.296999 0.5244517,-0.497883 1.0733947,-0.962708 1.6434517,-1.391936 -0.04604,-0.15867 -0.109367,-0.312257 -0.188752,-0.457195 l 0,0 c -0.02997,0.02442 -0.05996,0.04933 -0.08995,0.07425 -0.01942,0.01628 -0.03927,0.03255 -0.05869,0.04883 -0.03336,0.02747 -0.0663,0.05545 -0.09923,0.08341 l -0.04519,0.03865 c -0.03758,0.03205 -0.07474,0.06407 -0.111899,0.09613 l -0.02997,0.02594 c -0.04139,0.03611 -0.08235,0.07221 -0.123301,0.108332 l -0.02026,0.01832 c -0.04392,0.03918 -0.08741,0.07781 -0.130901,0.117485 l -0.01309,0.01169 c -0.04603,0.04223 -0.09206,0.08442 -0.13808,0.12714 l -0.0018,0.0014 c -0.04815,0.04476 -0.09585,0.0895 -0.143569,0.134769 -0.07685,0.07322 -0.15286,0.146467 -0.228867,0.221226 l -0.01098,0.01072 c -0.02026,0.02032 -0.04097,0.04018 -0.06123,0.06051 l -0.01858,0.01882 -0.05236,0.05238 -0.02956,0.03002 -0.04307,0.04376 -0.03801,0.03865 -0.01605,0.01627 -0.01562,0.01627 -0.04771,0.04883 -0.01562,0.01627 C 9.6459492,27.256383 9.50069,27.412511 9.3571211,27.571183 z"
969 id="path411"
970 inkscape:connector-curvature="0"
971 style="fill:#888678" />
972 <path
973 d="m 18.571057,23.295194 c 0.423955,-0.03051 0.815816,0.05645 1.121534,0.226311 0.320077,0.177997 0.559079,0.455163 0.629176,0.800985 0.07601,0.376844 -0.05954,0.764369 -0.359348,1.082221 -0.319232,0.338701 -0.812859,0.585354 -1.385028,0.636719 -0.577235,0.05138 -1.081841,-0.108827 -1.412472,-0.39617 -0.312477,-0.271573 -0.456047,-0.644349 -0.378351,-1.042043 0.07136,-0.364639 0.317965,-0.685034 0.647333,-0.914395 0.312897,-0.217665 0.713204,-0.363114 1.137156,-0.393628 z"
974 id="path418"
975 style="fill:#000000"
976 inkscape:connector-curvature="0" />
977 <path
978 d="m 25.268593,33.539157 c 0.209865,0.121549 0.37835,0.289372 0.487716,0.468895 0.11401,0.188169 0.167216,0.397695 0.123723,0.585864 -0.04687,0.20495 -0.198043,0.347856 -0.412131,0.403289 -0.228021,0.05951 -0.519383,0.01933 -0.804835,-0.139854 -0.288406,-0.160707 -0.494471,-0.399731 -0.589482,-0.643842 -0.08995,-0.230376 -0.07601,-0.455669 0.04941,-0.620952 0.114856,-0.152061 0.304451,-0.226311 0.51305,-0.230379 0.198043,-0.0036 0.422688,0.05543 0.632553,0.176979 z"
979 id="path425"
980 style="fill:#000000"
981 inkscape:connector-curvature="0" />
982 <polygon
983 points="182.526,321.973 188.385,321.662 183.827,319.426 190.01,322.008 "
984 id="polygon427"
985 transform="matrix(0.42226435,0,0,0.50856192,-47.726977,-111.72952)" />
986 <polygon
987 points="176.606,313.919 181.161,310.218 176.159,311.094 182.677,309.541 "
988 id="polygon429"
989 transform="matrix(0.42226435,0,0,0.50856192,-47.726977,-111.72952)" />
990 <polygon
991 points="180.144,285.178 188.996,281.271 183.955,287.956 191.129,279.553 "
992 id="polygon431"
993 transform="matrix(0.42226435,0,0,0.50856192,-47.726977,-111.72952)" />
994 <path
995 d="m 35.589578,54.524966 c -0.122034,0.197832 -0.247447,0.39312 -0.376237,0.586373 -3.139958,4.719964 -7.989242,7.864909 -13.609581,7.987982 C 15.929794,63.222902 10.97199,60.250356 7.7226683,55.572603 7.5229375,55.285266 7.3303849,54.991318 7.1445881,54.693299 c 3.5503959,4.555698 8.6741509,7.392458 14.4832419,7.265826 5.617804,-0.123069 10.532541,-3.002548 13.961748,-7.434159 z"
996 id="path440"
997 style="fill:#d9bb7a"
998 inkscape:connector-curvature="0" />
999 <path
1000 d="m 16.345302,52.251694 c -2.117655,-1.929991 -2.971052,-5.408047 -1.900189,-8.495019 1.184029,-3.41245 4.302452,-5.144614 7.182295,-4.121385 -2.791167,-0.695713 -5.69128,1.060859 -6.831394,4.34617 -1.023146,2.94966 -0.321343,6.249209 1.549288,8.270234 z"
1001 id="path442"
1002 inkscape:connector-curvature="0"
1003 style="fill:#ffffff" />
1004 <path
1005 d="m 7.9004418,49.211004 c 1.5839109,-1.826246 1.8765395,-5.188352 0.611861,-7.774387 -0.9606515,-1.964067 -2.560189,-2.949661 -4.0731622,-2.724366 1.4428771,-0.03307 2.911513,0.974913 3.8219146,2.837267 1.2266751,2.507718 1.0299008,5.725391 -0.3606134,7.661486 z"
1006 id="path444"
1007 inkscape:connector-curvature="0"
1008 style="fill:#ffffff" />
1009 <path
1010 d="m 46.744961,35.073491 -0.497006,-0.879306 c -0.446333,-0.789288 -2.616772,-1.271403 -3.063106,-2.060692 -0.04897,-0.08645 -0.08995,-0.178504 -0.124145,-0.273607 0.02111,0.05392 0.04434,0.106285 0.07093,0.157655 0.411286,0.799459 2.442378,0.780134 2.853664,1.579592 l 0.759653,1.476358 0,0 z m -3.840919,-4.235306 c -0.02154,-1.142737 0.276584,-2.476187 -0.211554,-3.339725 -0.684068,-1.210379 -3.109133,-1.708769 -3.070285,-3.678937 0.02618,-1.300901 0.05531,-2.044928 -0.877888,-0.830484 -0.474202,0.616888 -0.933204,1.256658 -1.378271,1.918806 0.532898,-0.895579 1.084376,-1.758098 1.656966,-2.58553 0.921382,-1.331414 0.877043,-0.549754 0.825104,0.815225 -0.02492,0.63723 0.05786,1.381764 0.330634,1.912701 0.487293,0.947452 2.164949,1.469236 2.652243,2.416687 0.464492,0.901679 0.07769,2.233605 0.07305,3.371257 z"
1011 id="path446"
1012 inkscape:connector-curvature="0"
1013 style="fill:#ffffff" />
1014 <path
1015 d="m 16.756588,33.897186 c 0.357235,-0.248687 0.77781,-0.246145 1.121111,-0.03865 -0.09501,0.0122 -0.189596,0.04832 -0.27785,0.109346 -0.338655,0.235464 -0.455199,0.757757 -0.25927,1.165625 0.19551,0.408372 0.629174,0.548229 0.96783,0.312255 0.08783,-0.06155 0.160883,-0.14189 0.217467,-0.234955 -0.02237,0.461773 -0.230979,0.901679 -0.588638,1.150367 -0.564566,0.39261 -1.287061,0.15918 -1.613471,-0.520769 -0.325145,-0.680454 -0.131747,-1.550096 0.432821,-1.943214 l 0,0 z m -8.4625961,1.183931 c 0.2575811,-0.179014 0.5603435,-0.177488 0.8077901,-0.02795 -0.068836,0.009 -0.1368128,0.03458 -0.2001525,0.07882 -0.2440687,0.169354 -0.327677,0.545687 -0.1866399,0.839639 0.1406128,0.293947 0.453088,0.394643 0.6971553,0.224782 0.063334,-0.04425 0.1161241,-0.102217 0.1570835,-0.16935 C 9.5527694,36.35966 9.4024339,36.676495 9.1452751,36.855507 8.7386349,37.138248 8.2179844,36.970431 7.983206,36.480169 7.7475821,35.990933 7.887351,35.363875 8.2939919,35.081114 z"
1016 id="path448"
1017 inkscape:connector-curvature="0" />
1018 <path
1019 d="m 11.148494,37.665629 c -0.260113,-0.748095 -0.420152,-1.550096 -0.46449,-2.376002 -0.533741,1.967118 -1.8647168,3.382956 -3.4389171,3.862529 0.4619579,0.354468 0.8876005,0.829465 1.2503252,1.416854 1.1793816,-0.417022 2.1776139,-1.463641 2.6530819,-2.903381 z"
1020 id="path450"
1021 inkscape:connector-curvature="0"
1022 style="fill:#eeeeee" />
1023 <path
1024 d="m 3.5654754,33.263516 c -0.2884063,0.139348 -0.5160068,0.432279 -0.656621,0.92355 -0.6697112,2.341929 -0.5459877,4.035438 0.033358,5.072397 C 3.09465,39.150129 3.25131,39.055528 3.4109259,38.975177 3.537183,38.886186 3.6659737,38.807859 3.7972979,38.739713 3.1153408,37.498312 2.8611376,35.923805 3.2065499,34.3732 3.2935369,33.980083 3.4151486,33.609339 3.5654746,33.263516 z"
1025 id="path457"
1026 style="fill:#f0a513"
1027 inkscape:connector-curvature="0" />
1028 <path
1029 d="m 9.6346789,48.851958 c 0.7959681,1.053234 2.8688621,0.917445 3.5212611,-0.268012 -0.352592,0.781151 -1.04046,1.31209 -1.830517,1.31209 -0.695891,0 -1.312395,-0.411935 -1.6907441,-1.044078 z"
1030 id="path459"
1031 inkscape:connector-curvature="0"
1032 style="fill:#ffffff" />
1033 </g>
1034 </g>
1035 </svg>
0 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
1 <!-- Created with Inkscape (http://www.inkscape.org/) -->
2
3 <svg
4 xmlns:dc="http://purl.org/dc/elements/1.1/"
5 xmlns:cc="http://creativecommons.org/ns#"
6 xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
7 xmlns:svg="http://www.w3.org/2000/svg"
8 xmlns="http://www.w3.org/2000/svg"
9 xmlns:xlink="http://www.w3.org/1999/xlink"
10 xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
11 xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
12 width="48"
13 height="48"
14 id="svg26756"
15 version="1.1"
16 inkscape:version="0.48.3.1 r9886"
17 sodipodi:docname="diodon.svg">
18 <defs
19 id="defs26758">
20 <radialGradient
21 inkscape:collect="always"
22 xlink:href="#SVGID_3_"
23 id="radialGradient3305"
24 gradientUnits="userSpaceOnUse"
25 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
26 cx="163.4902"
27 cy="274.86621"
28 r="2.8801" />
29 <radialGradient
30 gradientUnits="userSpaceOnUse"
31 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
32 r="2.8801"
33 cy="274.86621"
34 cx="163.4902"
35 id="SVGID_3_">
36 <stop
37 id="stop190"
38 style="stop-color:#FAF0BB"
39 offset="0.0112" />
40 <stop
41 id="stop192"
42 style="stop-color:#FAF0BD"
43 offset="0.4917" />
44 <stop
45 id="stop194"
46 style="stop-color:#FBF2C5"
47 offset="0.6648" />
48 <stop
49 id="stop196"
50 style="stop-color:#FCF6D0"
51 offset="0.7882" />
52 <stop
53 id="stop198"
54 style="stop-color:#FCF8E1"
55 offset="0.8879" />
56 <stop
57 id="stop200"
58 style="stop-color:#FFFDF7"
59 offset="0.9723" />
60 <stop
61 id="stop202"
62 style="stop-color:#FFFFFF"
63 offset="1" />
64 </radialGradient>
65 <radialGradient
66 inkscape:collect="always"
67 xlink:href="#SVGID_4_"
68 id="radialGradient3307"
69 gradientUnits="userSpaceOnUse"
70 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
71 cx="155.3242"
72 cy="310.6777"
73 r="4.4867001" />
74 <radialGradient
75 gradientUnits="userSpaceOnUse"
76 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
77 r="4.4867001"
78 cy="310.6777"
79 cx="155.3242"
80 id="SVGID_4_">
81 <stop
82 id="stop207"
83 style="stop-color:#FAF0BB"
84 offset="0.0112" />
85 <stop
86 id="stop209"
87 style="stop-color:#FAF0BD"
88 offset="0.4917" />
89 <stop
90 id="stop211"
91 style="stop-color:#FBF2C5"
92 offset="0.6648" />
93 <stop
94 id="stop213"
95 style="stop-color:#FCF6D0"
96 offset="0.7882" />
97 <stop
98 id="stop215"
99 style="stop-color:#FCF8E1"
100 offset="0.8879" />
101 <stop
102 id="stop217"
103 style="stop-color:#FFFDF7"
104 offset="0.9723" />
105 <stop
106 id="stop219"
107 style="stop-color:#FFFFFF"
108 offset="1" />
109 </radialGradient>
110 <radialGradient
111 inkscape:collect="always"
112 xlink:href="#SVGID_5_"
113 id="radialGradient3310"
114 gradientUnits="userSpaceOnUse"
115 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
116 cx="170.3125"
117 cy="302.00781"
118 r="5.0811" />
119 <radialGradient
120 gradientUnits="userSpaceOnUse"
121 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
122 r="5.0811"
123 cy="302.00781"
124 cx="170.3125"
125 id="SVGID_5_">
126 <stop
127 id="stop224"
128 style="stop-color:#FAF0BB"
129 offset="0.0112" />
130 <stop
131 id="stop226"
132 style="stop-color:#FAF0BD"
133 offset="0.4917" />
134 <stop
135 id="stop228"
136 style="stop-color:#FBF2C5"
137 offset="0.6648" />
138 <stop
139 id="stop230"
140 style="stop-color:#FCF6D0"
141 offset="0.7882" />
142 <stop
143 id="stop232"
144 style="stop-color:#FCF8E1"
145 offset="0.8879" />
146 <stop
147 id="stop234"
148 style="stop-color:#FFFDF7"
149 offset="0.9723" />
150 <stop
151 id="stop236"
152 style="stop-color:#FFFFFF"
153 offset="1" />
154 </radialGradient>
155 <radialGradient
156 inkscape:collect="always"
157 xlink:href="#SVGID_6_"
158 id="radialGradient3312"
159 gradientUnits="userSpaceOnUse"
160 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
161 cx="173.2812"
162 cy="283.68359"
163 r="2.8803999" />
164 <radialGradient
165 gradientUnits="userSpaceOnUse"
166 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
167 r="2.8803999"
168 cy="283.68359"
169 cx="173.2812"
170 id="SVGID_6_">
171 <stop
172 id="stop241"
173 style="stop-color:#FAF0BB"
174 offset="0.0112" />
175 <stop
176 id="stop243"
177 style="stop-color:#FAF0BD"
178 offset="0.4917" />
179 <stop
180 id="stop245"
181 style="stop-color:#FBF2C5"
182 offset="0.6648" />
183 <stop
184 id="stop247"
185 style="stop-color:#FCF6D0"
186 offset="0.7882" />
187 <stop
188 id="stop249"
189 style="stop-color:#FCF8E1"
190 offset="0.8879" />
191 <stop
192 id="stop251"
193 style="stop-color:#FFFDF7"
194 offset="0.9723" />
195 <stop
196 id="stop253"
197 style="stop-color:#FFFFFF"
198 offset="1" />
199 </radialGradient>
200 <radialGradient
201 inkscape:collect="always"
202 xlink:href="#SVGID_7_"
203 id="radialGradient3314"
204 gradientUnits="userSpaceOnUse"
205 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
206 cx="148.9492"
207 cy="270.04489"
208 r="2.8799" />
209 <radialGradient
210 gradientUnits="userSpaceOnUse"
211 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
212 r="2.8799"
213 cy="270.04489"
214 cx="148.9492"
215 id="SVGID_7_">
216 <stop
217 id="stop258"
218 style="stop-color:#FAF0BB"
219 offset="0.0112" />
220 <stop
221 id="stop260"
222 style="stop-color:#FAF0BD"
223 offset="0.4917" />
224 <stop
225 id="stop262"
226 style="stop-color:#FBF2C5"
227 offset="0.6648" />
228 <stop
229 id="stop264"
230 style="stop-color:#FCF6D0"
231 offset="0.7882" />
232 <stop
233 id="stop266"
234 style="stop-color:#FCF8E1"
235 offset="0.8879" />
236 <stop
237 id="stop268"
238 style="stop-color:#FFFDF7"
239 offset="0.9723" />
240 <stop
241 id="stop270"
242 style="stop-color:#FFFFFF"
243 offset="1" />
244 </radialGradient>
245 <radialGradient
246 inkscape:collect="always"
247 xlink:href="#SVGID_8_"
248 id="radialGradient3316"
249 gradientUnits="userSpaceOnUse"
250 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
251 cx="148.0723"
252 cy="319.09381"
253 r="3.9265001" />
254 <radialGradient
255 gradientUnits="userSpaceOnUse"
256 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
257 r="3.9265001"
258 cy="319.09381"
259 cx="148.0723"
260 id="SVGID_8_">
261 <stop
262 id="stop275"
263 style="stop-color:#FAF0BB"
264 offset="0.0112" />
265 <stop
266 id="stop277"
267 style="stop-color:#FAF0BD"
268 offset="0.4917" />
269 <stop
270 id="stop279"
271 style="stop-color:#FBF2C5"
272 offset="0.6648" />
273 <stop
274 id="stop281"
275 style="stop-color:#FCF6D0"
276 offset="0.7882" />
277 <stop
278 id="stop283"
279 style="stop-color:#FCF8E1"
280 offset="0.8879" />
281 <stop
282 id="stop285"
283 style="stop-color:#FFFDF7"
284 offset="0.9723" />
285 <stop
286 id="stop287"
287 style="stop-color:#FFFFFF"
288 offset="1" />
289 </radialGradient>
290 <radialGradient
291 inkscape:collect="always"
292 xlink:href="#SVGID_9_"
293 id="radialGradient3318"
294 gradientUnits="userSpaceOnUse"
295 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
296 cx="112.9551"
297 cy="315.56049"
298 r="3.0683999" />
299 <radialGradient
300 gradientUnits="userSpaceOnUse"
301 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
302 r="3.0683999"
303 cy="315.56049"
304 cx="112.9551"
305 id="SVGID_9_">
306 <stop
307 id="stop292"
308 style="stop-color:#FAF0BB"
309 offset="0.0112" />
310 <stop
311 id="stop294"
312 style="stop-color:#FAF0BD"
313 offset="0.4917" />
314 <stop
315 id="stop296"
316 style="stop-color:#FBF2C5"
317 offset="0.6648" />
318 <stop
319 id="stop298"
320 style="stop-color:#FCF6D0"
321 offset="0.7882" />
322 <stop
323 id="stop300"
324 style="stop-color:#FCF8E1"
325 offset="0.8879" />
326 <stop
327 id="stop302"
328 style="stop-color:#FFFDF7"
329 offset="0.9723" />
330 <stop
331 id="stop304"
332 style="stop-color:#FFFFFF"
333 offset="1" />
334 </radialGradient>
335 <radialGradient
336 inkscape:collect="always"
337 xlink:href="#SVGID_10_"
338 id="radialGradient3320"
339 gradientUnits="userSpaceOnUse"
340 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
341 cx="132.0938"
342 cy="320.1113"
343 r="4.1712999" />
344 <radialGradient
345 gradientUnits="userSpaceOnUse"
346 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
347 r="4.1712999"
348 cy="320.1113"
349 cx="132.0938"
350 id="SVGID_10_">
351 <stop
352 id="stop309"
353 style="stop-color:#FAF0BB"
354 offset="0.0112" />
355 <stop
356 id="stop311"
357 style="stop-color:#FAF0BD"
358 offset="0.4917" />
359 <stop
360 id="stop313"
361 style="stop-color:#FBF2C5"
362 offset="0.6648" />
363 <stop
364 id="stop315"
365 style="stop-color:#FCF6D0"
366 offset="0.7882" />
367 <stop
368 id="stop317"
369 style="stop-color:#FCF8E1"
370 offset="0.8879" />
371 <stop
372 id="stop319"
373 style="stop-color:#FFFDF7"
374 offset="0.9723" />
375 <stop
376 id="stop321"
377 style="stop-color:#FFFFFF"
378 offset="1" />
379 </radialGradient>
380 <radialGradient
381 inkscape:collect="always"
382 xlink:href="#SVGID_11_"
383 id="radialGradient3322"
384 gradientUnits="userSpaceOnUse"
385 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
386 cx="147.44189"
387 cy="301.21091"
388 r="2.5313001" />
389 <radialGradient
390 gradientUnits="userSpaceOnUse"
391 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
392 r="2.5313001"
393 cy="301.21091"
394 cx="147.44189"
395 id="SVGID_11_">
396 <stop
397 id="stop326"
398 style="stop-color:#FAF0BB"
399 offset="0.0112" />
400 <stop
401 id="stop328"
402 style="stop-color:#FAF0BD"
403 offset="0.4917" />
404 <stop
405 id="stop330"
406 style="stop-color:#FBF2C5"
407 offset="0.6648" />
408 <stop
409 id="stop332"
410 style="stop-color:#FCF6D0"
411 offset="0.7882" />
412 <stop
413 id="stop334"
414 style="stop-color:#FCF8E1"
415 offset="0.8879" />
416 <stop
417 id="stop336"
418 style="stop-color:#FFFDF7"
419 offset="0.9723" />
420 <stop
421 id="stop338"
422 style="stop-color:#FFFFFF"
423 offset="1" />
424 </radialGradient>
425 </defs>
426 <sodipodi:namedview
427 id="base"
428 pagecolor="#ffffff"
429 bordercolor="#666666"
430 borderopacity="1.0"
431 inkscape:pageopacity="0.0"
432 inkscape:pageshadow="2"
433 inkscape:zoom="22.395604"
434 inkscape:cx="23.985929"
435 inkscape:cy="34.824759"
436 inkscape:current-layer="layer1"
437 showgrid="true"
438 inkscape:grid-bbox="true"
439 inkscape:document-units="px"
440 inkscape:window-width="1600"
441 inkscape:window-height="876"
442 inkscape:window-x="0"
443 inkscape:window-y="24"
444 inkscape:window-maximized="1">
445 <inkscape:grid
446 type="xygrid"
447 id="grid3184" />
448 </sodipodi:namedview>
449 <metadata
450 id="metadata26761">
451 <rdf:RDF>
452 <cc:Work
453 rdf:about="">
454 <dc:format>image/svg+xml</dc:format>
455 <dc:type
456 rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
457 <dc:title />
458 </cc:Work>
459 </rdf:RDF>
460 </metadata>
461 <g
462 id="layer1"
463 inkscape:label="Layer 1"
464 inkscape:groupmode="layer"
465 transform="translate(0,16)">
466 <g
467 id="g3183"
468 transform="matrix(0.97648829,0,0,0.80895713,0.24705205,-24.411802)">
469 <path
470 d="m 47.748262,36.240641 c -0.304876,-0.669777 -0.939962,-2.526029 -1.264261,-3.180039 -0.499962,-1.005938 -2.409862,-0.340737 -2.850285,-1.402107 -0.615238,-1.481949 0.402841,-3.075783 -0.26687,-4.517046 -0.51052,-1.098494 -2.320767,-1.749962 -2.830861,-2.848458 -0.374128,-0.804542 0.05785,-5.080024 -0.915894,-3.703855 -1.643875,2.32362 -3.133623,4.929999 -4.51865,7.769812 -0.227178,-0.299544 -0.460268,-0.590441 -0.699692,-0.872694 l 1.273972,-2.395837 -1.94875,1.641638 C 33.517528,26.509306 33.303862,26.293167 33.085974,26.08364 l 0.936581,-2.162914 -1.564066,1.585187 C 31.923058,25.034986 31.365246,24.598131 30.785899,24.1984 l 1.168829,-5.78896 -2.873088,4.753021 C 28.796189,23.01091 28.507361,22.866987 28.213887,22.732727 l 0.283762,-3.540102 -1.360114,3.093074 C 25.924369,21.832064 24.65631,21.526925 23.350669,21.385545 l -0.349636,-4.806419 -1.226255,4.716403 c -0.0033,0 -0.0071,0 -0.01056,0 -1.422186,-0.0066 -2.818193,0.185117 -4.164371,0.553823 l -1.190787,-2.856081 0.196351,3.163762 c -0.403261,0.139347 -0.801035,0.294459 -1.193319,0.465334 l -0.676466,-1.193086 0.243647,1.388883 c -0.482226,0.226309 -0.954317,0.47703 -1.416273,0.750127 l -2.649288,-2.676561 1.488058,3.425166 c -0.733893,0.515174 -1.434852,1.088322 -2.09654,1.715887 -0.09374,0.089 -0.187063,0.180031 -0.279538,0.271064 l -2.6176137,-1.775898 1.7557735,2.685206 c -0.2643372,0.297002 -0.5214955,0.60519 -0.7718972,0.922533 l -2.0728961,-1.396004 1.4580788,2.215805 c -0.340767,0.479065 -0.6650662,0.978474 -0.9716305,1.49568 -1.2705932,0.251233 -2.4081735,1.157486 -3.0905527,2.497041 0.00253,-0.005 0.00508,-0.01071 0.00802,-0.01578 -0.5079841,0.01071 -0.9074462,0.311242 -1.1177337,1.046115 -0.7347402,2.568744 -0.5366981,4.375156 0.1689057,5.408554 -0.1199231,0.09664 -0.2373126,0.202409 -0.3517463,0.317854 -1.90145688,1.925922 -2.20548742,5.78845 -0.6790012,8.625208 0.8470624,1.574001 2.0796522,2.501617 3.3341996,2.686733 0.6452198,1.719448 1.4880601,3.337183 2.5116286,4.809977 3.3333522,4.799809 8.4203702,7.849148 14.2412852,7.722516 5.766442,-0.126125 10.741561,-3.352949 13.962593,-8.195477 2.268826,-3.410417 3.604027,-7.536378 3.803758,-11.87187 L 41.77997,42.904823 39.623044,42.4461 c 0.003,-0.734364 -0.02618,-1.473813 -0.08952,-2.215806 l 3.332089,-2.112565 -3.537731,0.400746 C 39.264542,38.110618 39.19107,37.708348 39.108306,37.31116 l 0.959807,-0.628583 -1.067483,0.13782 c -0.02618,-0.113909 -0.05278,-0.226818 -0.08023,-0.33972 2.756541,-0.434818 5.473393,-0.393116 8.225288,0.328024 0.699694,0.183591 0.893512,0.07272 0.602574,-0.568064 z M 3.2551113,34.170284 c -0.017313,0.06662 -0.033782,0.134262 -0.04856,0.202916 -0.0114,0.05139 -0.022381,0.102733 -0.032514,0.154602 0.010132,-0.05188 0.020692,-0.10325 0.032514,-0.154602 0.01478,-0.06866 0.031247,-0.136294 0.04856,-0.202916 z m 0.4049515,-1.11121 c -0.010132,0.02085 -0.020269,0.04223 -0.030404,0.06306 0.010132,-0.02085 0.02027,-0.04222 0.030404,-0.06306 z m -0.079808,0.172404 c -0.010557,0.02339 -0.020692,0.0473 -0.030825,0.07119 0.010132,-0.02389 0.02027,-0.04782 0.030825,-0.07119 z m -0.075164,0.177488 c -0.010557,0.02644 -0.021113,0.0529 -0.031248,0.07984 0.010132,-0.02694 0.020692,-0.0534 0.031248,-0.07984 z m -0.070097,0.182573 c -0.010979,0.03002 -0.021535,0.06 -0.032092,0.09001 0.010557,-0.03002 0.021113,-0.06002 0.032092,-0.09001 z m -0.06545,0.187661 c -0.01098,0.03407 -0.021535,0.06866 -0.032515,0.103238 0.010979,-0.03458 0.021113,-0.06866 0.032515,-0.103238 z m -0.059962,0.193252 c -0.011823,0.04119 -0.023225,0.08289 -0.034626,0.124599 0.0114,-0.04172 0.022381,-0.08342 0.034626,-0.124599 z m -0.2558905,1.703683 c -8.452e-4,0.05034 -8.452e-4,0.100695 -4.223e-4,0.150535 -4.223e-4,-0.05034 -4.223e-4,-0.100705 4.223e-4,-0.150535 z m 0.1106333,-1.097477 c -0.00633,0.03458 -0.012668,0.06866 -0.018578,0.103239 0.00591,-0.03407 0.012245,-0.06866 0.018578,-0.103239 z m -0.028713,0.164775 c -0.00507,0.03153 -0.010132,0.06256 -0.01478,0.09357 0.00464,-0.03101 0.00971,-0.06204 0.01478,-0.09357 z m -0.023646,0.15867 c -0.00423,0.03053 -0.00802,0.06053 -0.011823,0.09052 0.00379,-0.03052 0.0076,-0.06054 0.011823,-0.09052 z m -0.019423,0.156131 c -0.00338,0.03002 -0.00633,0.05949 -0.00929,0.0895 0.00296,-0.03002 0.00591,-0.05951 0.00929,-0.0895 z m -0.015624,0.155617 c -0.00253,0.03002 -0.00464,0.06001 -0.00717,0.09001 0.00253,-0.03002 0.00508,-0.06001 0.00717,-0.09001 z m -0.0114,0.154604 c -0.0017,0.03154 -0.00338,0.06256 -0.00507,0.09408 0.0017,-0.03153 0.00338,-0.06256 0.00507,-0.09408 z m -0.0076,0.154095 c -0.00127,0.03662 -0.00211,0.07322 -0.00296,0.109332 4.221e-4,-0.03662 0.00127,-0.07272 0.00296,-0.109332 z m 0.1634162,1.705207 c -0.0076,-0.03203 -0.01478,-0.06407 -0.021535,-0.09611 0.00718,0.03205 0.013934,0.06407 0.021535,0.09611 z m -0.037161,-0.168331 c -0.00802,-0.03865 -0.015624,-0.07728 -0.023225,-0.115944 0.0076,0.03865 0.015624,0.07729 0.023225,0.115944 z m -0.033785,-0.176983 c -0.00507,-0.02847 -0.010132,-0.05696 -0.01478,-0.08543 0.00464,0.02795 0.010132,0.05696 0.01478,0.08543 z m -0.024491,-0.152059 c -0.00423,-0.02694 -0.00844,-0.05392 -0.012245,-0.08138 0.00379,0.02694 0.0076,0.05442 0.012245,0.08138 z m -0.021113,-0.150025 c -0.00338,-0.02694 -0.00675,-0.0534 -0.00971,-0.08086 0.00296,0.02747 0.00633,0.05442 0.00971,0.08086 z m -0.017313,-0.149518 c -0.00296,-0.02694 -0.00549,-0.05392 -0.00802,-0.08137 0.00253,0.02747 0.00508,0.05441 0.00802,0.08137 z m -0.013934,-0.150024 c -0.00211,-0.02795 -0.00423,-0.05546 -0.00591,-0.08341 0.0017,0.02747 0.00379,0.05544 0.00591,0.08341 z m -0.010132,-0.150536 c -0.0017,-0.0295 -0.00296,-0.059 -0.00423,-0.0885 0.00127,0.0295 0.00253,0.05898 0.00423,0.0885 z m -0.00675,-0.15206 c -0.00127,-0.03356 -0.0017,-0.06765 -0.00211,-0.101717 0,0.03407 8.451e-4,0.06814 0.00211,0.101717 z m 0.180307,1.313616 c 0.00633,0.02644 0.012668,0.0529 0.019424,0.07882 -0.00633,-0.02644 -0.012668,-0.05239 -0.019424,-0.07882 z m 0.1811488,1.679273 c -0.00211,9.74e-4 -0.00423,0.0021 -0.00633,0.003 0,0 0,0 4.224e-4,0 0.015624,-0.01072 0.031247,-0.02137 0.046871,-0.03205 -0.013511,0.0097 -0.027025,0.01933 -0.04096,0.02896 z M 3.2745435,37.437285 c 0.00675,0.02492 0.013511,0.04984 0.020692,0.07476 -0.00717,-0.02492 -0.013934,-0.04984 -0.020692,-0.07476 z m 0.040537,0.141888 c 0.00717,0.0244 0.014357,0.04883 0.021957,0.07272 -0.00717,-0.0244 -0.014779,-0.04832 -0.021957,-0.07272 z m 0.043072,0.139347 c 0.00802,0.02389 0.015624,0.04782 0.023646,0.0717 -0.0076,-0.02389 -0.015624,-0.04728 -0.023646,-0.0717 z m 0.046449,0.137819 c 0.00844,0.02389 0.016891,0.04782 0.025758,0.07171 -0.00844,-0.02389 -0.017313,-0.0473 -0.025758,-0.07171 z m 0.049405,0.135789 c 0.00929,0.0244 0.019001,0.04883 0.028292,0.07322 -0.00929,-0.02441 -0.019001,-0.04831 -0.028292,-0.07322 z m 0.052361,0.134256 c 0.010979,0.02747 0.022803,0.05442 0.034203,0.08188 -0.0114,-0.02747 -0.023225,-0.05442 -0.034203,-0.08188 z m 0.055317,0.13223 c 0.018158,0.04223 0.037159,0.08491 0.056584,0.12663 -0.019001,-0.04223 -0.038005,-0.0844 -0.056584,-0.12663 z m 0.081498,0.178505 c 0.012245,0.02543 0.024491,0.05086 0.036737,0.07627 -0.012668,-0.02543 -0.024491,-0.05086 -0.036737,-0.07627 z m 0.065028,0.132734 c 0.011824,0.02339 0.023646,0.04678 0.035893,0.07019 -0.012246,-0.02339 -0.024069,-0.04678 -0.035893,-0.07019 z m 0.066295,0.12714 c 0.00802,0.01423 0.015624,0.029 0.023646,0.04272 -0.012668,0.0066 -0.025336,0.01272 -0.037582,0.01933 0.012246,-0.0066 0.02449,-0.01373 0.036737,-0.01983 -0.00802,-0.01373 -0.015202,-0.02797 -0.022803,-0.04223 z"
471 id="path5"
472 inkscape:connector-curvature="0" />
473 <path
474 d="m 46.872485,35.321668 c -0.295587,-0.574676 -0.59117,-1.149351 -0.887179,-1.724024 -0.411284,-0.79946 -2.442377,-0.780135 -2.853662,-1.579594 -0.640154,-1.243435 0.339923,-3.306671 -0.300232,-4.550104 -0.487293,-0.94745 -2.164949,-1.469746 -2.652242,-2.417196 -0.272784,-0.53043 -0.355546,-1.274964 -0.330633,-1.912193 0.05237,-1.364979 0.09627,-2.14664 -0.825104,-0.815224 -1.463147,2.115108 -2.790324,4.459071 -4.019957,7.001881 0.08403,0.130191 0.166794,0.262928 0.248715,0.39617 1.867674,-0.780645 3.579534,-1.925924 5.084062,-3.359053 -1.390517,1.582138 -3.033126,2.860154 -4.860686,3.733354 0.119078,0.203934 0.236469,0.410917 0.350057,0.620953 -0.87662,-1.47788 -1.904834,-2.797597 -3.043681,-3.931183 l -0.220844,0.510597 1.016812,-2.721313 -1.72115,1.539922 0.100502,-0.101717 c -0.426911,-0.375317 -0.869023,-0.727243 -1.324646,-1.05679 l -0.259691,1.287172 0.928137,-6.116986 -3.276349,4.782515 0.695047,-1.149347 C 27.064907,22.874104 25.27366,22.28112 23.39754,22.038534 l 0.05785,0.790309 -0.581035,-4.788622 -1.425989,4.509928 0.165107,-0.635193 c -0.02449,0 -0.04899,-9.74e-4 -0.07348,-9.74e-4 -2.69658,-0.0122 -5.297306,0.706904 -7.628628,2.005263 l 0.994011,1.003896 -3.222299,-2.891682 1.639229,4.403639 -0.736427,-1.695038 c -0.777812,0.531955 -1.518886,1.130533 -2.214777,1.791154 -0.5865257,0.556877 -1.1460249,1.161557 -1.6734311,1.809973 l 0.3800423,0.25581 -2.2287093,-1.303955 1.2275217,2.117143 -0.091631,-0.139345 c -0.260959,0.36159 -0.5122061,0.73538 -0.7533194,1.120363 0,0 4.226e-4,0 4.226e-4,0 0.058698,-0.0046 0.1178119,-0.0076 0.1769282,-0.0097 0.4197311,-0.01322 0.848329,0.04476 1.274816,0.182576 0.9543158,0.307679 1.753238,0.965757 2.327517,1.82777 1.042571,-3.636727 4.259803,-5.735561 7.393005,-4.724541 3.275504,1.057303 5.220032,5.114101 4.342567,9.059015 -0.238157,1.070014 -0.659578,2.022044 -1.212743,2.819977 0.07093,0.03205 0.14188,0.06509 0.212399,0.100705 0.08361,0.04223 0.165949,0.08645 0.247024,0.132733 -2.976541,-1.313107 -6.314119,0.418546 -7.548398,3.975938 -1.2347,3.558409 0.08783,7.634533 2.955006,9.262947 -0.08446,-0.03713 -0.168483,-0.07627 -0.252515,-0.118496 -3.038191,-1.529246 -4.4722,-5.736577 -3.202452,-9.39619 0.218733,-0.629601 0.502918,-1.20224 0.839884,-1.711309 -1.472858,-0.618921 -2.639575,-1.861338 -3.348979,-3.411436 -0.588214,1.277509 -1.5788438,2.193938 -2.71769,2.574851 0.033789,0.06461 0.067143,0.129174 0.099654,0.195797 1.344911,2.750302 0.9285586,6.379401 -0.9298248,8.103932 -0.051515,0.04782 -0.1038771,0.09407 -0.1566596,0.137821 h 0 c 0.026184,-0.02694 0.05236,-0.05442 0.078121,-0.08188 8.773e-4,-0.0014 0.00167,-0.0026 0.00296,-0.0036 0.024916,-0.02694 0.049402,-0.05442 0.073895,-0.08239 0.00128,-0.0021 0.00296,-0.0036 0.00462,-0.005 0.024071,-0.02795 0.047713,-0.05545 0.070937,-0.08341 0.00167,-0.0026 0.00384,-0.0046 0.0055,-0.0071 0.023227,-0.02796 0.045607,-0.05543 0.067989,-0.08391 0.00216,-0.003 0.00423,-0.0061 0.00675,-0.0086 0.021955,-0.02847 0.043919,-0.05646 0.065029,-0.08542 0.00251,-0.003 0.00512,-0.0066 0.0072,-0.0097 0.021109,-0.02847 0.042228,-0.05696 0.062493,-0.08645 0.00251,-0.0036 0.00512,-0.0072 0.00755,-0.01071 0.020265,-0.0295 0.040538,-0.05799 0.060379,-0.08797 0.00251,-0.004 0.00512,-0.0076 0.008,-0.01121 0.01942,-0.0295 0.038848,-0.05898 0.058277,-0.08899 0.00251,-0.0046 0.00549,-0.0086 0.008,-0.0122 0.018997,-0.03002 0.037589,-0.06 0.055741,-0.09052 0.00251,-0.0046 0.00549,-0.0086 0.008,-0.01272 0.018152,-0.03052 0.036322,-0.06103 0.054051,-0.09204 0.00251,-0.0046 0.00512,-0.009 0.008,-0.01322 0.017729,-0.03153 0.035054,-0.06204 0.052361,-0.09357 0.00251,-0.005 0.00513,-0.0097 0.00755,-0.01373 0.017306,-0.03153 0.033789,-0.06306 0.050253,-0.09508 0.00251,-0.005 0.00513,-0.0097 0.00755,-0.01423 0.016464,-0.03153 0.032521,-0.06407 0.048559,-0.09613 0.00213,-0.005 0.00455,-0.0097 0.00716,-0.01425 0.015622,-0.03253 0.031254,-0.06509 0.046458,-0.09816 0.00213,-0.0046 0.00426,-0.0097 0.00677,-0.01373 0.015206,-0.03304 0.030402,-0.06713 0.045191,-0.100694 0.00213,-0.004 0.00387,-0.009 0.0059,-0.01272 0.01478,-0.03409 0.029559,-0.06865 0.043913,-0.102733 0.00175,-0.0046 0.00329,-0.0086 0.00513,-0.0122 0.014354,-0.03508 0.028291,-0.07019 0.042229,-0.105275 0.00126,-0.004 0.003,-0.0082 0.00426,-0.0112 0.013937,-0.0356 0.027449,-0.07222 0.040961,-0.108333 8.768e-4,-0.003 0.00213,-0.0061 0.00329,-0.0097 0.013511,-0.03662 0.026607,-0.07425 0.039693,-0.111368 8.769e-4,-0.0026 0.00175,-0.005 0.00251,-0.0076 0.013085,-0.03815 0.026181,-0.07627 0.038425,-0.115439 0,-9.73e-4 4.229e-4,-0.0021 8.769e-4,-0.0026 0.1570825,-0.485678 0.2630703,-1.002882 0.3166975,-1.535857 4.228e-4,-0.004 8.777e-4,-0.0082 0.00124,-0.01118 0.00383,-0.03762 0.00713,-0.07528 0.010132,-0.113404 4.219e-4,-0.0082 0.00124,-0.01576 0.00217,-0.02389 0.003,-0.03458 0.00548,-0.06968 0.00755,-0.104238 8.767e-4,-0.01071 0.00176,-0.02238 0.00248,-0.03305 0.00217,-0.03253 0.00383,-0.06561 0.00548,-0.09816 4.218e-4,-0.01322 0.00124,-0.02644 0.00217,-0.03917 0.00176,-0.03153 0.00248,-0.06306 0.00383,-0.09459 4.229e-4,-0.01474 8.778e-4,-0.03002 0.00176,-0.04425 8.777e-4,-0.03052 0.00124,-0.06053 0.00217,-0.09052 4.228e-4,-0.01627 8.777e-4,-0.03253 8.777e-4,-0.04883 4.229e-4,-0.0295 4.229e-4,-0.05799 4.229e-4,-0.08747 0,-0.01728 0,-0.03459 0,-0.05239 0,-0.02847 -4.229e-4,-0.05644 -8.778e-4,-0.08492 0,-0.01831 -4.228e-4,-0.03611 -4.228e-4,-0.05441 -4.208e-4,-0.02796 -0.00124,-0.05544 -0.00217,-0.08339 -4.229e-4,-0.0188 -8.767e-4,-0.03763 -0.00176,-0.05645 -8.767e-4,-0.02694 -0.00217,-0.0534 -0.00331,-0.08086 -8.768e-4,-0.01984 -0.00176,-0.03918 -0.003,-0.05899 -0.00124,-0.02694 -0.003,-0.0529 -0.00455,-0.07935 -0.00124,-0.02032 -0.00248,-0.04068 -0.00383,-0.06053 -0.00176,-0.02644 -0.00383,-0.05238 -0.00589,-0.07832 -0.00176,-0.02085 -0.00331,-0.04119 -0.00517,-0.06204 -0.00217,-0.02594 -0.00455,-0.05138 -0.00713,-0.0768 -0.00176,-0.02136 -0.00424,-0.04222 -0.00631,-0.06307 -0.00248,-0.02543 -0.00548,-0.05086 -0.00842,-0.07577 -0.00251,-0.02185 -0.00513,-0.04323 -0.00755,-0.06461 -0.003,-0.02492 -0.0059,-0.04985 -0.00929,-0.07425 -0.003,-0.02185 -0.0059,-0.04375 -0.0089,-0.06561 -0.00329,-0.02492 -0.00677,-0.04934 -0.01056,-0.07425 -0.00329,-0.02185 -0.00677,-0.04425 -0.010132,-0.06612 -0.00387,-0.02439 -0.00755,-0.04883 -0.011401,-0.07322 -0.00387,-0.02237 -0.00755,-0.04476 -0.011401,-0.06661 -0.00426,-0.02441 -0.00842,-0.04831 -0.01267,-0.07221 -0.00426,-0.02288 -0.00842,-0.04526 -0.01267,-0.06765 -0.00455,-0.02389 -0.0089,-0.04782 -0.013937,-0.07119 -0.00455,-0.02288 -0.00929,-0.04526 -0.013938,-0.06815 -0.00513,-0.0234 -0.00971,-0.04729 -0.015206,-0.07069 -0.00513,-0.02288 -0.010132,-0.04576 -0.015206,-0.06866 -0.00513,-0.02288 -0.010549,-0.04629 -0.016047,-0.06915 -0.00552,-0.02339 -0.010976,-0.04629 -0.01688,-0.06915 -0.00552,-0.02288 -0.010975,-0.04576 -0.01688,-0.06814 -0.0059,-0.02339 -0.011827,-0.04678 -0.018148,-0.06968 -0.0059,-0.02288 -0.011818,-0.04527 -0.018148,-0.06765 -0.0063,-0.0234 -0.01267,-0.04628 -0.019416,-0.06968 -0.0063,-0.02238 -0.01267,-0.04425 -0.018999,-0.06661 -0.00677,-0.0234 -0.013937,-0.04678 -0.021109,-0.07019 -0.00677,-0.02185 -0.013086,-0.04374 -0.019842,-0.0656 -0.00755,-0.02389 -0.015206,-0.0473 -0.022804,-0.0707 -0.00677,-0.02136 -0.013937,-0.0427 -0.020683,-0.0646 -0.00803,-0.02339 -0.016038,-0.04679 -0.024071,-0.07069 -0.00755,-0.02085 -0.014354,-0.04222 -0.021952,-0.06306 -0.00842,-0.0244 -0.017306,-0.04831 -0.026181,-0.07221 -0.00755,-0.02031 -0.01478,-0.04069 -0.022378,-0.06103 -0.0089,-0.02441 -0.018574,-0.04883 -0.027875,-0.07272 -0.00755,-0.02032 -0.015206,-0.04018 -0.022804,-0.05949 -0.00971,-0.02492 -0.019842,-0.04933 -0.029985,-0.07425 -0.00803,-0.01865 -0.015622,-0.03799 -0.023645,-0.05732 -0.010975,-0.02594 -0.021952,-0.05188 -0.033363,-0.0768 -0.00755,-0.0178 -0.015206,-0.0351 -0.022804,-0.0529 -0.01267,-0.0295 -0.026182,-0.05799 -0.039267,-0.08696 -0.00677,-0.0137 -0.01267,-0.02845 -0.019416,-0.04219 C 8.552808,41.518875 8.532531,41.476167 8.511847,41.433436 7.1669757,38.683133 4.5692051,37.851124 2.7108196,39.57515 0.85243366,41.299176 0.436081,44.928276 1.7809934,47.678578 c 0.023225,0.04782 0.046871,0.0951 0.07094,0.140872 0.0076,0.01474 0.015624,0.0295 0.023225,0.04425 0.01689,0.03153 0.033358,0.06307 0.05025,0.09459 0.00887,0.01626 0.018158,0.03307 0.027448,0.04985 0.016468,0.0295 0.032514,0.05799 0.048982,0.08645 0.00929,0.01627 0.018578,0.03253 0.028291,0.04883 0.017735,0.03002 0.035048,0.0595 0.053205,0.0885 0.00844,0.01373 0.01689,0.02795 0.025336,0.04172 0.024491,0.03917 0.048983,0.07729 0.073473,0.115944 0.00211,0.0036 0.00423,0.0072 0.00633,0.01012 0.027025,0.0417 0.054894,0.0824 0.082765,0.123071 0.00802,0.01121 0.015624,0.02237 0.023646,0.03305 0.020269,0.02896 0.040538,0.05746 0.061228,0.08595 0.00971,0.01322 0.019424,0.02694 0.029136,0.03966 0.019423,0.02644 0.038848,0.05239 0.058271,0.07729 0.00971,0.01271 0.019847,0.02594 0.029981,0.03865 0.020692,0.02694 0.041381,0.0529 0.062496,0.0783 0.00887,0.01071 0.017735,0.02185 0.026181,0.03255 0.027025,0.03305 0.054473,0.06561 0.082342,0.09764 0.00253,0.003 0.00464,0.0061 0.00718,0.0086 0.031248,0.03611 0.062496,0.07119 0.094165,0.105779 0.00591,0.0066 0.011823,0.0122 0.017735,0.0188 0.025337,0.02747 0.050671,0.05392 0.076429,0.08086 0.00887,0.0097 0.018158,0.0183 0.027448,0.02796 0.023226,0.02339 0.046027,0.0468 0.069674,0.06969 0.00929,0.0097 0.019001,0.0183 0.028292,0.02796 0.024491,0.02339 0.048982,0.04678 0.073473,0.06915 0.00802,0.0076 0.016046,0.01474 0.024069,0.02238 0.031247,0.02847 0.062496,0.05645 0.094587,0.08391 0.00127,9.74e-4 0.00253,0.0021 0.00338,0.003 0.035048,0.03002 0.070097,0.05898 0.1051438,0.08747 0.0017,0.0014 0.00338,0.003 0.00508,0.0046 0.032091,0.02594 0.064184,0.05086 0.096698,0.07527 0.00718,0.0056 0.014357,0.01073 0.021535,0.01578 0.027448,0.02085 0.055317,0.04069 0.083186,0.0605 0.00802,0.0061 0.016046,0.01121 0.024069,0.01678 0.028293,0.02032 0.057006,0.03967 0.08572,0.059 0.00633,0.004 0.012668,0.0086 0.019424,0.0122 0.1072551,0.07119 0.2166217,0.135784 0.3268326,0.193761 0.00423,0.0021 0.00887,0.0046 0.01309,0.0066 0.032515,0.01678 0.064607,0.03307 0.097121,0.04883 0.0059,0.003 0.012246,0.0061 0.018158,0.009 0.032092,0.01524 0.064607,0.03052 0.096698,0.04425 0.00464,0.0021 0.00929,0.0046 0.014356,0.0066 0.1135892,0.04933 0.2284449,0.09256 0.3433009,0.128156 0.0017,5.1e-4 0.00338,9.74e-4 0.00549,0.0014 0.035892,0.0112 0.071785,0.02187 0.1076773,0.03154 0.00464,9.73e-4 0.00929,0.0026 0.013934,0.0036 0.034626,0.0097 0.068829,0.0178 0.1034547,0.02594 0.00379,9.74e-4 0.00802,0.0021 0.011824,0.003 0.1169673,0.02694 0.2343567,0.04679 0.3517462,0.05951 l 0,0 c 0.6481757,1.849131 1.52733,3.584344 2.6163505,5.151733 3.2493206,4.67828 8.2075476,7.650825 13.8810926,7.526736 5.62076,-0.12256 10.470044,-3.267511 13.60958,-7.987475 2.711782,-4.077649 4.055427,-9.202937 3.667366,-14.468077 l -0.625796,0.397186 3.441877,-2.497548 -4.004333,0.160197 0.94925,-0.107311 c -0.220421,-1.378712 -0.556544,-2.696396 -0.990631,-3.942371 0.168484,0.428718 0.325565,0.867097 0.469134,1.315141 2.798347,-0.571116 5.565447,-0.68554 8.28863,-0.151043 0.771477,0.153076 0.933204,0.41702 0.464491,-0.493815 z m -12.799679,3.703349 c -0.150327,4.243438 -1.599116,6.202419 -3.283952,6.35143 -0.291784,0.02594 -0.581036,-0.003 -0.882953,-0.08339 0.127101,0.01169 0.25378,0.01373 0.380461,0.005 0.947982,-0.0656 1.826292,-0.718089 2.438574,-2.048996 -1.654432,-1.002882 -3.38487,-1.607564 -5.059992,-1.826755 1.684833,0.07272 3.4651,0.599086 5.159647,1.598919 0.215777,-0.520259 0.393129,-1.134093 0.522342,-1.846589 -1.866407,-0.63926 -3.746752,-0.830988 -5.497882,-0.626039 1.72875,-0.355486 3.641185,-0.255806 5.541374,0.37074 0.08615,-0.535514 0.146526,-1.122905 0.176508,-1.764709 0.0114,-0.238514 -0.003,-0.451602 -0.03927,-0.641804 -2.009135,-0.114427 -3.941838,0.243602 -5.656652,0.971863 1.643451,-0.864048 3.568132,-1.320736 5.586133,-1.236826 -0.412129,-1.186475 -1.895967,-1.250044 -3.554621,-0.903205 2.210554,-0.579759 4.250091,-0.552808 4.170283,1.68029 z m 2.44111,-7.055789 c 1.92468,-0.563996 3.721414,-1.511446 5.334888,-2.770136 -1.510441,1.419396 -3.24806,2.506191 -5.138958,3.16783 -0.06418,-0.133245 -0.129212,-0.265977 -0.19593,-0.397694 z m 0.825526,1.842519 c -0.05574,-0.141379 -0.112746,-0.282252 -0.171017,-0.421598 1.999844,-0.298525 3.997577,-0.112402 5.887635,0.505511 -1.862188,-0.401765 -3.791937,-0.442449 -5.716618,-0.08392 z"
475 id="path14"
476 style="fill:#f0a513;fill-opacity:1"
477 inkscape:connector-curvature="0" />
478 <path
479 d="m 17.971864,28.383357 c 3.029325,0.977457 4.82775,4.729117 4.016157,8.37805 -0.214087,0.963215 -0.589481,1.823193 -1.080996,2.549419 -2.202109,-0.672827 -4.51105,0.238008 -5.964907,2.257001 -2.974852,-1.022212 -4.729782,-4.734713 -3.926214,-8.347029 0.811593,-3.648933 3.926636,-5.815407 6.95596,-4.837441 z"
480 id="path16"
481 inkscape:connector-curvature="0"
482 style="fill:#ffffff" />
483 <path
484 d="m 21.46948,31.675787 c 0.688291,1.496188 0.915048,3.303109 0.518541,5.08562 -0.214087,0.963215 -0.589481,1.823193 -1.080996,2.549419 -2.202532,-0.672827 -4.511474,0.238008 -5.965329,2.257001 -1.217389,-0.418038 -2.2304,-1.28768 -2.947405,-2.415671 0.307831,0.161723 0.630018,0.298527 0.964451,0.406343 3.605716,1.163589 7.313197,-1.414313 8.279337,-5.756922 0.157927,-0.710463 0.232246,-1.423974 0.231401,-2.12579 z"
485 id="path18"
486 inkscape:connector-curvature="0"
487 style="fill:#eeeeee" />
488 <path
489 d="m 11.148494,37.665629 c -0.473779,-1.361928 -0.61397,-2.903379 -0.33232,-4.44127 -0.52952,-1.020176 -1.3685584,-1.810482 -2.4090152,-2.146133 -2.1826849,-0.704357 -4.4270197,0.856418 -5.0118558,3.484667 -0.3242991,1.457031 -0.070517,2.936437 0.5915924,4.085786 1.0683288,-0.4694 2.2489802,-0.271571 3.2581915,0.503477 0.4619579,0.354468 0.8876005,0.829465 1.2503252,1.416854 1.1793816,-0.417022 2.1776139,-1.463641 2.6530819,-2.903381 z"
490 id="path20"
491 inkscape:connector-curvature="0"
492 style="fill:#ffffff" />
493 <path
494 d="m 31.2411,51.394259 1.26637,0.637229 -2.465178,-0.01373 c -4.530473,2.179698 -9.426207,2.60994 -12.629927,1.007461 -0.08825,-0.03864 -0.176507,-0.07984 -0.264338,-0.124092 -3.038191,-1.529243 -4.472201,-5.736578 -3.202453,-9.39619 0.218732,-0.6296 0.503339,-1.202239 0.840306,-1.710803 l 0,-5.07e-4 c -1.472857,-0.618925 -2.639574,-1.861849 -3.348978,-3.411437 -0.588215,1.277507 -1.5788467,2.193936 -2.7176907,2.574848 0.033779,0.06461 0.067143,0.129175 0.099655,0.195796 1.3449097,2.750303 0.9285573,6.379402 -0.9298254,8.103935 -0.051515,0.04782 -0.1038771,0.09408 -0.1566605,0.137821 l 0,0 c -0.048979,0.05034 -0.098387,0.09866 -0.1494812,0.145956 -0.7486746,0.694696 -1.6176949,0.974406 -2.4761587,0.880322 l 0,5.08e-4 c 0.6477536,1.848622 1.5273307,3.584344 2.6159279,5.151732 3.2493226,4.678262 8.2075486,7.650298 13.8810926,7.526717 5.620762,-0.12256 10.470046,-3.268018 13.609581,-7.987982 2.123568,-3.192243 3.407673,-7.028327 3.678768,-11.070884 -1.87021,3.185631 -4.634352,5.665888 -7.651009,7.353296 z"
495 id="path183"
496 style="fill:#fdd99b"
497 inkscape:connector-curvature="0" />
498 <path
499 d="m 11.261241,44.175223 c -0.158773,-0.250722 -0.250827,-0.566539 -0.243648,-0.906768 0.01224,-0.584846 0.312898,-1.079675 0.733895,-1.291745 -0.616928,0.507545 -0.839039,1.75098 -0.173129,2.336839 0.277429,0.243604 0.439579,0.574168 0.370749,1.028824 -0.05363,0.355991 -0.262648,0.802509 -0.591168,1.144265 -0.374972,0.389558 -0.833129,0.599593 -1.228791,0.541109 0.37835,-0.112404 0.757541,-0.387016 1.06284,-0.752165 0.26307,-0.314291 0.444644,-0.675369 0.519384,-0.97542 0.14906,-0.596542 -0.181995,-0.701818 -0.450132,-1.124939 l 0,0 z m 1.895122,4.408723 c -0.233935,0.931683 -0.952208,1.610106 -1.802226,1.610106 -0.765564,0 -1.4251397,-0.551279 -1.7190352,-1.342094 0.3783472,0.632143 0.9944302,1.044078 1.6907442,1.044078 0.790057,0 1.477502,-0.530939 1.830517,-1.31209 z"
500 id="path185"
501 inkscape:connector-curvature="0" />
502 <g
503 id="g187"
504 transform="matrix(0.42226435,0,0,0.50856192,-47.726977,-111.72952)">
505 <radialGradient
506 id="radialGradient3241"
507 cx="163.4902"
508 cy="274.86621"
509 r="2.8801"
510 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
511 gradientUnits="userSpaceOnUse">
512 <stop
513 offset="0.0112"
514 style="stop-color:#FAF0BB"
515 id="stop3243" />
516 <stop
517 offset="0.4917"
518 style="stop-color:#FAF0BD"
519 id="stop3245" />
520 <stop
521 offset="0.6648"
522 style="stop-color:#FBF2C5"
523 id="stop3247" />
524 <stop
525 offset="0.7882"
526 style="stop-color:#FCF6D0"
527 id="stop3249" />
528 <stop
529 offset="0.8879"
530 style="stop-color:#FCF8E1"
531 id="stop3251" />
532 <stop
533 offset="0.9723"
534 style="stop-color:#FFFDF7"
535 id="stop3253" />
536 <stop
537 offset="1"
538 style="stop-color:#FFFFFF"
539 id="stop3255" />
540 </radialGradient>
541 <path
542 d="m 189.806,311.298 c -0.681,-0.478 -1.432,-0.68 -2.1,-0.645 -0.633,0.034 -1.217,0.284 -1.625,0.739 -0.408,0.454 -0.59,1.052 -0.559,1.676 0.034,0.653 0.305,1.364 0.834,1.98 0.577,0.671 1.35,1.108 2.143,1.244 0.845,0.145 1.679,-0.06 2.247,-0.657 0.573,-0.604 0.725,-1.448 0.515,-2.282 -0.199,-0.789 -0.713,-1.534 -1.455,-2.055 z"
543 id="path204"
544 style="fill:url(#radialGradient3305)"
545 inkscape:connector-curvature="0" />
546 <radialGradient
547 id="radialGradient3258"
548 cx="155.3242"
549 cy="310.6777"
550 r="4.4867001"
551 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
552 gradientUnits="userSpaceOnUse">
553 <stop
554 offset="0.0112"
555 style="stop-color:#FAF0BB"
556 id="stop3260" />
557 <stop
558 offset="0.4917"
559 style="stop-color:#FAF0BD"
560 id="stop3262" />
561 <stop
562 offset="0.6648"
563 style="stop-color:#FBF2C5"
564 id="stop3264" />
565 <stop
566 offset="0.7882"
567 style="stop-color:#FCF6D0"
568 id="stop3266" />
569 <stop
570 offset="0.8879"
571 style="stop-color:#FCF8E1"
572 id="stop3268" />
573 <stop
574 offset="0.9723"
575 style="stop-color:#FFFDF7"
576 id="stop3270" />
577 <stop
578 offset="1"
579 style="stop-color:#FFFFFF"
580 id="stop3272" />
581 </radialGradient>
582 <path
583 d="m 183.164,274.256 c -0.777,-0.621 -1.774,-0.996 -2.853,-1 -1.077,-0.004 -2.096,0.366 -2.89,0.992 -0.839,0.661 -1.465,1.633 -1.646,2.791 -0.197,1.263 0.167,2.499 0.961,3.449 0.841,1.005 2.124,1.644 3.592,1.617 1.455,-0.026 2.71,-0.702 3.522,-1.716 0.762,-0.951 1.106,-2.168 0.913,-3.4 -0.179,-1.131 -0.786,-2.082 -1.599,-2.733 z"
584 id="path221"
585 style="fill:url(#radialGradient3307)"
586 inkscape:connector-curvature="0" />
587 <radialGradient
588 id="radialGradient3275"
589 cx="170.3125"
590 cy="302.00781"
591 r="5.0811"
592 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
593 gradientUnits="userSpaceOnUse">
594 <stop
595 offset="0.0112"
596 style="stop-color:#FAF0BB"
597 id="stop3277" />
598 <stop
599 offset="0.4917"
600 style="stop-color:#FAF0BD"
601 id="stop3279" />
602 <stop
603 offset="0.6648"
604 style="stop-color:#FBF2C5"
605 id="stop3281" />
606 <stop
607 offset="0.7882"
608 style="stop-color:#FCF6D0"
609 id="stop3283" />
610 <stop
611 offset="0.8879"
612 style="stop-color:#FCF8E1"
613 id="stop3285" />
614 <stop
615 offset="0.9723"
616 style="stop-color:#FFFDF7"
617 id="stop3287" />
618 <stop
619 offset="1"
620 style="stop-color:#FFFFFF"
621 id="stop3289" />
622 </radialGradient>
623 <path
624 d="m 197.254,290.925 c 1.482,-0.322 2.697,-1.225 3.201,-2.604 0.5,-1.367 0.166,-2.845 -0.726,-4.066 -0.835,-1.146 -2.134,-2.023 -3.647,-2.408 -1.389,-0.352 -2.723,-0.223 -3.781,0.238 -1.011,0.439 -1.812,1.196 -2.21,2.198 -0.397,1.001 -0.335,2.12 0.108,3.146 0.468,1.083 1.377,2.112 2.666,2.812 1.407,0.762 2.987,0.989 4.389,0.684 z"
625 id="path238"
626 style="fill:url(#radialGradient3310)"
627 inkscape:connector-curvature="0" />
628 <radialGradient
629 id="radialGradient3292"
630 cx="173.2812"
631 cy="283.68359"
632 r="2.8803999"
633 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
634 gradientUnits="userSpaceOnUse">
635 <stop
636 offset="0.0112"
637 style="stop-color:#FAF0BB"
638 id="stop3294" />
639 <stop
640 offset="0.4917"
641 style="stop-color:#FAF0BD"
642 id="stop3296" />
643 <stop
644 offset="0.6648"
645 style="stop-color:#FBF2C5"
646 id="stop3298" />
647 <stop
648 offset="0.7882"
649 style="stop-color:#FCF6D0"
650 id="stop3300" />
651 <stop
652 offset="0.8879"
653 style="stop-color:#FCF8E1"
654 id="stop3302" />
655 <stop
656 offset="0.9723"
657 style="stop-color:#FFFDF7"
658 id="stop3304" />
659 <stop
660 offset="1"
661 style="stop-color:#FFFFFF"
662 id="stop3306" />
663 </radialGradient>
664 <path
665 d="m 200.538,302.533 c -0.568,-0.598 -1.402,-0.802 -2.248,-0.657 -0.792,0.136 -1.565,0.573 -2.143,1.244 -0.529,0.616 -0.8,1.327 -0.833,1.98 -0.032,0.624 0.15,1.222 0.559,1.676 0.408,0.455 0.991,0.705 1.624,0.739 0.668,0.035 1.42,-0.167 2.101,-0.645 0.741,-0.521 1.256,-1.267 1.454,-2.056 0.21,-0.833 0.058,-1.677 -0.514,-2.281 z"
666 id="path255"
667 style="fill:url(#radialGradient3312)"
668 inkscape:connector-curvature="0" />
669 <radialGradient
670 id="radialGradient3309"
671 cx="148.9492"
672 cy="270.04489"
673 r="2.8799"
674 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
675 gradientUnits="userSpaceOnUse">
676 <stop
677 offset="0.0112"
678 style="stop-color:#FAF0BB"
679 id="stop3311" />
680 <stop
681 offset="0.4917"
682 style="stop-color:#FAF0BD"
683 id="stop3313" />
684 <stop
685 offset="0.6648"
686 style="stop-color:#FBF2C5"
687 id="stop3315" />
688 <stop
689 offset="0.7882"
690 style="stop-color:#FCF6D0"
691 id="stop3317" />
692 <stop
693 offset="0.8879"
694 style="stop-color:#FCF8E1"
695 id="stop3319" />
696 <stop
697 offset="0.9723"
698 style="stop-color:#FFFDF7"
699 id="stop3321" />
700 <stop
701 offset="1"
702 style="stop-color:#FFFFFF"
703 id="stop3323" />
704 </radialGradient>
705 <path
706 d="m 173.958,315.516 c -0.793,0.136 -1.566,0.573 -2.143,1.244 -0.529,0.616 -0.801,1.327 -0.834,1.98 -0.031,0.623 0.15,1.222 0.559,1.676 0.408,0.455 0.991,0.705 1.624,0.738 0.669,0.036 1.42,-0.166 2.101,-0.645 0.741,-0.521 1.256,-1.266 1.454,-2.055 0.211,-0.834 0.06,-1.679 -0.514,-2.282 -0.568,-0.598 -1.402,-0.801 -2.247,-0.656 z"
707 id="path272"
708 style="fill:url(#radialGradient3314)"
709 inkscape:connector-curvature="0" />
710 <radialGradient
711 id="radialGradient3326"
712 cx="148.0723"
713 cy="319.09381"
714 r="3.9265001"
715 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
716 gradientUnits="userSpaceOnUse">
717 <stop
718 offset="0.0112"
719 style="stop-color:#FAF0BB"
720 id="stop3328" />
721 <stop
722 offset="0.4917"
723 style="stop-color:#FAF0BD"
724 id="stop3330" />
725 <stop
726 offset="0.6648"
727 style="stop-color:#FBF2C5"
728 id="stop3332" />
729 <stop
730 offset="0.7882"
731 style="stop-color:#FCF6D0"
732 id="stop3334" />
733 <stop
734 offset="0.8879"
735 style="stop-color:#FCF8E1"
736 id="stop3336" />
737 <stop
738 offset="0.9723"
739 style="stop-color:#FFFDF7"
740 id="stop3338" />
741 <stop
742 offset="1"
743 style="stop-color:#FFFFFF"
744 id="stop3340" />
745 </radialGradient>
746 <path
747 d="m 171.282,272.336 c 1.106,0.549 2.333,0.68 3.407,0.405 1.136,-0.291 2.049,-1.022 2.398,-2.102 0.347,-1.069 0.048,-2.201 -0.675,-3.119 -0.678,-0.861 -1.706,-1.502 -2.885,-1.756 -1.083,-0.233 -2.109,-0.095 -2.914,0.291 -0.768,0.368 -1.365,0.975 -1.645,1.76 -0.278,0.785 -0.198,1.646 0.173,2.426 0.394,0.822 1.125,1.592 2.141,2.095 z"
748 id="path289"
749 style="fill:url(#radialGradient3316)"
750 inkscape:connector-curvature="0" />
751 <radialGradient
752 id="radialGradient3343"
753 cx="112.9551"
754 cy="315.56049"
755 r="3.0683999"
756 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
757 gradientUnits="userSpaceOnUse">
758 <stop
759 offset="0.0112"
760 style="stop-color:#FAF0BB"
761 id="stop3345" />
762 <stop
763 offset="0.4917"
764 style="stop-color:#FAF0BD"
765 id="stop3347" />
766 <stop
767 offset="0.6648"
768 style="stop-color:#FBF2C5"
769 id="stop3349" />
770 <stop
771 offset="0.7882"
772 style="stop-color:#FCF6D0"
773 id="stop3351" />
774 <stop
775 offset="0.8879"
776 style="stop-color:#FCF8E1"
777 id="stop3353" />
778 <stop
779 offset="0.9723"
780 style="stop-color:#FFFDF7"
781 id="stop3355" />
782 <stop
783 offset="1"
784 style="stop-color:#FFFFFF"
785 id="stop3357" />
786 </radialGradient>
787 <path
788 d="m 140.776,270.8 c -0.132,-0.306 -0.298,-0.603 -0.496,-0.884 0,0 -0.001,-10e-4 -0.001,-10e-4 -0.031,0.02 -0.061,0.042 -0.091,0.062 -0.1,0.067 -0.199,0.135 -0.298,0.203 -0.12,0.082 -0.24,0.163 -0.358,0.246 -0.123,0.085 -0.245,0.173 -0.366,0.26 -0.096,0.068 -0.193,0.136 -0.289,0.206 -0.146,0.106 -0.29,0.213 -0.434,0.321 -0.072,0.054 -0.145,0.106 -0.216,0.161 -0.215,0.163 -0.429,0.328 -0.641,0.495 -0.223,0.175 -0.443,0.354 -0.663,0.535 -0.064,0.053 -0.129,0.107 -0.194,0.161 -0.171,0.143 -0.341,0.287 -0.51,0.432 -0.054,0.046 -0.108,0.092 -0.162,0.139 -0.193,0.167 -0.384,0.337 -0.574,0.509 -0.098,0.088 -0.196,0.178 -0.293,0.268 -0.099,0.09 -0.196,0.182 -0.294,0.274 -0.079,0.074 -0.16,0.146 -0.238,0.222 0,0 0.001,0.001 0.001,0.001 0.177,0.156 0.363,0.299 0.555,0.429 0.596,0.402 1.257,0.671 1.927,0.786 1.185,0.202 2.356,-0.083 3.152,-0.922 0.804,-0.847 1.017,-2.032 0.722,-3.202 -0.06,-0.24 -0.14,-0.473 -0.239,-0.701 z"
789 id="path306"
790 style="fill:url(#radialGradient3318)"
791 inkscape:connector-curvature="0" />
792 <radialGradient
793 id="radialGradient3360"
794 cx="132.0938"
795 cy="320.1113"
796 r="4.1712999"
797 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
798 gradientUnits="userSpaceOnUse">
799 <stop
800 offset="0.0112"
801 style="stop-color:#FAF0BB"
802 id="stop3362" />
803 <stop
804 offset="0.4917"
805 style="stop-color:#FAF0BD"
806 id="stop3364" />
807 <stop
808 offset="0.6648"
809 style="stop-color:#FBF2C5"
810 id="stop3366" />
811 <stop
812 offset="0.7882"
813 style="stop-color:#FCF6D0"
814 id="stop3368" />
815 <stop
816 offset="0.8879"
817 style="stop-color:#FCF8E1"
818 id="stop3370" />
819 <stop
820 offset="0.9723"
821 style="stop-color:#FFFDF7"
822 id="stop3372" />
823 <stop
824 offset="1"
825 style="stop-color:#FFFFFF"
826 id="stop3374" />
827 </radialGradient>
828 <path
829 d="m 160.2,265.6 c -0.85,-0.392 -1.938,-0.592 -3.115,-0.521 -1.177,0.07 -2.29,0.405 -3.157,0.906 -0.916,0.53 -1.6,1.269 -1.798,2.11 -0.216,0.917 0.182,1.777 1.05,2.403 0.918,0.663 2.32,1.032 3.923,0.914 1.588,-0.118 2.959,-0.687 3.847,-1.468 0.833,-0.732 1.209,-1.627 0.998,-2.496 -0.195,-0.799 -0.859,-1.438 -1.748,-1.848 z"
830 id="path323"
831 style="fill:url(#radialGradient3320)"
832 inkscape:connector-curvature="0" />
833 <radialGradient
834 id="radialGradient3377"
835 cx="147.44189"
836 cy="301.21091"
837 r="2.5313001"
838 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
839 gradientUnits="userSpaceOnUse">
840 <stop
841 offset="0.0112"
842 style="stop-color:#FAF0BB"
843 id="stop3379" />
844 <stop
845 offset="0.4917"
846 style="stop-color:#FAF0BD"
847 id="stop3381" />
848 <stop
849 offset="0.6648"
850 style="stop-color:#FBF2C5"
851 id="stop3383" />
852 <stop
853 offset="0.7882"
854 style="stop-color:#FCF6D0"
855 id="stop3385" />
856 <stop
857 offset="0.8879"
858 style="stop-color:#FCF8E1"
859 id="stop3387" />
860 <stop
861 offset="0.9723"
862 style="stop-color:#FFFDF7"
863 id="stop3389" />
864 <stop
865 offset="1"
866 style="stop-color:#FFFFFF"
867 id="stop3391" />
868 </radialGradient>
869 <path
870 d="m 173.961,289.2 c 0.657,-0.143 1.12,-0.506 1.265,-1.029 0.133,-0.48 -0.03,-1.015 -0.381,-1.495 -0.335,-0.458 -0.853,-0.886 -1.498,-1.196 -0.645,-0.31 -1.333,-0.461 -1.94,-0.451 -0.643,0.011 -1.223,0.2 -1.576,0.587 -0.385,0.422 -0.428,0.996 -0.152,1.584 0.291,0.622 0.925,1.231 1.811,1.642 0.876,0.408 1.77,0.51 2.471,0.358 z"
871 id="path340"
872 style="fill:url(#radialGradient3322)"
873 inkscape:connector-curvature="0" />
874 </g>
875 <path
876 d="m 32.300561,46.79686 c -0.244913,-0.207495 -0.516006,-0.294969 -0.756275,-0.27971 -0.2276,0.01425 -0.437888,0.12307 -0.584836,0.320395 -0.147371,0.197321 -0.212822,0.456181 -0.201419,0.726735 0.01182,0.283777 0.109788,0.591457 0.300228,0.85845 0.207332,0.290901 0.486027,0.480592 0.771056,0.539586 0.304451,0.06256 0.605105,-0.02543 0.809057,-0.284794 0.206488,-0.26191 0.260961,-0.628075 0.185374,-0.989662 -0.07136,-0.342262 -0.256312,-0.665199 -0.523185,-0.891 z"
877 id="path347"
878 style="fill:#000000"
879 inkscape:connector-curvature="0" />
880 <g
881 id="g349"
882 transform="matrix(0.42226435,0,0,0.50856192,-47.726977,-111.72952)">
883 <path
884 d="m 168.559,264.427 c 4.145,0.407 8.127,1.382 11.858,2.845 l 0.623,-0.856 c -3.919,-1.741 -8.161,-2.906 -12.604,-3.384 l 0.123,1.395 z"
885 id="path351"
886 inkscape:connector-curvature="0"
887 style="fill:#ffffff" />
888 <path
889 d="m 145.971,266.73 1.059,0.888 c 5.193,-2.147 10.87,-3.351 16.738,-3.403 l 0.009,-0.038 0.435,-1.388 c -0.059,0 -0.116,-0.002 -0.175,-0.002 -6.387,-0.024 -12.545,1.39 -18.066,3.943 z"
890 id="path353"
891 inkscape:connector-curvature="0"
892 style="fill:#ffffff" />
893 <path
894 d="m 185.374,269.579 c 0.97,0.527 1.917,1.087 2.84,1.683 l 0.494,-0.416 c -1.011,-0.738 -2.058,-1.431 -3.138,-2.078 l -0.196,0.811 z"
895 id="path355"
896 inkscape:connector-curvature="0"
897 style="fill:#ffffff" />
898 <path
899 d="m 190.66,272.366 -0.224,0.429 c 0.458,0.338 0.91,0.683 1.354,1.038 1.494,1.193 2.916,2.493 4.25,3.889 -1.633,-1.962 -3.44,-3.752 -5.38,-5.356 z"
900 id="path357"
901 inkscape:connector-curvature="0"
902 style="fill:#ffffff" />
903 <path
904 d="m 140.28,269.916 c 0.198,0.281 0.363,0.578 0.496,0.884 0.84,-0.514 1.699,-1.002 2.575,-1.462 l -0.52,-0.994 c -0.871,0.494 -1.721,1.019 -2.551,1.572 z"
905 id="path359"
906 inkscape:connector-curvature="0"
907 style="fill:#ffffff" />
908 <path
909 d="m 133.625,275.426 0.562,0.314 c 0.338,-0.307 0.681,-0.608 1.028,-0.904 -0.192,-0.129 -0.378,-0.272 -0.555,-0.429 -0.35,0.333 -0.696,0.673 -1.035,1.019 z"
910 id="path361"
911 inkscape:connector-curvature="0"
912 style="fill:#ffffff" />
913 <path
914 d="m 130.152,279.456 c 0.139,-0.009 0.279,-0.015 0.419,-0.019 0.538,-0.62 1.091,-1.224 1.66,-1.81 l -0.295,-0.374 c -0.618,0.713 -1.212,1.447 -1.784,2.203 z"
915 id="path363"
916 inkscape:connector-curvature="0"
917 style="fill:#ffffff" />
918 </g>
919 <path
920 d="m 11.717707,25.989048 c -0.05574,-0.15562 -0.125834,-0.306666 -0.209444,-0.44957 -0.01309,0.01012 -0.02618,0.02032 -0.03885,0.03052 -0.04223,0.03408 -0.08403,0.06866 -0.125835,0.10324 -0.05067,0.0417 -0.101339,0.08289 -0.151171,0.125104 -0.05194,0.04324 -0.103455,0.08798 -0.154549,0.132228 -0.04054,0.03459 -0.0815,0.06916 -0.122034,0.104767 -0.06165,0.0534 -0.122457,0.108333 -0.183263,0.16325 -0.03041,0.02747 -0.06122,0.05392 -0.09122,0.08188 -0.09078,0.08288 -0.181151,0.166809 -0.27067,0.251737 -0.09416,0.0895 -0.187063,0.180031 -0.279961,0.272083 -0.02703,0.02695 -0.05447,0.05442 -0.08192,0.08188 -0.07221,0.07272 -0.1439917,0.145958 -0.2153547,0.219699 -0.02281,0.02339 -0.0456,0.04679 -0.068411,0.07019 -0.081499,0.08492 -0.1621494,0.171895 -0.24238,0.258858 -0.041385,0.04477 -0.08276,0.09052 -0.1237229,0.136294 -0.041799,0.04628 -0.08276,0.09308 -0.1241459,0.139347 -0.033364,0.03762 -0.066717,0.07527 -0.1000776,0.113908 0.074741,0.07935 0.1532821,0.152062 0.2343573,0.218175 C 9.5506288,27.855494 9.7347353,27.672921 9.9217999,27.495432 10.4927,26.95178 11.092737,26.44983 11.717689,25.989072 z"
921 id="path365"
922 inkscape:connector-curvature="0"
923 style="fill:#eeeeee" />
924 <path
925 d="m 28.381526,27.537111 c 0.388483,0.0014 0.747409,0.164265 1.026947,0.433802 0.293051,0.282252 0.512205,0.694697 0.575969,1.184949 0.06968,0.534499 -0.05447,1.061878 -0.328523,1.474322 -0.292629,0.439906 -0.744451,0.732838 -1.26806,0.744027 -0.528674,0.01119 -0.990631,-0.26547 -1.292973,-0.70131 -0.286295,-0.411932 -0.417197,-0.947959 -0.345834,-1.495681 0.06503,-0.501949 0.290517,-0.923546 0.592437,-1.209867 0.28545,-0.271063 0.652399,-0.431769 1.040037,-0.430242 z"
926 id="path372"
927 style="fill:#000000"
928 inkscape:connector-curvature="0" />
929 <path
930 d="m 13.466305,55.28374 c 0.178195,0.09256 0.329787,0.214614 0.43662,0.342772 0.111901,0.134768 0.178619,0.281236 0.168063,0.408885 -0.0114,0.139346 -0.111902,0.231394 -0.271518,0.261399 -0.170172,0.03153 -0.401994,-0.0082 -0.64353,-0.129175 -0.244069,-0.12256 -0.433666,-0.295472 -0.53712,-0.467367 -0.09797,-0.162232 -0.114433,-0.316834 -0.03674,-0.425668 0.07093,-0.100193 0.209021,-0.143413 0.37117,-0.13782 0.152859,0.005 0.334856,0.05491 0.513051,0.146974 l 0,0 z m -2.368059,-0.261399 c 0.05025,0.0122 0.09585,0.04017 0.130479,0.0768 0.03588,0.03815 0.06165,0.08797 0.06671,0.140364 0.0055,0.05696 -0.01435,0.10731 -0.05278,0.141381 -0.04097,0.0356 -0.101763,0.05188 -0.169749,0.03611 -0.06883,-0.01525 -0.127102,-0.05848 -0.163417,-0.113404 -0.03463,-0.05139 -0.04772,-0.110861 -0.03463,-0.164774 0.01183,-0.04984 0.04392,-0.08594 0.0853,-0.10578 0.03885,-0.01831 0.08741,-0.02339 0.138081,-0.01071 l 0,0 z m 3.807979,2.368373 c 0.09627,0.02389 0.183263,0.07728 0.248714,0.147481 0.06925,0.07322 0.117813,0.167318 0.127101,0.267506 0.01013,0.109332 -0.02745,0.204948 -0.100915,0.270045 -0.07854,0.06866 -0.194242,0.09866 -0.324299,0.06968 -0.131324,-0.03002 -0.24238,-0.111886 -0.311631,-0.216139 -0.06545,-0.09816 -0.09122,-0.21156 -0.0663,-0.314799 0.02281,-0.09459 0.08446,-0.163757 0.162995,-0.2019 0.07515,-0.03611 0.16806,-0.04576 0.264336,-0.02185 l 0,0 z m -2.357501,-1.035942 c -0.09333,-0.04831 -0.188754,-0.07425 -0.269405,-0.0768 -0.08487,-0.003 -0.157504,0.01983 -0.194242,0.07222 -0.04054,0.05696 -0.03209,0.137821 0.01942,0.222749 0.05405,0.09052 0.153704,0.18054 0.281651,0.245128 0.126679,0.06356 0.247869,0.08391 0.337388,0.06765 0.08362,-0.01576 0.136392,-0.06407 0.142304,-0.137313 0.0055,-0.06713 -0.02956,-0.143414 -0.08783,-0.214102 -0.05658,-0.06714 -0.135969,-0.13121 -0.22929,-0.179526 z"
931 id="path374"
932 inkscape:connector-curvature="0"
933 style="fill:#d9bb7a" />
934 <path
935 d="m 32.89722,32.895826 c 0.143148,-0.434312 0.431555,-0.762333 0.795547,-0.953043 0.380884,-0.199865 0.861841,-0.255808 1.361803,-0.10325 0.544721,0.166808 1.012166,0.547722 1.313242,1.044079 0.320921,0.529412 0.440844,1.170201 0.26096,1.762675 -0.181574,0.59807 -0.618618,0.989661 -1.15236,1.129517 -0.504607,0.132224 -1.073818,0.03356 -1.579691,-0.297003 -0.464491,-0.303099 -0.791747,-0.749617 -0.960229,-1.219019 -0.160039,-0.444994 -0.182419,-0.929651 -0.03927,-1.363962 z"
936 id="path381"
937 style="fill:#000000"
938 inkscape:connector-curvature="0" />
939 <path
940 d="m 35.093418,44.08063 c -0.146948,-0.197323 -0.212399,-0.456178 -0.200998,-0.726732 0.01182,-0.28378 0.109367,-0.591461 0.299807,-0.858457 0.207754,-0.290895 0.486028,-0.480589 0.771477,-0.540093 0.304453,-0.06256 0.604685,0.02594 0.809059,0.285306 0.206487,0.261909 0.26096,0.628075 0.184952,0.989659 -0.07137,0.342262 -0.256313,0.6652 -0.523607,0.891001 -0.244913,0.207492 -0.515586,0.294965 -0.755853,0.27971 -0.227601,-0.01423 -0.437466,-0.123072 -0.584837,-0.320394 z"
941 id="path388"
942 style="fill:#000000"
943 inkscape:connector-curvature="0" />
944 <path
945 d="m 24.819304,51.017414 c -0.147371,-0.197322 -0.212821,-0.456179 -0.201421,-0.727243 0.01183,-0.283269 0.10979,-0.590948 0.30023,-0.858455 0.207333,-0.290896 0.485604,-0.481098 0.771055,-0.540089 0.304453,-0.06256 0.605106,0.02594 0.809059,0.285303 0.206487,0.261908 0.260959,0.628074 0.184952,0.989661 -0.07136,0.342263 -0.256314,0.6652 -0.523608,0.891002 -0.24449,0.207493 -0.515584,0.294964 -0.755854,0.279709 -0.2276,-0.01425 -0.437465,-0.123071 -0.584413,-0.319888 z"
946 id="path395"
947 style="fill:#000000"
948 inkscape:connector-curvature="0" />
949 <path
950 d="m 23.786446,24.445052 c 0.102186,-0.347855 0.322609,-0.616885 0.605104,-0.779624 0.296007,-0.170876 0.673933,-0.232414 1.072129,-0.128666 0.433667,0.112897 0.812438,0.396678 1.061996,0.778609 0.266026,0.406849 0.376235,0.908289 0.24829,1.382269 -0.12879,0.47805 -0.464913,0.802512 -0.882532,0.931685 -0.395661,0.12205 -0.84664,0.06357 -1.254126,-0.17952 -0.374125,-0.222751 -0.642686,-0.563996 -0.787099,-0.928635 -0.137237,-0.346331 -0.166373,-0.728261 -0.06377,-1.076118 z"
951 id="path402"
952 style="fill:#000000"
953 inkscape:connector-curvature="0" />
954 <path
955 d="m 9.3572511,27.571182 c 0.2537814,0.256316 0.5518992,0.424651 0.8555069,0.487204 0.426486,0.08747 0.848329,-0.03611 1.135047,-0.399731 0.28925,-0.367181 0.366103,-0.880828 0.259692,-1.388372 -0.0456,-0.217666 -0.123723,-0.429227 -0.230557,-0.625532 -0.344568,0.281745 -0.680268,0.577726 -1.006255,0.886932 -0.347524,0.330057 -0.6857564,0.676897 -1.0134339,1.039499 z"
956 id="path409"
957 style="fill:#000000"
958 inkscape:connector-curvature="0" />
959 <path
960 d="m 9.3572511,27.571182 c 0.081923,0.08289 0.1684839,0.15664 0.2584255,0.220208 0.1013389,-0.100194 0.2031087,-0.199865 0.3061417,-0.296999 0.5244517,-0.497883 1.0733947,-0.962708 1.6434517,-1.391936 -0.04604,-0.15867 -0.109367,-0.312257 -0.188752,-0.457195 l 0,0 c -0.02997,0.02442 -0.05996,0.04933 -0.08995,0.07425 -0.01942,0.01628 -0.03927,0.03255 -0.05869,0.04883 -0.03336,0.02747 -0.0663,0.05545 -0.09923,0.08341 l -0.04519,0.03865 c -0.03758,0.03205 -0.07474,0.06407 -0.111899,0.09613 l -0.02997,0.02594 c -0.04139,0.03611 -0.08235,0.07221 -0.123301,0.108332 l -0.02026,0.01832 c -0.04392,0.03918 -0.08741,0.07781 -0.130901,0.117485 l -0.01309,0.01169 c -0.04603,0.04223 -0.09206,0.08442 -0.13808,0.12714 l -0.0018,0.0014 c -0.04815,0.04476 -0.09585,0.0895 -0.143569,0.134769 -0.07685,0.07322 -0.15286,0.146467 -0.228867,0.221226 l -0.01098,0.01072 c -0.02026,0.02032 -0.04097,0.04018 -0.06123,0.06051 l -0.01858,0.01882 -0.05236,0.05238 -0.02956,0.03002 -0.04307,0.04376 -0.03801,0.03865 -0.01605,0.01627 -0.01562,0.01627 -0.04771,0.04883 -0.01562,0.01627 C 9.6459492,27.256383 9.50069,27.412511 9.3571211,27.571183 z"
961 id="path411"
962 inkscape:connector-curvature="0"
963 style="fill:#888678" />
964 <path
965 d="m 18.571057,23.295194 c 0.423955,-0.03051 0.815816,0.05645 1.121534,0.226311 0.320077,0.177997 0.559079,0.455163 0.629176,0.800985 0.07601,0.376844 -0.05954,0.764369 -0.359348,1.082221 -0.319232,0.338701 -0.812859,0.585354 -1.385028,0.636719 -0.577235,0.05138 -1.081841,-0.108827 -1.412472,-0.39617 -0.312477,-0.271573 -0.456047,-0.644349 -0.378351,-1.042043 0.07136,-0.364639 0.317965,-0.685034 0.647333,-0.914395 0.312897,-0.217665 0.713204,-0.363114 1.137156,-0.393628 z"
966 id="path418"
967 style="fill:#000000"
968 inkscape:connector-curvature="0" />
969 <path
970 d="m 25.268593,33.539157 c 0.209865,0.121549 0.37835,0.289372 0.487716,0.468895 0.11401,0.188169 0.167216,0.397695 0.123723,0.585864 -0.04687,0.20495 -0.198043,0.347856 -0.412131,0.403289 -0.228021,0.05951 -0.519383,0.01933 -0.804835,-0.139854 -0.288406,-0.160707 -0.494471,-0.399731 -0.589482,-0.643842 -0.08995,-0.230376 -0.07601,-0.455669 0.04941,-0.620952 0.114856,-0.152061 0.304451,-0.226311 0.51305,-0.230379 0.198043,-0.0036 0.422688,0.05543 0.632553,0.176979 z"
971 id="path425"
972 style="fill:#000000"
973 inkscape:connector-curvature="0" />
974 <polygon
975 points="188.385,321.662 183.827,319.426 190.01,322.008 182.526,321.973 "
976 id="polygon427"
977 transform="matrix(0.42226435,0,0,0.50856192,-47.726977,-111.72952)" />
978 <polygon
979 points="181.161,310.218 176.159,311.094 182.677,309.541 176.606,313.919 "
980 id="polygon429"
981 transform="matrix(0.42226435,0,0,0.50856192,-47.726977,-111.72952)" />
982 <polygon
983 points="188.996,281.271 183.955,287.956 191.129,279.553 180.144,285.178 "
984 id="polygon431"
985 transform="matrix(0.42226435,0,0,0.50856192,-47.726977,-111.72952)" />
986 <path
987 d="m 35.589578,54.524966 c -0.122034,0.197832 -0.247447,0.39312 -0.376237,0.586373 -3.139958,4.719964 -7.989242,7.864909 -13.609581,7.987982 C 15.929794,63.222902 10.97199,60.250356 7.7226683,55.572603 7.5229375,55.285266 7.3303849,54.991318 7.1445881,54.693299 c 3.5503959,4.555698 8.6741509,7.392458 14.4832419,7.265826 5.617804,-0.123069 10.532541,-3.002548 13.961748,-7.434159 z"
988 id="path440"
989 style="fill:#d9bb7a"
990 inkscape:connector-curvature="0" />
991 <path
992 d="m 16.345302,52.251694 c -2.117655,-1.929991 -2.971052,-5.408047 -1.900189,-8.495019 1.184029,-3.41245 4.302452,-5.144614 7.182295,-4.121385 -2.791167,-0.695713 -5.69128,1.060859 -6.831394,4.34617 -1.023146,2.94966 -0.321343,6.249209 1.549288,8.270234 z"
993 id="path442"
994 inkscape:connector-curvature="0"
995 style="fill:#ffffff" />
996 <path
997 d="m 7.9004418,49.211004 c 1.5839109,-1.826246 1.8765395,-5.188352 0.611861,-7.774387 -0.9606515,-1.964067 -2.560189,-2.949661 -4.0731622,-2.724366 1.4428771,-0.03307 2.911513,0.974913 3.8219146,2.837267 1.2266751,2.507718 1.0299008,5.725391 -0.3606134,7.661486 z"
998 id="path444"
999 inkscape:connector-curvature="0"
1000 style="fill:#ffffff" />
1001 <path
1002 d="m 46.744961,35.073491 -0.497006,-0.879306 c -0.446333,-0.789288 -2.616772,-1.271403 -3.063106,-2.060692 -0.04897,-0.08645 -0.08995,-0.178504 -0.124145,-0.273607 0.02111,0.05392 0.04434,0.106285 0.07093,0.157655 0.411286,0.799459 2.442378,0.780134 2.853664,1.579592 l 0.759653,1.476358 0,0 z m -3.840919,-4.235306 c -0.02154,-1.142737 0.276584,-2.476187 -0.211554,-3.339725 -0.684068,-1.210379 -3.109133,-1.708769 -3.070285,-3.678937 0.02618,-1.300901 0.05531,-2.044928 -0.877888,-0.830484 -0.474202,0.616888 -0.933204,1.256658 -1.378271,1.918806 0.532898,-0.895579 1.084376,-1.758098 1.656966,-2.58553 0.921382,-1.331414 0.877043,-0.549754 0.825104,0.815225 -0.02492,0.63723 0.05786,1.381764 0.330634,1.912701 0.487293,0.947452 2.164949,1.469236 2.652243,2.416687 0.464492,0.901679 0.07769,2.233605 0.07305,3.371257 z"
1003 id="path446"
1004 inkscape:connector-curvature="0"
1005 style="fill:#ffffff" />
1006 <path
1007 d="m 16.756588,33.897186 c 0.357235,-0.248687 0.77781,-0.246145 1.121111,-0.03865 -0.09501,0.0122 -0.189596,0.04832 -0.27785,0.109346 -0.338655,0.235464 -0.455199,0.757757 -0.25927,1.165625 0.19551,0.408372 0.629174,0.548229 0.96783,0.312255 0.08783,-0.06155 0.160883,-0.14189 0.217467,-0.234955 -0.02237,0.461773 -0.230979,0.901679 -0.588638,1.150367 -0.564566,0.39261 -1.287061,0.15918 -1.613471,-0.520769 -0.325145,-0.680454 -0.131747,-1.550096 0.432821,-1.943214 l 0,0 z m -8.4625961,1.183931 c 0.2575811,-0.179014 0.5603435,-0.177488 0.8077901,-0.02795 -0.068836,0.009 -0.1368128,0.03458 -0.2001525,0.07882 -0.2440687,0.169354 -0.327677,0.545687 -0.1866399,0.839639 0.1406128,0.293947 0.453088,0.394643 0.6971553,0.224782 0.063334,-0.04425 0.1161241,-0.102217 0.1570835,-0.16935 C 9.5527694,36.35966 9.4024339,36.676495 9.1452751,36.855507 8.7386349,37.138248 8.2179844,36.970431 7.983206,36.480169 7.7475821,35.990933 7.887351,35.363875 8.2939919,35.081114 z"
1008 id="path448"
1009 inkscape:connector-curvature="0" />
1010 <path
1011 d="m 11.148494,37.665629 c -0.260113,-0.748095 -0.420152,-1.550096 -0.46449,-2.376002 -0.533741,1.967118 -1.8647168,3.382956 -3.4389171,3.862529 0.4619579,0.354468 0.8876005,0.829465 1.2503252,1.416854 1.1793816,-0.417022 2.1776139,-1.463641 2.6530819,-2.903381 z"
1012 id="path450"
1013 inkscape:connector-curvature="0"
1014 style="fill:#eeeeee" />
1015 <path
1016 d="m 3.5654754,33.263516 c -0.2884063,0.139348 -0.5160068,0.432279 -0.656621,0.92355 -0.6697112,2.341929 -0.5459877,4.035438 0.033358,5.072397 C 3.09465,39.150129 3.25131,39.055528 3.4109259,38.975177 3.537183,38.886186 3.6659737,38.807859 3.7972979,38.739713 3.1153408,37.498312 2.8611376,35.923805 3.2065499,34.3732 3.2935369,33.980083 3.4151486,33.609339 3.5654746,33.263516 z"
1017 id="path457"
1018 style="fill:#f0a513"
1019 inkscape:connector-curvature="0" />
1020 <path
1021 d="m 9.6346789,48.851958 c 0.7959681,1.053234 2.8688621,0.917445 3.5212611,-0.268012 -0.352592,0.781151 -1.04046,1.31209 -1.830517,1.31209 -0.695891,0 -1.312395,-0.411935 -1.6907441,-1.044078 z"
1022 id="path459"
1023 inkscape:connector-curvature="0"
1024 style="fill:#ffffff" />
1025 </g>
1026 </g>
1027 </svg>
0 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
1 <!-- Created with Inkscape (http://www.inkscape.org/) -->
2
3 <svg
4 xmlns:dc="http://purl.org/dc/elements/1.1/"
5 xmlns:cc="http://creativecommons.org/ns#"
6 xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
7 xmlns:svg="http://www.w3.org/2000/svg"
8 xmlns="http://www.w3.org/2000/svg"
9 xmlns:xlink="http://www.w3.org/1999/xlink"
10 xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
11 xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
12 width="48"
13 height="48"
14 id="svg26756"
15 version="1.1"
16 inkscape:version="0.48.3.1 r9886"
17 sodipodi:docname="diodon.svg">
18 <defs
19 id="defs26758">
20 <radialGradient
21 inkscape:collect="always"
22 xlink:href="#SVGID_3_"
23 id="radialGradient3305"
24 gradientUnits="userSpaceOnUse"
25 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
26 cx="163.4902"
27 cy="274.86621"
28 r="2.8801" />
29 <radialGradient
30 gradientUnits="userSpaceOnUse"
31 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
32 r="2.8801"
33 cy="274.86621"
34 cx="163.4902"
35 id="SVGID_3_">
36 <stop
37 id="stop190"
38 style="stop-color:#FAF0BB"
39 offset="0.0112" />
40 <stop
41 id="stop192"
42 style="stop-color:#FAF0BD"
43 offset="0.4917" />
44 <stop
45 id="stop194"
46 style="stop-color:#FBF2C5"
47 offset="0.6648" />
48 <stop
49 id="stop196"
50 style="stop-color:#FCF6D0"
51 offset="0.7882" />
52 <stop
53 id="stop198"
54 style="stop-color:#FCF8E1"
55 offset="0.8879" />
56 <stop
57 id="stop200"
58 style="stop-color:#FFFDF7"
59 offset="0.9723" />
60 <stop
61 id="stop202"
62 style="stop-color:#FFFFFF"
63 offset="1" />
64 </radialGradient>
65 <radialGradient
66 inkscape:collect="always"
67 xlink:href="#SVGID_4_"
68 id="radialGradient3307"
69 gradientUnits="userSpaceOnUse"
70 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
71 cx="155.3242"
72 cy="310.6777"
73 r="4.4867001" />
74 <radialGradient
75 gradientUnits="userSpaceOnUse"
76 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
77 r="4.4867001"
78 cy="310.6777"
79 cx="155.3242"
80 id="SVGID_4_">
81 <stop
82 id="stop207"
83 style="stop-color:#FAF0BB"
84 offset="0.0112" />
85 <stop
86 id="stop209"
87 style="stop-color:#FAF0BD"
88 offset="0.4917" />
89 <stop
90 id="stop211"
91 style="stop-color:#FBF2C5"
92 offset="0.6648" />
93 <stop
94 id="stop213"
95 style="stop-color:#FCF6D0"
96 offset="0.7882" />
97 <stop
98 id="stop215"
99 style="stop-color:#FCF8E1"
100 offset="0.8879" />
101 <stop
102 id="stop217"
103 style="stop-color:#FFFDF7"
104 offset="0.9723" />
105 <stop
106 id="stop219"
107 style="stop-color:#FFFFFF"
108 offset="1" />
109 </radialGradient>
110 <radialGradient
111 inkscape:collect="always"
112 xlink:href="#SVGID_5_"
113 id="radialGradient3310"
114 gradientUnits="userSpaceOnUse"
115 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
116 cx="170.3125"
117 cy="302.00781"
118 r="5.0811" />
119 <radialGradient
120 gradientUnits="userSpaceOnUse"
121 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
122 r="5.0811"
123 cy="302.00781"
124 cx="170.3125"
125 id="SVGID_5_">
126 <stop
127 id="stop224"
128 style="stop-color:#FAF0BB"
129 offset="0.0112" />
130 <stop
131 id="stop226"
132 style="stop-color:#FAF0BD"
133 offset="0.4917" />
134 <stop
135 id="stop228"
136 style="stop-color:#FBF2C5"
137 offset="0.6648" />
138 <stop
139 id="stop230"
140 style="stop-color:#FCF6D0"
141 offset="0.7882" />
142 <stop
143 id="stop232"
144 style="stop-color:#FCF8E1"
145 offset="0.8879" />
146 <stop
147 id="stop234"
148 style="stop-color:#FFFDF7"
149 offset="0.9723" />
150 <stop
151 id="stop236"
152 style="stop-color:#FFFFFF"
153 offset="1" />
154 </radialGradient>
155 <radialGradient
156 inkscape:collect="always"
157 xlink:href="#SVGID_6_"
158 id="radialGradient3312"
159 gradientUnits="userSpaceOnUse"
160 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
161 cx="173.2812"
162 cy="283.68359"
163 r="2.8803999" />
164 <radialGradient
165 gradientUnits="userSpaceOnUse"
166 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
167 r="2.8803999"
168 cy="283.68359"
169 cx="173.2812"
170 id="SVGID_6_">
171 <stop
172 id="stop241"
173 style="stop-color:#FAF0BB"
174 offset="0.0112" />
175 <stop
176 id="stop243"
177 style="stop-color:#FAF0BD"
178 offset="0.4917" />
179 <stop
180 id="stop245"
181 style="stop-color:#FBF2C5"
182 offset="0.6648" />
183 <stop
184 id="stop247"
185 style="stop-color:#FCF6D0"
186 offset="0.7882" />
187 <stop
188 id="stop249"
189 style="stop-color:#FCF8E1"
190 offset="0.8879" />
191 <stop
192 id="stop251"
193 style="stop-color:#FFFDF7"
194 offset="0.9723" />
195 <stop
196 id="stop253"
197 style="stop-color:#FFFFFF"
198 offset="1" />
199 </radialGradient>
200 <radialGradient
201 inkscape:collect="always"
202 xlink:href="#SVGID_7_"
203 id="radialGradient3314"
204 gradientUnits="userSpaceOnUse"
205 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
206 cx="148.9492"
207 cy="270.04489"
208 r="2.8799" />
209 <radialGradient
210 gradientUnits="userSpaceOnUse"
211 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
212 r="2.8799"
213 cy="270.04489"
214 cx="148.9492"
215 id="SVGID_7_">
216 <stop
217 id="stop258"
218 style="stop-color:#FAF0BB"
219 offset="0.0112" />
220 <stop
221 id="stop260"
222 style="stop-color:#FAF0BD"
223 offset="0.4917" />
224 <stop
225 id="stop262"
226 style="stop-color:#FBF2C5"
227 offset="0.6648" />
228 <stop
229 id="stop264"
230 style="stop-color:#FCF6D0"
231 offset="0.7882" />
232 <stop
233 id="stop266"
234 style="stop-color:#FCF8E1"
235 offset="0.8879" />
236 <stop
237 id="stop268"
238 style="stop-color:#FFFDF7"
239 offset="0.9723" />
240 <stop
241 id="stop270"
242 style="stop-color:#FFFFFF"
243 offset="1" />
244 </radialGradient>
245 <radialGradient
246 inkscape:collect="always"
247 xlink:href="#SVGID_8_"
248 id="radialGradient3316"
249 gradientUnits="userSpaceOnUse"
250 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
251 cx="148.0723"
252 cy="319.09381"
253 r="3.9265001" />
254 <radialGradient
255 gradientUnits="userSpaceOnUse"
256 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
257 r="3.9265001"
258 cy="319.09381"
259 cx="148.0723"
260 id="SVGID_8_">
261 <stop
262 id="stop275"
263 style="stop-color:#FAF0BB"
264 offset="0.0112" />
265 <stop
266 id="stop277"
267 style="stop-color:#FAF0BD"
268 offset="0.4917" />
269 <stop
270 id="stop279"
271 style="stop-color:#FBF2C5"
272 offset="0.6648" />
273 <stop
274 id="stop281"
275 style="stop-color:#FCF6D0"
276 offset="0.7882" />
277 <stop
278 id="stop283"
279 style="stop-color:#FCF8E1"
280 offset="0.8879" />
281 <stop
282 id="stop285"
283 style="stop-color:#FFFDF7"
284 offset="0.9723" />
285 <stop
286 id="stop287"
287 style="stop-color:#FFFFFF"
288 offset="1" />
289 </radialGradient>
290 <radialGradient
291 inkscape:collect="always"
292 xlink:href="#SVGID_9_"
293 id="radialGradient3318"
294 gradientUnits="userSpaceOnUse"
295 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
296 cx="112.9551"
297 cy="315.56049"
298 r="3.0683999" />
299 <radialGradient
300 gradientUnits="userSpaceOnUse"
301 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
302 r="3.0683999"
303 cy="315.56049"
304 cx="112.9551"
305 id="SVGID_9_">
306 <stop
307 id="stop292"
308 style="stop-color:#FAF0BB"
309 offset="0.0112" />
310 <stop
311 id="stop294"
312 style="stop-color:#FAF0BD"
313 offset="0.4917" />
314 <stop
315 id="stop296"
316 style="stop-color:#FBF2C5"
317 offset="0.6648" />
318 <stop
319 id="stop298"
320 style="stop-color:#FCF6D0"
321 offset="0.7882" />
322 <stop
323 id="stop300"
324 style="stop-color:#FCF8E1"
325 offset="0.8879" />
326 <stop
327 id="stop302"
328 style="stop-color:#FFFDF7"
329 offset="0.9723" />
330 <stop
331 id="stop304"
332 style="stop-color:#FFFFFF"
333 offset="1" />
334 </radialGradient>
335 <radialGradient
336 inkscape:collect="always"
337 xlink:href="#SVGID_10_"
338 id="radialGradient3320"
339 gradientUnits="userSpaceOnUse"
340 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
341 cx="132.0938"
342 cy="320.1113"
343 r="4.1712999" />
344 <radialGradient
345 gradientUnits="userSpaceOnUse"
346 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
347 r="4.1712999"
348 cy="320.1113"
349 cx="132.0938"
350 id="SVGID_10_">
351 <stop
352 id="stop309"
353 style="stop-color:#FAF0BB"
354 offset="0.0112" />
355 <stop
356 id="stop311"
357 style="stop-color:#FAF0BD"
358 offset="0.4917" />
359 <stop
360 id="stop313"
361 style="stop-color:#FBF2C5"
362 offset="0.6648" />
363 <stop
364 id="stop315"
365 style="stop-color:#FCF6D0"
366 offset="0.7882" />
367 <stop
368 id="stop317"
369 style="stop-color:#FCF8E1"
370 offset="0.8879" />
371 <stop
372 id="stop319"
373 style="stop-color:#FFFDF7"
374 offset="0.9723" />
375 <stop
376 id="stop321"
377 style="stop-color:#FFFFFF"
378 offset="1" />
379 </radialGradient>
380 <radialGradient
381 inkscape:collect="always"
382 xlink:href="#SVGID_11_"
383 id="radialGradient3322"
384 gradientUnits="userSpaceOnUse"
385 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
386 cx="147.44189"
387 cy="301.21091"
388 r="2.5313001" />
389 <radialGradient
390 gradientUnits="userSpaceOnUse"
391 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
392 r="2.5313001"
393 cy="301.21091"
394 cx="147.44189"
395 id="SVGID_11_">
396 <stop
397 id="stop326"
398 style="stop-color:#FAF0BB"
399 offset="0.0112" />
400 <stop
401 id="stop328"
402 style="stop-color:#FAF0BD"
403 offset="0.4917" />
404 <stop
405 id="stop330"
406 style="stop-color:#FBF2C5"
407 offset="0.6648" />
408 <stop
409 id="stop332"
410 style="stop-color:#FCF6D0"
411 offset="0.7882" />
412 <stop
413 id="stop334"
414 style="stop-color:#FCF8E1"
415 offset="0.8879" />
416 <stop
417 id="stop336"
418 style="stop-color:#FFFDF7"
419 offset="0.9723" />
420 <stop
421 id="stop338"
422 style="stop-color:#FFFFFF"
423 offset="1" />
424 </radialGradient>
425 </defs>
426 <sodipodi:namedview
427 id="base"
428 pagecolor="#ffffff"
429 bordercolor="#666666"
430 borderopacity="1.0"
431 inkscape:pageopacity="0.0"
432 inkscape:pageshadow="2"
433 inkscape:zoom="22.395604"
434 inkscape:cx="23.985929"
435 inkscape:cy="34.824759"
436 inkscape:current-layer="layer1"
437 showgrid="true"
438 inkscape:grid-bbox="true"
439 inkscape:document-units="px"
440 inkscape:window-width="1600"
441 inkscape:window-height="876"
442 inkscape:window-x="0"
443 inkscape:window-y="24"
444 inkscape:window-maximized="1">
445 <inkscape:grid
446 type="xygrid"
447 id="grid3184" />
448 </sodipodi:namedview>
449 <metadata
450 id="metadata26761">
451 <rdf:RDF>
452 <cc:Work
453 rdf:about="">
454 <dc:format>image/svg+xml</dc:format>
455 <dc:type
456 rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
457 <dc:title />
458 </cc:Work>
459 </rdf:RDF>
460 </metadata>
461 <g
462 id="layer1"
463 inkscape:label="Layer 1"
464 inkscape:groupmode="layer"
465 transform="translate(0,16)">
466 <g
467 id="g3183"
468 transform="matrix(0.97648829,0,0,0.80895713,0.24705205,-24.411802)">
469 <path
470 d="m 47.748262,36.240641 c -0.304876,-0.669777 -0.939962,-2.526029 -1.264261,-3.180039 -0.499962,-1.005938 -2.409862,-0.340737 -2.850285,-1.402107 -0.615238,-1.481949 0.402841,-3.075783 -0.26687,-4.517046 -0.51052,-1.098494 -2.320767,-1.749962 -2.830861,-2.848458 -0.374128,-0.804542 0.05785,-5.080024 -0.915894,-3.703855 -1.643875,2.32362 -3.133623,4.929999 -4.51865,7.769812 -0.227178,-0.299544 -0.460268,-0.590441 -0.699692,-0.872694 l 1.273972,-2.395837 -1.94875,1.641638 C 33.517528,26.509306 33.303862,26.293167 33.085974,26.08364 l 0.936581,-2.162914 -1.564066,1.585187 C 31.923058,25.034986 31.365246,24.598131 30.785899,24.1984 l 1.168829,-5.78896 -2.873088,4.753021 C 28.796189,23.01091 28.507361,22.866987 28.213887,22.732727 l 0.283762,-3.540102 -1.360114,3.093074 C 25.924369,21.832064 24.65631,21.526925 23.350669,21.385545 l -0.349636,-4.806419 -1.226255,4.716403 c -0.0033,0 -0.0071,0 -0.01056,0 -1.422186,-0.0066 -2.818193,0.185117 -4.164371,0.553823 l -1.190787,-2.856081 0.196351,3.163762 c -0.403261,0.139347 -0.801035,0.294459 -1.193319,0.465334 l -0.676466,-1.193086 0.243647,1.388883 c -0.482226,0.226309 -0.954317,0.47703 -1.416273,0.750127 l -2.649288,-2.676561 1.488058,3.425166 c -0.733893,0.515174 -1.434852,1.088322 -2.09654,1.715887 -0.09374,0.089 -0.187063,0.180031 -0.279538,0.271064 l -2.6176137,-1.775898 1.7557735,2.685206 c -0.2643372,0.297002 -0.5214955,0.60519 -0.7718972,0.922533 l -2.0728961,-1.396004 1.4580788,2.215805 c -0.340767,0.479065 -0.6650662,0.978474 -0.9716305,1.49568 -1.2705932,0.251233 -2.4081735,1.157486 -3.0905527,2.497041 0.00253,-0.005 0.00508,-0.01071 0.00802,-0.01578 -0.5079841,0.01071 -0.9074462,0.311242 -1.1177337,1.046115 -0.7347402,2.568744 -0.5366981,4.375156 0.1689057,5.408554 -0.1199231,0.09664 -0.2373126,0.202409 -0.3517463,0.317854 -1.90145688,1.925922 -2.20548742,5.78845 -0.6790012,8.625208 0.8470624,1.574001 2.0796522,2.501617 3.3341996,2.686733 0.6452198,1.719448 1.4880601,3.337183 2.5116286,4.809977 3.3333522,4.799809 8.4203702,7.849148 14.2412852,7.722516 5.766442,-0.126125 10.741561,-3.352949 13.962593,-8.195477 2.268826,-3.410417 3.604027,-7.536378 3.803758,-11.87187 L 41.77997,42.904823 39.623044,42.4461 c 0.003,-0.734364 -0.02618,-1.473813 -0.08952,-2.215806 l 3.332089,-2.112565 -3.537731,0.400746 C 39.264542,38.110618 39.19107,37.708348 39.108306,37.31116 l 0.959807,-0.628583 -1.067483,0.13782 c -0.02618,-0.113909 -0.05278,-0.226818 -0.08023,-0.33972 2.756541,-0.434818 5.473393,-0.393116 8.225288,0.328024 0.699694,0.183591 0.893512,0.07272 0.602574,-0.568064 z M 3.2551113,34.170284 c -0.017313,0.06662 -0.033782,0.134262 -0.04856,0.202916 -0.0114,0.05139 -0.022381,0.102733 -0.032514,0.154602 0.010132,-0.05188 0.020692,-0.10325 0.032514,-0.154602 0.01478,-0.06866 0.031247,-0.136294 0.04856,-0.202916 z m 0.4049515,-1.11121 c -0.010132,0.02085 -0.020269,0.04223 -0.030404,0.06306 0.010132,-0.02085 0.02027,-0.04222 0.030404,-0.06306 z m -0.079808,0.172404 c -0.010557,0.02339 -0.020692,0.0473 -0.030825,0.07119 0.010132,-0.02389 0.02027,-0.04782 0.030825,-0.07119 z m -0.075164,0.177488 c -0.010557,0.02644 -0.021113,0.0529 -0.031248,0.07984 0.010132,-0.02694 0.020692,-0.0534 0.031248,-0.07984 z m -0.070097,0.182573 c -0.010979,0.03002 -0.021535,0.06 -0.032092,0.09001 0.010557,-0.03002 0.021113,-0.06002 0.032092,-0.09001 z m -0.06545,0.187661 c -0.01098,0.03407 -0.021535,0.06866 -0.032515,0.103238 0.010979,-0.03458 0.021113,-0.06866 0.032515,-0.103238 z m -0.059962,0.193252 c -0.011823,0.04119 -0.023225,0.08289 -0.034626,0.124599 0.0114,-0.04172 0.022381,-0.08342 0.034626,-0.124599 z m -0.2558905,1.703683 c -8.452e-4,0.05034 -8.452e-4,0.100695 -4.223e-4,0.150535 -4.223e-4,-0.05034 -4.223e-4,-0.100705 4.223e-4,-0.150535 z m 0.1106333,-1.097477 c -0.00633,0.03458 -0.012668,0.06866 -0.018578,0.103239 0.00591,-0.03407 0.012245,-0.06866 0.018578,-0.103239 z m -0.028713,0.164775 c -0.00507,0.03153 -0.010132,0.06256 -0.01478,0.09357 0.00464,-0.03101 0.00971,-0.06204 0.01478,-0.09357 z m -0.023646,0.15867 c -0.00423,0.03053 -0.00802,0.06053 -0.011823,0.09052 0.00379,-0.03052 0.0076,-0.06054 0.011823,-0.09052 z m -0.019423,0.156131 c -0.00338,0.03002 -0.00633,0.05949 -0.00929,0.0895 0.00296,-0.03002 0.00591,-0.05951 0.00929,-0.0895 z m -0.015624,0.155617 c -0.00253,0.03002 -0.00464,0.06001 -0.00717,0.09001 0.00253,-0.03002 0.00508,-0.06001 0.00717,-0.09001 z m -0.0114,0.154604 c -0.0017,0.03154 -0.00338,0.06256 -0.00507,0.09408 0.0017,-0.03153 0.00338,-0.06256 0.00507,-0.09408 z m -0.0076,0.154095 c -0.00127,0.03662 -0.00211,0.07322 -0.00296,0.109332 4.221e-4,-0.03662 0.00127,-0.07272 0.00296,-0.109332 z m 0.1634162,1.705207 c -0.0076,-0.03203 -0.01478,-0.06407 -0.021535,-0.09611 0.00718,0.03205 0.013934,0.06407 0.021535,0.09611 z m -0.037161,-0.168331 c -0.00802,-0.03865 -0.015624,-0.07728 -0.023225,-0.115944 0.0076,0.03865 0.015624,0.07729 0.023225,0.115944 z m -0.033785,-0.176983 c -0.00507,-0.02847 -0.010132,-0.05696 -0.01478,-0.08543 0.00464,0.02795 0.010132,0.05696 0.01478,0.08543 z m -0.024491,-0.152059 c -0.00423,-0.02694 -0.00844,-0.05392 -0.012245,-0.08138 0.00379,0.02694 0.0076,0.05442 0.012245,0.08138 z m -0.021113,-0.150025 c -0.00338,-0.02694 -0.00675,-0.0534 -0.00971,-0.08086 0.00296,0.02747 0.00633,0.05442 0.00971,0.08086 z m -0.017313,-0.149518 c -0.00296,-0.02694 -0.00549,-0.05392 -0.00802,-0.08137 0.00253,0.02747 0.00508,0.05441 0.00802,0.08137 z m -0.013934,-0.150024 c -0.00211,-0.02795 -0.00423,-0.05546 -0.00591,-0.08341 0.0017,0.02747 0.00379,0.05544 0.00591,0.08341 z m -0.010132,-0.150536 c -0.0017,-0.0295 -0.00296,-0.059 -0.00423,-0.0885 0.00127,0.0295 0.00253,0.05898 0.00423,0.0885 z m -0.00675,-0.15206 c -0.00127,-0.03356 -0.0017,-0.06765 -0.00211,-0.101717 0,0.03407 8.451e-4,0.06814 0.00211,0.101717 z m 0.180307,1.313616 c 0.00633,0.02644 0.012668,0.0529 0.019424,0.07882 -0.00633,-0.02644 -0.012668,-0.05239 -0.019424,-0.07882 z m 0.1811488,1.679273 c -0.00211,9.74e-4 -0.00423,0.0021 -0.00633,0.003 0,0 0,0 4.224e-4,0 0.015624,-0.01072 0.031247,-0.02137 0.046871,-0.03205 -0.013511,0.0097 -0.027025,0.01933 -0.04096,0.02896 z M 3.2745435,37.437285 c 0.00675,0.02492 0.013511,0.04984 0.020692,0.07476 -0.00717,-0.02492 -0.013934,-0.04984 -0.020692,-0.07476 z m 0.040537,0.141888 c 0.00717,0.0244 0.014357,0.04883 0.021957,0.07272 -0.00717,-0.0244 -0.014779,-0.04832 -0.021957,-0.07272 z m 0.043072,0.139347 c 0.00802,0.02389 0.015624,0.04782 0.023646,0.0717 -0.0076,-0.02389 -0.015624,-0.04728 -0.023646,-0.0717 z m 0.046449,0.137819 c 0.00844,0.02389 0.016891,0.04782 0.025758,0.07171 -0.00844,-0.02389 -0.017313,-0.0473 -0.025758,-0.07171 z m 0.049405,0.135789 c 0.00929,0.0244 0.019001,0.04883 0.028292,0.07322 -0.00929,-0.02441 -0.019001,-0.04831 -0.028292,-0.07322 z m 0.052361,0.134256 c 0.010979,0.02747 0.022803,0.05442 0.034203,0.08188 -0.0114,-0.02747 -0.023225,-0.05442 -0.034203,-0.08188 z m 0.055317,0.13223 c 0.018158,0.04223 0.037159,0.08491 0.056584,0.12663 -0.019001,-0.04223 -0.038005,-0.0844 -0.056584,-0.12663 z m 0.081498,0.178505 c 0.012245,0.02543 0.024491,0.05086 0.036737,0.07627 -0.012668,-0.02543 -0.024491,-0.05086 -0.036737,-0.07627 z m 0.065028,0.132734 c 0.011824,0.02339 0.023646,0.04678 0.035893,0.07019 -0.012246,-0.02339 -0.024069,-0.04678 -0.035893,-0.07019 z m 0.066295,0.12714 c 0.00802,0.01423 0.015624,0.029 0.023646,0.04272 -0.012668,0.0066 -0.025336,0.01272 -0.037582,0.01933 0.012246,-0.0066 0.02449,-0.01373 0.036737,-0.01983 -0.00802,-0.01373 -0.015202,-0.02797 -0.022803,-0.04223 z"
471 id="path5"
472 inkscape:connector-curvature="0" />
473 <path
474 d="m 46.872485,35.321668 c -0.295587,-0.574676 -0.59117,-1.149351 -0.887179,-1.724024 -0.411284,-0.79946 -2.442377,-0.780135 -2.853662,-1.579594 -0.640154,-1.243435 0.339923,-3.306671 -0.300232,-4.550104 -0.487293,-0.94745 -2.164949,-1.469746 -2.652242,-2.417196 -0.272784,-0.53043 -0.355546,-1.274964 -0.330633,-1.912193 0.05237,-1.364979 0.09627,-2.14664 -0.825104,-0.815224 -1.463147,2.115108 -2.790324,4.459071 -4.019957,7.001881 0.08403,0.130191 0.166794,0.262928 0.248715,0.39617 1.867674,-0.780645 3.579534,-1.925924 5.084062,-3.359053 -1.390517,1.582138 -3.033126,2.860154 -4.860686,3.733354 0.119078,0.203934 0.236469,0.410917 0.350057,0.620953 -0.87662,-1.47788 -1.904834,-2.797597 -3.043681,-3.931183 l -0.220844,0.510597 1.016812,-2.721313 -1.72115,1.539922 0.100502,-0.101717 c -0.426911,-0.375317 -0.869023,-0.727243 -1.324646,-1.05679 l -0.259691,1.287172 0.928137,-6.116986 -3.276349,4.782515 0.695047,-1.149347 C 27.064907,22.874104 25.27366,22.28112 23.39754,22.038534 l 0.05785,0.790309 -0.581035,-4.788622 -1.425989,4.509928 0.165107,-0.635193 c -0.02449,0 -0.04899,-9.74e-4 -0.07348,-9.74e-4 -2.69658,-0.0122 -5.297306,0.706904 -7.628628,2.005263 l 0.994011,1.003896 -3.222299,-2.891682 1.639229,4.403639 -0.736427,-1.695038 c -0.777812,0.531955 -1.518886,1.130533 -2.214777,1.791154 -0.5865257,0.556877 -1.1460249,1.161557 -1.6734311,1.809973 l 0.3800423,0.25581 -2.2287093,-1.303955 1.2275217,2.117143 -0.091631,-0.139345 c -0.260959,0.36159 -0.5122061,0.73538 -0.7533194,1.120363 0,0 4.226e-4,0 4.226e-4,0 0.058698,-0.0046 0.1178119,-0.0076 0.1769282,-0.0097 0.4197311,-0.01322 0.848329,0.04476 1.274816,0.182576 0.9543158,0.307679 1.753238,0.965757 2.327517,1.82777 1.042571,-3.636727 4.259803,-5.735561 7.393005,-4.724541 3.275504,1.057303 5.220032,5.114101 4.342567,9.059015 -0.238157,1.070014 -0.659578,2.022044 -1.212743,2.819977 0.07093,0.03205 0.14188,0.06509 0.212399,0.100705 0.08361,0.04223 0.165949,0.08645 0.247024,0.132733 -2.976541,-1.313107 -6.314119,0.418546 -7.548398,3.975938 -1.2347,3.558409 0.08783,7.634533 2.955006,9.262947 -0.08446,-0.03713 -0.168483,-0.07627 -0.252515,-0.118496 -3.038191,-1.529246 -4.4722,-5.736577 -3.202452,-9.39619 0.218733,-0.629601 0.502918,-1.20224 0.839884,-1.711309 -1.472858,-0.618921 -2.639575,-1.861338 -3.348979,-3.411436 -0.588214,1.277509 -1.5788438,2.193938 -2.71769,2.574851 0.033789,0.06461 0.067143,0.129174 0.099654,0.195797 1.344911,2.750302 0.9285586,6.379401 -0.9298248,8.103932 -0.051515,0.04782 -0.1038771,0.09407 -0.1566596,0.137821 h 0 c 0.026184,-0.02694 0.05236,-0.05442 0.078121,-0.08188 8.773e-4,-0.0014 0.00167,-0.0026 0.00296,-0.0036 0.024916,-0.02694 0.049402,-0.05442 0.073895,-0.08239 0.00128,-0.0021 0.00296,-0.0036 0.00462,-0.005 0.024071,-0.02795 0.047713,-0.05545 0.070937,-0.08341 0.00167,-0.0026 0.00384,-0.0046 0.0055,-0.0071 0.023227,-0.02796 0.045607,-0.05543 0.067989,-0.08391 0.00216,-0.003 0.00423,-0.0061 0.00675,-0.0086 0.021955,-0.02847 0.043919,-0.05646 0.065029,-0.08542 0.00251,-0.003 0.00512,-0.0066 0.0072,-0.0097 0.021109,-0.02847 0.042228,-0.05696 0.062493,-0.08645 0.00251,-0.0036 0.00512,-0.0072 0.00755,-0.01071 0.020265,-0.0295 0.040538,-0.05799 0.060379,-0.08797 0.00251,-0.004 0.00512,-0.0076 0.008,-0.01121 0.01942,-0.0295 0.038848,-0.05898 0.058277,-0.08899 0.00251,-0.0046 0.00549,-0.0086 0.008,-0.0122 0.018997,-0.03002 0.037589,-0.06 0.055741,-0.09052 0.00251,-0.0046 0.00549,-0.0086 0.008,-0.01272 0.018152,-0.03052 0.036322,-0.06103 0.054051,-0.09204 0.00251,-0.0046 0.00512,-0.009 0.008,-0.01322 0.017729,-0.03153 0.035054,-0.06204 0.052361,-0.09357 0.00251,-0.005 0.00513,-0.0097 0.00755,-0.01373 0.017306,-0.03153 0.033789,-0.06306 0.050253,-0.09508 0.00251,-0.005 0.00513,-0.0097 0.00755,-0.01423 0.016464,-0.03153 0.032521,-0.06407 0.048559,-0.09613 0.00213,-0.005 0.00455,-0.0097 0.00716,-0.01425 0.015622,-0.03253 0.031254,-0.06509 0.046458,-0.09816 0.00213,-0.0046 0.00426,-0.0097 0.00677,-0.01373 0.015206,-0.03304 0.030402,-0.06713 0.045191,-0.100694 0.00213,-0.004 0.00387,-0.009 0.0059,-0.01272 0.01478,-0.03409 0.029559,-0.06865 0.043913,-0.102733 0.00175,-0.0046 0.00329,-0.0086 0.00513,-0.0122 0.014354,-0.03508 0.028291,-0.07019 0.042229,-0.105275 0.00126,-0.004 0.003,-0.0082 0.00426,-0.0112 0.013937,-0.0356 0.027449,-0.07222 0.040961,-0.108333 8.768e-4,-0.003 0.00213,-0.0061 0.00329,-0.0097 0.013511,-0.03662 0.026607,-0.07425 0.039693,-0.111368 8.769e-4,-0.0026 0.00175,-0.005 0.00251,-0.0076 0.013085,-0.03815 0.026181,-0.07627 0.038425,-0.115439 0,-9.73e-4 4.229e-4,-0.0021 8.769e-4,-0.0026 0.1570825,-0.485678 0.2630703,-1.002882 0.3166975,-1.535857 4.228e-4,-0.004 8.777e-4,-0.0082 0.00124,-0.01118 0.00383,-0.03762 0.00713,-0.07528 0.010132,-0.113404 4.219e-4,-0.0082 0.00124,-0.01576 0.00217,-0.02389 0.003,-0.03458 0.00548,-0.06968 0.00755,-0.104238 8.767e-4,-0.01071 0.00176,-0.02238 0.00248,-0.03305 0.00217,-0.03253 0.00383,-0.06561 0.00548,-0.09816 4.218e-4,-0.01322 0.00124,-0.02644 0.00217,-0.03917 0.00176,-0.03153 0.00248,-0.06306 0.00383,-0.09459 4.229e-4,-0.01474 8.778e-4,-0.03002 0.00176,-0.04425 8.777e-4,-0.03052 0.00124,-0.06053 0.00217,-0.09052 4.228e-4,-0.01627 8.777e-4,-0.03253 8.777e-4,-0.04883 4.229e-4,-0.0295 4.229e-4,-0.05799 4.229e-4,-0.08747 0,-0.01728 0,-0.03459 0,-0.05239 0,-0.02847 -4.229e-4,-0.05644 -8.778e-4,-0.08492 0,-0.01831 -4.228e-4,-0.03611 -4.228e-4,-0.05441 -4.208e-4,-0.02796 -0.00124,-0.05544 -0.00217,-0.08339 -4.229e-4,-0.0188 -8.767e-4,-0.03763 -0.00176,-0.05645 -8.767e-4,-0.02694 -0.00217,-0.0534 -0.00331,-0.08086 -8.768e-4,-0.01984 -0.00176,-0.03918 -0.003,-0.05899 -0.00124,-0.02694 -0.003,-0.0529 -0.00455,-0.07935 -0.00124,-0.02032 -0.00248,-0.04068 -0.00383,-0.06053 -0.00176,-0.02644 -0.00383,-0.05238 -0.00589,-0.07832 -0.00176,-0.02085 -0.00331,-0.04119 -0.00517,-0.06204 -0.00217,-0.02594 -0.00455,-0.05138 -0.00713,-0.0768 -0.00176,-0.02136 -0.00424,-0.04222 -0.00631,-0.06307 -0.00248,-0.02543 -0.00548,-0.05086 -0.00842,-0.07577 -0.00251,-0.02185 -0.00513,-0.04323 -0.00755,-0.06461 -0.003,-0.02492 -0.0059,-0.04985 -0.00929,-0.07425 -0.003,-0.02185 -0.0059,-0.04375 -0.0089,-0.06561 -0.00329,-0.02492 -0.00677,-0.04934 -0.01056,-0.07425 -0.00329,-0.02185 -0.00677,-0.04425 -0.010132,-0.06612 -0.00387,-0.02439 -0.00755,-0.04883 -0.011401,-0.07322 -0.00387,-0.02237 -0.00755,-0.04476 -0.011401,-0.06661 -0.00426,-0.02441 -0.00842,-0.04831 -0.01267,-0.07221 -0.00426,-0.02288 -0.00842,-0.04526 -0.01267,-0.06765 -0.00455,-0.02389 -0.0089,-0.04782 -0.013937,-0.07119 -0.00455,-0.02288 -0.00929,-0.04526 -0.013938,-0.06815 -0.00513,-0.0234 -0.00971,-0.04729 -0.015206,-0.07069 -0.00513,-0.02288 -0.010132,-0.04576 -0.015206,-0.06866 -0.00513,-0.02288 -0.010549,-0.04629 -0.016047,-0.06915 -0.00552,-0.02339 -0.010976,-0.04629 -0.01688,-0.06915 -0.00552,-0.02288 -0.010975,-0.04576 -0.01688,-0.06814 -0.0059,-0.02339 -0.011827,-0.04678 -0.018148,-0.06968 -0.0059,-0.02288 -0.011818,-0.04527 -0.018148,-0.06765 -0.0063,-0.0234 -0.01267,-0.04628 -0.019416,-0.06968 -0.0063,-0.02238 -0.01267,-0.04425 -0.018999,-0.06661 -0.00677,-0.0234 -0.013937,-0.04678 -0.021109,-0.07019 -0.00677,-0.02185 -0.013086,-0.04374 -0.019842,-0.0656 -0.00755,-0.02389 -0.015206,-0.0473 -0.022804,-0.0707 -0.00677,-0.02136 -0.013937,-0.0427 -0.020683,-0.0646 -0.00803,-0.02339 -0.016038,-0.04679 -0.024071,-0.07069 -0.00755,-0.02085 -0.014354,-0.04222 -0.021952,-0.06306 -0.00842,-0.0244 -0.017306,-0.04831 -0.026181,-0.07221 -0.00755,-0.02031 -0.01478,-0.04069 -0.022378,-0.06103 -0.0089,-0.02441 -0.018574,-0.04883 -0.027875,-0.07272 -0.00755,-0.02032 -0.015206,-0.04018 -0.022804,-0.05949 -0.00971,-0.02492 -0.019842,-0.04933 -0.029985,-0.07425 -0.00803,-0.01865 -0.015622,-0.03799 -0.023645,-0.05732 -0.010975,-0.02594 -0.021952,-0.05188 -0.033363,-0.0768 -0.00755,-0.0178 -0.015206,-0.0351 -0.022804,-0.0529 -0.01267,-0.0295 -0.026182,-0.05799 -0.039267,-0.08696 -0.00677,-0.0137 -0.01267,-0.02845 -0.019416,-0.04219 C 8.552808,41.518875 8.532531,41.476167 8.511847,41.433436 7.1669757,38.683133 4.5692051,37.851124 2.7108196,39.57515 0.85243366,41.299176 0.436081,44.928276 1.7809934,47.678578 c 0.023225,0.04782 0.046871,0.0951 0.07094,0.140872 0.0076,0.01474 0.015624,0.0295 0.023225,0.04425 0.01689,0.03153 0.033358,0.06307 0.05025,0.09459 0.00887,0.01626 0.018158,0.03307 0.027448,0.04985 0.016468,0.0295 0.032514,0.05799 0.048982,0.08645 0.00929,0.01627 0.018578,0.03253 0.028291,0.04883 0.017735,0.03002 0.035048,0.0595 0.053205,0.0885 0.00844,0.01373 0.01689,0.02795 0.025336,0.04172 0.024491,0.03917 0.048983,0.07729 0.073473,0.115944 0.00211,0.0036 0.00423,0.0072 0.00633,0.01012 0.027025,0.0417 0.054894,0.0824 0.082765,0.123071 0.00802,0.01121 0.015624,0.02237 0.023646,0.03305 0.020269,0.02896 0.040538,0.05746 0.061228,0.08595 0.00971,0.01322 0.019424,0.02694 0.029136,0.03966 0.019423,0.02644 0.038848,0.05239 0.058271,0.07729 0.00971,0.01271 0.019847,0.02594 0.029981,0.03865 0.020692,0.02694 0.041381,0.0529 0.062496,0.0783 0.00887,0.01071 0.017735,0.02185 0.026181,0.03255 0.027025,0.03305 0.054473,0.06561 0.082342,0.09764 0.00253,0.003 0.00464,0.0061 0.00718,0.0086 0.031248,0.03611 0.062496,0.07119 0.094165,0.105779 0.00591,0.0066 0.011823,0.0122 0.017735,0.0188 0.025337,0.02747 0.050671,0.05392 0.076429,0.08086 0.00887,0.0097 0.018158,0.0183 0.027448,0.02796 0.023226,0.02339 0.046027,0.0468 0.069674,0.06969 0.00929,0.0097 0.019001,0.0183 0.028292,0.02796 0.024491,0.02339 0.048982,0.04678 0.073473,0.06915 0.00802,0.0076 0.016046,0.01474 0.024069,0.02238 0.031247,0.02847 0.062496,0.05645 0.094587,0.08391 0.00127,9.74e-4 0.00253,0.0021 0.00338,0.003 0.035048,0.03002 0.070097,0.05898 0.1051438,0.08747 0.0017,0.0014 0.00338,0.003 0.00508,0.0046 0.032091,0.02594 0.064184,0.05086 0.096698,0.07527 0.00718,0.0056 0.014357,0.01073 0.021535,0.01578 0.027448,0.02085 0.055317,0.04069 0.083186,0.0605 0.00802,0.0061 0.016046,0.01121 0.024069,0.01678 0.028293,0.02032 0.057006,0.03967 0.08572,0.059 0.00633,0.004 0.012668,0.0086 0.019424,0.0122 0.1072551,0.07119 0.2166217,0.135784 0.3268326,0.193761 0.00423,0.0021 0.00887,0.0046 0.01309,0.0066 0.032515,0.01678 0.064607,0.03307 0.097121,0.04883 0.0059,0.003 0.012246,0.0061 0.018158,0.009 0.032092,0.01524 0.064607,0.03052 0.096698,0.04425 0.00464,0.0021 0.00929,0.0046 0.014356,0.0066 0.1135892,0.04933 0.2284449,0.09256 0.3433009,0.128156 0.0017,5.1e-4 0.00338,9.74e-4 0.00549,0.0014 0.035892,0.0112 0.071785,0.02187 0.1076773,0.03154 0.00464,9.73e-4 0.00929,0.0026 0.013934,0.0036 0.034626,0.0097 0.068829,0.0178 0.1034547,0.02594 0.00379,9.74e-4 0.00802,0.0021 0.011824,0.003 0.1169673,0.02694 0.2343567,0.04679 0.3517462,0.05951 l 0,0 c 0.6481757,1.849131 1.52733,3.584344 2.6163505,5.151733 3.2493206,4.67828 8.2075476,7.650825 13.8810926,7.526736 5.62076,-0.12256 10.470044,-3.267511 13.60958,-7.987475 2.711782,-4.077649 4.055427,-9.202937 3.667366,-14.468077 l -0.625796,0.397186 3.441877,-2.497548 -4.004333,0.160197 0.94925,-0.107311 c -0.220421,-1.378712 -0.556544,-2.696396 -0.990631,-3.942371 0.168484,0.428718 0.325565,0.867097 0.469134,1.315141 2.798347,-0.571116 5.565447,-0.68554 8.28863,-0.151043 0.771477,0.153076 0.933204,0.41702 0.464491,-0.493815 z m -12.799679,3.703349 c -0.150327,4.243438 -1.599116,6.202419 -3.283952,6.35143 -0.291784,0.02594 -0.581036,-0.003 -0.882953,-0.08339 0.127101,0.01169 0.25378,0.01373 0.380461,0.005 0.947982,-0.0656 1.826292,-0.718089 2.438574,-2.048996 -1.654432,-1.002882 -3.38487,-1.607564 -5.059992,-1.826755 1.684833,0.07272 3.4651,0.599086 5.159647,1.598919 0.215777,-0.520259 0.393129,-1.134093 0.522342,-1.846589 -1.866407,-0.63926 -3.746752,-0.830988 -5.497882,-0.626039 1.72875,-0.355486 3.641185,-0.255806 5.541374,0.37074 0.08615,-0.535514 0.146526,-1.122905 0.176508,-1.764709 0.0114,-0.238514 -0.003,-0.451602 -0.03927,-0.641804 -2.009135,-0.114427 -3.941838,0.243602 -5.656652,0.971863 1.643451,-0.864048 3.568132,-1.320736 5.586133,-1.236826 -0.412129,-1.186475 -1.895967,-1.250044 -3.554621,-0.903205 2.210554,-0.579759 4.250091,-0.552808 4.170283,1.68029 z m 2.44111,-7.055789 c 1.92468,-0.563996 3.721414,-1.511446 5.334888,-2.770136 -1.510441,1.419396 -3.24806,2.506191 -5.138958,3.16783 -0.06418,-0.133245 -0.129212,-0.265977 -0.19593,-0.397694 z m 0.825526,1.842519 c -0.05574,-0.141379 -0.112746,-0.282252 -0.171017,-0.421598 1.999844,-0.298525 3.997577,-0.112402 5.887635,0.505511 -1.862188,-0.401765 -3.791937,-0.442449 -5.716618,-0.08392 z"
475 id="path14"
476 style="fill:#f0a513;fill-opacity:1"
477 inkscape:connector-curvature="0" />
478 <path
479 d="m 17.971864,28.383357 c 3.029325,0.977457 4.82775,4.729117 4.016157,8.37805 -0.214087,0.963215 -0.589481,1.823193 -1.080996,2.549419 -2.202109,-0.672827 -4.51105,0.238008 -5.964907,2.257001 -2.974852,-1.022212 -4.729782,-4.734713 -3.926214,-8.347029 0.811593,-3.648933 3.926636,-5.815407 6.95596,-4.837441 z"
480 id="path16"
481 inkscape:connector-curvature="0"
482 style="fill:#ffffff" />
483 <path
484 d="m 21.46948,31.675787 c 0.688291,1.496188 0.915048,3.303109 0.518541,5.08562 -0.214087,0.963215 -0.589481,1.823193 -1.080996,2.549419 -2.202532,-0.672827 -4.511474,0.238008 -5.965329,2.257001 -1.217389,-0.418038 -2.2304,-1.28768 -2.947405,-2.415671 0.307831,0.161723 0.630018,0.298527 0.964451,0.406343 3.605716,1.163589 7.313197,-1.414313 8.279337,-5.756922 0.157927,-0.710463 0.232246,-1.423974 0.231401,-2.12579 z"
485 id="path18"
486 inkscape:connector-curvature="0"
487 style="fill:#eeeeee" />
488 <path
489 d="m 11.148494,37.665629 c -0.473779,-1.361928 -0.61397,-2.903379 -0.33232,-4.44127 -0.52952,-1.020176 -1.3685584,-1.810482 -2.4090152,-2.146133 -2.1826849,-0.704357 -4.4270197,0.856418 -5.0118558,3.484667 -0.3242991,1.457031 -0.070517,2.936437 0.5915924,4.085786 1.0683288,-0.4694 2.2489802,-0.271571 3.2581915,0.503477 0.4619579,0.354468 0.8876005,0.829465 1.2503252,1.416854 1.1793816,-0.417022 2.1776139,-1.463641 2.6530819,-2.903381 z"
490 id="path20"
491 inkscape:connector-curvature="0"
492 style="fill:#ffffff" />
493 <path
494 d="m 31.2411,51.394259 1.26637,0.637229 -2.465178,-0.01373 c -4.530473,2.179698 -9.426207,2.60994 -12.629927,1.007461 -0.08825,-0.03864 -0.176507,-0.07984 -0.264338,-0.124092 -3.038191,-1.529243 -4.472201,-5.736578 -3.202453,-9.39619 0.218732,-0.6296 0.503339,-1.202239 0.840306,-1.710803 l 0,-5.07e-4 c -1.472857,-0.618925 -2.639574,-1.861849 -3.348978,-3.411437 -0.588215,1.277507 -1.5788467,2.193936 -2.7176907,2.574848 0.033779,0.06461 0.067143,0.129175 0.099655,0.195796 1.3449097,2.750303 0.9285573,6.379402 -0.9298254,8.103935 -0.051515,0.04782 -0.1038771,0.09408 -0.1566605,0.137821 l 0,0 c -0.048979,0.05034 -0.098387,0.09866 -0.1494812,0.145956 -0.7486746,0.694696 -1.6176949,0.974406 -2.4761587,0.880322 l 0,5.08e-4 c 0.6477536,1.848622 1.5273307,3.584344 2.6159279,5.151732 3.2493226,4.678262 8.2075486,7.650298 13.8810926,7.526717 5.620762,-0.12256 10.470046,-3.268018 13.609581,-7.987982 2.123568,-3.192243 3.407673,-7.028327 3.678768,-11.070884 -1.87021,3.185631 -4.634352,5.665888 -7.651009,7.353296 z"
495 id="path183"
496 style="fill:#fdd99b"
497 inkscape:connector-curvature="0" />
498 <path
499 d="m 11.261241,44.175223 c -0.158773,-0.250722 -0.250827,-0.566539 -0.243648,-0.906768 0.01224,-0.584846 0.312898,-1.079675 0.733895,-1.291745 -0.616928,0.507545 -0.839039,1.75098 -0.173129,2.336839 0.277429,0.243604 0.439579,0.574168 0.370749,1.028824 -0.05363,0.355991 -0.262648,0.802509 -0.591168,1.144265 -0.374972,0.389558 -0.833129,0.599593 -1.228791,0.541109 0.37835,-0.112404 0.757541,-0.387016 1.06284,-0.752165 0.26307,-0.314291 0.444644,-0.675369 0.519384,-0.97542 0.14906,-0.596542 -0.181995,-0.701818 -0.450132,-1.124939 l 0,0 z m 1.895122,4.408723 c -0.233935,0.931683 -0.952208,1.610106 -1.802226,1.610106 -0.765564,0 -1.4251397,-0.551279 -1.7190352,-1.342094 0.3783472,0.632143 0.9944302,1.044078 1.6907442,1.044078 0.790057,0 1.477502,-0.530939 1.830517,-1.31209 z"
500 id="path185"
501 inkscape:connector-curvature="0" />
502 <g
503 id="g187"
504 transform="matrix(0.42226435,0,0,0.50856192,-47.726977,-111.72952)">
505 <radialGradient
506 id="radialGradient3241"
507 cx="163.4902"
508 cy="274.86621"
509 r="2.8801"
510 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
511 gradientUnits="userSpaceOnUse">
512 <stop
513 offset="0.0112"
514 style="stop-color:#FAF0BB"
515 id="stop3243" />
516 <stop
517 offset="0.4917"
518 style="stop-color:#FAF0BD"
519 id="stop3245" />
520 <stop
521 offset="0.6648"
522 style="stop-color:#FBF2C5"
523 id="stop3247" />
524 <stop
525 offset="0.7882"
526 style="stop-color:#FCF6D0"
527 id="stop3249" />
528 <stop
529 offset="0.8879"
530 style="stop-color:#FCF8E1"
531 id="stop3251" />
532 <stop
533 offset="0.9723"
534 style="stop-color:#FFFDF7"
535 id="stop3253" />
536 <stop
537 offset="1"
538 style="stop-color:#FFFFFF"
539 id="stop3255" />
540 </radialGradient>
541 <path
542 d="m 189.806,311.298 c -0.681,-0.478 -1.432,-0.68 -2.1,-0.645 -0.633,0.034 -1.217,0.284 -1.625,0.739 -0.408,0.454 -0.59,1.052 -0.559,1.676 0.034,0.653 0.305,1.364 0.834,1.98 0.577,0.671 1.35,1.108 2.143,1.244 0.845,0.145 1.679,-0.06 2.247,-0.657 0.573,-0.604 0.725,-1.448 0.515,-2.282 -0.199,-0.789 -0.713,-1.534 -1.455,-2.055 z"
543 id="path204"
544 style="fill:url(#radialGradient3305)"
545 inkscape:connector-curvature="0" />
546 <radialGradient
547 id="radialGradient3258"
548 cx="155.3242"
549 cy="310.6777"
550 r="4.4867001"
551 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
552 gradientUnits="userSpaceOnUse">
553 <stop
554 offset="0.0112"
555 style="stop-color:#FAF0BB"
556 id="stop3260" />
557 <stop
558 offset="0.4917"
559 style="stop-color:#FAF0BD"
560 id="stop3262" />
561 <stop
562 offset="0.6648"
563 style="stop-color:#FBF2C5"
564 id="stop3264" />
565 <stop
566 offset="0.7882"
567 style="stop-color:#FCF6D0"
568 id="stop3266" />
569 <stop
570 offset="0.8879"
571 style="stop-color:#FCF8E1"
572 id="stop3268" />
573 <stop
574 offset="0.9723"
575 style="stop-color:#FFFDF7"
576 id="stop3270" />
577 <stop
578 offset="1"
579 style="stop-color:#FFFFFF"
580 id="stop3272" />
581 </radialGradient>
582 <path
583 d="m 183.164,274.256 c -0.777,-0.621 -1.774,-0.996 -2.853,-1 -1.077,-0.004 -2.096,0.366 -2.89,0.992 -0.839,0.661 -1.465,1.633 -1.646,2.791 -0.197,1.263 0.167,2.499 0.961,3.449 0.841,1.005 2.124,1.644 3.592,1.617 1.455,-0.026 2.71,-0.702 3.522,-1.716 0.762,-0.951 1.106,-2.168 0.913,-3.4 -0.179,-1.131 -0.786,-2.082 -1.599,-2.733 z"
584 id="path221"
585 style="fill:url(#radialGradient3307)"
586 inkscape:connector-curvature="0" />
587 <radialGradient
588 id="radialGradient3275"
589 cx="170.3125"
590 cy="302.00781"
591 r="5.0811"
592 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
593 gradientUnits="userSpaceOnUse">
594 <stop
595 offset="0.0112"
596 style="stop-color:#FAF0BB"
597 id="stop3277" />
598 <stop
599 offset="0.4917"
600 style="stop-color:#FAF0BD"
601 id="stop3279" />
602 <stop
603 offset="0.6648"
604 style="stop-color:#FBF2C5"
605 id="stop3281" />
606 <stop
607 offset="0.7882"
608 style="stop-color:#FCF6D0"
609 id="stop3283" />
610 <stop
611 offset="0.8879"
612 style="stop-color:#FCF8E1"
613 id="stop3285" />
614 <stop
615 offset="0.9723"
616 style="stop-color:#FFFDF7"
617 id="stop3287" />
618 <stop
619 offset="1"
620 style="stop-color:#FFFFFF"
621 id="stop3289" />
622 </radialGradient>
623 <path
624 d="m 197.254,290.925 c 1.482,-0.322 2.697,-1.225 3.201,-2.604 0.5,-1.367 0.166,-2.845 -0.726,-4.066 -0.835,-1.146 -2.134,-2.023 -3.647,-2.408 -1.389,-0.352 -2.723,-0.223 -3.781,0.238 -1.011,0.439 -1.812,1.196 -2.21,2.198 -0.397,1.001 -0.335,2.12 0.108,3.146 0.468,1.083 1.377,2.112 2.666,2.812 1.407,0.762 2.987,0.989 4.389,0.684 z"
625 id="path238"
626 style="fill:url(#radialGradient3310)"
627 inkscape:connector-curvature="0" />
628 <radialGradient
629 id="radialGradient3292"
630 cx="173.2812"
631 cy="283.68359"
632 r="2.8803999"
633 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
634 gradientUnits="userSpaceOnUse">
635 <stop
636 offset="0.0112"
637 style="stop-color:#FAF0BB"
638 id="stop3294" />
639 <stop
640 offset="0.4917"
641 style="stop-color:#FAF0BD"
642 id="stop3296" />
643 <stop
644 offset="0.6648"
645 style="stop-color:#FBF2C5"
646 id="stop3298" />
647 <stop
648 offset="0.7882"
649 style="stop-color:#FCF6D0"
650 id="stop3300" />
651 <stop
652 offset="0.8879"
653 style="stop-color:#FCF8E1"
654 id="stop3302" />
655 <stop
656 offset="0.9723"
657 style="stop-color:#FFFDF7"
658 id="stop3304" />
659 <stop
660 offset="1"
661 style="stop-color:#FFFFFF"
662 id="stop3306" />
663 </radialGradient>
664 <path
665 d="m 200.538,302.533 c -0.568,-0.598 -1.402,-0.802 -2.248,-0.657 -0.792,0.136 -1.565,0.573 -2.143,1.244 -0.529,0.616 -0.8,1.327 -0.833,1.98 -0.032,0.624 0.15,1.222 0.559,1.676 0.408,0.455 0.991,0.705 1.624,0.739 0.668,0.035 1.42,-0.167 2.101,-0.645 0.741,-0.521 1.256,-1.267 1.454,-2.056 0.21,-0.833 0.058,-1.677 -0.514,-2.281 z"
666 id="path255"
667 style="fill:url(#radialGradient3312)"
668 inkscape:connector-curvature="0" />
669 <radialGradient
670 id="radialGradient3309"
671 cx="148.9492"
672 cy="270.04489"
673 r="2.8799"
674 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
675 gradientUnits="userSpaceOnUse">
676 <stop
677 offset="0.0112"
678 style="stop-color:#FAF0BB"
679 id="stop3311" />
680 <stop
681 offset="0.4917"
682 style="stop-color:#FAF0BD"
683 id="stop3313" />
684 <stop
685 offset="0.6648"
686 style="stop-color:#FBF2C5"
687 id="stop3315" />
688 <stop
689 offset="0.7882"
690 style="stop-color:#FCF6D0"
691 id="stop3317" />
692 <stop
693 offset="0.8879"
694 style="stop-color:#FCF8E1"
695 id="stop3319" />
696 <stop
697 offset="0.9723"
698 style="stop-color:#FFFDF7"
699 id="stop3321" />
700 <stop
701 offset="1"
702 style="stop-color:#FFFFFF"
703 id="stop3323" />
704 </radialGradient>
705 <path
706 d="m 173.958,315.516 c -0.793,0.136 -1.566,0.573 -2.143,1.244 -0.529,0.616 -0.801,1.327 -0.834,1.98 -0.031,0.623 0.15,1.222 0.559,1.676 0.408,0.455 0.991,0.705 1.624,0.738 0.669,0.036 1.42,-0.166 2.101,-0.645 0.741,-0.521 1.256,-1.266 1.454,-2.055 0.211,-0.834 0.06,-1.679 -0.514,-2.282 -0.568,-0.598 -1.402,-0.801 -2.247,-0.656 z"
707 id="path272"
708 style="fill:url(#radialGradient3314)"
709 inkscape:connector-curvature="0" />
710 <radialGradient
711 id="radialGradient3326"
712 cx="148.0723"
713 cy="319.09381"
714 r="3.9265001"
715 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
716 gradientUnits="userSpaceOnUse">
717 <stop
718 offset="0.0112"
719 style="stop-color:#FAF0BB"
720 id="stop3328" />
721 <stop
722 offset="0.4917"
723 style="stop-color:#FAF0BD"
724 id="stop3330" />
725 <stop
726 offset="0.6648"
727 style="stop-color:#FBF2C5"
728 id="stop3332" />
729 <stop
730 offset="0.7882"
731 style="stop-color:#FCF6D0"
732 id="stop3334" />
733 <stop
734 offset="0.8879"
735 style="stop-color:#FCF8E1"
736 id="stop3336" />
737 <stop
738 offset="0.9723"
739 style="stop-color:#FFFDF7"
740 id="stop3338" />
741 <stop
742 offset="1"
743 style="stop-color:#FFFFFF"
744 id="stop3340" />
745 </radialGradient>
746 <path
747 d="m 171.282,272.336 c 1.106,0.549 2.333,0.68 3.407,0.405 1.136,-0.291 2.049,-1.022 2.398,-2.102 0.347,-1.069 0.048,-2.201 -0.675,-3.119 -0.678,-0.861 -1.706,-1.502 -2.885,-1.756 -1.083,-0.233 -2.109,-0.095 -2.914,0.291 -0.768,0.368 -1.365,0.975 -1.645,1.76 -0.278,0.785 -0.198,1.646 0.173,2.426 0.394,0.822 1.125,1.592 2.141,2.095 z"
748 id="path289"
749 style="fill:url(#radialGradient3316)"
750 inkscape:connector-curvature="0" />
751 <radialGradient
752 id="radialGradient3343"
753 cx="112.9551"
754 cy="315.56049"
755 r="3.0683999"
756 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
757 gradientUnits="userSpaceOnUse">
758 <stop
759 offset="0.0112"
760 style="stop-color:#FAF0BB"
761 id="stop3345" />
762 <stop
763 offset="0.4917"
764 style="stop-color:#FAF0BD"
765 id="stop3347" />
766 <stop
767 offset="0.6648"
768 style="stop-color:#FBF2C5"
769 id="stop3349" />
770 <stop
771 offset="0.7882"
772 style="stop-color:#FCF6D0"
773 id="stop3351" />
774 <stop
775 offset="0.8879"
776 style="stop-color:#FCF8E1"
777 id="stop3353" />
778 <stop
779 offset="0.9723"
780 style="stop-color:#FFFDF7"
781 id="stop3355" />
782 <stop
783 offset="1"
784 style="stop-color:#FFFFFF"
785 id="stop3357" />
786 </radialGradient>
787 <path
788 d="m 140.776,270.8 c -0.132,-0.306 -0.298,-0.603 -0.496,-0.884 0,0 -0.001,-10e-4 -0.001,-10e-4 -0.031,0.02 -0.061,0.042 -0.091,0.062 -0.1,0.067 -0.199,0.135 -0.298,0.203 -0.12,0.082 -0.24,0.163 -0.358,0.246 -0.123,0.085 -0.245,0.173 -0.366,0.26 -0.096,0.068 -0.193,0.136 -0.289,0.206 -0.146,0.106 -0.29,0.213 -0.434,0.321 -0.072,0.054 -0.145,0.106 -0.216,0.161 -0.215,0.163 -0.429,0.328 -0.641,0.495 -0.223,0.175 -0.443,0.354 -0.663,0.535 -0.064,0.053 -0.129,0.107 -0.194,0.161 -0.171,0.143 -0.341,0.287 -0.51,0.432 -0.054,0.046 -0.108,0.092 -0.162,0.139 -0.193,0.167 -0.384,0.337 -0.574,0.509 -0.098,0.088 -0.196,0.178 -0.293,0.268 -0.099,0.09 -0.196,0.182 -0.294,0.274 -0.079,0.074 -0.16,0.146 -0.238,0.222 0,0 0.001,0.001 0.001,0.001 0.177,0.156 0.363,0.299 0.555,0.429 0.596,0.402 1.257,0.671 1.927,0.786 1.185,0.202 2.356,-0.083 3.152,-0.922 0.804,-0.847 1.017,-2.032 0.722,-3.202 -0.06,-0.24 -0.14,-0.473 -0.239,-0.701 z"
789 id="path306"
790 style="fill:url(#radialGradient3318)"
791 inkscape:connector-curvature="0" />
792 <radialGradient
793 id="radialGradient3360"
794 cx="132.0938"
795 cy="320.1113"
796 r="4.1712999"
797 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
798 gradientUnits="userSpaceOnUse">
799 <stop
800 offset="0.0112"
801 style="stop-color:#FAF0BB"
802 id="stop3362" />
803 <stop
804 offset="0.4917"
805 style="stop-color:#FAF0BD"
806 id="stop3364" />
807 <stop
808 offset="0.6648"
809 style="stop-color:#FBF2C5"
810 id="stop3366" />
811 <stop
812 offset="0.7882"
813 style="stop-color:#FCF6D0"
814 id="stop3368" />
815 <stop
816 offset="0.8879"
817 style="stop-color:#FCF8E1"
818 id="stop3370" />
819 <stop
820 offset="0.9723"
821 style="stop-color:#FFFDF7"
822 id="stop3372" />
823 <stop
824 offset="1"
825 style="stop-color:#FFFFFF"
826 id="stop3374" />
827 </radialGradient>
828 <path
829 d="m 160.2,265.6 c -0.85,-0.392 -1.938,-0.592 -3.115,-0.521 -1.177,0.07 -2.29,0.405 -3.157,0.906 -0.916,0.53 -1.6,1.269 -1.798,2.11 -0.216,0.917 0.182,1.777 1.05,2.403 0.918,0.663 2.32,1.032 3.923,0.914 1.588,-0.118 2.959,-0.687 3.847,-1.468 0.833,-0.732 1.209,-1.627 0.998,-2.496 -0.195,-0.799 -0.859,-1.438 -1.748,-1.848 z"
830 id="path323"
831 style="fill:url(#radialGradient3320)"
832 inkscape:connector-curvature="0" />
833 <radialGradient
834 id="radialGradient3377"
835 cx="147.44189"
836 cy="301.21091"
837 r="2.5313001"
838 gradientTransform="matrix(1,0,0,-1,24.9448,588.3594)"
839 gradientUnits="userSpaceOnUse">
840 <stop
841 offset="0.0112"
842 style="stop-color:#FAF0BB"
843 id="stop3379" />
844 <stop
845 offset="0.4917"
846 style="stop-color:#FAF0BD"
847 id="stop3381" />
848 <stop
849 offset="0.6648"
850 style="stop-color:#FBF2C5"
851 id="stop3383" />
852 <stop
853 offset="0.7882"
854 style="stop-color:#FCF6D0"
855 id="stop3385" />
856 <stop
857 offset="0.8879"
858 style="stop-color:#FCF8E1"
859 id="stop3387" />
860 <stop
861 offset="0.9723"
862 style="stop-color:#FFFDF7"
863 id="stop3389" />
864 <stop
865 offset="1"
866 style="stop-color:#FFFFFF"
867 id="stop3391" />
868 </radialGradient>
869 <path
870 d="m 173.961,289.2 c 0.657,-0.143 1.12,-0.506 1.265,-1.029 0.133,-0.48 -0.03,-1.015 -0.381,-1.495 -0.335,-0.458 -0.853,-0.886 -1.498,-1.196 -0.645,-0.31 -1.333,-0.461 -1.94,-0.451 -0.643,0.011 -1.223,0.2 -1.576,0.587 -0.385,0.422 -0.428,0.996 -0.152,1.584 0.291,0.622 0.925,1.231 1.811,1.642 0.876,0.408 1.77,0.51 2.471,0.358 z"
871 id="path340"
872 style="fill:url(#radialGradient3322)"
873 inkscape:connector-curvature="0" />
874 </g>
875 <path
876 d="m 32.300561,46.79686 c -0.244913,-0.207495 -0.516006,-0.294969 -0.756275,-0.27971 -0.2276,0.01425 -0.437888,0.12307 -0.584836,0.320395 -0.147371,0.197321 -0.212822,0.456181 -0.201419,0.726735 0.01182,0.283777 0.109788,0.591457 0.300228,0.85845 0.207332,0.290901 0.486027,0.480592 0.771056,0.539586 0.304451,0.06256 0.605105,-0.02543 0.809057,-0.284794 0.206488,-0.26191 0.260961,-0.628075 0.185374,-0.989662 -0.07136,-0.342262 -0.256312,-0.665199 -0.523185,-0.891 z"
877 id="path347"
878 style="fill:#000000"
879 inkscape:connector-curvature="0" />
880 <g
881 id="g349"
882 transform="matrix(0.42226435,0,0,0.50856192,-47.726977,-111.72952)">
883 <path
884 d="m 168.559,264.427 c 4.145,0.407 8.127,1.382 11.858,2.845 l 0.623,-0.856 c -3.919,-1.741 -8.161,-2.906 -12.604,-3.384 l 0.123,1.395 z"
885 id="path351"
886 inkscape:connector-curvature="0"
887 style="fill:#ffffff" />
888 <path
889 d="m 145.971,266.73 1.059,0.888 c 5.193,-2.147 10.87,-3.351 16.738,-3.403 l 0.009,-0.038 0.435,-1.388 c -0.059,0 -0.116,-0.002 -0.175,-0.002 -6.387,-0.024 -12.545,1.39 -18.066,3.943 z"
890 id="path353"
891 inkscape:connector-curvature="0"
892 style="fill:#ffffff" />
893 <path
894 d="m 185.374,269.579 c 0.97,0.527 1.917,1.087 2.84,1.683 l 0.494,-0.416 c -1.011,-0.738 -2.058,-1.431 -3.138,-2.078 l -0.196,0.811 z"
895 id="path355"
896 inkscape:connector-curvature="0"
897 style="fill:#ffffff" />
898 <path
899 d="m 190.66,272.366 -0.224,0.429 c 0.458,0.338 0.91,0.683 1.354,1.038 1.494,1.193 2.916,2.493 4.25,3.889 -1.633,-1.962 -3.44,-3.752 -5.38,-5.356 z"
900 id="path357"
901 inkscape:connector-curvature="0"
902 style="fill:#ffffff" />
903 <path
904 d="m 140.28,269.916 c 0.198,0.281 0.363,0.578 0.496,0.884 0.84,-0.514 1.699,-1.002 2.575,-1.462 l -0.52,-0.994 c -0.871,0.494 -1.721,1.019 -2.551,1.572 z"
905 id="path359"
906 inkscape:connector-curvature="0"
907 style="fill:#ffffff" />
908 <path
909 d="m 133.625,275.426 0.562,0.314 c 0.338,-0.307 0.681,-0.608 1.028,-0.904 -0.192,-0.129 -0.378,-0.272 -0.555,-0.429 -0.35,0.333 -0.696,0.673 -1.035,1.019 z"
910 id="path361"
911 inkscape:connector-curvature="0"
912 style="fill:#ffffff" />
913 <path
914 d="m 130.152,279.456 c 0.139,-0.009 0.279,-0.015 0.419,-0.019 0.538,-0.62 1.091,-1.224 1.66,-1.81 l -0.295,-0.374 c -0.618,0.713 -1.212,1.447 -1.784,2.203 z"
915 id="path363"
916 inkscape:connector-curvature="0"
917 style="fill:#ffffff" />
918 </g>
919 <path
920 d="m 11.717707,25.989048 c -0.05574,-0.15562 -0.125834,-0.306666 -0.209444,-0.44957 -0.01309,0.01012 -0.02618,0.02032 -0.03885,0.03052 -0.04223,0.03408 -0.08403,0.06866 -0.125835,0.10324 -0.05067,0.0417 -0.101339,0.08289 -0.151171,0.125104 -0.05194,0.04324 -0.103455,0.08798 -0.154549,0.132228 -0.04054,0.03459 -0.0815,0.06916 -0.122034,0.104767 -0.06165,0.0534 -0.122457,0.108333 -0.183263,0.16325 -0.03041,0.02747 -0.06122,0.05392 -0.09122,0.08188 -0.09078,0.08288 -0.181151,0.166809 -0.27067,0.251737 -0.09416,0.0895 -0.187063,0.180031 -0.279961,0.272083 -0.02703,0.02695 -0.05447,0.05442 -0.08192,0.08188 -0.07221,0.07272 -0.1439917,0.145958 -0.2153547,0.219699 -0.02281,0.02339 -0.0456,0.04679 -0.068411,0.07019 -0.081499,0.08492 -0.1621494,0.171895 -0.24238,0.258858 -0.041385,0.04477 -0.08276,0.09052 -0.1237229,0.136294 -0.041799,0.04628 -0.08276,0.09308 -0.1241459,0.139347 -0.033364,0.03762 -0.066717,0.07527 -0.1000776,0.113908 0.074741,0.07935 0.1532821,0.152062 0.2343573,0.218175 C 9.5506288,27.855494 9.7347353,27.672921 9.9217999,27.495432 10.4927,26.95178 11.092737,26.44983 11.717689,25.989072 z"
921 id="path365"
922 inkscape:connector-curvature="0"
923 style="fill:#eeeeee" />
924 <path
925 d="m 28.381526,27.537111 c 0.388483,0.0014 0.747409,0.164265 1.026947,0.433802 0.293051,0.282252 0.512205,0.694697 0.575969,1.184949 0.06968,0.534499 -0.05447,1.061878 -0.328523,1.474322 -0.292629,0.439906 -0.744451,0.732838 -1.26806,0.744027 -0.528674,0.01119 -0.990631,-0.26547 -1.292973,-0.70131 -0.286295,-0.411932 -0.417197,-0.947959 -0.345834,-1.495681 0.06503,-0.501949 0.290517,-0.923546 0.592437,-1.209867 0.28545,-0.271063 0.652399,-0.431769 1.040037,-0.430242 z"
926 id="path372"
927 style="fill:#000000"
928 inkscape:connector-curvature="0" />
929 <path
930 d="m 13.466305,55.28374 c 0.178195,0.09256 0.329787,0.214614 0.43662,0.342772 0.111901,0.134768 0.178619,0.281236 0.168063,0.408885 -0.0114,0.139346 -0.111902,0.231394 -0.271518,0.261399 -0.170172,0.03153 -0.401994,-0.0082 -0.64353,-0.129175 -0.244069,-0.12256 -0.433666,-0.295472 -0.53712,-0.467367 -0.09797,-0.162232 -0.114433,-0.316834 -0.03674,-0.425668 0.07093,-0.100193 0.209021,-0.143413 0.37117,-0.13782 0.152859,0.005 0.334856,0.05491 0.513051,0.146974 l 0,0 z m -2.368059,-0.261399 c 0.05025,0.0122 0.09585,0.04017 0.130479,0.0768 0.03588,0.03815 0.06165,0.08797 0.06671,0.140364 0.0055,0.05696 -0.01435,0.10731 -0.05278,0.141381 -0.04097,0.0356 -0.101763,0.05188 -0.169749,0.03611 -0.06883,-0.01525 -0.127102,-0.05848 -0.163417,-0.113404 -0.03463,-0.05139 -0.04772,-0.110861 -0.03463,-0.164774 0.01183,-0.04984 0.04392,-0.08594 0.0853,-0.10578 0.03885,-0.01831 0.08741,-0.02339 0.138081,-0.01071 l 0,0 z m 3.807979,2.368373 c 0.09627,0.02389 0.183263,0.07728 0.248714,0.147481 0.06925,0.07322 0.117813,0.167318 0.127101,0.267506 0.01013,0.109332 -0.02745,0.204948 -0.100915,0.270045 -0.07854,0.06866 -0.194242,0.09866 -0.324299,0.06968 -0.131324,-0.03002 -0.24238,-0.111886 -0.311631,-0.216139 -0.06545,-0.09816 -0.09122,-0.21156 -0.0663,-0.314799 0.02281,-0.09459 0.08446,-0.163757 0.162995,-0.2019 0.07515,-0.03611 0.16806,-0.04576 0.264336,-0.02185 l 0,0 z m -2.357501,-1.035942 c -0.09333,-0.04831 -0.188754,-0.07425 -0.269405,-0.0768 -0.08487,-0.003 -0.157504,0.01983 -0.194242,0.07222 -0.04054,0.05696 -0.03209,0.137821 0.01942,0.222749 0.05405,0.09052 0.153704,0.18054 0.281651,0.245128 0.126679,0.06356 0.247869,0.08391 0.337388,0.06765 0.08362,-0.01576 0.136392,-0.06407 0.142304,-0.137313 0.0055,-0.06713 -0.02956,-0.143414 -0.08783,-0.214102 -0.05658,-0.06714 -0.135969,-0.13121 -0.22929,-0.179526 z"
931 id="path374"
932 inkscape:connector-curvature="0"
933 style="fill:#d9bb7a" />
934 <path
935 d="m 32.89722,32.895826 c 0.143148,-0.434312 0.431555,-0.762333 0.795547,-0.953043 0.380884,-0.199865 0.861841,-0.255808 1.361803,-0.10325 0.544721,0.166808 1.012166,0.547722 1.313242,1.044079 0.320921,0.529412 0.440844,1.170201 0.26096,1.762675 -0.181574,0.59807 -0.618618,0.989661 -1.15236,1.129517 -0.504607,0.132224 -1.073818,0.03356 -1.579691,-0.297003 -0.464491,-0.303099 -0.791747,-0.749617 -0.960229,-1.219019 -0.160039,-0.444994 -0.182419,-0.929651 -0.03927,-1.363962 z"
936 id="path381"
937 style="fill:#000000"
938 inkscape:connector-curvature="0" />
939 <path
940 d="m 35.093418,44.08063 c -0.146948,-0.197323 -0.212399,-0.456178 -0.200998,-0.726732 0.01182,-0.28378 0.109367,-0.591461 0.299807,-0.858457 0.207754,-0.290895 0.486028,-0.480589 0.771477,-0.540093 0.304453,-0.06256 0.604685,0.02594 0.809059,0.285306 0.206487,0.261909 0.26096,0.628075 0.184952,0.989659 -0.07137,0.342262 -0.256313,0.6652 -0.523607,0.891001 -0.244913,0.207492 -0.515586,0.294965 -0.755853,0.27971 -0.227601,-0.01423 -0.437466,-0.123072 -0.584837,-0.320394 z"
941 id="path388"
942 style="fill:#000000"
943 inkscape:connector-curvature="0" />
944 <path
945 d="m 24.819304,51.017414 c -0.147371,-0.197322 -0.212821,-0.456179 -0.201421,-0.727243 0.01183,-0.283269 0.10979,-0.590948 0.30023,-0.858455 0.207333,-0.290896 0.485604,-0.481098 0.771055,-0.540089 0.304453,-0.06256 0.605106,0.02594 0.809059,0.285303 0.206487,0.261908 0.260959,0.628074 0.184952,0.989661 -0.07136,0.342263 -0.256314,0.6652 -0.523608,0.891002 -0.24449,0.207493 -0.515584,0.294964 -0.755854,0.279709 -0.2276,-0.01425 -0.437465,-0.123071 -0.584413,-0.319888 z"
946 id="path395"
947 style="fill:#000000"
948 inkscape:connector-curvature="0" />
949 <path
950 d="m 23.786446,24.445052 c 0.102186,-0.347855 0.322609,-0.616885 0.605104,-0.779624 0.296007,-0.170876 0.673933,-0.232414 1.072129,-0.128666 0.433667,0.112897 0.812438,0.396678 1.061996,0.778609 0.266026,0.406849 0.376235,0.908289 0.24829,1.382269 -0.12879,0.47805 -0.464913,0.802512 -0.882532,0.931685 -0.395661,0.12205 -0.84664,0.06357 -1.254126,-0.17952 -0.374125,-0.222751 -0.642686,-0.563996 -0.787099,-0.928635 -0.137237,-0.346331 -0.166373,-0.728261 -0.06377,-1.076118 z"
951 id="path402"
952 style="fill:#000000"
953 inkscape:connector-curvature="0" />
954 <path
955 d="m 9.3572511,27.571182 c 0.2537814,0.256316 0.5518992,0.424651 0.8555069,0.487204 0.426486,0.08747 0.848329,-0.03611 1.135047,-0.399731 0.28925,-0.367181 0.366103,-0.880828 0.259692,-1.388372 -0.0456,-0.217666 -0.123723,-0.429227 -0.230557,-0.625532 -0.344568,0.281745 -0.680268,0.577726 -1.006255,0.886932 -0.347524,0.330057 -0.6857564,0.676897 -1.0134339,1.039499 z"
956 id="path409"
957 style="fill:#000000"
958 inkscape:connector-curvature="0" />
959 <path
960 d="m 9.3572511,27.571182 c 0.081923,0.08289 0.1684839,0.15664 0.2584255,0.220208 0.1013389,-0.100194 0.2031087,-0.199865 0.3061417,-0.296999 0.5244517,-0.497883 1.0733947,-0.962708 1.6434517,-1.391936 -0.04604,-0.15867 -0.109367,-0.312257 -0.188752,-0.457195 l 0,0 c -0.02997,0.02442 -0.05996,0.04933 -0.08995,0.07425 -0.01942,0.01628 -0.03927,0.03255 -0.05869,0.04883 -0.03336,0.02747 -0.0663,0.05545 -0.09923,0.08341 l -0.04519,0.03865 c -0.03758,0.03205 -0.07474,0.06407 -0.111899,0.09613 l -0.02997,0.02594 c -0.04139,0.03611 -0.08235,0.07221 -0.123301,0.108332 l -0.02026,0.01832 c -0.04392,0.03918 -0.08741,0.07781 -0.130901,0.117485 l -0.01309,0.01169 c -0.04603,0.04223 -0.09206,0.08442 -0.13808,0.12714 l -0.0018,0.0014 c -0.04815,0.04476 -0.09585,0.0895 -0.143569,0.134769 -0.07685,0.07322 -0.15286,0.146467 -0.228867,0.221226 l -0.01098,0.01072 c -0.02026,0.02032 -0.04097,0.04018 -0.06123,0.06051 l -0.01858,0.01882 -0.05236,0.05238 -0.02956,0.03002 -0.04307,0.04376 -0.03801,0.03865 -0.01605,0.01627 -0.01562,0.01627 -0.04771,0.04883 -0.01562,0.01627 C 9.6459492,27.256383 9.50069,27.412511 9.3571211,27.571183 z"
961 id="path411"
962 inkscape:connector-curvature="0"
963 style="fill:#888678" />
964 <path
965 d="m 18.571057,23.295194 c 0.423955,-0.03051 0.815816,0.05645 1.121534,0.226311 0.320077,0.177997 0.559079,0.455163 0.629176,0.800985 0.07601,0.376844 -0.05954,0.764369 -0.359348,1.082221 -0.319232,0.338701 -0.812859,0.585354 -1.385028,0.636719 -0.577235,0.05138 -1.081841,-0.108827 -1.412472,-0.39617 -0.312477,-0.271573 -0.456047,-0.644349 -0.378351,-1.042043 0.07136,-0.364639 0.317965,-0.685034 0.647333,-0.914395 0.312897,-0.217665 0.713204,-0.363114 1.137156,-0.393628 z"
966 id="path418"
967 style="fill:#000000"
968 inkscape:connector-curvature="0" />
969 <path
970 d="m 25.268593,33.539157 c 0.209865,0.121549 0.37835,0.289372 0.487716,0.468895 0.11401,0.188169 0.167216,0.397695 0.123723,0.585864 -0.04687,0.20495 -0.198043,0.347856 -0.412131,0.403289 -0.228021,0.05951 -0.519383,0.01933 -0.804835,-0.139854 -0.288406,-0.160707 -0.494471,-0.399731 -0.589482,-0.643842 -0.08995,-0.230376 -0.07601,-0.455669 0.04941,-0.620952 0.114856,-0.152061 0.304451,-0.226311 0.51305,-0.230379 0.198043,-0.0036 0.422688,0.05543 0.632553,0.176979 z"
971 id="path425"
972 style="fill:#000000"
973 inkscape:connector-curvature="0" />
974 <polygon
975 points="188.385,321.662 183.827,319.426 190.01,322.008 182.526,321.973 "
976 id="polygon427"
977 transform="matrix(0.42226435,0,0,0.50856192,-47.726977,-111.72952)" />
978 <polygon
979 points="181.161,310.218 176.159,311.094 182.677,309.541 176.606,313.919 "
980 id="polygon429"
981 transform="matrix(0.42226435,0,0,0.50856192,-47.726977,-111.72952)" />
982 <polygon
983 points="188.996,281.271 183.955,287.956 191.129,279.553 180.144,285.178 "
984 id="polygon431"
985 transform="matrix(0.42226435,0,0,0.50856192,-47.726977,-111.72952)" />
986 <path
987 d="m 35.589578,54.524966 c -0.122034,0.197832 -0.247447,0.39312 -0.376237,0.586373 -3.139958,4.719964 -7.989242,7.864909 -13.609581,7.987982 C 15.929794,63.222902 10.97199,60.250356 7.7226683,55.572603 7.5229375,55.285266 7.3303849,54.991318 7.1445881,54.693299 c 3.5503959,4.555698 8.6741509,7.392458 14.4832419,7.265826 5.617804,-0.123069 10.532541,-3.002548 13.961748,-7.434159 z"
988 id="path440"
989 style="fill:#d9bb7a"
990 inkscape:connector-curvature="0" />
991 <path
992 d="m 16.345302,52.251694 c -2.117655,-1.929991 -2.971052,-5.408047 -1.900189,-8.495019 1.184029,-3.41245 4.302452,-5.144614 7.182295,-4.121385 -2.791167,-0.695713 -5.69128,1.060859 -6.831394,4.34617 -1.023146,2.94966 -0.321343,6.249209 1.549288,8.270234 z"
993 id="path442"
994 inkscape:connector-curvature="0"
995 style="fill:#ffffff" />
996 <path
997 d="m 7.9004418,49.211004 c 1.5839109,-1.826246 1.8765395,-5.188352 0.611861,-7.774387 -0.9606515,-1.964067 -2.560189,-2.949661 -4.0731622,-2.724366 1.4428771,-0.03307 2.911513,0.974913 3.8219146,2.837267 1.2266751,2.507718 1.0299008,5.725391 -0.3606134,7.661486 z"
998 id="path444"
999 inkscape:connector-curvature="0"
1000 style="fill:#ffffff" />
1001 <path
1002 d="m 46.744961,35.073491 -0.497006,-0.879306 c -0.446333,-0.789288 -2.616772,-1.271403 -3.063106,-2.060692 -0.04897,-0.08645 -0.08995,-0.178504 -0.124145,-0.273607 0.02111,0.05392 0.04434,0.106285 0.07093,0.157655 0.411286,0.799459 2.442378,0.780134 2.853664,1.579592 l 0.759653,1.476358 0,0 z m -3.840919,-4.235306 c -0.02154,-1.142737 0.276584,-2.476187 -0.211554,-3.339725 -0.684068,-1.210379 -3.109133,-1.708769 -3.070285,-3.678937 0.02618,-1.300901 0.05531,-2.044928 -0.877888,-0.830484 -0.474202,0.616888 -0.933204,1.256658 -1.378271,1.918806 0.532898,-0.895579 1.084376,-1.758098 1.656966,-2.58553 0.921382,-1.331414 0.877043,-0.549754 0.825104,0.815225 -0.02492,0.63723 0.05786,1.381764 0.330634,1.912701 0.487293,0.947452 2.164949,1.469236 2.652243,2.416687 0.464492,0.901679 0.07769,2.233605 0.07305,3.371257 z"
1003 id="path446"
1004 inkscape:connector-curvature="0"
1005 style="fill:#ffffff" />
1006 <path
1007 d="m 16.756588,33.897186 c 0.357235,-0.248687 0.77781,-0.246145 1.121111,-0.03865 -0.09501,0.0122 -0.189596,0.04832 -0.27785,0.109346 -0.338655,0.235464 -0.455199,0.757757 -0.25927,1.165625 0.19551,0.408372 0.629174,0.548229 0.96783,0.312255 0.08783,-0.06155 0.160883,-0.14189 0.217467,-0.234955 -0.02237,0.461773 -0.230979,0.901679 -0.588638,1.150367 -0.564566,0.39261 -1.287061,0.15918 -1.613471,-0.520769 -0.325145,-0.680454 -0.131747,-1.550096 0.432821,-1.943214 l 0,0 z m -8.4625961,1.183931 c 0.2575811,-0.179014 0.5603435,-0.177488 0.8077901,-0.02795 -0.068836,0.009 -0.1368128,0.03458 -0.2001525,0.07882 -0.2440687,0.169354 -0.327677,0.545687 -0.1866399,0.839639 0.1406128,0.293947 0.453088,0.394643 0.6971553,0.224782 0.063334,-0.04425 0.1161241,-0.102217 0.1570835,-0.16935 C 9.5527694,36.35966 9.4024339,36.676495 9.1452751,36.855507 8.7386349,37.138248 8.2179844,36.970431 7.983206,36.480169 7.7475821,35.990933 7.887351,35.363875 8.2939919,35.081114 z"
1008 id="path448"
1009 inkscape:connector-curvature="0" />
1010 <path
1011 d="m 11.148494,37.665629 c -0.260113,-0.748095 -0.420152,-1.550096 -0.46449,-2.376002 -0.533741,1.967118 -1.8647168,3.382956 -3.4389171,3.862529 0.4619579,0.354468 0.8876005,0.829465 1.2503252,1.416854 1.1793816,-0.417022 2.1776139,-1.463641 2.6530819,-2.903381 z"
1012 id="path450"
1013 inkscape:connector-curvature="0"
1014 style="fill:#eeeeee" />
1015 <path
1016 d="m 3.5654754,33.263516 c -0.2884063,0.139348 -0.5160068,0.432279 -0.656621,0.92355 -0.6697112,2.341929 -0.5459877,4.035438 0.033358,5.072397 C 3.09465,39.150129 3.25131,39.055528 3.4109259,38.975177 3.537183,38.886186 3.6659737,38.807859 3.7972979,38.739713 3.1153408,37.498312 2.8611376,35.923805 3.2065499,34.3732 3.2935369,33.980083 3.4151486,33.609339 3.5654746,33.263516 z"
1017 id="path457"
1018 style="fill:#f0a513"
1019 inkscape:connector-curvature="0" />
1020 <path
1021 d="m 9.6346789,48.851958 c 0.7959681,1.053234 2.8688621,0.917445 3.5212611,-0.268012 -0.352592,0.781151 -1.04046,1.31209 -1.830517,1.31209 -0.695891,0 -1.312395,-0.411935 -1.6907441,-1.044078 z"
1022 id="path459"
1023 inkscape:connector-curvature="0"
1024 style="fill:#ffffff" />
1025 </g>
1026 </g>
1027 </svg>
0 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
1 <!-- Created with Inkscape (http://www.inkscape.org/) -->
2
3 <svg
4 xmlns:dc="http://purl.org/dc/elements/1.1/"
5 xmlns:cc="http://creativecommons.org/ns#"
6 xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
7 xmlns:svg="http://www.w3.org/2000/svg"
8 xmlns="http://www.w3.org/2000/svg"
9 xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
10 xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
11 width="16"
12 height="16"
13 id="svg3465"
14 version="1.1"
15 inkscape:version="0.48.3.1 r9886"
16 sodipodi:docname="diodon-panel.svg">
17 <defs
18 id="defs3467" />
19 <sodipodi:namedview
20 id="base"
21 pagecolor="#ffffff"
22 bordercolor="#666666"
23 borderopacity="1.0"
24 inkscape:pageopacity="0.0"
25 inkscape:pageshadow="2"
26 inkscape:zoom="33.136364"
27 inkscape:cx="5.6886145"
28 inkscape:cy="11"
29 inkscape:document-units="px"
30 inkscape:current-layer="layer1"
31 showgrid="true"
32 inkscape:window-width="1600"
33 inkscape:window-height="876"
34 inkscape:window-x="0"
35 inkscape:window-y="24"
36 inkscape:window-maximized="1">
37 <inkscape:grid
38 type="xygrid"
39 id="grid3491"
40 empspacing="5"
41 visible="true"
42 enabled="true"
43 snapvisiblegridlinesonly="true" />
44 </sodipodi:namedview>
45 <metadata
46 id="metadata3470">
47 <rdf:RDF>
48 <cc:Work
49 rdf:about="">
50 <dc:format>image/svg+xml</dc:format>
51 <dc:type
52 rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
53 <dc:title />
54 </cc:Work>
55 </rdf:RDF>
56 </metadata>
57 <g
58 inkscape:label="Layer 1"
59 inkscape:groupmode="layer"
60 id="layer1"
61 transform="translate(0,-1036.3622)">
62 <path
63 inkscape:connector-curvature="0"
64 d="m 5.5599543,1049.2716 c -0.8232063,0.813 -2.1206548,0.7711 -2.9329794,-0.03 -0.8091263,-0.8039 -0.851687,-2.0892 -0.030879,-2.9046 l 6.7730044,-6.7072 c 1.0705697,-1.0569 2.7552197,-1.0036 3.8137877,0.042 1.055049,1.0489 1.108809,2.7171 0.04208,3.7772 l -5.6442016,5.5896 c -0.1246407,0.1236 -0.3267204,0.1236 -0.4508812,0 -0.1248014,-0.1236 -0.1252814,-0.3235 -4.866e-4,-0.447 l 5.6437194,-5.5899 c 0.812806,-0.8059 0.780006,-2.0625 -0.04176,-2.883 -0.827365,-0.8133 -2.096655,-0.8455 -2.9109021,-0.041 l -6.7730045,6.7066 c -0.5652841,0.5623 -0.544164,1.4353 0.030879,2.0105 0.5817645,0.5707 1.4625706,0.5906 2.0307346,0.031 l 5.643719,-5.5891 c 0.293441,-0.2903 0.282722,-0.7592 -0.04592,-1.0913 -0.334722,-0.3247 -0.8081661,-0.3355 -1.1016081,-0.044 l -5.0793948,5.0301 c -0.1246406,0.1241 -0.326722,0.1235 -0.4513626,0 -0.1246415,-0.1235 -0.1251215,-0.3239 -4.848e-4,-0.4473 l 5.0803532,-5.0299 c 0.561604,-0.5546 1.4512121,-0.5006 2.0038581,0.045 0.55184,0.5481 0.605602,1.4294 0.0464,1.9854 l -5.6446796,5.5891 z"
65 style="fill:#dfdbd2;fill-opacity:1;fill-rule:nonzero;stroke:none"
66 id="path108" />
67 </g>
68 </svg>
0 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
1 <!-- Created with Inkscape (http://www.inkscape.org/) -->
2
3 <svg
4 xmlns:dc="http://purl.org/dc/elements/1.1/"
5 xmlns:cc="http://creativecommons.org/ns#"
6 xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
7 xmlns:svg="http://www.w3.org/2000/svg"
8 xmlns="http://www.w3.org/2000/svg"
9 xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
10 xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
11 width="22"
12 height="22"
13 id="svg3465"
14 version="1.1"
15 inkscape:version="0.48.3.1 r9886"
16 sodipodi:docname="diodon-panel.svg">
17 <defs
18 id="defs3467" />
19 <sodipodi:namedview
20 id="base"
21 pagecolor="#ffffff"
22 bordercolor="#666666"
23 borderopacity="1.0"
24 inkscape:pageopacity="0.0"
25 inkscape:pageshadow="2"
26 inkscape:zoom="33.136364"
27 inkscape:cx="4.4814815"
28 inkscape:cy="11"
29 inkscape:document-units="px"
30 inkscape:current-layer="layer1"
31 showgrid="true"
32 inkscape:window-width="1600"
33 inkscape:window-height="876"
34 inkscape:window-x="0"
35 inkscape:window-y="24"
36 inkscape:window-maximized="1"
37 showguides="true"
38 inkscape:guide-bbox="true">
39 <inkscape:grid
40 type="xygrid"
41 id="grid3491"
42 empspacing="5"
43 visible="true"
44 enabled="true"
45 snapvisiblegridlinesonly="true" />
46 </sodipodi:namedview>
47 <metadata
48 id="metadata3470">
49 <rdf:RDF>
50 <cc:Work
51 rdf:about="">
52 <dc:format>image/svg+xml</dc:format>
53 <dc:type
54 rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
55 <dc:title />
56 </cc:Work>
57 </rdf:RDF>
58 </metadata>
59 <g
60 inkscape:label="Layer 1"
61 inkscape:groupmode="layer"
62 id="layer1"
63 transform="translate(0,-1030.3622)">
64 <path
65 inkscape:connector-curvature="0"
66 d="m 7.1365954,1049.1727 c -1.3034099,1.2933 -3.357704,1.2267 -4.643885,-0.048 -1.2811166,-1.2786 -1.3485043,-3.3235 -0.048893,-4.6207 l 10.7239266,-10.6701 c 1.695066,-1.6812 4.362429,-1.5964 6.038495,0.067 1.670493,1.6687 1.755614,4.3227 0.06663,6.0091 l -8.936649,8.892 c -0.197348,0.1967 -0.5173082,0.1967 -0.7138962,0 -0.197601,-0.1967 -0.198361,-0.5144 -7.7e-4,-0.711 l 8.9358872,-8.8928 c 1.286943,-1.2821 1.23501,-3.2813 -0.06612,-4.5864 -1.309995,-1.2939 -3.319703,-1.3451 -4.608925,-0.065 l -10.7239271,10.6694 c -0.8950333,0.8943 -0.8615932,2.2834 0.048893,3.1983 0.9211278,0.9076 2.3157375,0.9394 3.2153307,0.049 l 8.9358884,-8.8914 c 0.464616,-0.4618 0.447643,-1.2079 -0.07271,-1.7359 -0.529977,-0.5167 -1.279595,-0.5339 -1.744211,-0.07 l -8.042377,8.0018 c -0.1973478,0.1975 -0.5173097,0.1968 -0.7146575,0 -0.1973489,-0.1963 -0.1981089,-0.515 -7.674e-4,-0.7116 l 8.0438949,-8.0016 c 0.889206,-0.8823 2.29775,-0.7964 3.172771,0.071 0.87375,0.8719 0.958873,2.2739 0.07347,3.1585 l -8.9374081,8.8914 z"
67 style="fill:#dfdbd2;fill-opacity:1;fill-rule:nonzero;stroke:none"
68 id="path108" />
69 </g>
70 </svg>
0 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
1 <!-- Created with Inkscape (http://www.inkscape.org/) -->
2
3 <svg
4 xmlns:dc="http://purl.org/dc/elements/1.1/"
5 xmlns:cc="http://creativecommons.org/ns#"
6 xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
7 xmlns:svg="http://www.w3.org/2000/svg"
8 xmlns="http://www.w3.org/2000/svg"
9 xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
10 xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
11 width="24"
12 height="24"
13 id="svg3465"
14 version="1.1"
15 inkscape:version="0.48.4 r9939"
16 sodipodi:docname="diodon-panel.svg">
17 <defs
18 id="defs3467" />
19 <sodipodi:namedview
20 id="base"
21 pagecolor="#ffffff"
22 bordercolor="#666666"
23 borderopacity="1.0"
24 inkscape:pageopacity="0.0"
25 inkscape:pageshadow="2"
26 inkscape:zoom="33.136364"
27 inkscape:cx="5.6886145"
28 inkscape:cy="11.36778"
29 inkscape:document-units="px"
30 inkscape:current-layer="layer1"
31 showgrid="true"
32 inkscape:window-width="1920"
33 inkscape:window-height="1056"
34 inkscape:window-x="0"
35 inkscape:window-y="24"
36 inkscape:window-maximized="1">
37 <inkscape:grid
38 type="xygrid"
39 id="grid3491"
40 empspacing="5"
41 visible="true"
42 enabled="true"
43 snapvisiblegridlinesonly="true" />
44 </sodipodi:namedview>
45 <metadata
46 id="metadata3470">
47 <rdf:RDF>
48 <cc:Work
49 rdf:about="">
50 <dc:format>image/svg+xml</dc:format>
51 <dc:type
52 rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
53 <dc:title />
54 </cc:Work>
55 </rdf:RDF>
56 </metadata>
57 <g
58 inkscape:label="Layer 1"
59 inkscape:groupmode="layer"
60 id="layer1"
61 transform="translate(0,-1028.3622)">
62 <path
63 inkscape:connector-curvature="0"
64 d="m 7.933259,1048.396 c -1.3720103,1.3302 -3.5344256,1.2617 -4.8883004,-0.05 -1.3485438,-1.3153 -1.4194783,-3.4186 -0.051468,-4.7527 l 11.2883454,-10.9747 c 1.784281,-1.7292 4.592032,-1.642 6.356312,0.069 1.758413,1.7161 1.848014,4.4461 0.07012,6.1806 l -9.406999,9.1461 c -0.207734,0.2023 -0.544534,0.2023 -0.751469,0 -0.208002,-0.2022 -0.208802,-0.529 -8.12e-4,-0.7313 l 9.406199,-9.1468 c 1.354677,-1.3188 1.300009,-3.3751 -0.0696,-4.7174 -1.378942,-1.331 -3.494426,-1.3836 -4.851501,-0.065 L 3.745743,1044.328 c -0.9421403,0.9198 -0.9069402,2.3485 0.051468,3.2896 0.9696083,0.9337 2.4376188,0.9663 3.384559,0.051 l 9.406199,-9.1454 c 0.489069,-0.475 0.471202,-1.2424 -0.07652,-1.7856 -0.557872,-0.5314 -1.346942,-0.549 -1.836013,-0.072 l -8.4656584,8.2305 c -0.2077346,0.2031 -0.5445368,0.2024 -0.7522714,0 -0.2077356,-0.202 -0.2085356,-0.5298 -8.077e-4,-0.7319 l 8.4672575,-8.2302 c 0.936006,-0.9076 2.418684,-0.8193 3.339759,0.073 0.919738,0.8969 1.00934,2.339 0.07732,3.2488 l -9.4077964,9.1445 z"
65 style="fill:#dfdbd2;fill-opacity:1;fill-rule:nonzero;stroke:none"
66 id="path108" />
67 </g>
68 </svg>
0 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
1 <!-- Created with Inkscape (http://www.inkscape.org/) -->
2
3 <svg
4 xmlns:dc="http://purl.org/dc/elements/1.1/"
5 xmlns:cc="http://creativecommons.org/ns#"
6 xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
7 xmlns:svg="http://www.w3.org/2000/svg"
8 xmlns="http://www.w3.org/2000/svg"
9 xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
10 xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
11 width="16"
12 height="16"
13 id="svg3465"
14 version="1.1"
15 inkscape:version="0.48.3.1 r9886"
16 sodipodi:docname="diodon-panel.svg">
17 <defs
18 id="defs3467" />
19 <sodipodi:namedview
20 id="base"
21 pagecolor="#ffffff"
22 bordercolor="#666666"
23 borderopacity="1.0"
24 inkscape:pageopacity="0.0"
25 inkscape:pageshadow="2"
26 inkscape:zoom="33.136364"
27 inkscape:cx="5.6886145"
28 inkscape:cy="11"
29 inkscape:document-units="px"
30 inkscape:current-layer="layer1"
31 showgrid="true"
32 inkscape:window-width="1600"
33 inkscape:window-height="876"
34 inkscape:window-x="0"
35 inkscape:window-y="24"
36 inkscape:window-maximized="1">
37 <inkscape:grid
38 type="xygrid"
39 id="grid3491"
40 empspacing="5"
41 visible="true"
42 enabled="true"
43 snapvisiblegridlinesonly="true" />
44 </sodipodi:namedview>
45 <metadata
46 id="metadata3470">
47 <rdf:RDF>
48 <cc:Work
49 rdf:about="">
50 <dc:format>image/svg+xml</dc:format>
51 <dc:type
52 rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
53 <dc:title />
54 </cc:Work>
55 </rdf:RDF>
56 </metadata>
57 <g
58 inkscape:label="Layer 1"
59 inkscape:groupmode="layer"
60 id="layer1"
61 transform="translate(0,-1036.3622)">
62 <path
63 inkscape:connector-curvature="0"
64 d="m 5.5599552,1049.2716 c -0.8232062,0.813 -2.1206553,0.7711 -2.9329801,-0.03 -0.8091263,-0.8038 -0.851687,-2.0892 -0.03088,-2.9046 l 6.7730063,-6.7073 c 1.0705676,-1.0568 2.7552186,-1.0034 3.8137866,0.042 1.055048,1.049 1.108809,2.7172 0.04208,3.7774 l -5.6441993,5.5895 c -0.1246406,0.1236 -0.3267207,0.1236 -0.4508814,0 -0.1248014,-0.1235 -0.1252814,-0.3234 -4.867e-4,-0.4469 l 5.6437184,-5.59 c 0.812806,-0.8059 0.780006,-2.0626 -0.04176,-2.883 -0.827366,-0.8134 -2.096655,-0.8455 -2.9109003,-0.041 l -6.7730067,6.7068 c -0.5652842,0.5622 -0.5441641,1.4353 0.03088,2.0105 0.581765,0.5705 1.4625712,0.5905 2.0307353,0.031 l 5.6437187,-5.5891 c 0.293442,-0.2903 0.282722,-0.7593 -0.04592,-1.0914 -0.334723,-0.3247 -0.8081653,-0.3355 -1.1016073,-0.044 l -5.0793955,5.0301 c -0.1246408,0.1241 -0.3267221,0.1236 -0.4513628,0 -0.1246414,-0.1235 -0.1251214,-0.3238 -4.847e-4,-0.4473 l 5.0803544,-5.0299 c 0.561604,-0.5546 1.4512109,-0.5006 2.0038549,0.045 0.551843,0.5481 0.605604,1.4295 0.0464,1.9854 l -5.6446784,5.5891 z"
65 style="fill:#3c3c3c;fill-opacity:1;fill-rule:nonzero;stroke:none"
66 id="path108" />
67 </g>
68 </svg>
0 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
1 <!-- Created with Inkscape (http://www.inkscape.org/) -->
2
3 <svg
4 xmlns:dc="http://purl.org/dc/elements/1.1/"
5 xmlns:cc="http://creativecommons.org/ns#"
6 xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
7 xmlns:svg="http://www.w3.org/2000/svg"
8 xmlns="http://www.w3.org/2000/svg"
9 xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
10 xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
11 width="22"
12 height="22"
13 id="svg3465"
14 version="1.1"
15 inkscape:version="0.48.3.1 r9886"
16 sodipodi:docname="diodon-panel.svg">
17 <defs
18 id="defs3467" />
19 <sodipodi:namedview
20 id="base"
21 pagecolor="#ffffff"
22 bordercolor="#666666"
23 borderopacity="1.0"
24 inkscape:pageopacity="0.0"
25 inkscape:pageshadow="2"
26 inkscape:zoom="33.136364"
27 inkscape:cx="5.6886145"
28 inkscape:cy="11"
29 inkscape:document-units="px"
30 inkscape:current-layer="layer1"
31 showgrid="true"
32 inkscape:window-width="1600"
33 inkscape:window-height="876"
34 inkscape:window-x="0"
35 inkscape:window-y="24"
36 inkscape:window-maximized="1">
37 <inkscape:grid
38 type="xygrid"
39 id="grid3491"
40 empspacing="5"
41 visible="true"
42 enabled="true"
43 snapvisiblegridlinesonly="true" />
44 </sodipodi:namedview>
45 <metadata
46 id="metadata3470">
47 <rdf:RDF>
48 <cc:Work
49 rdf:about="">
50 <dc:format>image/svg+xml</dc:format>
51 <dc:type
52 rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
53 <dc:title />
54 </cc:Work>
55 </rdf:RDF>
56 </metadata>
57 <g
58 inkscape:label="Layer 1"
59 inkscape:groupmode="layer"
60 id="layer1"
61 transform="translate(0,-1030.3622)">
62 <path
63 inkscape:connector-curvature="0"
64 d="m 7.1365956,1049.1727 c -1.3034099,1.2933 -3.3577042,1.2267 -4.6438852,-0.048 -1.2811166,-1.2787 -1.3485043,-3.3236 -0.048893,-4.6207 l 10.7239266,-10.6702 c 1.695066,-1.6813 4.362429,-1.5964 6.038495,0.067 1.670493,1.6686 1.755614,4.3227 0.06663,6.0091 l -8.936649,8.892 c -0.197348,0.1968 -0.5173081,0.1968 -0.7138961,0 -0.1976013,-0.1965 -0.1983613,-0.5144 -7.7e-4,-0.7109 l 8.9358871,-8.8929 c 1.286943,-1.2821 1.23501,-3.2813 -0.06612,-4.5864 -1.309995,-1.294 -3.319703,-1.3451 -4.608925,-0.064 l -10.7239271,10.6695 c -0.8950333,0.8942 -0.8615932,2.2833 0.048893,3.1983 0.9211278,0.9077 2.3157377,0.9394 3.2153309,0.049 l 8.9358882,-8.8915 c 0.464616,-0.4618 0.447643,-1.2078 -0.07271,-1.736 -0.529977,-0.5166 -1.279595,-0.5337 -1.744211,-0.07 l -8.0423768,8.002 c -0.1973478,0.1974 -0.5173099,0.1968 -0.7146577,0 -0.1973489,-0.1963 -0.1981089,-0.5151 -7.674e-4,-0.7116 l 8.0438949,-8.0017 c 0.889206,-0.8823 2.29775,-0.7964 3.172771,0.071 0.87375,0.872 0.958873,2.2741 0.07347,3.1586 l -8.9374079,8.8914 z"
65 style="fill:#3c3c3c;fill-opacity:1;fill-rule:nonzero;stroke:none"
66 id="path108" />
67 </g>
68 </svg>
0 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
1 <!-- Created with Inkscape (http://www.inkscape.org/) -->
2
3 <svg
4 xmlns:dc="http://purl.org/dc/elements/1.1/"
5 xmlns:cc="http://creativecommons.org/ns#"
6 xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
7 xmlns:svg="http://www.w3.org/2000/svg"
8 xmlns="http://www.w3.org/2000/svg"
9 xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
10 xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
11 width="24"
12 height="24"
13 id="svg3465"
14 version="1.1"
15 inkscape:version="0.48.4 r9939"
16 sodipodi:docname="diodon-panel.svg">
17 <defs
18 id="defs3467" />
19 <sodipodi:namedview
20 id="base"
21 pagecolor="#ffffff"
22 bordercolor="#666666"
23 borderopacity="1.0"
24 inkscape:pageopacity="0.0"
25 inkscape:pageshadow="2"
26 inkscape:zoom="25.774027"
27 inkscape:cx="16.14972"
28 inkscape:cy="11.394423"
29 inkscape:document-units="px"
30 inkscape:current-layer="layer1"
31 showgrid="true"
32 inkscape:window-width="1920"
33 inkscape:window-height="1056"
34 inkscape:window-x="0"
35 inkscape:window-y="24"
36 inkscape:window-maximized="1">
37 <inkscape:grid
38 type="xygrid"
39 id="grid3491"
40 empspacing="5"
41 visible="true"
42 enabled="true"
43 snapvisiblegridlinesonly="true" />
44 </sodipodi:namedview>
45 <metadata
46 id="metadata3470">
47 <rdf:RDF>
48 <cc:Work
49 rdf:about="">
50 <dc:format>image/svg+xml</dc:format>
51 <dc:type
52 rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
53 <dc:title />
54 </cc:Work>
55 </rdf:RDF>
56 </metadata>
57 <g
58 inkscape:label="Layer 1"
59 inkscape:groupmode="layer"
60 id="layer1"
61 transform="translate(0,-1028.3622)">
62 <path
63 inkscape:connector-curvature="0"
64 d="m 7.9332588,1048.3957 c -1.3720103,1.3304 -3.5344257,1.2619 -4.8883002,-0.048 -1.348544,-1.3153 -1.4194785,-3.4187 -0.051467,-4.7529 l 11.2883454,-10.9759 c 1.784279,-1.7293 4.592031,-1.642 6.356311,0.068 1.758412,1.7166 1.848014,4.4463 0.07013,6.181 l -9.406999,9.1465 c -0.207735,0.2023 -0.544535,0.2023 -0.751469,0 -0.208002,-0.2021 -0.208802,-0.5292 -8.11e-4,-0.7313 l 9.406197,-9.1472 c 1.354677,-1.3187 1.30001,-3.3751 -0.0696,-4.7176 -1.378944,-1.331 -3.494425,-1.3836 -4.8515,-0.066 l -11.2883487,10.9758 c -0.9421403,0.9199 -0.9069402,2.3486 0.051467,3.2899 0.9696083,0.9336 2.4376187,0.9662 3.3845589,0.049 l 9.4061978,-9.1458 c 0.489071,-0.475 0.471204,-1.2424 -0.07653,-1.7859 -0.557871,-0.5313 -1.346942,-0.5489 -1.836012,-0.072 l -8.4656589,8.231 c -0.2077347,0.2031 -0.544537,0.2023 -0.7522714,0 -0.2077357,-0.202 -0.2085357,-0.5297 -8.078e-4,-0.7319 l 8.4672571,-8.2306 c 0.936007,-0.9075 2.418686,-0.8191 3.339758,0.074 0.91974,0.897 1.00934,2.3392 0.07733,3.2489 l -9.4077958,9.1458 z"
65 style="fill:#3c3c3c;fill-opacity:1;fill-rule:nonzero;stroke:none"
66 id="path108" />
67 </g>
68 </svg>
0 <schemalist>
1 <schema gettext-domain="@GETTEXT_PACKAGE@" id="net.launchpad.Diodon.clipboard" path="/net/launchpad/diodon/clipboard/">
2 <key name="use-clipboard" type="b">
3 <default>true</default>
4 <_summary>Use clipboard (Ctrl+C)</_summary>
5 <_description>Adds content which is copied to the clipboard with e.g. Ctrl + C to the clipboard history.</_description>
6 </key>
7 <key name="use-primary" type="b">
8 <default>false</default>
9 <_summary>Use primary selection</_summary>
10 <_description>Adds the primary selection (an area of the screen which is selected with the mouse) to the clipboard history. Enabling will start process which continually checks what is selected. This might discharge your battery quicker.</_description>
11 </key>
12 <key name="add-images" type="b">
13 <default>false</default>
14 <_summary>Add images to clipboard history</_summary>
15 <_description>Add images copied to clipboard to clipboard history (e.g. when you right click on an image in your browser and choose copy image). Enabling this option will increase memory consumption. Images already added to clipboard history will remain even when disabled.</_description>
16 </key>
17 <key name="synchronize-clipboards" type="b">
18 <default>false</default>
19 <_summary>Synchronize clipboards</_summary>
20 <_description>Synchronizes the selection (an area of the screen which is selected with the mouse) and the clipboard so that anything in the selection is immediately available in the clipboard and vice versa e.g. for pasting with Ctrl + V and the middle mouse button.</_description>
21 </key>
22 <key name="keep-clipboard-content" type="b">
23 <default>true</default>
24 <_summary>Keep clipboard content</_summary>
25 <_description>Prevents an empty clipboard. For instance when an application exits, the clipboard would usually be emptied.</_description>
26 </key>
27 <key name="instant-paste" type="b">
28 <default>true</default>
29 <_summary>Automatically paste selected item</_summary>
30 <_description>Automatically paste selected item instead of just copying it to the clipboard.</_description>
31 </key>
32 <key name="recent-items-size" type="u">
33 <default>25</default>
34 <_summary>Number of recent clipboard items</_summary>
35 <_description>Number of recent clipboard items shown in clipboard menu.</_description>
36 </key>
37 <key name="filter-pattern" type="s">
38 <default>'^\\s+$'</default>
39 <_summary>Clipboard content filter pattern</_summary>
40 <_description>Regex filter pattern whereas all clipboard items matching this pattern will be filtered and not added to clipboard history.</_description>
41 </key>
42 <key name="app-paste-keybindings" type="as">
43 <default>['/usr/bin/gnome-terminal|&lt;Shift&gt;&lt;Ctrl&gt;V','/usr/lib/gnome-terminal/gnome-terminal-server|&lt;Shift&gt;&lt;Ctrl&gt;V', '/usr/bin/xfce4-terminal|&lt;Shift&gt;&lt;Ctrl&gt;V']</default>
44 <_summary>Lookup dictionary for application using different paste keybindings</_summary>
45 <_description>A lookup dictionary for applications using different paste keybindings than Ctrl + V. Pattern of each string in this array is path-of-app|keybinding</_description>
46 </key>
47 </schema>
48 <schema gettext-domain="@GETTEXT_PACKAGE@" id="net.launchpad.Diodon.plugins" path="/net/launchpad/diodon/plugins/">
49 <key name="active-plugins" type="as">
50 <default>[@ACTIVE_PLUGINS@]</default>
51 <_summary>Active plugins</_summary>
52 <_description>List of active plugins.</_description>
53 </key>
54 </schema>
55 </schemalist>
56
0 <?xml version="1.0" encoding="UTF-8"?>
1 <!-- Generated with glade 3.16.1 -->
2 <interface>
3 <requires lib="gtk+" version="3.10"/>
4 <object class="GtkAdjustment" id="adjustment_recent_items_size">
5 <property name="lower">1</property>
6 <property name="upper">100</property>
7 <property name="value">25</property>
8 <property name="step_increment">1</property>
9 </object>
10 <object class="GtkDialog" id="dialog_preferences">
11 <property name="can_focus">False</property>
12 <property name="border_width">5</property>
13 <property name="title" translatable="yes">Diodon Preferences</property>
14 <property name="window_position">center</property>
15 <property name="default_width">450</property>
16 <property name="default_height">300</property>
17 <property name="icon_name">diodon</property>
18 <property name="type_hint">dialog</property>
19 <child internal-child="vbox">
20 <object class="GtkBox" id="dialog-vbox1">
21 <property name="visible">True</property>
22 <property name="can_focus">False</property>
23 <property name="spacing">2</property>
24 <child internal-child="action_area">
25 <object class="GtkButtonBox" id="dialog-action_area1">
26 <property name="visible">True</property>
27 <property name="can_focus">False</property>
28 <property name="layout_style">end</property>
29 <child>
30 <object class="GtkButton" id="button_close">
31 <property name="label">gtk-close</property>
32 <property name="visible">True</property>
33 <property name="can_focus">True</property>
34 <property name="receives_default">True</property>
35 <property name="use_stock">True</property>
36 </object>
37 <packing>
38 <property name="expand">False</property>
39 <property name="fill">False</property>
40 <property name="position">0</property>
41 </packing>
42 </child>
43 </object>
44 <packing>
45 <property name="expand">False</property>
46 <property name="fill">True</property>
47 <property name="pack_type">end</property>
48 <property name="position">0</property>
49 </packing>
50 </child>
51 <child>
52 <object class="GtkNotebook" id="notebook_preferences">
53 <property name="visible">True</property>
54 <property name="can_focus">True</property>
55 <child>
56 <object class="GtkVBox" id="vbox1">
57 <property name="visible">True</property>
58 <property name="can_focus">False</property>
59 <child>
60 <object class="GtkCheckButton" id="checkbutton_use_clipboard">
61 <property name="label" translatable="yes">_Use clipboard (Ctrl+C)</property>
62 <property name="visible">True</property>
63 <property name="can_focus">True</property>
64 <property name="receives_default">False</property>
65 <property name="tooltip_text" translatable="yes">Adds content which is copied to the clipboard with e.g. Ctrl + C to the clipboard history.</property>
66 <property name="use_underline">True</property>
67 <property name="xalign">0.5</property>
68 <property name="draw_indicator">True</property>
69 </object>
70 <packing>
71 <property name="expand">True</property>
72 <property name="fill">True</property>
73 <property name="position">0</property>
74 </packing>
75 </child>
76 <child>
77 <object class="GtkCheckButton" id="checkbutton_use_primary">
78 <property name="label" translatable="yes">Use _primary selection</property>
79 <property name="visible">True</property>
80 <property name="can_focus">True</property>
81 <property name="receives_default">False</property>
82 <property name="tooltip_text" translatable="yes">Adds the primary selection (an area of the screen which is selected with the mouse) to the clipboard history. Enabling will start process which continually checks what is selected. This might discharge your battery quicker.</property>
83 <property name="use_underline">True</property>
84 <property name="xalign">0.5</property>
85 <property name="draw_indicator">True</property>
86 </object>
87 <packing>
88 <property name="expand">True</property>
89 <property name="fill">True</property>
90 <property name="position">1</property>
91 </packing>
92 </child>
93 <child>
94 <object class="GtkCheckButton" id="checkbutton_add_images">
95 <property name="label" translatable="yes">Add _images to clipboard history</property>
96 <property name="visible">True</property>
97 <property name="can_focus">True</property>
98 <property name="receives_default">False</property>
99 <property name="tooltip_text" translatable="yes">Add images copied to clipboard to clipboard history (e.g. when you right click on an image in your browser and choose copy image). Enabling this option will increase memory consumption. Images already added to clipboard history will remain even when disabled.</property>
100 <property name="use_underline">True</property>
101 <property name="xalign">0.5</property>
102 <property name="draw_indicator">True</property>
103 </object>
104 <packing>
105 <property name="expand">True</property>
106 <property name="fill">True</property>
107 <property name="position">2</property>
108 </packing>
109 </child>
110 <child>
111 <object class="GtkCheckButton" id="checkbutton_keep_clipboard_content">
112 <property name="label" translatable="yes">_Keep clipboard content</property>
113 <property name="visible">True</property>
114 <property name="can_focus">True</property>
115 <property name="receives_default">False</property>
116 <property name="tooltip_text" translatable="yes">Prevents an empty clipboard. For instance when an application exits, the clipboard would usually be emptied.</property>
117 <property name="use_underline">True</property>
118 <property name="xalign">0.5</property>
119 <property name="draw_indicator">True</property>
120 </object>
121 <packing>
122 <property name="expand">True</property>
123 <property name="fill">True</property>
124 <property name="position">3</property>
125 </packing>
126 </child>
127 <child>
128 <object class="GtkCheckButton" id="checkbutton_synchronize_clipboards">
129 <property name="label" translatable="yes">S_ynchronize clipboards</property>
130 <property name="visible">True</property>
131 <property name="can_focus">True</property>
132 <property name="receives_default">False</property>
133 <property name="tooltip_text" translatable="yes">Synchronizes the selection (an area of the screen which is selected with the mouse) and the clipboard so that anything in the selection is immediately available in the clipboard and vice versa e.g. for pasting with Ctrl + V and the middle mouse button.</property>
134 <property name="use_underline">True</property>
135 <property name="xalign">0.5</property>
136 <property name="draw_indicator">True</property>
137 </object>
138 <packing>
139 <property name="expand">True</property>
140 <property name="fill">True</property>
141 <property name="position">4</property>
142 </packing>
143 </child>
144 <child>
145 <object class="GtkCheckButton" id="checkbutton_instant_paste">
146 <property name="label" translatable="yes">_Automatically paste selected item</property>
147 <property name="visible">True</property>
148 <property name="can_focus">True</property>
149 <property name="receives_default">False</property>
150 <property name="tooltip_text" translatable="yes">Automatically paste selected item instead of just copying it to the clipboard.</property>
151 <property name="use_underline">True</property>
152 <property name="xalign">0.5</property>
153 <property name="draw_indicator">True</property>
154 </object>
155 <packing>
156 <property name="expand">True</property>
157 <property name="fill">True</property>
158 <property name="position">5</property>
159 </packing>
160 </child>
161 <child>
162 <object class="GtkHBox" id="hbox1">
163 <property name="visible">True</property>
164 <property name="can_focus">False</property>
165 <property name="tooltip_text" translatable="yes">Number of recent clipboard items to be shown in clipboard menu.</property>
166 <child>
167 <object class="GtkLabel" id="label_recent_items_size">
168 <property name="visible">True</property>
169 <property name="can_focus">False</property>
170 <property name="label" translatable="yes">Number of recent items</property>
171 <property name="ellipsize">start</property>
172 </object>
173 <packing>
174 <property name="expand">True</property>
175 <property name="fill">True</property>
176 <property name="position">0</property>
177 </packing>
178 </child>
179 <child>
180 <object class="GtkSpinButton" id="spinbutton_recent_items_size">
181 <property name="visible">True</property>
182 <property name="can_focus">True</property>
183 <property name="primary_icon_activatable">False</property>
184 <property name="secondary_icon_activatable">False</property>
185 <property name="adjustment">adjustment_recent_items_size</property>
186 <property name="numeric">True</property>
187 </object>
188 <packing>
189 <property name="expand">True</property>
190 <property name="fill">False</property>
191 <property name="position">1</property>
192 </packing>
193 </child>
194 </object>
195 <packing>
196 <property name="expand">True</property>
197 <property name="fill">True</property>
198 <property name="position">6</property>
199 </packing>
200 </child>
201 </object>
202 </child>
203 <child type="tab">
204 <object class="GtkLabel" id="label_clipboard">
205 <property name="visible">True</property>
206 <property name="can_focus">False</property>
207 <property name="label" translatable="yes">Clipboard</property>
208 </object>
209 <packing>
210 <property name="tab_fill">False</property>
211 </packing>
212 </child>
213 <child>
214 <object class="GtkVBox" id="vbox2">
215 <property name="visible">True</property>
216 <property name="can_focus">False</property>
217 <child>
218 <object class="GtkBox" id="box1">
219 <property name="visible">True</property>
220 <property name="can_focus">False</property>
221 <property name="orientation">vertical</property>
222 <child>
223 <object class="GtkLabel" id="label_hotkeys_description">
224 <property name="visible">True</property>
225 <property name="can_focus">False</property>
226 <property name="label" translatable="yes">Please register custom shortcut with
227 your desktop environment.
228 Use /usr/bin/diodon as command.</property>
229 </object>
230 <packing>
231 <property name="expand">False</property>
232 <property name="fill">True</property>
233 <property name="position">0</property>
234 </packing>
235 </child>
236 <child>
237 <object class="GtkLinkButton" id="linkbutton_hotkeys">
238 <property name="label" translatable="yes">More information</property>
239 <property name="visible">True</property>
240 <property name="can_focus">True</property>
241 <property name="receives_default">True</property>
242 <property name="relief">none</property>
243 <property name="uri">https://esite.ch/2015/07/using-custom-shortcuts-of-de-as-diodon-hotkey/</property>
244 </object>
245 <packing>
246 <property name="expand">False</property>
247 <property name="fill">True</property>
248 <property name="position">1</property>
249 </packing>
250 </child>
251 </object>
252 <packing>
253 <property name="expand">True</property>
254 <property name="fill">False</property>
255 <property name="position">0</property>
256 </packing>
257 </child>
258 </object>
259 <packing>
260 <property name="position">1</property>
261 </packing>
262 </child>
263 <child type="tab">
264 <object class="GtkLabel" id="label_hotkeys">
265 <property name="visible">True</property>
266 <property name="can_focus">False</property>
267 <property name="label" translatable="yes">Hotkeys</property>
268 </object>
269 <packing>
270 <property name="position">1</property>
271 <property name="tab_fill">False</property>
272 </packing>
273 </child>
274 <child>
275 <object class="GtkBox" id="plugins_box">
276 <property name="visible">True</property>
277 <property name="can_focus">False</property>
278 <property name="border_width">12</property>
279 <property name="orientation">vertical</property>
280 <child>
281 <placeholder/>
282 </child>
283 </object>
284 <packing>
285 <property name="position">2</property>
286 </packing>
287 </child>
288 <child type="tab">
289 <object class="GtkLabel" id="label_plugins">
290 <property name="visible">True</property>
291 <property name="can_focus">False</property>
292 <property name="label" translatable="yes">Plugins</property>
293 </object>
294 <packing>
295 <property name="position">2</property>
296 <property name="tab_fill">False</property>
297 </packing>
298 </child>
299 </object>
300 <packing>
301 <property name="expand">True</property>
302 <property name="fill">True</property>
303 <property name="position">1</property>
304 </packing>
305 </child>
306 </object>
307 </child>
308 <action-widgets>
309 <action-widget response="0">button_close</action-widget>
310 </action-widgets>
311 </object>
312 </interface>
0 #! /usr/bin/env python
1 # encoding: utf-8
2
3 from waflib import Build, Utils
4 import os
5
6 bld.new_task_gen (
7 features = "subst",
8 source= "net.launchpad.Diodon.gschema.xml.in.in",
9 target= "net.launchpad.Diodon.gschema.xml.in",
10 GETTEXT_PACKAGE = bld.env['GETTEXT_PACKAGE'],
11 ACTIVE_PLUGINS = bld.env['ACTIVE_PLUGINS'])
12
13 bld.new_task_gen (
14 features = 'intltool_in',
15 podir = '.', # no translations should get added to gschema file
16 source = 'net.launchpad.Diodon.gschema.xml.in',
17 install_path = '', # do not install it
18 flags = ["-x", "-q", "-u", "-c"])
19
20 task = bld.new_task_gen (
21 features = 'glib2')
22 task.add_settings_schemas ('net.launchpad.Diodon.gschema.xml')
23
24 bld.new_task_gen (
25 features = 'intltool_in',
26 podir = '../po',
27 source = 'diodon.desktop.in',
28 flags = ["-d", "-q", "-u", "-c"],
29 install_path = "${DATADIR}/applications")
30
31 bld.new_task_gen (
32 features = 'intltool_in',
33 podir = '../po',
34 source = 'diodon-autostart.desktop.in',
35 flags = ["-d", "-q", "-u", "-c"],
36 install_path = "${SYSCONFDIR}/xdg/autostart")
37
38 bld.new_task_gen (source='diodon.pc.in')
39
40 bld.install_files('${DATADIR}/diodon', 'preferences.ui')
41 bld.install_files('${MANDIR}/man1', 'diodon.1.gz')
42
43 bld.install_files('${DATADIR}/apport/package-hooks', 'apport/source_diodon.py')
44 bld.install_files('${SYSCONFDIR}/apport/crashdb.conf.d/', 'apport/diodon-crashdb.conf')
45
46 # install all icons files into the according directory
47 icons_path = bld.path.find_dir('../data/icons')
48 icons = icons_path.ant_glob(incl='**/*')
49 for icon in icons:
50 # difference between basedir and given dir
51 relfile = icon.path_from(icons_path)
52 pos = relfile.rfind(os.sep)
53 subpath = ''
54 if pos > -1:
55 subpath = relfile[:pos]
56 # add difference of path to install dir
57 install_dir = '${DATADIR}/icons/' + subpath
58 bld.install_files(install_dir, icon)
59
0 /*
1 * Diodon - GTK+ clipboard manager.
2 * Copyright (C) 2010-2014 Diodon Team <diodon-team@lists.launchpad.net>
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published
6 * by the Free Software Foundation, either version 2 of the License, or (at
7 * your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
11 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
12 * License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 *
17 * Author:
18 * Oliver Sauder <os@esite.ch>
19 */
20
21 namespace Diodon
22 {
23 public class DiodonApplication : Gtk.Application
24 {
25 /**
26 * collects all non-option arguments which would otherwise be left in argv.
27 */
28 private const string OPTION_REMAINING = "";
29
30 /**
31 * determine whether version information should be printed
32 */
33 private static bool show_version = false;
34
35 /**
36 * main clipboard controller
37 */
38 private Controller? controller = null;
39
40 /**
41 * determine whether help information should be printed
42 */
43 private static bool show_help = false;
44
45 /**
46 * store unmached options and possible actions
47 */
48 private static string[] remaining_options;
49
50 /**
51 * list of available command line options
52 */
53 private const OptionEntry[] options = {
54 { OPTION_REMAINING, '\0', 0, OptionArg.STRING_ARRAY, ref remaining_options, null, "<action> | [CHECKSUM]" },
55 { "help", 'h', 0, OptionArg.NONE, ref show_help, "Show help options", null },
56 { "version", 'v', 0, OptionArg.NONE, ref show_version, "Print version information", null },
57 { null }
58 };
59
60 public DiodonApplication()
61 {
62 Object(application_id: Config.BUSNAME, flags: ApplicationFlags.HANDLES_COMMAND_LINE);
63
64 command_line.connect (handle_command_line);
65
66 // add supported actions
67 SimpleAction paste_action = new SimpleAction("paste", VariantType.STRING);
68 paste_action.activate.connect(activate_paste_action);
69 add_action(paste_action);
70 }
71
72 public void activate_paste_action(GLib.Variant? parameter)
73 {
74 hold();
75
76 string checksum = parameter.get_string();
77 debug("Execute paste with checksum %s", checksum);
78 controller.select_item_by_checksum.begin(checksum);
79
80 release();
81 }
82
83 public override void activate()
84 {
85 debug("Activate DiodonApplication (Version %s)", Config.VERSION);
86
87 if(controller == null) {
88 // setup controller
89 controller = new Controller();
90 controller.init.begin();
91
92 Gtk.main();
93 } else {
94 // on DEs directly implementing x to grab key there is
95 // a race between XEvent and GEvent which leads to Diodon menu not
96 // opening when run by keyboard shortcut.
97 // this is due to the GTK bug reported here
98 // https://bugzilla.gnome.org/show_bug.cgi?id=699679
99 // This is a very dirty workaround to simply sleep 100ms till the XEvent has
100 // passed which works in most cases.
101 // Unity and GNOME are not affected therefore excluding those here.
102 unowned string desktop = Environment.get_variable("XDG_CURRENT_DESKTOP");
103 string s_desktop = (desktop == null) ? "" : desktop.down();
104 if(strcmp(s_desktop, "unity") != 0 && strcmp(s_desktop, "gnome") != 0) {
105 debug("Current desktop: %s", desktop);
106 Thread.usleep(100000);
107 }
108
109 // Diodon running already, let's show history
110 controller.show_history();
111 }
112 }
113
114 /**
115 * Process command line arguments
116 */
117 private int handle_command_line (ApplicationCommandLine command_line)
118 {
119 string[] args = command_line.get_arguments();
120 show_version = false;
121 show_help = false;
122 remaining_options = new string[args.length];
123
124 StringBuilder summary = new StringBuilder("Actions:\n");
125 if (controller != null)
126 {
127 HashTable<string,string> descs = controller.get_command_descriptions ();
128 if(descs.length > 0) {
129 descs.foreach((key, val) => summary.append_printf (" %-25s%s\n", key, val));
130 } else {
131 summary.append (" None");
132 }
133
134 } else {
135 summary.append(" Actions are only available while diodon is running.");
136 }
137
138 try
139 {
140 OptionContext opt_context = new OptionContext("- GTK+ Clipboard Manager");
141 opt_context.set_summary (summary.str);
142 opt_context.set_help_enabled(false);
143 opt_context.add_main_entries(options, null);
144 opt_context.add_group(Gtk.get_option_group(true));
145 opt_context.parse_strv (ref args);
146
147 if(show_help) {
148 command_line.print(opt_context.get_help (true, null));
149 return 0;
150 }
151
152 if(show_version) {
153 command_line.print("Diodon %s\n", Config.VERSION);
154 return 0;
155 }
156
157 if (remaining_options.length > 0 && remaining_options[0] != null
158 && controller != null)
159 {
160 // it might be an uri so we have to remove uri first before
161 // TODO:
162 // see ZeitgeistClipboardStorage.CLIPBOARD_URI why clipboard:
163 // is used statically here
164 string option = remaining_options[0].replace("clipboard:", "");
165
166 // check if diodon has been called with a registered action
167 if (has_action(option))
168 {
169 uint i = 1;
170 while (remaining_options[i] != null) {
171 i++;
172 }
173 activate_action(option, new Variant.strv(remaining_options[1:i]));
174 return 0;
175 }
176 // check if it is a checksum (length 40) and paste action can be executed
177 else if (option.length == 40) {
178 activate_action("paste", new Variant.string(option));
179 return 0;
180 } else {
181 warning("Invalid action '%s'", remaining_options[0]);
182 return 1;
183 }
184 }
185
186 // no options - activate Diodon by either starting or showing menu
187 activate ();
188 return 0;
189 } catch(OptionError e) {
190 stdout.printf("Option parsing failed: %s\n", e.message);
191 }
192
193 return 1;
194 }
195
196 public static int main(string[] args)
197 {
198 // setup gettext
199 Intl.textdomain(Config.GETTEXT_PACKAGE);
200 Intl.bindtextdomain(Config.GETTEXT_PACKAGE, Config.LOCALEDIR);
201 Intl.bind_textdomain_codeset(Config.GETTEXT_PACKAGE, "UTF-8");
202 Intl.setlocale(LocaleCategory.ALL, "");
203
204 // diodon should only show up in gnome
205 DesktopAppInfo.set_desktop_env("GNOME");
206
207 // requires x11 to run
208 Gdk.set_allowed_backends("x11");
209
210 DiodonApplication app = new DiodonApplication();
211 return app.run(args);
212 }
213 }
214 }
215
0 #! /usr/bin/env python
1 # encoding: utf-8
2 # Oliver Sauder, 2010
3
4 import Options
5
6 prog = bld.new_task_gen (
7 features = 'c cprogram',
8 target = 'diodon',
9 vapi_dirs = '../vapi ../libdiodon',
10 uselib = 'GTK GIOUNIX',
11 use = 'libdiodon',
12 cflags = ['-include', 'config.h'],
13 packages = 'gtk+-3.0 gio-unix-2.0 config',
14 source = 'main.vala')
15
0 #! /usr/bin/env python
1 # encoding: utf-8
2
3 from waflib import Build, Utils
4 import os
5
6 # FIXME: there must be an easier way to install a directory recursively
7 # best option would be to add an install option to valadoc task itself
8 def signature_task(task):
9 bld = task.generator.bld
10
11 path = bld.path.find_or_declare('../_build_/doc/html')
12 for x in path.ant_glob('**/*', remove=False):
13 x.sig = Utils.h_file(x.abspath())
14
15 doc = bld.new_task_gen (
16 features = 'valadoc',
17 output_dir = '../doc/html',
18 package_name = bld.env['PACKAGE_NAME'],
19 package_version = bld.env['VERSION'],
20 packages = 'gtk+-3.0 gdk-x11-3.0 libpeas-gtk-1.0 libpeas-1.0 config xtst gdk-3.0',
21 vapi_dirs = '../vapi',
22 force = True)
23
24 path = bld.path.find_dir ('../libdiodon')
25 doc.files = path.ant_glob (incl='**/*.vala')
26
27 output_dir = bld.path.find_or_declare('../doc/html')
28 output_dir.mkdir()
29
30 # install all html files into the according directory
31 nodes = output_dir.ant_glob(incl='**/*')
32 for node in nodes:
33 # difference between basedir and given dir
34 relfile = node.path_from(output_dir)
35 pos = relfile.rfind(os.sep)
36 subpath = ''
37 if pos > -1:
38 subpath = relfile[:pos]
39 # add difference of path to install dir
40 install_dir = '${PREFIX}/share/doc/diodon-dev/html/' + subpath
41 bld.install_files(install_dir, node)
42
43 bld.post_mode = Build.POST_LAZY
44 bld.add_group()
45
46 bld.new_task_gen(
47 name = 'signature_task',
48 always = True,
49 rule = signature_task)
50
0 /*
1 * Diodon - GTK+ clipboard manager.
2 * Copyright (C) 2010-2011 Diodon Team <diodon-team@lists.launchpad.net>
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published
6 * by the Free Software Foundation, either version 2 of the License, or (at
7 * your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
11 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
12 * License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 *
17 * Author:
18 * Oliver Sauder <os@esite.ch>
19 */
20
21 namespace Diodon
22 {
23 /**
24 * Clipboard configuration encapsulating configuration state.
25 */
26 public class ClipboardConfiguration : GLib.Object
27 {
28 private int _recent_items_size = 25;
29 /**
30 * flag whether primary selection is enabled
31 */
32 public bool use_primary { get; set; default = false; }
33
34 /**
35 * flag whether images should be aded to clipboard history
36 */
37 public bool add_images { get; set; default = false; }
38
39 /**
40 * flag whether clipboard is enabled
41 */
42 public bool use_clipboard { get; set; default = true; }
43
44 /**
45 * flag whether clipboards should be in sync
46 */
47 public bool synchronize_clipboards { get; set; default = false; }
48
49 /**
50 * flag whether clipboard content should be restored when lost.
51 */
52 public bool keep_clipboard_content { get; set; default = true; }
53
54 /**
55 * flag whether clipboard content should be automatically pasted
56 */
57 public bool instant_paste { get; set; default = true; }
58
59 /**
60 * regex pattern so all clipboard items matching this pattern will
61 * be filtered and not added to clipboard history.
62 */
63 public string filter_pattern { get; set; default = "^\\s+$"; }
64
65 /**
66 * a lookup dictionary for application using different paste keybindings
67 * than <Ctrl>V.
68 * pattern of each string in this array is path-app|<keybinding>
69 * e.g. /usr/bin/gnome-terminal|<Ctrl><Shift>V
70 */
71 public string[] app_paste_keybindings { get; set; }
72
73 /**
74 * Lookup whether app paste keybinding
75 *
76 * @return app paste keybinding or null if not available
77 */
78 public string? lookup_app_paste_keybinding(string? apppath)
79 {
80 if(app_paste_keybindings != null && apppath != null) {
81 foreach(string keybinding in app_paste_keybindings) {
82 string[] path_keybinding = keybinding.split("|");
83 if(path_keybinding.length == 2) {
84 if(strcmp(apppath, path_keybinding[0]) == 0) {
85 return path_keybinding[1];
86 }
87 }
88 }
89 }
90
91 return null;
92 }
93
94 /**
95 * number of recent items to be shown.
96 * Value must be bigger than 0 and lower or equal than 100.
97 */
98 public int recent_items_size
99 {
100 get {
101 return _recent_items_size;
102 }
103 set {
104 if(value > 0 && value <= 100) {
105 _recent_items_size = value;
106 }
107 }
108 }
109 }
110 }
111
0 /*
1 * Diodon - GTK+ clipboard manager.
2 * Copyright (C) 2011 Diodon Team <diodon-team@lists.launchpad.net>
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published
6 * by the Free Software Foundation, either version 2 of the License, or (at
7 * your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
11 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
12 * License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 *
17 * Author:
18 * Oliver Sauder <os@esite.ch>
19 */
20
21 namespace Diodon
22 {
23 /**
24 * Clipboard item interface to be implemented by various different
25 * clipboard item types such as Text,File or Image.
26 *
27 * TODO
28 * interface IClipboardItem should extends Gee.Hashable which currently ends
29 * in a compliation error of classes implenting this interface.
30 */
31 public interface IClipboardItem : GLib.Object
32 {
33 /**
34 * get clipboard type item is coming from
35 *
36 * @return type of clipboard
37 */
38 public abstract ClipboardType get_clipboard_type();
39
40 /**
41 * label of clipboard item used to show in user interface
42 *
43 * @return label of item
44 */
45 public abstract string get_label();
46
47 /**
48 * get mime type of given clipboard item
49 *
50 * @return mime type of item
51 */
52 public abstract string get_mime_type();
53
54 /**
55 * get clipboard category item belongs to
56 *
57 * @return clipboard category
58 */
59 public abstract ClipboardCategory get_category();
60
61 /**
62 * image to represent content of clipboard item
63 *
64 * @return image of item or null if not available
65 */
66 public abstract Gtk.Image? get_image();
67
68 /**
69 * icon to represent type of clipboard item
70 *
71 * @return icon of clipboard type
72 */
73 public abstract Icon get_icon();
74
75 /**
76 * Retrieves any additional data needed to reconstruct clipboard content
77 */
78 public abstract ByteArray? get_payload() throws GLib.Error;
79
80 /**
81 * Date of when clipboard item has been copied
82 *
83 * @return date
84 */
85 public abstract DateTime get_date_copied();
86
87 /**
88 * A string representing clipboard item.
89 *
90 * @return data
91 */
92 public abstract string get_text();
93
94 /**
95 * Get unique checksum for clipboard content.
96 */
97 public abstract string get_checksum();
98
99 /**
100 * Get origin resp. path of application which has triggered copy event
101 * creating this clipboard item.
102 *
103 * @return origin as application path if available; otherwise null
104 */
105 public abstract string? get_origin();
106
107 /**
108 * Select the current item in the given gtk clipboard
109 *
110 * @param clipboard gtk clipboard
111 */
112 public abstract void to_clipboard(Gtk.Clipboard clipboard);
113
114 /**
115 * Check if given item is equal.
116 *
117 * @return true if equal; otherwise false.
118 *
119 */
120 public abstract bool equals(IClipboardItem *item);
121
122 /**
123 * return hash code for implemented clipboard item
124 *
125 * @return hash code
126 *
127 */
128 public abstract uint hash();
129
130 /**
131 * equal func helper comparing two clipboard items.
132 *
133 * @param item_a item to be compared
134 * @param item_b other item to be compared
135 *
136 * @return true if equal; otherwise false.
137 */
138 public static bool equal_func(IClipboardItem* item_a, IClipboardItem* item_b)
139 {
140 return item_a->equals(item_b);
141 }
142
143 /**
144 * hash func helper creating hash code for clipboard item.
145 *
146 * @param item item to create hash from
147 *
148 * @return generated hash code
149 */
150 public static uint hash_func (IClipboardItem* item)
151 {
152 return item->hash();
153 }
154 }
155 }
156
0 /*
1 * Diodon - GTK+ clipboard manager.
2 * Copyright (C) 2010-2011 Diodon Team <diodon-team@lists.launchpad.net>
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published
6 * by the Free Software Foundation, either version 2 of the License, or (at
7 * your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
11 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
12 * License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 *
17 * Author:
18 * Oliver Sauder <os@esite.ch>
19 */
20
21 namespace Diodon
22 {
23 /**
24 * This class is in charge of retrieving information from
25 * the encapsulated gnome clipboard and passing on such to the processes connected
26 * to the given signals.
27 */
28 class ClipboardManager : GLib.Object
29 {
30 protected ClipboardType type;
31 protected Gtk.Clipboard _clipboard = null;
32 protected ClipboardConfiguration _configuration;
33
34 /**
35 * Called when text from the clipboard has been received
36 *
37 * @param type type of clipboard text belongs to
38 * @param text received text from clipboard which is never null or empty
39 */
40 public signal void on_text_received(ClipboardType type, string text, string? origin);
41
42 /**
43 * Called when uris have been received from clipboard.
44 * The given paths are not uris appended with file://
45 * but just full paths.
46 *
47 * @param type type of clipboard uris belong to
48 * @param paths paths separated with /n.
49 */
50 public signal void on_uris_received(ClipboardType type, string paths, string? origin);
51
52 /**
53 * Called when a image has been received from the clipboard.
54 *
55 * @param type type of clipboard image belongs to
56 * @param pixbuf image as a pixbuf object
57 */
58 public signal void on_image_received(ClipboardType type, Gdk.Pixbuf pixbuf, string? origin);
59
60 /**
61 * Called when the clipboard is empty
62 *
63 * @param type type of clipboard which is empty
64 */
65 public signal void on_empty(ClipboardType type);
66
67 /**
68 * get type of given clipboard manager
69 */
70 public ClipboardType clipboard_type { get { return type; } }
71
72 /**
73 * Constructor
74 *
75 * @param clipboard clipboard to be managed
76 * @param configuration access to clipboard configuration
77 * @param type of clipboard
78 */
79 public ClipboardManager(ClipboardType type, ClipboardConfiguration configuration)
80 {
81 // TODO: might consider this block to be replaced with a HashMap
82 if(type == ClipboardType.CLIPBOARD) {
83 _clipboard = Gtk.Clipboard.get(Gdk.SELECTION_CLIPBOARD);
84 } else if(type == ClipboardType.PRIMARY) {
85 _clipboard = Gtk.Clipboard.get(Gdk.SELECTION_PRIMARY);
86 }
87
88 this.type = type;
89 this._configuration = configuration;
90 }
91
92 /**
93 * Starts the process requesting data from encapsulated clipboard.
94 * The owner has to change when new data is set in the clipboard
95 * therefore just connecting to owner_change will do the trick.
96 */
97 public virtual void start()
98 {
99 _clipboard.owner_change.connect(check_clipboard);
100 }
101
102 /**
103 * Stop the process requesting data from encapsulated clipboard.
104 */
105 public virtual void stop()
106 {
107 _clipboard.owner_change.disconnect(check_clipboard);
108 }
109
110 /**
111 * Select item in the managed clipboard.
112 *
113 * @param item item to be selected
114 */
115 public virtual void select_item(IClipboardItem item)
116 {
117 item.to_clipboard(_clipboard);
118 }
119
120 /**
121 * Clear managed clipboard
122 */
123 public void clear()
124 {
125 // clearing only works when clipboard is called by a callback
126 // from clipboard itself. This is not the case here
127 // so therefore we just set an empty text to clear the clipboard
128 //clipboard.clear();
129 _clipboard.set_text("", -1);
130 }
131
132 /**
133 * Request text from managed clipboard. If result is valid
134 * on_text_received will be called.
135 *
136 * @param event owner change event
137 */
138 protected void check_clipboard()
139 {
140 // on java applications such as jEdit wait_is_text_available returns
141 // false even when some text is available
142 string? text = request_text();
143 bool text_available = (text != null && text != "") || _clipboard.wait_is_text_available();
144 bool image_available = _configuration.add_images && _clipboard.wait_is_image_available();
145 bool uris_available = _clipboard.wait_is_uris_available();
146
147 // checking if any content known is available
148 if(text_available || image_available || uris_available) {
149 string? origin = Utility.get_path_of_active_application();
150
151 // checking for uris
152 if(text_available) {
153 // check if text is valid
154 if(text != null && text != "") {
155 if(uris_available) {
156 on_uris_received(type, text, origin);
157 }
158 else {
159 on_text_received(type, text, origin);
160 }
161 }
162 }
163 // checking for image
164 else if(image_available) {
165 Gdk.Pixbuf? pixbuf = request_image();
166 if(pixbuf != null) {
167 on_image_received(type, pixbuf, origin);
168 }
169 }
170 }
171 // checking if clipboard might be empty
172 else {
173 check_clipboard_emptiness();
174 }
175 }
176
177 /**
178 * Request image from clipboard and return it
179 *
180 * @return returns requested image from clipboard
181 */
182 protected Gdk.Pixbuf? request_image()
183 {
184 Gdk.Pixbuf? result = _clipboard.wait_for_image();
185 return result;
186 }
187
188 /**
189 * request text from clipboard and return it
190 *
191 * @return returns text available in clipboard
192 */
193 protected string? request_text()
194 {
195 string? result = _clipboard.wait_for_text();
196 return result;
197 }
198
199 /**
200 * Check if clipboard content has been lost.
201 */
202 protected void check_clipboard_emptiness()
203 {
204 Gdk.Atom[] targets = null;
205 if(!_clipboard.wait_for_targets(out targets)) {
206 on_empty(type);
207 }
208 }
209 }
210 }
211
0 /*
1 * Diodon - GTK+ clipboard manager.
2 * Copyright (C) 2010-2011 Diodon Team <diodon-team@lists.launchpad.net>
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published
6 * by the Free Software Foundation, either version 2 of the License, or (at
7 * your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
11 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
12 * License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 *
17 * Author:
18 * Oliver Sauder <os@esite.ch>
19 */
20
21 namespace Diodon
22 {
23 /**
24 * A gtk menu item holding a checksum of a clipboard item. It only keeps
25 * the checksum as it would waste memory to keep the hole item available.
26 */
27 class ClipboardMenuItem : Gtk.ImageMenuItem
28 {
29 private string _checksum;
30
31 /**
32 * Clipboard item constructor
33 *
34 * @param item clipboard item
35 */
36 public ClipboardMenuItem(IClipboardItem item)
37 {
38 _checksum = item.get_checksum();
39 set_label(item.get_label());
40
41 // check if image needs to be shown
42 Gtk.Image? image = item.get_image();
43 if(image != null) {
44 set_image(image);
45 set_always_show_image(true);
46 }
47 }
48
49 /**
50 * Get encapsulated clipboard item checksum
51 *
52 * @return clipboard item checksum
53 */
54 public string get_item_checksum()
55 {
56 return _checksum;
57 }
58
59 /**
60 * Highlight item by changing label to bold
61 * TODO: get this up and running
62 */
63 /*public void highlight_item()
64 {
65 Gtk.Label label = get_menu_label();
66 label.set_markup("<b>%s</b>".printf(get_label()));
67 }*/
68
69 /**
70 * Gets the child of Gtk.Bin base class which represents
71 * a Gtk.Label object.
72 *
73 * @return gtk label
74 */
75 /*private Gtk.Label get_menu_label()
76 {
77 Gtk.Label menu_label = (Gtk.Label) get_child();
78 return menu_label;
79 }*/
80 }
81 }
82
0 /*
1 * Diodon - GTK+ clipboard manager.
2 * Copyright (C) 2011 Diodon Team <diodon-team@lists.launchpad.net>
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published
6 * by the Free Software Foundation, either version 2 of the License, or (at
7 * your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
11 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
12 * License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 *
17 * Author:
18 * Oliver Sauder <os@esite.ch>
19 */
20
21 namespace Diodon
22 {
23 /**
24 * A gtk menu item holding a list of clipboard items
25 */
26 class ClipboardMenu : Gtk.Menu
27 {
28 private Controller controller;
29 private unowned List<Gtk.Widget> static_menu_items;
30
31 /**
32 * Create clipboard menu
33 *
34 * @param controller reference to controller
35 * @param items clipboard items to be shown
36 * @param menu_items additional menu items to be added after separator
37 * @param privacy_mode check whether privacy mode is enabled
38 */
39 public ClipboardMenu(Controller controller, List<IClipboardItem> items, List<Gtk.MenuItem>? static_menu_items, bool privace_mode)
40 {
41 this.controller = controller;
42 this.static_menu_items = static_menu_items;
43
44 if(items.length() <= 0) {
45 Gtk.MenuItem empty_item = new Gtk.MenuItem.with_label(_("<Empty>"));
46 empty_item.set_sensitive(false);
47 append(empty_item);
48 }
49
50 if(privace_mode) {
51 Gtk.MenuItem privacy_item = new Gtk.MenuItem.with_label(
52 _("Privacy mode is enabled. No new items will be added to history!")
53 );
54 privacy_item.set_sensitive(false);
55 append(privacy_item);
56 }
57
58 foreach(IClipboardItem item in items) {
59 append_clipboard_item(item);
60 }
61
62 Gtk.SeparatorMenuItem sep_item = new Gtk.SeparatorMenuItem();
63 append(sep_item);
64
65 if(static_menu_items != null) {
66 foreach(Gtk.MenuItem menu_item in static_menu_items) {
67 append(menu_item);
68 }
69 }
70
71 Gtk.MenuItem clear_item = new Gtk.ImageMenuItem.from_stock(Gtk.Stock.CLEAR, null);
72 clear_item.activate.connect(on_clicked_clear);
73 append(clear_item);
74
75 Gtk.MenuItem preferences_item = new Gtk.ImageMenuItem.from_stock(Gtk.Stock.PREFERENCES, null);
76 preferences_item.activate.connect(on_clicked_preferences);
77 append(preferences_item);
78
79 Gtk.MenuItem quit_item = new Gtk.ImageMenuItem.from_stock(Gtk.Stock.QUIT, null);
80 quit_item.activate.connect(on_clicked_quit);
81 append(quit_item);
82
83 show_all();
84
85 this.key_press_event.connect(on_key_pressed);
86 }
87
88 /**
89 * Append given clipboard item to menu.
90 *
91 * @param entry entry to be added
92 */
93 public void append_clipboard_item(IClipboardItem item)
94 {
95 ClipboardMenuItem menu_item = new ClipboardMenuItem(item);
96 menu_item.activate.connect(on_clicked_item);
97 menu_item.show();
98 append(menu_item);
99 }
100
101 public void show_menu()
102 {
103 popup(null, null, null, 0, Gtk.get_current_event_time());
104 }
105
106 /**
107 * Completely destroy menu by cleaning up menu items and menu itself.
108 */
109 public void destroy_menu()
110 {
111 foreach(Gtk.Widget item in get_children()) {
112 remove(item);
113
114 // make sure that static items do not get destroyed
115 if(static_menu_items == null || static_menu_items.find(item) == null)
116 {
117 item.destroy();
118 item.dispose();
119 }
120 }
121
122 destroy();
123 dispose();
124 }
125
126 /**
127 * User event: clicked menu item clear
128 */
129 private void on_clicked_clear()
130 {
131 controller.clear.begin();
132 }
133
134 /**
135 * User event: clicked menu item preferences
136 */
137 private void on_clicked_preferences()
138 {
139 controller.show_preferences();
140 }
141
142 /**
143 * User event: clicked menu item quit
144 */
145 private void on_clicked_quit()
146 {
147 controller.quit();
148 }
149
150 /**
151 * User event: clicked clipboard menu item
152 *
153 * @param menu_item menu item clicked
154 */
155 private void on_clicked_item(Gtk.MenuItem menu_item)
156 {
157 ClipboardMenuItem clipboard_menu_item = (ClipboardMenuItem)menu_item;
158 controller.select_item_by_checksum.begin(clipboard_menu_item.get_item_checksum());
159 }
160
161 /**
162 * Allow moving of cursor with vi-style j and k keys
163 */
164 private bool on_key_pressed(Gdk.EventKey event)
165 {
166 uint down_keyval = Gdk.keyval_from_name("j");
167 uint up_keyval = Gdk.keyval_from_name("k");
168
169 uint pressed_keyval = Gdk.keyval_to_lower(event.keyval);
170 if(pressed_keyval == down_keyval) {
171 if(get_selected_item() == null) {
172 select_first(true);
173 } else {
174 move_selected(1);
175 }
176 return true;
177 }
178 if(pressed_keyval == up_keyval) {
179 if(get_selected_item() == null) {
180 select_first(true);
181 }
182 move_selected(-1);
183 return true;
184 }
185
186 return false;
187 }
188 }
189 }
0 /*
1 * Diodon - GTK+ clipboard manager.
2 * Copyright (C) 2010 Diodon Team <diodon-team@lists.launchpad.net>
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published
6 * by the Free Software Foundation, either version 2 of the License, or (at
7 * your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
11 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
12 * License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 *
17 * Author:
18 * Oliver Sauder <os@esite.ch>
19 */
20
21 namespace Diodon
22 {
23 public enum ClipboardType
24 {
25 /**
26 * e.g when item is coming from storage
27 */
28 NONE,
29
30 /**
31 * normal clipboard
32 */
33 CLIPBOARD,
34
35 /**
36 * primary selection clipboard
37 */
38 PRIMARY;
39 }
40
41 public enum ClipboardCategory
42 {
43 // resp. all items
44 CLIPBOARD = 0,
45 TEXT,
46 FILES,
47 IMAGES;
48
49 public static ClipboardCategory[] all()
50 {
51 // all categories excluding clipboard as it is a placeholder for all
52 return { TEXT, FILES, IMAGES };
53 }
54
55 public string to_string()
56 {
57 switch (this) {
58 case CLIPBOARD:
59 return "clipboard";
60
61 case TEXT:
62 return "text";
63
64 case FILES:
65 return "files";
66
67 case IMAGES:
68 return "images";
69
70 default:
71 assert_not_reached();
72 }
73 }
74
75 public static ClipboardCategory from_string(string type)
76 {
77 switch(type) {
78 case "clipboard":
79 return CLIPBOARD;
80 case "text":
81 return TEXT;
82 case "files":
83 return FILES;
84 case "images":
85 return IMAGES;
86 default:
87 assert_not_reached();
88 }
89 }
90 }
91
92 /**
93 * Clipboard time range to filter results according to when it has been copied
94 */
95 public enum ClipboardTimerange
96 {
97 ALL = 0,
98 LAST_24_HOURS,
99 LAST_7_DAYS,
100 LAST_30_DAYS,
101 LAST_YEAR;
102
103 public static ClipboardTimerange[] all()
104 {
105 // all time ranges excluding all as it represents all
106 return { LAST_24_HOURS, LAST_7_DAYS, LAST_30_DAYS, LAST_YEAR };
107 }
108
109 public string to_string()
110 {
111 switch (this) {
112 case ALL:
113 return "all";
114
115 case LAST_24_HOURS:
116 return "last-24-hours";
117
118 case LAST_7_DAYS:
119 return "last-7-days";
120
121 case LAST_30_DAYS:
122 return "last-30-days";
123
124 case LAST_YEAR:
125 return "last-year";
126
127 default:
128 assert_not_reached();
129 }
130 }
131
132 public static ClipboardTimerange from_string(string type)
133 {
134 switch(type) {
135 case "all":
136 return ALL;
137 case "last-24-hours":
138 return LAST_24_HOURS;
139 case "last-7-days":
140 return LAST_7_DAYS;
141 case "last-30-days":
142 return LAST_30_DAYS;
143 case "last-year":
144 return LAST_YEAR;
145 default:
146 assert_not_reached();
147 }
148 }
149 }
150 }
151
0 /*
1 * Diodon - GTK+ clipboard manager.
2 * Copyright (C) 2010-2013 Diodon Team <diodon-team@lists.launchpad.net>
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published
6 * by the Free Software Foundation, either version 2 of the License, or (at
7 * your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
11 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
12 * License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 *
17 * Author:
18 * Oliver Sauder <os@esite.ch>
19 */
20
21 namespace Diodon
22 {
23 /**
24 * The controller is responsible to interact with all managers and views
25 * passing on information between such and storing the application state
26 * in the available models.
27 */
28 public class Controller : GLib.Object
29 {
30 private Settings settings_clipboard;
31 private Settings settings_plugins;
32 private HashTable<ClipboardType, ClipboardManager> clipboard_managers;
33 private ZeitgeistClipboardStorage storage;
34 private ClipboardConfiguration configuration;
35 private PreferencesView preferences_view;
36 private Peas.ExtensionSet extension_set;
37 private Peas.Engine peas_engine;
38 private ClipboardMenu recent_menu = null;
39 private HashTable<string,string> command_descriptions;
40 private List<Gtk.MenuItem> static_recent_menu_items;
41 private GLib.Regex _filter_pattern = null;
42
43 /**
44 * Called when a item has been selected.
45 */
46 public signal void on_select_item(IClipboardItem item);
47
48 /**
49 * Called when a new item is added
50 */
51 public signal void on_add_item(IClipboardItem item);
52
53 /**
54 * Called when a item needs to be removed
55 */
56 public signal void on_remove_item(IClipboardItem item);
57
58 /**
59 * Called when all items need to be cleared
60 */
61 public signal void on_clear();
62
63 /**
64 * Called after recent menu has been rebuilt
65 */
66 public signal void on_recent_menu_changed(Gtk.Menu recent_menu);
67
68 public delegate void ActionCallback(string[] args);
69
70 public Controller()
71 {
72 string diodon_dir = Utility.get_user_data_dir();
73 clipboard_managers = new HashTable<ClipboardType, ClipboardManager>(null, null);
74 command_descriptions = new HashTable<string,string>(GLib.str_hash, GLib.str_equal);
75
76 settings_clipboard = new Settings("net.launchpad.Diodon.clipboard");
77 settings_plugins = new Settings("net.launchpad.Diodon.plugins");
78
79 peas_engine = Peas.Engine.get_default();
80 peas_engine.add_search_path(Config.PLUGINS_DIR, Config.PLUGINS_DATA_DIR);
81 string user_plugins_dir = Path.build_filename(diodon_dir, "plugins");
82 peas_engine.add_search_path(user_plugins_dir, user_plugins_dir);
83 peas_engine.enable_loader("python");
84
85 storage = new ZeitgeistClipboardStorage();
86
87 configuration = new ClipboardConfiguration();
88
89 clipboard_managers.set(ClipboardType.CLIPBOARD, new ClipboardManager(ClipboardType.CLIPBOARD, configuration));
90 clipboard_managers.set(ClipboardType.PRIMARY, new PrimaryClipboardManager(configuration));
91
92 preferences_view = new PreferencesView();
93 }
94
95 public Controller.with_configuration(ClipboardConfiguration configuration, bool with_zeitgeist=true)
96 {
97 clipboard_managers = new HashTable<ClipboardType, ClipboardManager>(null, null);
98 command_descriptions = new HashTable<string,string>(null, null);
99 if(with_zeitgeist) {
100 storage = new ZeitgeistClipboardStorage();
101 }
102 clipboard_managers.set(ClipboardType.CLIPBOARD, new ClipboardManager(ClipboardType.CLIPBOARD, configuration));
103 clipboard_managers.set(ClipboardType.PRIMARY, new PrimaryClipboardManager(configuration));
104 preferences_view = new PreferencesView();
105 this.configuration = configuration;
106
107 create_filter_pattern_regex(configuration.filter_pattern);
108 enable_clipboard_manager(ClipboardType.CLIPBOARD, configuration.use_clipboard);
109 enable_clipboard_manager(ClipboardType.PRIMARY, configuration.use_primary);
110 enable_keep_clipboard_content(configuration.keep_clipboard_content);
111 }
112
113 private static void on_extension_added(Peas.ExtensionSet set, Peas.PluginInfo info,
114 Peas.Extension activatable)
115 {
116 ((Peas.Activatable)activatable).activate();
117 }
118
119 private static void on_extension_removed(Peas.ExtensionSet set, Peas.PluginInfo info,
120 Peas.Extension activatable)
121 {
122 ((Peas.Activatable)activatable).deactivate();
123 }
124
125 /**
126 * Initializes views, models and managers.
127 */
128 public async void init()
129 {
130 init_configuration();
131
132 // make sure that recent menu gets rebuild when recent history changes
133 yield rebuild_recent_menu();
134
135 storage.on_items_deleted.connect(() => { rebuild_recent_menu.begin(); } );
136 storage.on_items_inserted.connect(() => { rebuild_recent_menu.begin(); } );
137
138 // init peas plugin system
139 extension_set = new Peas.ExtensionSet(peas_engine, typeof(Peas.Activatable),
140 "object", this);
141 extension_set.@foreach((Peas.ExtensionSetForeachFunc)on_extension_added);
142
143 extension_set.extension_added.connect((info, exten) => {
144 ((Peas.Activatable)exten).activate();
145 });
146 extension_set.extension_removed.connect((info, exten) => {
147 ((Peas.Activatable)exten).deactivate();
148 });
149
150 settings_plugins.bind("active-plugins", peas_engine, "loaded-plugins",
151 SettingsBindFlags.DEFAULT);
152 }
153
154 /**
155 * Initialize configuration values
156 */
157 private void init_configuration()
158 {
159 settings_clipboard.bind("synchronize-clipboards", configuration,
160 "synchronize-clipboards", SettingsBindFlags.DEFAULT);
161 settings_clipboard.bind("add-images", configuration,
162 "add-images", SettingsBindFlags.DEFAULT);
163 settings_clipboard.bind("app-paste-keybindings", configuration,
164 "app-paste-keybindings", SettingsBindFlags.DEFAULT);
165
166 settings_clipboard.bind("keep-clipboard-content", configuration,
167 "keep-clipboard-content", SettingsBindFlags.DEFAULT);
168 settings_clipboard.changed["keep-clipboard-content"].connect(
169 (key) => {
170 enable_keep_clipboard_content(
171 configuration.keep_clipboard_content);
172 }
173 );
174 enable_keep_clipboard_content(
175 configuration.keep_clipboard_content);
176
177 settings_clipboard.bind("instant-paste", configuration,
178 "instant-paste", SettingsBindFlags.DEFAULT);
179
180 settings_clipboard.bind("recent-items-size", configuration,
181 "recent-items-size", SettingsBindFlags.DEFAULT);
182 settings_clipboard.changed["recent-items-size"].connect(
183 (key) => {
184 rebuild_recent_menu.begin();
185 }
186 );
187
188 settings_clipboard.bind("filter-pattern", configuration,
189 "filter-pattern", SettingsBindFlags.DEFAULT);
190 settings_clipboard.changed["filter-pattern"].connect(
191 (key) => {
192 create_filter_pattern_regex(configuration.filter_pattern);
193 }
194 );
195 create_filter_pattern_regex(configuration.filter_pattern);
196
197 // use clipboard and use primary needs to be initialized last as this
198 // will start the polling of clipboard process
199 settings_clipboard.bind("use-clipboard", configuration,
200 "use-clipboard", SettingsBindFlags.DEFAULT);
201 settings_clipboard.changed["use-clipboard"].connect(
202 (key) => {
203 enable_clipboard_manager(ClipboardType.CLIPBOARD,
204 configuration.use_clipboard);
205 }
206 );
207 enable_clipboard_manager(ClipboardType.CLIPBOARD,
208 configuration.use_clipboard);
209
210 settings_clipboard.bind("use-primary", configuration,
211 "use-primary", SettingsBindFlags.DEFAULT);
212 settings_clipboard.changed["use-primary"].connect(
213 (key) => {
214 enable_clipboard_manager(ClipboardType.PRIMARY,
215 configuration.use_primary);
216 }
217 );
218 enable_clipboard_manager(ClipboardType.PRIMARY,
219 configuration.use_primary);
220 }
221
222 /**
223 * Add an action to the application
224 */
225 public void add_command_line_action(string name, string desc, ActionCallback callback)
226 {
227 SimpleAction action = new SimpleAction (name, VariantType.STRING_ARRAY);
228 action.activate.connect((parameter) => callback(parameter.dup_strv()));
229 Application.get_default ().add_action(action);
230 command_descriptions[name] = desc;
231 }
232
233 public HashTable<string,string> get_command_descriptions ()
234 {
235 return command_descriptions;
236 }
237
238 /**
239 * Select a clipboard item identified by its checksum
240 */
241 public async void select_item_by_checksum(string checksum)
242 {
243 IClipboardItem item = yield storage.get_item_by_checksum(checksum);
244 if(item != null) {
245 yield select_item(item);
246 }
247 }
248
249 /**
250 * Select clipboard item. Discouraged to use as it usually means to hold
251 * a complete item in memory before selecting it. See select_item_checksum
252 * for an alternative.
253 *
254 * @param item item to be selected
255 */
256 public async void select_item(IClipboardItem item)
257 {
258 yield storage.select_item(item, configuration.use_clipboard,
259 configuration.use_primary);
260
261 on_select_item(item);
262
263 if(configuration.instant_paste) {
264 execute_paste(item);
265 }
266 }
267
268 /**
269 * Execute paste instantly according to set preferences.
270 *
271 * @param item item to be pasted
272 */
273 public void execute_paste(IClipboardItem item)
274 {
275 string key = null;
276 if(configuration.use_clipboard) {
277 key = "<Ctrl>V";
278
279 string? origin = Utility.get_path_of_active_application();
280 string? app_key = configuration.lookup_app_paste_keybinding(origin);
281 if(app_key != null) {
282 key = app_key;
283 }
284 }
285
286 // prefer primary selection paste as such works
287 // in more cases (e.g. terminal)
288 // however it does not work with files and images
289 if(configuration.use_primary && item is TextClipboardItem) {
290 key = "<Shift>Insert";
291 }
292
293 if(key != null) {
294 debug("Execute paste with keybinding %s", key);
295 Utility.perform_key_event(key, true, 100);
296 Utility.perform_key_event(key, false, 0);
297 }
298 }
299
300 /**
301 * Remove given item from view, storage and finally destroy
302 * it gracefully.
303 *
304 * @param item item to be removed
305 */
306 public async void remove_item(IClipboardItem item)
307 {
308 yield storage.remove_item(item);
309 on_remove_item(item);
310 }
311
312 /**
313 * Add given text as text item to current clipboard history
314 *
315 * @param text text to be added
316 * @param origin origin of clipboard item as application path
317 */
318 public async void add_text_item(ClipboardType type, string text, string? origin)
319 {
320 IClipboardItem item = new TextClipboardItem(type, text, origin, new DateTime.now_utc());
321 yield add_item(item);
322 }
323
324 /**
325 * Handling paths retrieved from clipboard by adding it to the storage
326 * and appending it to the menu of the indicator
327 *
328 * @param paths paths received
329 * @param origin origin of clipboard item as application path
330 */
331 public async void add_file_item(ClipboardType type, string paths, string? origin)
332 {
333 try {
334 IClipboardItem item = new FileClipboardItem(type, paths, origin, new DateTime.now_utc());
335 yield add_item(item);
336 } catch(FileError e) {
337 warning("Adding file(s) to history failed: " + e.message);
338 }
339 }
340
341 /**
342 * Handling image retrieved from clipboard bu adding it to the storage
343 * and appending it to the menu of the indicator.
344 *
345 * @param origin origin of clipboard item as application path
346 */
347 public async void add_image_item(ClipboardType type, Gdk.Pixbuf pixbuf, string? origin)
348 {
349 try {
350 IClipboardItem item = new ImageClipboardItem.with_image(type, pixbuf, origin, new DateTime.now_utc());
351 yield add_item(item);
352 } catch(GLib.Error e) {
353 warning("Adding image to history failed: " + e.message);
354 }
355 }
356
357 /**
358 * Handling given item by checking if item is equal last added item
359 * and if not so, adding it to history
360 *
361 * @param item item received
362 */
363 public async void add_item(IClipboardItem item)
364 {
365 ClipboardType type = item.get_clipboard_type();
366 string label = item.get_label();
367 IClipboardItem current_item = storage.get_current_item(type);
368
369 // check if received item is different from last item
370 if(current_item == null || !IClipboardItem.equal_func(current_item, item)) {
371 // check whether item needs to be filtered
372 if(!filter_item(item)) {
373 debug("received item of type %s from clipboard %d with label %s",
374 item.get_type().name(), type, label);
375
376 yield storage.add_item(item);
377 on_add_item(item);
378
379 if(configuration.synchronize_clipboards) {
380 synchronize(item);
381 }
382 }
383 }
384 }
385
386 /**
387 * Verify whether given clipbiard item is filtered and should not be added
388 * to clipboard history
389 */
390 public bool filter_item(IClipboardItem item)
391 {
392 try {
393 if(this._filter_pattern != null) {
394 return this._filter_pattern.match_full(item.get_text());
395 }
396 } catch(RegexError e) {
397 warning("Error occorued while matching item with filter pattern, item not being filter: %s", e.message);
398 }
399
400 // do not filter if there is an error
401 return false;
402 }
403
404 /**
405 * Get recent items whereas size is not bigger than configured recent
406 * item size
407 *
408 * @param cats categories of recent items to get; null for all
409 * @param date_copied filter results by given timerange; all per default
410 * @param cancellable optional cancellable handler
411 * @return list of recent clipboard items
412 */
413 public async List<IClipboardItem> get_recent_items(ClipboardCategory[]? cats = null,
414 ClipboardTimerange date_copied = ClipboardTimerange.ALL, Cancellable? cancellable = null)
415 {
416 return yield storage.get_recent_items(configuration.recent_items_size, cats, date_copied, cancellable);
417 }
418
419 /**
420 * Get clipboard items which match given search query
421 *
422 * @param search_query query to search items for
423 * @param cats categories for search query or null for all
424 * @param date_copied filter results by given timerange; all per default
425 * @param cancellable optional cancellable handler
426 * @return clipboard items matching given search query
427 */
428 public async List<IClipboardItem> get_items_by_search_query(string search_query,
429 ClipboardCategory[]? cats = null, ClipboardTimerange date_copied = ClipboardTimerange.ALL,
430 Cancellable? cancellable = null)
431 {
432 return yield storage.get_items_by_search_query(search_query, cats, date_copied, cancellable);
433 }
434
435 /**
436 * Get clipboard item by its given checksum
437 *
438 * @param checksum checksum of clipboard item
439 * @return clipboard item of given checksum; othterwise null if not available
440 */
441 public async IClipboardItem? get_item_by_checksum(string checksum, Cancellable? cancellable = null)
442 {
443 return yield storage.get_item_by_checksum(checksum, cancellable);
444 }
445
446 /**
447 * Get currently selected item for given clipboard type
448 *
449 * @param type clipboard type
450 * @return clipboard item
451 */
452 public IClipboardItem get_current_item(ClipboardType type)
453 {
454 return storage.get_current_item(type);
455 }
456
457 /**
458 * access to current configuration settings
459 */
460 public ClipboardConfiguration get_configuration()
461 {
462 return configuration;
463 }
464
465 /**
466 * Set text on all other clipboards then current type
467 */
468 private void synchronize(IClipboardItem item)
469 {
470 // only text clipboard item can be synced
471 if(item is TextClipboardItem) {
472 ClipboardType type = item.get_clipboard_type();
473 foreach(ClipboardManager clipboard_manager in clipboard_managers.get_values()) {
474 if(type != clipboard_manager.clipboard_type) {
475 // check if item is already active in clipboard
476 // which will be synced to
477 IClipboardItem current_item = storage.get_current_item(
478 clipboard_manager.clipboard_type);
479 if(current_item == null || !IClipboardItem.equal_func(current_item, item)) {
480 clipboard_manager.select_item(item);
481 }
482 }
483 }
484 }
485 }
486
487 /**
488 * Called when clipboard is empty and data might be needed to restored
489 *
490 * @param type clipboard type
491 */
492 private void clipboard_empty(ClipboardType type)
493 {
494 // check if a item is there to restore lost content
495 IClipboardItem item = storage.get_current_item(type);
496 if(item != null) {
497 debug("Clipboard " + "%d".printf(type) + " is empty.");
498 ClipboardManager manager = clipboard_managers.get(type);
499 manager.select_item(item);
500 }
501 }
502
503 private void create_filter_pattern_regex(string filter_pattern)
504 {
505 try {
506 if(filter_pattern != null && filter_pattern != "") {
507 debug("Creating filter pattern %s", filter_pattern);
508 this._filter_pattern = new GLib.Regex(filter_pattern, RegexCompileFlags.DOLLAR_ENDONLY);
509 return;
510 }
511 } catch(RegexError e) {
512 warning("Invalid regex pattern %s, Error: %s", filter_pattern, e.message);
513 }
514
515 this._filter_pattern = null;
516 }
517
518 /**
519 * Create clipboard menu with current recent items.
520 */
521 public async void rebuild_recent_menu()
522 {
523 List<IClipboardItem> items = yield get_recent_items();
524
525 if(recent_menu != null) {
526 recent_menu.destroy_menu();
527 }
528
529 recent_menu = new ClipboardMenu(this, items, static_recent_menu_items,
530 storage.is_privacy_mode_enabled());
531 on_recent_menu_changed(recent_menu);
532 }
533
534 /**
535 * Add a static recent menu item which will always be shown below separator
536 * even after recent menu has been rebuilt.
537 *
538 * @param menu_item menu item to be added
539 */
540 public async void add_static_recent_menu_item(Gtk.MenuItem menu_item)
541 {
542 if(static_recent_menu_items == null) {
543 static_recent_menu_items = new List<Gtk.MenuItem>();
544 }
545
546 static_recent_menu_items.append(menu_item);
547 yield rebuild_recent_menu();
548 }
549
550 /**
551 * Remove static recent menu item so it won't appear on the recent menu
552 * anymore. This method doesn't dispose the menu item - caller
553 * needs to take care of this in case menu item should be destroyed.
554 *
555 * @param menu_item item to be removed
556 */
557 public async void remove_static_recent_menu_item(Gtk.MenuItem menu_item)
558 {
559 if(static_recent_menu_items == null) {
560 warning("Remove recent menu item has been called but no registered static recent menu items are available");
561 return;
562 }
563
564 static_recent_menu_items.remove(menu_item);
565 yield rebuild_recent_menu();
566 }
567
568 /**
569 * Open menu to view history
570 */
571 public void show_history()
572 {
573 recent_menu.show_menu();
574 }
575
576 /**
577 * Get current recent menu. Recent menu can change at any time so
578 * consider registering to on_recent_menu_changed() event.
579 */
580 public Gtk.Menu get_recent_menu()
581 {
582 return recent_menu;
583 }
584
585 /**
586 * connect/disconnect and attach/disattach to signals of given clipboard
587 * type to enable/disable it.
588 *
589 * @param type type of clipboard
590 * @param enable true for enabling; false for disabling
591 */
592 private void enable_clipboard_manager(ClipboardType type, bool enable)
593 {
594 ClipboardManager manager = clipboard_managers.get(type);
595
596 if(enable) {
597 manager.on_text_received.connect(add_text_item);
598 manager.on_uris_received.connect(add_file_item);
599 manager.on_image_received.connect(add_image_item);
600 on_select_item.connect(manager.select_item);
601 on_clear.connect(manager.clear);
602 manager.start();
603 }
604 else {
605 manager.stop();
606 manager.on_text_received.disconnect(add_text_item);
607 manager.on_uris_received.disconnect(add_file_item);
608 manager.on_image_received.disconnect(add_image_item);
609 on_select_item.disconnect(manager.select_item);
610 on_clear.disconnect(manager.clear);
611 }
612 }
613
614 /**
615 * connect/disconnect to signals of all clipboard manager to
616 * enable/disable keep clipboard content support
617 *
618 * @param enable true for enabling; false for disabling
619 */
620 private void enable_keep_clipboard_content(bool enable)
621 {
622 foreach(ClipboardManager clipboard_manager in clipboard_managers.get_values()) {
623 if(enable) {
624 clipboard_manager.on_empty.connect(clipboard_empty);
625 }
626 else {
627 clipboard_manager.on_empty.disconnect(clipboard_empty);
628 }
629 }
630 }
631
632 /**
633 * Show preferences dialog
634 */
635 public void show_preferences()
636 {
637 preferences_view.show(configuration);
638 }
639
640 /**
641 * Clear all clipboard items from history
642 */
643 public async void clear()
644 {
645 yield storage.clear();
646 on_clear();
647
648 // Bug #1383013:
649 // in some rare circumstances doesn't the recent menu get refreshed
650 // when clear is executed; therefore forcing it here as a workaround
651 yield rebuild_recent_menu();
652 }
653
654 /**
655 * Quit diodon
656 */
657 public void quit()
658 {
659 Gtk.main_quit();
660
661 // shutdown all plugins
662 if(extension_set != null) {
663 extension_set.@foreach((Peas.ExtensionSetForeachFunc)on_extension_removed);
664 }
665 }
666 }
667 }
668
0 /*
1 * Diodon - GTK+ clipboard manager.
2 * Copyright (C) 2011 Diodon Team <diodon-team@lists.launchpad.net>
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published
6 * by the Free Software Foundation, either version 2 of the License, or (at
7 * your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
11 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
12 * License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 *
17 * Author:
18 * Oliver Sauder <os@esite.ch>
19 */
20
21 namespace Diodon
22 {
23 /**
24 * Represents a file clipboard item holding a path to a file.
25 */
26 public class FileClipboardItem : GLib.Object, IClipboardItem
27 {
28 /**
29 * a special target type for copying files so nautilus can paste it
30 */
31 private static Gdk.Atom copy_files = Gdk.Atom.intern_static_string("x-special/gnome-copied-files");
32
33 /**
34 * file paths separated with \n
35 */
36 private string _paths;
37 private string? _origin;
38 private ClipboardType _clipboard_type;
39 private DateTime _date_copied;
40
41 /**
42 * Default data constructor needed for reflection.
43 *
44 * @param clipboard_type clipboard type item is coming from
45 * @param data paths separated with \n
46 * @param origin origin of clipboard item as application path
47 */
48 public FileClipboardItem(ClipboardType clipboard_type, string data, string? origin, DateTime date_copied) throws FileError
49 {
50 _clipboard_type = clipboard_type;
51 _paths = data;
52 _origin = origin;
53 _date_copied = date_copied;
54
55 // check if all paths are available
56 string[] paths = convert_to_paths(_paths);
57 foreach(unowned string path in paths) {
58 File file = File.new_for_path(path);
59 if(!file.query_exists()) {
60 throw new FileError.NOENT("No such file or directory " + path);
61 }
62 }
63 }
64
65 /**
66 * {@inheritDoc}
67 */
68 public ClipboardType get_clipboard_type()
69 {
70 return _clipboard_type;
71 }
72
73 /**
74 * {@inheritDoc}
75 */
76 public DateTime get_date_copied()
77 {
78 return _date_copied;
79 }
80
81 /**
82 * {@inheritDoc}
83 */
84 public string get_text()
85 {
86 return _paths;
87 }
88
89 /**
90 * {@inheritDoc}
91 */
92 public string? get_origin()
93 {
94 return _origin;
95 }
96
97 /**
98 * {@inheritDoc}
99 */
100 public string get_label()
101 {
102 string home = Environment.get_home_dir();
103
104 // label should not be longer than 50 letters
105 string label = _paths.replace("\n", " ");
106
107 // replacing home dir with common known tilde
108 label = label.replace(home, "~");
109
110 if (label.char_count() > 50) {
111 long index_char = label.index_of_nth_char(50);
112 label = label.substring(0, index_char) + "...";
113 }
114
115 return label;
116 }
117
118 /**
119 * {@inheritDoc}
120 */
121 public string get_mime_type()
122 {
123 // mime type of first file is used
124 // if retrieving of content type fails, use text/plain as fallback
125 string mime_type = "text/plain";
126 string[] uris = convert_to_uris(_paths);
127 File file = File.new_for_uri(uris[0]);
128 try {
129 FileInfo file_info = file.query_info(FileAttribute.STANDARD_FAST_CONTENT_TYPE, 0, null);
130 mime_type = file_info.get_attribute_as_string(FileAttribute.STANDARD_FAST_CONTENT_TYPE);
131 } catch(GLib.Error e) {
132 warning("Could not determine mime type of file %s", uris[0]);
133 }
134
135 return mime_type;
136 }
137
138 /**
139 * {@inheritDoc}
140 */
141 public ClipboardCategory get_category()
142 {
143 return ClipboardCategory.FILES;
144 }
145
146 /**
147 * {@inheritDoc}
148 */
149 public Gtk.Image? get_image()
150 {
151 Gtk.Image image = new Gtk.Image.from_gicon(get_icon(), Gtk.IconSize.MENU);
152 return image;
153 }
154
155 /**
156 * {@inheritDoc}
157 */
158 public Icon get_icon()
159 {
160 const string FILE_ATTRS =
161 FileAttribute.THUMBNAIL_PATH;
162
163 // icon of first file is used
164 string mime_type = get_mime_type();
165 string[] uris = convert_to_uris(_paths);
166 File file = File.new_for_uri(uris[0]);
167 try {
168 FileInfo info = file.query_info(FILE_ATTRS, 0);
169 Icon icon = info.get_icon();
170 string thumbnail_path = info.get_attribute_byte_string(FileAttribute.THUMBNAIL_PATH);
171 if(thumbnail_path != null) {
172 return new FileIcon(File.new_for_path(thumbnail_path));
173 }
174 else if(icon != null) {
175 return icon;
176 }
177 } catch(GLib.Error e) {
178 warning("Could not determine mime type of file %s", uris[0]);
179 }
180
181 // default icon of mime type
182 return ContentType.get_icon(mime_type);
183 }
184
185 /**
186 * {@inheritDoc}
187 */
188 public ByteArray? get_payload()
189 {
190 return null;
191 }
192
193 /**
194 * {@inheritDoc}
195 */
196 public string get_checksum()
197 {
198 return Checksum.compute_for_string(ChecksumType.SHA1, _paths);
199 }
200
201 /**
202 * {@inheritDoc}
203 */
204 public void to_clipboard(Gtk.Clipboard clipboard)
205 {
206 // create default uri target and text target
207 Gtk.TargetEntry[] targets = null;
208 Gtk.TargetList target_list = new Gtk.TargetList(targets);
209 target_list.add_text_targets(0);
210 target_list.add_uri_targets(0);
211 target_list.add(copy_files, 0, 0); // add special nautilus target
212 targets = Gtk.target_table_new_from_list(target_list);
213
214 // set data callbacks with a empty clear func as
215 // there is nothing to be cleared
216 clipboard.set_with_owner(targets,
217 (Gtk.ClipboardGetFunc)get_clipboard_data_callback,
218 (Gtk.ClipboardClearFunc)clear_clipboard_data_callback, this);
219
220 // store data in clipboard so when diodon is closed
221 // data still can be pasted
222 clipboard.store();
223 }
224
225 /**
226 * {@inheritDoc}
227 */
228 public bool equals(IClipboardItem* item)
229 {
230 bool equals = false;
231
232 if(item is FileClipboardItem) {
233 equals = strcmp(_paths, item->get_text()) == 0;
234 }
235
236 return equals;
237 }
238
239 /**
240 * {@inheritDoc}
241 */
242 public uint hash()
243 {
244 return str_hash(_paths);
245 }
246
247 /**
248 * Callback method called by Gtk.Clipboard to get the clipboard data
249 * whereas in this case it is the path as text and the uri for
250 * pasting file itself. Static as instance to FileClipboardItem is passed on
251 * as user_data.
252 */
253 private static void get_clipboard_data_callback(Gtk.Clipboard clipboard, Gtk.SelectionData selection_data,
254 uint info, void* user_data)
255 {
256 FileClipboardItem item = (FileClipboardItem) user_data;
257
258 Gdk.Atom[] targets = new Gdk.Atom[1];
259 targets[0] = selection_data.get_target();
260
261 // set content according to requested target
262 if(Gtk.targets_include_text(targets)) {
263 debug("get clipboard file data as text");
264 selection_data.set_text(item._paths, -1);
265 }
266 else if(Gtk.targets_include_uri(targets)) {
267 debug("get clipboard file data as uris");
268 string[] uris = convert_to_uris(item._paths);
269 selection_data.set_uris(uris);
270 }
271 else {
272 debug("get clipboard file data as copied files");
273 string[] uris = convert_to_uris(item._paths);
274 // set special nautilus target which should copy the files
275 // 8 number of bits in a unit are used
276 string copy_files_data = "copy\n" + join("\n", uris);
277 selection_data.set(copy_files, 8, string_to_uchar_array(copy_files_data));
278 }
279 }
280
281 /**
282 * Callback method called by Gtk.Clipboard to clear data.
283 * Currently empty method as there is nothing to be cleared.
284 */
285 private static void clear_clipboard_data_callback(Gtk.Clipboard clipboard, void* user_data)
286 {
287 }
288
289 /**
290 * Helper method to convert string to uchar array.
291 *
292 * @param str string to be converted
293 */
294 private static uchar[] string_to_uchar_array(string str)
295 {
296 uchar[] data = new uchar[0];
297 for (int i = 0; i < str.length; ++i) {
298 data += (uchar) str[i];
299 }
300 return data;
301 }
302
303 /**
304 * Helper method to join a array of string together with
305 * given separator.
306 *
307 * @param separator separator to join string
308 * @param array array of strings to be joined
309 */
310 private static string join(string separator, string[] array)
311 {
312 string result = "";
313 if(array.length > 0) {
314 result = array[0];
315 for(int i = 1; i < array.length; ++i) {
316 result += separator;
317 result += array[i];
318 }
319 }
320
321 return result;
322 }
323
324 /**
325 * Convert given paths to uris
326 *
327 * @param paths paths to be converted
328 */
329 private static string[] convert_to_uris(string paths)
330 {
331 string[] uris = convert_to_paths(paths);
332 for(int i = 0; i < uris.length; ++i) {
333 string uri = uris[i];
334 uri = "file://" + uri;
335 uris[i] = uri;
336 }
337
338 return uris;
339 }
340
341 /**
342 * Helper method to convert paths string to a path array
343 *
344 * @param path string with new line separator per path
345 */
346 private static string[] convert_to_paths(string paths)
347 {
348 string[] result = paths.split("\n");
349 return result;
350 }
351 }
352 }
353
0 /*
1 * Diodon - GTK+ clipboard manager.
2 * Copyright (C) 2011-2013 Diodon Team <diodon-team@lists.launchpad.net>
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published
6 * by the Free Software Foundation, either version 2 of the License, or (at
7 * your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
11 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
12 * License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 *
17 * Author:
18 * Oliver Sauder <os@esite.ch>
19 */
20
21 namespace Diodon
22 {
23 /**
24 * An image clipboard item representing such in a preview image.
25 */
26 public class ImageClipboardItem : GLib.Object, IClipboardItem
27 {
28 private ClipboardType _clipboard_type;
29 private string _checksum; // checksum to identify pic content
30 private Gdk.Pixbuf _pixbuf;
31 private string _label;
32 private string? _origin;
33 private DateTime _date_copied;
34
35 /**
36 * Create image clipboard item by a pixbuf.
37 *
38 * @param clipboard_type clipboard type item is coming from
39 * @param pixbuf image from clipboard
40 * @param origin origin of clipboard item as application path
41 */
42 public ImageClipboardItem.with_image(ClipboardType clipboard_type, Gdk.Pixbuf pixbuf, string? origin, DateTime date_copied) throws GLib.Error
43 {
44 _clipboard_type = clipboard_type;
45 _origin = origin;
46 _date_copied = date_copied;
47 extract_pixbuf_info(pixbuf);
48 }
49
50 /**
51 * Create image clipboard item by given payload.
52 *
53 * @param clipboard_type clipboard type item is coming from
54 * @param pixbuf image from clipboard
55 * @param origin origin of clipboard item as application path
56 */
57 public ImageClipboardItem.with_payload(ClipboardType clipboard_type, ByteArray payload, string? origin, DateTime date_copied) throws GLib.Error
58 {
59 _clipboard_type = clipboard_type;
60 _origin = origin;
61 _date_copied = date_copied;
62
63 Gdk.PixbufLoader loader = new Gdk.PixbufLoader();
64 loader.write(payload.data);
65 loader.close();
66 Gdk.Pixbuf pixbuf = loader.get_pixbuf();
67 extract_pixbuf_info(pixbuf);
68 }
69
70 /**
71 * {@inheritDoc}
72 */
73 public ClipboardType get_clipboard_type()
74 {
75 return _clipboard_type;
76 }
77
78 /**
79 * {@inheritDoc}
80 */
81 public DateTime get_date_copied()
82 {
83 return _date_copied;
84 }
85
86 /**
87 * {@inheritDoc}
88 */
89 public string get_text()
90 {
91 return _label; // label is representation of image
92 }
93
94 /**
95 * {@inheritDoc}
96 */
97 public string? get_origin()
98 {
99 return _origin;
100 }
101
102 /**
103 * {@inheritDoc}
104 */
105 public string get_label()
106 {
107 return _label;
108 }
109
110 /**
111 * {@inheritDoc}
112 */
113 public string get_mime_type()
114 {
115 // images are always converted to png
116 return "image/png";
117 }
118
119 /**
120 * {@inheritDoc}
121 */
122 public Icon get_icon()
123 {
124 try {
125 File file = save_tmp_pixbuf(_pixbuf);
126 FileIcon icon = new FileIcon(file);
127 return icon;
128 } catch(Error e) {
129 warning("Could not create icon for image %s. Fallback to content type",
130 _checksum);
131 return ContentType.get_icon(get_mime_type());
132 }
133 }
134
135 /**
136 * {@inheritDoc}
137 */
138 public ClipboardCategory get_category()
139 {
140 return ClipboardCategory.IMAGES;
141 }
142
143 /**
144 * {@inheritDoc}
145 */
146 public Gtk.Image? get_image()
147 {
148 Gdk.Pixbuf pixbuf_preview = create_scaled_pixbuf(_pixbuf);
149 return new Gtk.Image.from_pixbuf(pixbuf_preview);
150 }
151
152 /**
153 * {@inheritDoc}
154 */
155 public ByteArray? get_payload() throws GLib.Error
156 {
157 uint8[] buffer;
158 _pixbuf.save_to_buffer(out buffer, "png");
159 return new ByteArray.take(buffer);
160 }
161
162 /**
163 * {@inheritDoc}
164 */
165 public string get_checksum()
166 {
167 return _checksum;
168 }
169
170 /**
171 * {@inheritDoc}
172 */
173 public void to_clipboard(Gtk.Clipboard clipboard)
174 {
175 clipboard.set_image(_pixbuf);
176 clipboard.store();
177 }
178
179 /**
180 * {@inheritDoc}
181 */
182 public bool equals(IClipboardItem* item)
183 {
184 bool equals = false;
185
186 if(item is ImageClipboardItem) {
187 ImageClipboardItem* image_item = (ImageClipboardItem*)item;
188 equals = strcmp(_checksum, image_item->_checksum) == 0;
189 }
190
191 return equals;
192 }
193
194 /**
195 * {@inheritDoc}
196 */
197 public uint hash()
198 {
199 // use checksum to create hash code
200 return str_hash(_checksum);
201 }
202
203 /**
204 * Extracts all pixbuf information which are needed to show image
205 * in the view without having the pixbuf in the memory.
206 *
207 * @param pixbuf pixbuf to extract info from
208 */
209 private void extract_pixbuf_info(Gdk.Pixbuf pixbuf)
210 {
211 // create checksum of picture
212 Checksum checksum = new Checksum(ChecksumType.SHA1);
213 checksum.update(pixbuf.get_pixels(), pixbuf.height * pixbuf.rowstride);
214 _checksum = checksum.get_string().dup();
215
216 // label in format [{width}x{height}]
217 _label ="[%dx%d]".printf(pixbuf.width, pixbuf.height);
218 _pixbuf = pixbuf;
219 }
220
221 /**
222 * Create a menu icon size scaled pix buf
223 *
224 * @param pixbuf scaled pixbuf
225 */
226 private static Gdk.Pixbuf create_scaled_pixbuf(Gdk.Pixbuf pixbuf)
227 {
228 // get menu icon size
229 Gtk.IconSize size = Gtk.IconSize.MENU;
230 int width, height;
231 if(!Gtk.icon_size_lookup(size, out width, out height)) {
232 // set default when icon size lookup fails
233 width = 16;
234 height = 16;
235 }
236
237 // scale pixbuf to menu icon size
238 Gdk.Pixbuf scaled = pixbuf.scale_simple(width, height, Gdk.InterpType.BILINEAR);
239 return scaled;
240 }
241
242 /**
243 * Store pixbuf in tmp folder but only if it does not exist
244 *
245 * @param pixbuf pixbuf to be stored
246 * @return file object of stored pixbuf
247 */
248 private File save_tmp_pixbuf(Gdk.Pixbuf pixbuf) throws GLib.Error
249 {
250 string filename = Path.build_filename(Environment.get_tmp_dir(),
251 "diodon-" + _checksum + ".png");
252
253 File file = File.new_for_path(filename);
254 if(!file.query_exists(null)) {
255 pixbuf.save(filename, "png");
256 }
257
258 return file;
259 }
260 }
261 }
262
0 /*
1 * Diodon - GTK+ clipboard manager.
2 * Copyright (C) 2010-2011 Diodon Team <diodon-team@lists.launchpad.net>
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published
6 * by the Free Software Foundation, either version 2 of the License, or (at
7 * your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
11 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
12 * License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 *
17 * Author:
18 * Oliver Sauder <os@esite.ch>
19 */
20
21 namespace Diodon
22 {
23 /**
24 * Preferences dialog view loading user interface from preferences.ui
25 */
26 class PreferencesView : GLib.Object
27 {
28 private Gtk.Dialog preferences;
29
30 public PreferencesView()
31 {
32 }
33
34 /**
35 * Show preferences view
36 *
37 * @param configuraiton configuration to initialize dialog
38 */
39 public void show(ClipboardConfiguration configuration)
40 {
41 // check if preferences window is already open
42 if(preferences == null) {
43 try {
44 // builder
45 Gtk.Builder builder = new Gtk.Builder();
46 builder.set_translation_domain(Config.GETTEXT_PACKAGE);
47 builder.add_from_file(Path.build_filename(Config.SHAREDIR, "preferences.ui"));
48
49 // use_clipboard
50 Gtk.ToggleButton use_clipboard =
51 builder.get_object("checkbutton_use_clipboard") as Gtk.ToggleButton;
52 use_clipboard.active = configuration.use_clipboard;
53 use_clipboard.toggled.connect(() => {
54 configuration.use_clipboard = !configuration.use_clipboard;
55 } );
56
57 // use_primary
58 Gtk.ToggleButton use_primary = builder.get_object("checkbutton_use_primary") as Gtk.ToggleButton;
59 use_primary.active = configuration.use_primary;
60 use_primary.toggled.connect(() => {
61 configuration.use_primary = !configuration.use_primary;
62 } );
63
64 // add images
65 Gtk.ToggleButton add_images = builder.get_object("checkbutton_add_images") as Gtk.ToggleButton;
66 add_images.active = configuration.add_images;
67 add_images.toggled.connect(() => {
68 configuration.add_images = !configuration.add_images;
69 } );
70
71 // synchronize_clipboards
72 Gtk.ToggleButton synchronize_clipboards =
73 builder.get_object("checkbutton_synchronize_clipboards") as Gtk.ToggleButton;
74 synchronize_clipboards.active = configuration.synchronize_clipboards;
75 synchronize_clipboards.toggled.connect(() => {
76 configuration.synchronize_clipboards = !configuration.synchronize_clipboards;
77 } );
78
79 // keep clipboard content
80 Gtk.ToggleButton keep_clipboard_content =
81 builder.get_object("checkbutton_keep_clipboard_content") as Gtk.ToggleButton;
82 keep_clipboard_content.active = configuration.keep_clipboard_content;
83 keep_clipboard_content.toggled.connect(() => {
84 configuration.keep_clipboard_content = !configuration.keep_clipboard_content;
85 } );
86
87 // instant paste
88 Gtk.ToggleButton instant_paste =
89 builder.get_object("checkbutton_instant_paste") as Gtk.ToggleButton;
90 instant_paste.active = configuration.instant_paste;
91 instant_paste.toggled.connect(() => {
92 configuration.instant_paste = !configuration.instant_paste;
93 } );
94
95 // recent_items_size
96 Gtk.SpinButton recent_items_size =
97 builder.get_object("spinbutton_recent_items_size") as Gtk.SpinButton;
98 recent_items_size.value = configuration.recent_items_size;
99 recent_items_size.value_changed.connect(() => {
100 configuration.recent_items_size = recent_items_size.get_value_as_int();
101 });
102 recent_items_size.editing_done.connect(() => {
103 configuration.recent_items_size = recent_items_size.get_value_as_int();
104 });
105
106 // plugins
107 PeasGtk.PluginManager manager = new PeasGtk.PluginManager(
108 Peas.Engine.get_default());
109 Gtk.Box plugins_box = builder.get_object("plugins_box") as Gtk.Box;
110 plugins_box.pack_start(manager);
111
112 // close
113 Gtk.Button close = builder.get_object("button_close") as Gtk.Button;
114 close.clicked.connect(hide);
115
116 // preferences
117 preferences = builder.get_object("dialog_preferences") as Gtk.Dialog;
118 preferences.destroy.connect_after(reset);
119 preferences.show_all();
120 }
121 catch(Error e) {
122 warning("Could not initialize preferences dialog. Error: " + e.message);
123 }
124 }
125 }
126
127 /**
128 * Hide preferences view
129 */
130 public void hide()
131 {
132 preferences.close();
133 }
134
135 /**
136 * Reset preferences dialog
137 */
138 public void reset()
139 {
140 preferences = null;
141 }
142 }
143 }
144
0 /*
1 * Diodon - GTK+ clipboard manager.
2 * Copyright (C) 2011 Diodon Team <diodon-team@lists.launchpad.net>
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published
6 * by the Free Software Foundation, either version 2 of the License, or (at
7 * your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
11 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
12 * License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 *
17 * Author:
18 * Oliver Sauder <os@esite.ch>
19 */
20
21 namespace Diodon
22 {
23 /**
24 * Specific clipboard manager for primary selection extending
25 * basic functionality with primary selection specific use cases.
26 * Note that primary selection clipboard manager only supports text.
27 */
28 class PrimaryClipboardManager : ClipboardManager
29 {
30 private bool stopped = false;
31 private string? _last_received = null;
32
33 /**
34 * Type is alwawys ClipboardType.PRIMARY for this specific primary
35 * selection manager.
36 */
37 public PrimaryClipboardManager(ClipboardConfiguration configuration)
38 {
39 base(ClipboardType.PRIMARY, configuration);
40 }
41
42 /**
43 * Owner does not always get changed when selection has been changed
44 * therefore we need a timer for the primary selection.
45 */
46 public override void start()
47 {
48 stopped = false;
49 Timeout.add(500, request_text_callback);
50 }
51
52 /**
53 * Owner does not always get changed when selection has been changed
54 * therefore we need a timer for the primary selection.
55 */
56 public override void stop()
57 {
58 stopped = true;
59 }
60
61 /**
62 * Primary selection only supports text therefore ignoring
63 * all others.
64 *
65 * @param item clipboard item to be selected
66 */
67 public override void select_item(IClipboardItem item)
68 {
69 if(item is TextClipboardItem) {
70 base.select_item(item);
71 }
72 }
73
74 /**
75 * Check if the mouse button or shift button is pressed
76 * before primary selection gets accepted. As otherwise the history
77 * gets flooded with several clipboard items.
78 *
79 * @return true if button are in an acceptable state; otherwise false.
80 */
81 private bool check_button_state()
82 {
83 Gdk.Window rootwin = Gdk.get_default_root_window();
84 Gdk.Display display = rootwin.get_display();
85 Gdk.ModifierType modifier = 0;
86
87 Gdk.Device device = display.get_device_manager().get_client_pointer();
88 device.get_state(rootwin, (double[])null, out modifier);
89
90 // only accepted when left mouse button and shift button
91 // are not pressed
92 if((modifier & Gdk.ModifierType.BUTTON1_MASK) == 0) {
93 if((modifier & Gdk.ModifierType.SHIFT_MASK) == 0) {
94 return true;
95 }
96 }
97
98 return false;
99 }
100
101 /**
102 * Helper method for requesting primary text within a timer
103 *
104 * @return false to stop timer if requested; otherwise true.
105 */
106 private bool request_text_callback()
107 {
108 if(!stopped) {
109 // checking for text
110 string? text = request_text();
111 if(text != null && text != "") {
112 // check if text can be accepted
113 if(check_button_state()) {
114 // we are in a timer here and because of performance
115 // reasons we want to make sure that this is not the same
116 // content again before we check path_of_active_application
117 if(_last_received == null || strcmp(text, _last_received) != 0) {
118 string? origin = Utility.get_path_of_active_application();
119 _last_received = text;
120 on_text_received(type, text, origin);
121 }
122 }
123 }
124 // checking if clipboard might be empty
125 else {
126 check_clipboard_emptiness();
127 }
128 }
129
130 return !stopped; // if stopped return false to stop timer
131 }
132 }
133 }
134
0 /*
1 * Diodon - GTK+ clipboard manager.
2 * Copyright (C) 2010-2011 Diodon Team <diodon-team@lists.launchpad.net>
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published
6 * by the Free Software Foundation, either version 2 of the License, or (at
7 * your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
11 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
12 * License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 *
17 * Author:
18 * Oliver Sauder <os@esite.ch>
19 */
20
21 namespace Diodon
22 {
23 /**
24 * Represents a text clipboard item holding simple text.
25 */
26 public class TextClipboardItem : GLib.Object, IClipboardItem
27 {
28 private string _text;
29 private string? _origin;
30 private ClipboardType _clipboard_type;
31 private DateTime _date_copied;
32
33 /**
34 * Default data constructor needed for reflection.
35 *
36 * @param clipboard_type clipboard type item is coming from
37 * @param data simple text
38 * @param origin origin of clipboard item as application path
39 */
40 public TextClipboardItem(ClipboardType clipboard_type, string data, string? origin, DateTime date_copied)
41 {
42 _clipboard_type = clipboard_type;
43 _text = data;
44 _origin = origin;
45 _date_copied = date_copied;
46 }
47
48 /**
49 * {@inheritDoc}
50 */
51 public ClipboardType get_clipboard_type()
52 {
53 return _clipboard_type;
54 }
55
56 /**
57 * {@inheritDoc}
58 */
59 public DateTime get_date_copied()
60 {
61 return _date_copied;
62 }
63
64 /**
65 * {@inheritDoc}
66 */
67 public string get_text()
68 {
69 return _text;
70 }
71
72 /**
73 * {@inheritDoc}
74 */
75 public string? get_origin()
76 {
77 return _origin;
78 }
79
80 /**
81 * {@inheritDoc}
82 */
83 public string get_label()
84 {
85 // label should not be longer than 50 letters
86 string label = _text.replace("\n", " ");
87 if (label.char_count() > 50) {
88 long index_char = label.index_of_nth_char(50);
89 label = label.substring(0, index_char) + "...";
90 }
91
92 return label;
93 }
94
95 /**
96 * {@inheritDoc}
97 */
98 public string get_mime_type()
99 {
100 return "text/plain";
101 }
102
103 /**
104 * {@inheritDoc}
105 */
106 public ClipboardCategory get_category()
107 {
108 return ClipboardCategory.TEXT;
109 }
110
111 /**
112 * {@inheritDoc}
113 */
114 public Gtk.Image? get_image()
115 {
116 return null; // no image available for text content
117 }
118
119 /**
120 * {@inheritDoc}
121 */
122 public Icon get_icon()
123 {
124 return ContentType.get_icon(get_mime_type());
125 }
126
127 /**
128 * {@inheritDoc}
129 */
130 public ByteArray? get_payload()
131 {
132 return null;
133 }
134
135 /**
136 * {@inheritDoc}
137 */
138 public string get_checksum()
139 {
140 return Checksum.compute_for_string(ChecksumType.SHA1, _text);
141 }
142
143 /**
144 * {@inheritDoc}
145 */
146 public void to_clipboard(Gtk.Clipboard clipboard)
147 {
148 clipboard.set_text(_text, -1);
149 clipboard.store();
150 }
151
152 /**
153 * {@inheritDoc}
154 */
155 public bool equals(IClipboardItem* item)
156 {
157 bool equals = false;
158
159 if(item is TextClipboardItem) {
160 equals = strcmp(_text, item->get_text()) == 0;
161 }
162
163 return equals;
164 }
165
166 /**
167 * {@inheritDoc}
168 */
169 public uint hash()
170 {
171 return str_hash(_text);
172 }
173 }
174 }
0 /*
1 * Diodon - GTK+ clipboard manager.
2 * Copyright (C) 2011 Diodon Team <diodon-team@lists.launchpad.net>
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published
6 * by the Free Software Foundation, either version 2 of the License, or (at
7 * your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
11 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
12 * License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 *
17 * Author:
18 * Oliver Sauder <os@esite.ch>
19 */
20
21 namespace Diodon
22 {
23 /**
24 * Class for defining utility methods to be used in any part of diodon.
25 */
26 public abstract class Utility : GLib.Object
27 {
28 /**
29 * Get diodon user data dir.
30 *
31 * @return path to diodon user data dir
32 */
33 public static string get_user_data_dir()
34 {
35 return Path.build_filename(Environment.get_user_data_dir(), Config.PACKAGE_NAME);
36 }
37
38 /**
39 * Create directory with all its parents logging error if not successful.
40 * Checks first if directory already exists.
41 *
42 * @param directory directory to be created
43 * @return returns true if directory already exists or creation was successful
44 */
45 public static bool make_directory_with_parents(string directory)
46 {
47 bool result = true;
48
49 // make sure that all parent directories exist
50 try {
51 File dir = File.new_for_path(directory);
52 if(!dir.query_exists(null)) {
53 result = dir.make_directory_with_parents(null);
54 }
55 } catch (Error e) {
56 warning ("could not create directory %s", directory);
57 result = false;
58 }
59
60 return result;
61 }
62
63 /**
64 * Get executable path of application which is currently running.
65 *
66 * @return path of currently active application or null if not possible to determine
67 */
68 public static string? get_path_of_active_application()
69 {
70 Gdk.error_trap_push();
71 string? path = null;
72
73 X.Window window = get_active_window();
74 if(window != X.None) {
75 ulong pid = get_pid(window);
76
77 if(pid != 0) {
78 File file = File.new_for_path("/proc/" + pid.to_string() + "/exe");
79 try {
80 FileInfo info = file.query_info(FileAttribute.STANDARD_SYMLINK_TARGET,
81 FileQueryInfoFlags.NOFOLLOW_SYMLINKS);
82 if(info != null) {
83 path = info.get_attribute_as_string(
84 FileAttribute.STANDARD_SYMLINK_TARGET);
85 if(path == null) {
86 // in case we do not have permission to read exe, we try to parse cmdline
87 File cmdline = File.new_for_path("/proc/" + pid.to_string() + "/cmdline");
88 if (file.query_exists()) {
89 DataInputStream cmdline_data = new DataInputStream(cmdline.read());
90 string cmd = cmdline_data.read_line();
91 if(cmd != null) {
92 path = Environment.find_program_in_path(cmd);
93 }
94 }
95 }
96 debug("Path is %s", path);
97 }
98 }
99 catch(GLib.Error e) {
100 debug("Error occurred while reading %s: %s",
101 file.get_path(), e.message);
102 }
103 }
104 }
105
106 Gdk.error_trap_pop_ignored();
107 return path;
108 }
109
110 /**
111 * Helper method performing given accelerator on current active
112 * window.
113 *
114 * @param accelerator accelerator parsable by Gtk.accelerator_parse
115 * @param press true for press key; false for releasing
116 * @param delay delay in milli seconds
117 * @return true if creation was successful; otherwise false.
118 */
119 public static bool perform_key_event(string accelerator, bool press, ulong delay)
120 {
121 // convert accelerator
122 uint keysym;
123 Gdk.ModifierType modifiers;
124 Gtk.accelerator_parse(accelerator, out keysym, out modifiers);
125 unowned X.Display display = Gdk.X11.get_default_xdisplay();
126 int keycode = display.keysym_to_keycode(keysym);
127
128 if(keycode != 0) {
129
130 if(Gdk.ModifierType.CONTROL_MASK in modifiers) {
131 int modcode = display.keysym_to_keycode(Gdk.Key.Control_L);
132 XTest.fake_key_event(display, modcode, press, delay);
133 }
134 if(Gdk.ModifierType.SHIFT_MASK in modifiers) {
135 int modcode = display.keysym_to_keycode(Gdk.Key.Shift_L);
136 XTest.fake_key_event(display, modcode, press, delay);
137 }
138
139 XTest.fake_key_event(display, keycode, press, delay);
140
141 return true;
142 }
143
144 return false;
145 }
146
147 private static X.Window get_active_window()
148 {
149 unowned Gdk.Screen screen = Gdk.Screen.get_default();
150 Gdk.Window active_window = screen.get_active_window();
151 if(active_window != null) {
152 X.Window xactive_window = Gdk.X11Window.get_xid(active_window);
153 debug("Active window %#x", (int)xactive_window);
154 return xactive_window;
155 }
156
157 return X.None;
158 }
159
160 private static ulong get_pid(X.Window window)
161 {
162 unowned X.Display display = Gdk.X11.get_default_xdisplay();
163 X.Atom wm_pid = display.intern_atom("_NET_WM_PID", false);
164
165 if(wm_pid != X.None) {
166 X.Atom actual_type_return;
167 int actual_format_return;
168 ulong nitems_return;
169 ulong bytes_after_return;
170 void* prop_return = null;
171
172 int status = display.get_window_property(window, wm_pid, 0,
173 long.MAX, false, 0, out actual_type_return, out actual_format_return,
174 out nitems_return, out bytes_after_return, out prop_return);
175
176 if(status == X.Success) {
177 if(prop_return != null) {
178 ulong pid = *((ulong*)prop_return);
179 debug("Copied by process with pid %lu", pid);
180 X.free(prop_return);
181 return pid;
182 }
183 }
184 }
185
186 return 0;
187 }
188 }
189 }
190
0 #! /usr/bin/env python
1 # encoding: utf-8
2 # Oliver Sauder, 2010
3
4 import Options
5
6 lib = bld.shlib (
7 features = 'c cshlib',
8 target = 'diodon',
9 name = 'libdiodon',
10 vnum = '0.0.0',
11 vapi_dirs = '../vapi',
12 uselib = 'GTK X11 GDKX PEAS PEASGTK XTST GDK ZEITGEIST',
13 cflags = ['-include', 'config.h'],
14 header_path = '${INCLUDEDIR}/diodon',
15 gir = 'Diodon-1.0',
16 packages = 'gtk+-3.0',
17 packages_private = 'zeitgeist-2.0 gdk-x11-3.0 libpeas-gtk-1.0 libpeas-1.0 config xtst gdk-3.0',
18 source = bld.path.ant_glob (incl='**/*.vala'))
19
20 lib_typelib = bld.new_task_gen(
21 name = 'libdiodon_typelib',
22 after = 'libdiodon',
23 source = 'Diodon-1.0.gir',
24 target = 'Diodon-1.0.typelib',
25 install_path = '${LIBDIR}/girepository-1.0',
26 rule='g-ir-compiler --shared-library=libdiodon -o ${TGT} ${SRC}')
27
0 /*
1 * Diodon - GTK+ clipboard manager.
2 * Copyright (C) 2013 Diodon Team <diodon-team@lists.launchpad.net>
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published
6 * by the Free Software Foundation, either version 2 of the License, or (at
7 * your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
11 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
12 * License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 *
17 * Author:
18 * Oliver Sauder <os@esite.ch>
19 */
20
21 using Zeitgeist;
22
23 namespace Diodon
24 {
25 [DBus (name = "org.gnome.zeitgeist.Blacklist")]
26 interface BlacklistInterface : Object {
27 public signal void template_added (string blacklist_id, [DBus (signature = "(asaasay)")] Variant blacklist_template);
28
29 public signal void template_removed (string blacklist_id, [DBus (signature = "(asaasay)")] Variant blacklist_template);
30
31 [DBus (signature = "a{s(asaasay)}")]
32 public abstract Variant get_templates () throws IOError;
33 }
34
35
36 /**
37 * Zeitgeist clipboard storage implementation using
38 * libzeitgeist to store clipboard items as events with subjects.
39 */
40 public class ZeitgeistClipboardStorage : GLib.Object
41 {
42 // FIXME this should be clipboard:// however as such is currently filtered
43 // by zeitgeist we have to set an accepted uri otherwise clipboard events
44 // won't be indexed by fts
45 // see https://bugs.freedesktop.org/show_bug.cgi?id=70173
46 public const string CLIPBOARD_URI = "dav:";
47
48 private Zeitgeist.Log log;
49 private Index index;
50 private Monitor monitor;
51 private BlacklistInterface blacklist;
52
53 private HashTable<ClipboardType, IClipboardItem> current_items;
54 private HashTable<int?, Event> cat_templates;
55
56 /**
57 * Called when a item has been inserted.
58 */
59 public signal void on_items_inserted();
60
61 /**
62 * Called when a item has been deleted.
63 */
64 public signal void on_items_deleted();
65
66 public ZeitgeistClipboardStorage()
67 {
68 this.cat_templates = new HashTable<int?, Event>(int_hash, int_equal);
69 prepare_category_templates(this.cat_templates);
70
71 try {
72 this.blacklist = Bus.get_proxy_sync(
73 BusType.SESSION, "org.gnome.zeitgeist.Engine",
74 "/org/gnome/zeitgeist/blacklist"
75 );
76 this.blacklist.template_added.connect((id, variant) => { on_items_inserted(); } );
77 this.blacklist.template_removed.connect((id, variant) => { on_items_deleted(); } );
78 } catch(GLib.Error e) {
79 warning("Could not connect to blacklist interface: %s", e.message);
80 }
81
82 this.monitor = new Monitor(new TimeRange.from_now(),
83 get_items_event_templates());
84 this.monitor.events_inserted.connect(() => { on_items_inserted(); } );
85 this.monitor.events_deleted.connect(() => { on_items_deleted(); } );
86
87 this.log = Zeitgeist.Log.get_default();
88
89 try {
90 this.log.install_monitor(monitor);
91 } catch(GLib.Error e) {
92 error("Could not install monitor: %s", e.message);
93 }
94
95 this.index = new Index();
96
97 this.current_items = new HashTable<ClipboardType, IClipboardItem>(null, null);
98 }
99
100 /**
101 * Check whether privacy mode is enabled or not. When privacy
102 * mode is enabled no new clipboard items will be added to history.
103 *
104 * @return true if privacy mode is enabled; otherwise false.
105 */
106 public bool is_privacy_mode_enabled()
107 {
108 if(this.blacklist == null) {
109 return false;
110 }
111
112 try {
113 Variant var_blacklists = this.blacklist.get_templates();
114
115 foreach(Variant variant in var_blacklists) {
116 VariantIter iter = variant.iterator();
117 string template_id = iter.next_value().get_string();
118 if(template_id == "block-all" || template_id == "interpretation-document") {
119 debug("Zeitgeist privacy mode is enabled");
120 return true;
121 }
122 }
123 } catch(GLib.Error e) {
124 warning("Could not determine state of privacy mode: %s", e.message);
125 }
126
127 debug("Zeitgeist privacy mode is disabled");
128 return false;
129 }
130
131 /**
132 * Get currently selected item for given clipboard type
133 *
134 * @param type clipboard type
135 * @return clipboard item
136 */
137 public IClipboardItem get_current_item(ClipboardType type)
138 {
139 return current_items.get(type);
140 }
141
142 /**
143 * Remove all events matching given clipboard item
144 *
145 * @param clipboard item to be removed
146 */
147 public async void remove_item(IClipboardItem item, Cancellable? cancellable = null)
148 {
149 debug("Remove item with given checksum %s", item.get_checksum());
150
151 try {
152 GenericArray<Event> templates = create_item_event_templates(item);
153 uint32[] ids = yield log.find_event_ids(
154 new TimeRange.anytime(),
155 templates,
156 StorageState.ANY,
157 uint32.MAX,
158 ResultType.MOST_RECENT_EVENTS, // all events
159 cancellable);
160
161 Array<uint32> events = new Array<uint32>();
162 events.append_vals(ids, ids.length);
163 yield log.delete_events(events, cancellable);
164 } catch (IOError.CANCELLED ioe) {
165 debug("Remove item %s got cancelled, error: %s",
166 item.get_checksum(), ioe.message);
167 } catch(GLib.Error e) {
168 warning("Remove item %s not successful, error: %s",
169 item.get_checksum(), e.message);
170 }
171 }
172
173 /**
174 * Get clipboard item by its given checksum
175 *
176 * @param checksum checksum of clipboard item
177 * @return clipboard item of given checksum; otherwise null if not available
178 */
179 public async IClipboardItem? get_item_by_checksum(string checksum, Cancellable? cancellable = null)
180 {
181 debug("Get item with given checksum %s", checksum);
182
183 GenericArray<Event> templates = new GenericArray<Event>();
184 TimeRange time_range = new TimeRange.anytime();
185 Event template = new Event.full(
186 ZG.CREATE_EVENT,
187 ZG.USER_ACTIVITY,
188 null,
189 "application://diodon.desktop", // origin events only added by diodon
190 new Subject.full (CLIPBOARD_URI + checksum,
191 null,
192 NFO.DATA_CONTAINER,
193 null,
194 null,
195 null,
196 null));
197 templates.add(template);
198
199 IClipboardItem item = null;
200 try {
201 ResultSet events = yield log.find_events(
202 time_range,
203 templates,
204 StorageState.ANY,
205 1,
206 // this will filter duplicates according to their uri
207 ResultType.MOST_RECENT_SUBJECTS,
208 cancellable
209 );
210
211 foreach(Event event in events) {
212 if (event.num_subjects() > 0) {
213 Subject subject = event.get_subject(0);
214 item = create_clipboard_item(event, subject);
215 break;
216 }
217 }
218 } catch (IOError.CANCELLED ioe) {
219 debug("Get item by checksum '%s' got cancelled, error: %s",
220 checksum, ioe.message);
221 } catch(GLib.Error e) {
222 warning("Get item by checksum not successful, error: %s",
223 e.message);
224 }
225
226 if(item == null) {
227 debug("Item with checksum %s could not be found", checksum);
228 }
229
230 return item;
231 }
232
233 /**
234 * Get clipboard items which match given search query
235 *
236 * @param search_query query to search items for
237 * @param cats categories for search query or null for all
238 * @param date_copied filter results by given timerange; all per default
239 * @param cancellable optional cancellable handler
240 * @return clipboard items matching given search query
241 */
242 public async List<IClipboardItem> get_items_by_search_query(string search_query, ClipboardCategory[]? cats = null,
243 ClipboardTimerange date_copied = ClipboardTimerange.ALL, Cancellable? cancellable = null)
244 {
245 TimeRange time_range = create_timerange(date_copied);
246 GenericArray<Event> templates = get_items_event_templates(cats);
247
248 string query = prepare_search_string(search_query);
249 if(query != "") {
250 debug("Get items by search query %s", search_query);
251 try {
252 ResultSet events = yield index.search(
253 query,
254 time_range,
255 templates,
256 0,
257 100, // setting limit to 100 for now, for memory reasons
258 // this will filter duplicates according to their uri
259 ResultType.MOST_RECENT_SUBJECTS,
260 cancellable);
261
262 return create_clipboard_items(events);
263 } catch (IOError.CANCELLED ioe) {
264 debug("Get items with search query '%s' got cancelled, error: %s",
265 search_query, ioe.message);
266 } catch(GLib.Error e) {
267 warning("Get items by search query '%s' not successful, error: %s",
268 search_query, e.message);
269 }
270 // when there is no search query show last 100 items
271 } else {
272 return yield get_recent_items(100, cats, date_copied, cancellable);
273 }
274
275 return new List<IClipboardItem>();
276 }
277
278 /**
279 * Get most recent items limited by assigned num_items. List will filter
280 * out any duplicates according to their checksum resp. uri in zeitgeist.
281 * Most recent item will be on the top.
282 *
283 * @param num_items number of recent items
284 * @param cats categories of recent items to get; null for all
285 * @param date_copied filter results by given timerange; all per default
286 * @param cancellable optional cancellable handler
287 * @return list of recent clipboard items
288 */
289 public async List<IClipboardItem> get_recent_items(uint32 num_items, ClipboardCategory[]? cats = null,
290 ClipboardTimerange date_copied = ClipboardTimerange.ALL, Cancellable? cancellable = null)
291 {
292 debug("Get recent %u items", num_items);
293
294 TimeRange time_range = create_timerange(date_copied);
295 GenericArray<Event> templates = get_items_event_templates(cats);
296
297 try {
298 ResultSet events = yield log.find_events(
299 time_range,
300 templates,
301 StorageState.ANY,
302 num_items,
303 // this will filter duplicates according to their uri
304 ResultType.MOST_RECENT_SUBJECTS,
305 cancellable
306 );
307
308 return create_clipboard_items(events);
309 } catch (IOError.CANCELLED ioe) {
310 debug("Get recent items got cancelled, error: %s", ioe.message);
311 } catch(GLib.Error e) {
312 warning("Get recent items not successful, error: %s",
313 e.message);
314 }
315
316 return new List<IClipboardItem>();
317 }
318
319 /**
320 * Add clipboard item as Zeitgeist event and subject to zeitgeist log.
321 */
322 public async void add_item(IClipboardItem item, Cancellable? cancellable = null)
323 {
324 debug("Add item to clipboard (Label: %s Checksum: %s)",
325 item.get_label(), item.get_checksum()
326 );
327
328 try {
329 string interpretation = get_interpretation(item);
330
331 Subject subject = new Subject();
332 subject.uri = CLIPBOARD_URI + item.get_checksum();
333 subject.interpretation = interpretation;
334 subject.manifestation = NFO.DATA_CONTAINER;
335 subject.mimetype = item.get_mime_type();
336 subject.origin = item.get_origin();
337 subject.text = item.get_text();
338
339 Event event = new Event();
340 // TODO: this should actually be a copy event
341 event.interpretation = ZG.CREATE_EVENT;
342 event.manifestation = ZG.USER_ACTIVITY;
343 // event origin is which clipboard manager event comes from
344 event.origin = "application://diodon.desktop";
345
346 // actor is application triggering copy event
347 if(subject.origin != null) {
348 try {
349 AppInfo appInfo = AppInfo.create_from_commandline(subject.origin,
350 null, AppInfoCreateFlags.NONE);
351 event.set_actor_from_app_info(appInfo);
352 } catch(GLib.Error e) {
353 warning("Could not create AppInfo for %s: %s",
354 subject.origin, e.message);
355 }
356 }
357 // actor is mandantory, fallback to diodon
358 if(event.actor == null) {
359 event.actor = "application://diodon.desktop";
360 }
361 debug("event actor set to %s", event.actor);
362
363 event.add_subject(subject);
364
365 ByteArray? payload = item.get_payload();
366 if(payload != null) {
367 event.payload = payload;
368 }
369
370 TimeVal cur_time = TimeVal();
371 int64 timestamp = Timestamp.from_timeval(cur_time);
372 event.timestamp = timestamp;
373
374 GenericArray<Event> events = new GenericArray<Event>();
375 events.add(event);
376
377 yield log.insert_events(events, cancellable);
378 } catch (IOError.CANCELLED ioe) {
379 debug("Add item got cancelled, error: %s", ioe.message);
380 } catch(GLib.Error e) {
381 warning("Add item %s not successful, error: %s",
382 item.get_text(), e.message);
383 }
384
385 current_items.set(item.get_clipboard_type(), item);
386 }
387
388 /**
389 * Select clipboard item.
390 *
391 * @param item item to be selected
392 * @param use_clipboard whether item gets selected for clipboard
393 * @param use_primary whether item gets selected for primary selection
394 */
395 public async void select_item(IClipboardItem item, bool use_clipboard, bool use_primary, Cancellable? cancellable = null)
396 {
397 // selected item is always at the end of history, so we need to
398 // add it again
399 yield add_item(item, cancellable);
400
401 // verify that current items are selected correctly
402 if(use_clipboard) {
403 current_items.set(ClipboardType.CLIPBOARD, item);
404 }
405 if(use_primary) {
406 current_items.set(ClipboardType.PRIMARY, item);
407 }
408 }
409
410 /**
411 * Clear all clipboard items in zeitgeist storage
412 */
413 public async void clear(Cancellable? cancellable = null)
414 {
415 debug("Clear clipboard history");
416
417 GenericArray<Event> templates = get_items_event_templates();
418 TimeRange time_range = new TimeRange.anytime();
419
420 try {
421 uint32[] ids = yield log.find_event_ids(
422 time_range,
423 templates,
424 StorageState.ANY,
425 uint32.MAX,
426 ResultType.MOST_RECENT_EVENTS,
427 cancellable
428 );
429
430 Array<uint32> events = new Array<uint32>();
431 events.append_vals(ids, ids.length);
432 yield log.delete_events(events, cancellable);
433
434 } catch (IOError.CANCELLED ioe) {
435 debug("Clear items got cancelled, error: %s", ioe.message);
436 } catch(GLib.Error e) {
437 warning("Failed to clear items: %s", e.message);
438 }
439
440 current_items.remove_all();
441 }
442
443 private static void prepare_category_templates(HashTable<int?, Event> templates)
444 {
445 // match all
446 templates[ClipboardCategory.CLIPBOARD] = new Event.full(
447 ZG.CREATE_EVENT, ZG.USER_ACTIVITY,
448 null,
449 // origin events only added by diodon
450 "application://diodon.desktop",
451 new Subject.full(
452 CLIPBOARD_URI + "*",
453 null,
454 NFO.DATA_CONTAINER,
455 null,
456 null,
457 null,
458 null));
459
460 templates[ClipboardCategory.TEXT] = new Event.full(
461 ZG.CREATE_EVENT, ZG.USER_ACTIVITY,
462 null,
463 // origin events only added by diodon
464 "application://diodon.desktop",
465 new Subject.full(
466 CLIPBOARD_URI + "*",
467 NFO.PLAIN_TEXT_DOCUMENT,
468 NFO.DATA_CONTAINER,
469 null,
470 null,
471 null,
472 null));
473
474 templates[ClipboardCategory.FILES] = new Event.full(
475 ZG.CREATE_EVENT, ZG.USER_ACTIVITY,
476 null,
477 // origin events only added by diodon
478 "application://diodon.desktop",
479 new Subject.full(
480 CLIPBOARD_URI + "*",
481 NFO.FILE_DATA_OBJECT,
482 NFO.DATA_CONTAINER,
483 null,
484 null,
485 null,
486 null));
487
488 templates[ClipboardCategory.IMAGES] = new Event.full(
489 ZG.CREATE_EVENT, ZG.USER_ACTIVITY,
490 null,
491 // origin events only added by diodon
492 "application://diodon.desktop",
493 new Subject.full(
494 CLIPBOARD_URI + "*",
495 NFO.IMAGE,
496 NFO.DATA_CONTAINER,
497 null,
498 null,
499 null,
500 null));
501 }
502
503 private static TimeRange create_timerange(ClipboardTimerange timerange)
504 {
505 switch(timerange)
506 {
507 case ClipboardTimerange.LAST_24_HOURS:
508 return new TimeRange(Timestamp.from_now() - Timestamp.HOUR * 24, Timestamp.from_now());
509 case ClipboardTimerange.LAST_7_DAYS:
510 return new TimeRange (Timestamp.from_now() - Timestamp.WEEK, Timestamp.from_now());
511 case ClipboardTimerange.LAST_30_DAYS:
512 return new TimeRange (Timestamp.from_now() - (Timestamp.WEEK * 4), Timestamp.from_now());
513 case ClipboardTimerange.LAST_YEAR:
514 return new TimeRange (Timestamp.from_now() - Timestamp.YEAR, Timestamp.from_now ());
515 default:
516 return new TimeRange.anytime();
517 }
518 }
519
520 private static IClipboardItem? create_clipboard_item(Event event, Subject subject)
521 {
522 string interpretation = subject.interpretation;
523 IClipboardItem item = null;
524 string text = subject.text;
525 string? origin = subject.origin;
526 unowned ByteArray payload = event.payload;
527 DateTime date_copied = new DateTime.from_timeval_utc(Zeitgeist.Timestamp.to_timeval(event.timestamp));
528
529 try {
530 if(strcmp(NFO.PLAIN_TEXT_DOCUMENT, interpretation) == 0) {
531 item = new TextClipboardItem(ClipboardType.NONE, text, origin, date_copied);
532 }
533
534 else if(strcmp(NFO.FILE_DATA_OBJECT, interpretation) == 0) {
535 item = new FileClipboardItem(ClipboardType.NONE, text, origin, date_copied);
536 }
537
538 else if(strcmp(NFO.IMAGE, interpretation) == 0) {
539 item = new ImageClipboardItem.with_payload(ClipboardType.NONE, payload, origin, date_copied);
540 }
541
542 else {
543 warning("Unknown subject with interpretation: %s", interpretation);
544 }
545 } catch(GLib.FileError e) {
546 // file errors happen constantly when e.g. some moved/deleted a file which has been
547 // copied in the past. Therefore we just note this as debug.
548 debug("Could not create FileClipboardItem: %s", e.message);
549 } catch (Error e) {
550 warning ("loading of item of interpreation %s with data %s failed. Cause: %s",
551 interpretation, text, e.message);
552 }
553
554 return item;
555 }
556
557 private static string get_interpretation(IClipboardItem item)
558 {
559 string interpretation = NFO.PLAIN_TEXT_DOCUMENT;
560 if(item is FileClipboardItem) {
561 interpretation = NFO.FILE_DATA_OBJECT;
562 }
563 else if (item is ImageClipboardItem) {
564 interpretation = NFO.IMAGE;
565 }
566
567 return interpretation;
568 }
569
570 private static List<IClipboardItem> create_clipboard_items(ResultSet events)
571 {
572 List<IClipboardItem> items = new List<IClipboardItem>();
573
574 foreach(Event event in events) {
575 if (event.num_subjects() > 0) {
576 Subject subject = event.get_subject(0);
577 IClipboardItem item = create_clipboard_item(event, subject);
578 if(item != null) {
579 items.append(item);
580 }
581 } else {
582 warning ("Unexpected event without subject");
583 continue;
584 }
585 }
586
587 debug("Created %d clipboard items", (int) items.length());
588
589 return items;
590 }
591
592 /**
593 * Get array of event templates which matches clipboard items with
594 * given categories.
595 *
596 * @param cats list of clipboard item cats or null if all
597 */
598 private GenericArray<Event> get_items_event_templates(ClipboardCategory[]? cats = null)
599 {
600 GenericArray<Event> templates = new GenericArray<Event>();
601
602 if(cats == null || cats.length == 0) {
603 templates.add(cat_templates[ClipboardCategory.CLIPBOARD]);
604 } else {
605 foreach(unowned ClipboardCategory cat in cats) {
606 templates.add(cat_templates[cat]);
607 }
608 }
609
610 return templates;
611 }
612
613 private static GenericArray<Event> create_item_event_templates(IClipboardItem item)
614 {
615 GenericArray<Event> events = new GenericArray<Event>();
616
617 Event event = new Event.full(
618 ZG.CREATE_EVENT,
619 ZG.USER_ACTIVITY,
620 null, // find copy events for all actors / applications
621 "application://diodon.desktop", // origin events only added by diodon
622 new Subject.full (
623 CLIPBOARD_URI + item.get_checksum(),
624 get_interpretation(item),
625 NFO.DATA_CONTAINER,
626 null,
627 null,
628 null,
629 null));
630
631 events.add(event);
632 return events;
633 }
634
635 private static string prepare_search_string(string search_string)
636 {
637 string s = search_string.strip();
638
639 // TODO: query can have several parts and this needs to be taken
640 // into consideration
641 if (!s.has_suffix ("*") && s != "") {
642 s = s + "*";
643 }
644
645 return s;
646 }
647 }
648 }
649
0 /*
1 * Diodon - GTK+ clipboard manager.
2 * Copyright (C) 2011 Diodon Team <diodon-team@lists.launchpad.net>
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published
6 * by the Free Software Foundation, either version 2 of the License, or (at
7 * your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
11 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
12 * License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 *
17 * Author:
18 * Oliver Sauder <os@esite.ch>
19 */
20
21 namespace Diodon.Plugins
22 {
23 /**
24 * Providing access to clipboard history through an application
25 * indicator.
26 */
27 public class IndicatorPlugin : Peas.ExtensionBase, Peas.Activatable
28 {
29 private AppIndicator.Indicator indicator;
30 public Object object { owned get; construct; }
31
32 public IndicatorPlugin()
33 {
34 Object();
35 }
36
37 public void activate()
38 {
39 Controller controller = object as Controller;
40
41 if(indicator == null) {
42 indicator = new AppIndicator.Indicator("Diodon", "diodon-panel",
43 AppIndicator.IndicatorCategory.APPLICATION_STATUS);
44
45 indicator.set_menu(controller.get_recent_menu());
46
47 controller.on_recent_menu_changed.connect(change_menu);
48 }
49
50 indicator.set_status(AppIndicator.IndicatorStatus.ACTIVE);
51 }
52
53 public void deactivate()
54 {
55 Controller controller = object as Controller;
56
57 if(indicator != null) {
58 indicator.set_status(AppIndicator.IndicatorStatus.PASSIVE);
59 controller.on_recent_menu_changed.disconnect(change_menu);
60 }
61 }
62
63 public void update_state()
64 {
65 }
66
67 private void change_menu(Gtk.Menu recent_menu)
68 {
69 indicator.set_menu(recent_menu);
70 }
71 }
72 }
73
74 [ModuleInit]
75 public void peas_register_types (GLib.TypeModule module)
76 {
77 Peas.ObjectModule objmodule = module as Peas.ObjectModule;
78 objmodule.register_extension_type (typeof (Peas.Activatable),
79 typeof (Diodon.Plugins.IndicatorPlugin));
80 }
81
0 [Plugin]
1 Module=indicator
2 _Name=Application Indicator
3 _Description=Access clipboard history with an application indicator.
4 Authors=Oliver Sauder <os@esite.ch>
5 _Copyright=Copyright © 2011 Diodon Team
6
0 #! /usr/bin/env python
1 # encoding: utf-8
2 # Oliver Sauder, 2010
3
4 import os
5
6 lib = bld.shlib (
7 features = 'c cshlib',
8 target = 'indicator',
9 vapi_dirs = '../../vapi ../../libdiodon',
10 uselib = 'APPINDICATOR PEAS',
11 use = 'libdiodon',
12 install_binding = False,
13 cflags = ['-include', 'config.h'],
14 packages = 'appindicator3-0.1 libpeas-1.0',
15 source = bld.path.ant_glob (incl='**/*.vala'))
16
17 lib.install_path = os.path.join(bld.env['PLUGINS_DIR'], lib.target)
18
19 bld.new_task_gen (
20 features = 'intltool_in',
21 podir = '../../po',
22 source = 'indicator.plugin.in',
23 flags = ["-d", "-q", "-u", "-c"],
24 install_path = lib.install_path)
0 #! /usr/bin/env python
1 # encoding: utf-8
2 # Oliver Sauder, 2010
3
4 if bld.env['INDICATOR']:
5 bld.add_subdirs('indicator')
0 # please keep this list sorted alphabetically
1 bg
2 ca
3 cs
4 de
5 en_GB
6 es
7 et
8 fi
9 fr
10 gl
11 hu
12 it
13 ja
14 lt
15 nb
16 nl
17 pl
18 pt
19 pt_BR
20 ro
21 ru
22 se
23 sk
24 sv
25 tr
26 uk
27 zh_CN
28
0 # List of source files containing translatable strings.
1 # Please keep this file sorted alphabetically.
2
3 data/diodon.desktop.in
4 data/net.launchpad.Diodon.gschema.xml.in.in
5 [type: gettext/glade]data/preferences.ui
6 libdiodon/clipboard-menu.vala
7 [type: gettext/ini]plugins/indicator/indicator.plugin.in
8 [type: gettext/ini]unity-scope-diodon/clipboard.scope.in.in
9 unity-scope-diodon/unity-scope-diodon.vala
0 # Bulgarian translation for diodon
1 # Copyright (c) 2011 Rosetta Contributors and Canonical Ltd 2011
2 # This file is distributed under the same license as the diodon package.
3 # FIRST AUTHOR <EMAIL@ADDRESS>, 2011.
4 #
5 msgid ""
6 msgstr ""
7 "Project-Id-Version: diodon\n"
8 "Report-Msgid-Bugs-To: \n"
9 "POT-Creation-Date: 2017-06-05 14:18+0200\n"
10 "PO-Revision-Date: 2013-12-29 00:12+0000\n"
11 "Last-Translator: Svetoslav Stefanov <svetlisashkov@yahoo.com>\n"
12 "Language-Team: Bulgarian <bg@li.org>\n"
13 "MIME-Version: 1.0\n"
14 "Content-Type: text/plain; charset=UTF-8\n"
15 "Content-Transfer-Encoding: 8bit\n"
16 "X-Launchpad-Export-Date: 2017-06-06 05:55+0000\n"
17 "X-Generator: Launchpad (build 18399)\n"
18 "Language: bg\n"
19
20 #: ../data/diodon.desktop.in.h:1
21 msgid "Clipboard Manager"
22 msgstr "Мениджър на системния буфер"
23
24 #: ../data/diodon.desktop.in.h:2
25 msgid "GTK+ Clipboard Manager"
26 msgstr ""
27
28 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:1
29 msgid "Use clipboard (Ctrl+C)"
30 msgstr "Използване на буфела (Ctrl+C)"
31
32 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:2
33 #: ../data/preferences.ui.h:3
34 msgid ""
35 "Adds content which is copied to the clipboard with e.g. Ctrl + C to the "
36 "clipboard history."
37 msgstr ""
38
39 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:3
40 msgid "Use primary selection"
41 msgstr "Използване на първичната селекция"
42
43 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:4
44 #: ../data/preferences.ui.h:5
45 msgid ""
46 "Adds the primary selection (an area of the screen which is selected with the "
47 "mouse) to the clipboard history. Enabling will start process which "
48 "continually checks what is selected. This might discharge your battery "
49 "quicker."
50 msgstr ""
51
52 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:5
53 msgid "Add images to clipboard history"
54 msgstr ""
55
56 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:6
57 #: ../data/preferences.ui.h:7
58 msgid ""
59 "Add images copied to clipboard to clipboard history (e.g. when you right "
60 "click on an image in your browser and choose copy image). Enabling this "
61 "option will increase memory consumption. Images already added to clipboard "
62 "history will remain even when disabled."
63 msgstr ""
64
65 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:7
66 msgid "Synchronize clipboards"
67 msgstr "Синхронизиране на буферите"
68
69 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:8
70 #: ../data/preferences.ui.h:11
71 msgid ""
72 "Synchronizes the selection (an area of the screen which is selected with the "
73 "mouse) and the clipboard so that anything in the selection is immediately "
74 "available in the clipboard and vice versa e.g. for pasting with Ctrl + V and "
75 "the middle mouse button."
76 msgstr ""
77 "Синхронизира селекцията (област от екрана, избрана с мишката) и буфера, така "
78 "че всичко в нея е моментално налично в буфера и обратно, например за "
79 "поставяне с Ctrl + V и със средния бутон на мишката."
80
81 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:9
82 msgid "Keep clipboard content"
83 msgstr "Запазване съдържанието на буфера"
84
85 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:10
86 #: ../data/preferences.ui.h:9
87 msgid ""
88 "Prevents an empty clipboard. For instance when an application exits, the "
89 "clipboard would usually be emptied."
90 msgstr ""
91 "Предотвратява празен буфер. Например при изход от приложение обикновено "
92 "буферът се изпразва."
93
94 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:11
95 msgid "Automatically paste selected item"
96 msgstr "Автоматично поставяне на избрания обект"
97
98 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:12
99 #: ../data/preferences.ui.h:13
100 msgid ""
101 "Automatically paste selected item instead of just copying it to the "
102 "clipboard."
103 msgstr ""
104 "Автоматично поставяне на избрания обект, вместо само да се копира в буфера."
105
106 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:13
107 msgid "Number of recent clipboard items"
108 msgstr ""
109
110 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:14
111 msgid "Number of recent clipboard items shown in clipboard menu."
112 msgstr ""
113
114 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:15
115 msgid "Clipboard content filter pattern"
116 msgstr ""
117
118 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:16
119 msgid ""
120 "Regex filter pattern whereas all clipboard items matching this pattern will "
121 "be filtered and not added to clipboard history."
122 msgstr ""
123
124 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:17
125 msgid "Lookup dictionary for application using different paste keybindings"
126 msgstr ""
127
128 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:18
129 msgid ""
130 "A lookup dictionary for applications using different paste keybindings than "
131 "Ctrl + V. Pattern of each string in this array is path-of-app|keybinding"
132 msgstr ""
133
134 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:19
135 msgid "Active plugins"
136 msgstr ""
137
138 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:20
139 msgid "List of active plugins."
140 msgstr ""
141
142 #: ../data/preferences.ui.h:1
143 msgid "Diodon Preferences"
144 msgstr "Настройки на Diodon"
145
146 #: ../data/preferences.ui.h:2
147 msgid "_Use clipboard (Ctrl+C)"
148 msgstr "_Използване на буфера (Ctrl+C)"
149
150 #: ../data/preferences.ui.h:4
151 msgid "Use _primary selection"
152 msgstr "Използване на _първичната селекция"
153
154 #: ../data/preferences.ui.h:6
155 msgid "Add _images to clipboard history"
156 msgstr ""
157
158 #: ../data/preferences.ui.h:8
159 msgid "_Keep clipboard content"
160 msgstr "_Запазване съдържанието на буфера"
161
162 #: ../data/preferences.ui.h:10
163 msgid "S_ynchronize clipboards"
164 msgstr "_Синхронизиране на буферите"
165
166 #: ../data/preferences.ui.h:12
167 msgid "_Automatically paste selected item"
168 msgstr "_Автоматично поставяне на избрания обект"
169
170 #: ../data/preferences.ui.h:14
171 msgid "Number of recent clipboard items to be shown in clipboard menu."
172 msgstr ""
173
174 #: ../data/preferences.ui.h:15
175 msgid "Number of recent items"
176 msgstr ""
177
178 #: ../data/preferences.ui.h:16 ../unity-scope-diodon/unity-scope-diodon.vala:75
179 msgid "Clipboard"
180 msgstr "Системен буфер"
181
182 #: ../data/preferences.ui.h:17
183 msgid ""
184 "Please register custom shortcut with\n"
185 "your desktop environment.\n"
186 "Use /usr/bin/diodon as command."
187 msgstr ""
188
189 #: ../data/preferences.ui.h:20
190 msgid "More information"
191 msgstr ""
192
193 #: ../data/preferences.ui.h:21
194 msgid "Hotkeys"
195 msgstr ""
196
197 #: ../data/preferences.ui.h:22
198 msgid "Plugins"
199 msgstr ""
200
201 #: ../libdiodon/clipboard-menu.vala:46
202 msgid "<Empty>"
203 msgstr "<Празно>"
204
205 #: ../libdiodon/clipboard-menu.vala:53
206 msgid "Privacy mode is enabled. No new items will be added to history!"
207 msgstr ""
208
209 #: ../plugins/indicator/indicator.plugin.in.h:1
210 msgid "Application Indicator"
211 msgstr ""
212
213 #: ../plugins/indicator/indicator.plugin.in.h:2
214 msgid "Access clipboard history with an application indicator."
215 msgstr ""
216
217 #: ../plugins/indicator/indicator.plugin.in.h:3
218 msgid "Copyright © 2011 Diodon Team"
219 msgstr ""
220
221 #: ../unity-scope-diodon/clipboard.scope.in.in.h:1
222 msgid "Clipboard History"
223 msgstr ""
224
225 #: ../unity-scope-diodon/clipboard.scope.in.in.h:2
226 msgid ""
227 "This is an Ubuntu search plugin that enables information from Diodon to be "
228 "searched and displayed in the Dash underneath the Clipboard header."
229 msgstr ""
230
231 #: ../unity-scope-diodon/clipboard.scope.in.in.h:3
232 msgid "Search clipboard"
233 msgstr ""
234
235 #: ../unity-scope-diodon/clipboard.scope.in.in.h:4
236 #: ../unity-scope-diodon/unity-scope-diodon.vala:79
237 #: ../unity-scope-diodon/unity-scope-diodon.vala:104
238 msgid "Text"
239 msgstr ""
240
241 #: ../unity-scope-diodon/clipboard.scope.in.in.h:5
242 #: ../unity-scope-diodon/unity-scope-diodon.vala:84
243 #: ../unity-scope-diodon/unity-scope-diodon.vala:105
244 msgid "Files"
245 msgstr ""
246
247 #: ../unity-scope-diodon/clipboard.scope.in.in.h:6
248 #: ../unity-scope-diodon/unity-scope-diodon.vala:89
249 #: ../unity-scope-diodon/unity-scope-diodon.vala:106
250 msgid "Images"
251 msgstr ""
252
253 #: ../unity-scope-diodon/clipboard.scope.in.in.h:7
254 #: ../unity-scope-diodon/unity-scope-diodon.vala:101
255 msgid "Category"
256 msgstr ""
257
258 #: ../unity-scope-diodon/clipboard.scope.in.in.h:8
259 msgid "Text;Files;Images"
260 msgstr ""
261
262 #: ../unity-scope-diodon/clipboard.scope.in.in.h:9
263 msgid "Last 24 hours;Last 7 days;Last 30 days;Last year;"
264 msgstr ""
265
266 #: ../unity-scope-diodon/unity-scope-diodon.vala:45
267 msgid "Search Clipboard"
268 msgstr ""
269
270 #: ../unity-scope-diodon/unity-scope-diodon.vala:110
271 #: ../unity-scope-diodon/unity-scope-diodon.vala:231
272 msgid "Date copied"
273 msgstr ""
274
275 #: ../unity-scope-diodon/unity-scope-diodon.vala:112
276 msgid "Last 24 hours"
277 msgstr ""
278
279 #: ../unity-scope-diodon/unity-scope-diodon.vala:113
280 msgid "Last 7 days"
281 msgstr ""
282
283 #: ../unity-scope-diodon/unity-scope-diodon.vala:114
284 msgid "Last 30 days"
285 msgstr ""
286
287 #: ../unity-scope-diodon/unity-scope-diodon.vala:115
288 msgid "Last year"
289 msgstr ""
290
291 #: ../unity-scope-diodon/unity-scope-diodon.vala:216
292 msgid "Paste"
293 msgstr ""
294
295 #: ../unity-scope-diodon/unity-scope-diodon.vala:224
296 msgid "Origin"
297 msgstr ""
0 # Catalan translation for diodon
1 # Copyright (c) 2016 Rosetta Contributors and Canonical Ltd 2016
2 # This file is distributed under the same license as the diodon package.
3 # FIRST AUTHOR <EMAIL@ADDRESS>, 2016.
4 #
5 msgid ""
6 msgstr ""
7 "Project-Id-Version: diodon\n"
8 "Report-Msgid-Bugs-To: \n"
9 "POT-Creation-Date: 2017-06-05 14:18+0200\n"
10 "PO-Revision-Date: 2016-08-23 17:22+0000\n"
11 "Last-Translator: pataquets <Unknown>\n"
12 "Language-Team: Catalan <ca@li.org>\n"
13 "MIME-Version: 1.0\n"
14 "Content-Type: text/plain; charset=UTF-8\n"
15 "Content-Transfer-Encoding: 8bit\n"
16 "X-Launchpad-Export-Date: 2017-06-06 05:55+0000\n"
17 "X-Generator: Launchpad (build 18399)\n"
18 "Language: ca\n"
19
20 #: ../data/diodon.desktop.in.h:1
21 msgid "Clipboard Manager"
22 msgstr "Gestor de porta-retalls"
23
24 #: ../data/diodon.desktop.in.h:2
25 msgid "GTK+ Clipboard Manager"
26 msgstr "Gestor porta-retalls GTK+"
27
28 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:1
29 msgid "Use clipboard (Ctrl+C)"
30 msgstr "Fes servir porta-retalls (CTRL+C)"
31
32 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:2
33 #: ../data/preferences.ui.h:3
34 msgid ""
35 "Adds content which is copied to the clipboard with e.g. Ctrl + C to the "
36 "clipboard history."
37 msgstr ""
38
39 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:3
40 msgid "Use primary selection"
41 msgstr "Fes servir selecció primària"
42
43 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:4
44 #: ../data/preferences.ui.h:5
45 msgid ""
46 "Adds the primary selection (an area of the screen which is selected with the "
47 "mouse) to the clipboard history. Enabling will start process which "
48 "continually checks what is selected. This might discharge your battery "
49 "quicker."
50 msgstr ""
51
52 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:5
53 msgid "Add images to clipboard history"
54 msgstr "Afegeix imatges a l'històric del porta-retalls"
55
56 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:6
57 #: ../data/preferences.ui.h:7
58 msgid ""
59 "Add images copied to clipboard to clipboard history (e.g. when you right "
60 "click on an image in your browser and choose copy image). Enabling this "
61 "option will increase memory consumption. Images already added to clipboard "
62 "history will remain even when disabled."
63 msgstr ""
64
65 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:7
66 msgid "Synchronize clipboards"
67 msgstr "Sincronitza porta-retalls"
68
69 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:8
70 #: ../data/preferences.ui.h:11
71 msgid ""
72 "Synchronizes the selection (an area of the screen which is selected with the "
73 "mouse) and the clipboard so that anything in the selection is immediately "
74 "available in the clipboard and vice versa e.g. for pasting with Ctrl + V and "
75 "the middle mouse button."
76 msgstr ""
77
78 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:9
79 msgid "Keep clipboard content"
80 msgstr "Conserva el contingut del porta-retalls"
81
82 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:10
83 #: ../data/preferences.ui.h:9
84 msgid ""
85 "Prevents an empty clipboard. For instance when an application exits, the "
86 "clipboard would usually be emptied."
87 msgstr ""
88
89 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:11
90 msgid "Automatically paste selected item"
91 msgstr "Enganxa automàticament l'element seleccionat"
92
93 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:12
94 #: ../data/preferences.ui.h:13
95 msgid ""
96 "Automatically paste selected item instead of just copying it to the "
97 "clipboard."
98 msgstr ""
99
100 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:13
101 msgid "Number of recent clipboard items"
102 msgstr "Número d'elements de porta-retalls recents"
103
104 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:14
105 msgid "Number of recent clipboard items shown in clipboard menu."
106 msgstr ""
107
108 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:15
109 msgid "Clipboard content filter pattern"
110 msgstr "Patró de filtrat de contingut de porta-retalls"
111
112 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:16
113 msgid ""
114 "Regex filter pattern whereas all clipboard items matching this pattern will "
115 "be filtered and not added to clipboard history."
116 msgstr ""
117
118 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:17
119 msgid "Lookup dictionary for application using different paste keybindings"
120 msgstr ""
121
122 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:18
123 msgid ""
124 "A lookup dictionary for applications using different paste keybindings than "
125 "Ctrl + V. Pattern of each string in this array is path-of-app|keybinding"
126 msgstr ""
127
128 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:19
129 msgid "Active plugins"
130 msgstr ""
131
132 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:20
133 msgid "List of active plugins."
134 msgstr ""
135
136 #: ../data/preferences.ui.h:1
137 msgid "Diodon Preferences"
138 msgstr "Preferències de Diodon"
139
140 #: ../data/preferences.ui.h:2
141 msgid "_Use clipboard (Ctrl+C)"
142 msgstr ""
143
144 #: ../data/preferences.ui.h:4
145 msgid "Use _primary selection"
146 msgstr ""
147
148 #: ../data/preferences.ui.h:6
149 msgid "Add _images to clipboard history"
150 msgstr ""
151
152 #: ../data/preferences.ui.h:8
153 msgid "_Keep clipboard content"
154 msgstr ""
155
156 #: ../data/preferences.ui.h:10
157 msgid "S_ynchronize clipboards"
158 msgstr ""
159
160 #: ../data/preferences.ui.h:12
161 msgid "_Automatically paste selected item"
162 msgstr ""
163
164 #: ../data/preferences.ui.h:14
165 msgid "Number of recent clipboard items to be shown in clipboard menu."
166 msgstr ""
167
168 #: ../data/preferences.ui.h:15
169 msgid "Number of recent items"
170 msgstr "Número d'elements recents"
171
172 #: ../data/preferences.ui.h:16 ../unity-scope-diodon/unity-scope-diodon.vala:75
173 msgid "Clipboard"
174 msgstr "Porta-retalls"
175
176 #: ../data/preferences.ui.h:17
177 msgid ""
178 "Please register custom shortcut with\n"
179 "your desktop environment.\n"
180 "Use /usr/bin/diodon as command."
181 msgstr ""
182
183 #: ../data/preferences.ui.h:20
184 msgid "More information"
185 msgstr "Més informació"
186
187 #: ../data/preferences.ui.h:21
188 msgid "Hotkeys"
189 msgstr ""
190
191 #: ../data/preferences.ui.h:22
192 msgid "Plugins"
193 msgstr ""
194
195 #: ../libdiodon/clipboard-menu.vala:46
196 msgid "<Empty>"
197 msgstr "<Buit>"
198
199 #: ../libdiodon/clipboard-menu.vala:53
200 msgid "Privacy mode is enabled. No new items will be added to history!"
201 msgstr ""
202
203 #: ../plugins/indicator/indicator.plugin.in.h:1
204 msgid "Application Indicator"
205 msgstr ""
206
207 #: ../plugins/indicator/indicator.plugin.in.h:2
208 msgid "Access clipboard history with an application indicator."
209 msgstr ""
210
211 #: ../plugins/indicator/indicator.plugin.in.h:3
212 msgid "Copyright © 2011 Diodon Team"
213 msgstr ""
214
215 #: ../unity-scope-diodon/clipboard.scope.in.in.h:1
216 msgid "Clipboard History"
217 msgstr "Historial del porta-retalls"
218
219 #: ../unity-scope-diodon/clipboard.scope.in.in.h:2
220 msgid ""
221 "This is an Ubuntu search plugin that enables information from Diodon to be "
222 "searched and displayed in the Dash underneath the Clipboard header."
223 msgstr ""
224
225 #: ../unity-scope-diodon/clipboard.scope.in.in.h:3
226 msgid "Search clipboard"
227 msgstr ""
228
229 #: ../unity-scope-diodon/clipboard.scope.in.in.h:4
230 #: ../unity-scope-diodon/unity-scope-diodon.vala:79
231 #: ../unity-scope-diodon/unity-scope-diodon.vala:104
232 msgid "Text"
233 msgstr "Text"
234
235 #: ../unity-scope-diodon/clipboard.scope.in.in.h:5
236 #: ../unity-scope-diodon/unity-scope-diodon.vala:84
237 #: ../unity-scope-diodon/unity-scope-diodon.vala:105
238 msgid "Files"
239 msgstr "Arxius"
240
241 #: ../unity-scope-diodon/clipboard.scope.in.in.h:6
242 #: ../unity-scope-diodon/unity-scope-diodon.vala:89
243 #: ../unity-scope-diodon/unity-scope-diodon.vala:106
244 msgid "Images"
245 msgstr "Imatges"
246
247 #: ../unity-scope-diodon/clipboard.scope.in.in.h:7
248 #: ../unity-scope-diodon/unity-scope-diodon.vala:101
249 msgid "Category"
250 msgstr "Categoria"
251
252 #: ../unity-scope-diodon/clipboard.scope.in.in.h:8
253 msgid "Text;Files;Images"
254 msgstr "Text;Arxius;Imatges"
255
256 #: ../unity-scope-diodon/clipboard.scope.in.in.h:9
257 msgid "Last 24 hours;Last 7 days;Last 30 days;Last year;"
258 msgstr ""
259
260 #: ../unity-scope-diodon/unity-scope-diodon.vala:45
261 msgid "Search Clipboard"
262 msgstr ""
263
264 #: ../unity-scope-diodon/unity-scope-diodon.vala:110
265 #: ../unity-scope-diodon/unity-scope-diodon.vala:231
266 msgid "Date copied"
267 msgstr ""
268
269 #: ../unity-scope-diodon/unity-scope-diodon.vala:112
270 msgid "Last 24 hours"
271 msgstr "Últimes 24 hores"
272
273 #: ../unity-scope-diodon/unity-scope-diodon.vala:113
274 msgid "Last 7 days"
275 msgstr "Últims 7 dies"
276
277 #: ../unity-scope-diodon/unity-scope-diodon.vala:114
278 msgid "Last 30 days"
279 msgstr "Últims 30 dies"
280
281 #: ../unity-scope-diodon/unity-scope-diodon.vala:115
282 msgid "Last year"
283 msgstr "L'últim any"
284
285 #: ../unity-scope-diodon/unity-scope-diodon.vala:216
286 msgid "Paste"
287 msgstr "Enganxa"
288
289 #: ../unity-scope-diodon/unity-scope-diodon.vala:224
290 msgid "Origin"
291 msgstr "Origen"
0 # Czech translation for diodon
1 # Copyright (c) 2011 Rosetta Contributors and Canonical Ltd 2011
2 # This file is distributed under the same license as the diodon package.
3 # FIRST AUTHOR <EMAIL@ADDRESS>, 2011.
4 #
5 msgid ""
6 msgstr ""
7 "Project-Id-Version: diodon\n"
8 "Report-Msgid-Bugs-To: \n"
9 "POT-Creation-Date: 2017-06-05 14:18+0200\n"
10 "PO-Revision-Date: 2014-05-04 19:57+0000\n"
11 "Last-Translator: Vojta Staněk <Unknown>\n"
12 "Language-Team: Czech <cs@li.org>\n"
13 "MIME-Version: 1.0\n"
14 "Content-Type: text/plain; charset=UTF-8\n"
15 "Content-Transfer-Encoding: 8bit\n"
16 "X-Launchpad-Export-Date: 2017-06-06 05:55+0000\n"
17 "X-Generator: Launchpad (build 18399)\n"
18 "Language: cs\n"
19
20 #: ../data/diodon.desktop.in.h:1
21 msgid "Clipboard Manager"
22 msgstr "Správce schránky"
23
24 #: ../data/diodon.desktop.in.h:2
25 msgid "GTK+ Clipboard Manager"
26 msgstr "GTK+ Správce schránky"
27
28 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:1
29 msgid "Use clipboard (Ctrl+C)"
30 msgstr "Použít schránku (Ctrl+C)"
31
32 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:2
33 #: ../data/preferences.ui.h:3
34 msgid ""
35 "Adds content which is copied to the clipboard with e.g. Ctrl + C to the "
36 "clipboard history."
37 msgstr ""
38 "Přidává obsah, který je zkopírovaný do schránky pomocí např. Ctrl + C, do "
39 "historie schránky"
40
41 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:3
42 msgid "Use primary selection"
43 msgstr "Použít primární výběr"
44
45 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:4
46 #: ../data/preferences.ui.h:5
47 msgid ""
48 "Adds the primary selection (an area of the screen which is selected with the "
49 "mouse) to the clipboard history. Enabling will start process which "
50 "continually checks what is selected. This might discharge your battery "
51 "quicker."
52 msgstr ""
53
54 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:5
55 msgid "Add images to clipboard history"
56 msgstr "Přidává obrázky do historie schránky"
57
58 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:6
59 #: ../data/preferences.ui.h:7
60 msgid ""
61 "Add images copied to clipboard to clipboard history (e.g. when you right "
62 "click on an image in your browser and choose copy image). Enabling this "
63 "option will increase memory consumption. Images already added to clipboard "
64 "history will remain even when disabled."
65 msgstr ""
66
67 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:7
68 msgid "Synchronize clipboards"
69 msgstr "Synchronizovat schránky"
70
71 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:8
72 #: ../data/preferences.ui.h:11
73 msgid ""
74 "Synchronizes the selection (an area of the screen which is selected with the "
75 "mouse) and the clipboard so that anything in the selection is immediately "
76 "available in the clipboard and vice versa e.g. for pasting with Ctrl + V and "
77 "the middle mouse button."
78 msgstr ""
79 "Synchronizuje výběr (oblast vyznačená myší) a schránku takže to, co vyberete "
80 "myší můžete vložit pomocí Ctrl+V a naopak to, co zkopírujete přes Ctrl+C "
81 "můžete vložit prostředním tlačítkem myši."
82
83 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:9
84 msgid "Keep clipboard content"
85 msgstr "Udržujte obsah schránky"
86
87 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:10
88 #: ../data/preferences.ui.h:9
89 msgid ""
90 "Prevents an empty clipboard. For instance when an application exits, the "
91 "clipboard would usually be emptied."
92 msgstr ""
93 "Zabrání vyprázdnění schránky. Například při ukončení aplikace je schránka "
94 "obvykle vyprázdněna."
95
96 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:11
97 msgid "Automatically paste selected item"
98 msgstr "Automaticky vložit vybranou položku"
99
100 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:12
101 #: ../data/preferences.ui.h:13
102 msgid ""
103 "Automatically paste selected item instead of just copying it to the "
104 "clipboard."
105 msgstr ""
106 "Po kliknutí na položku v historii ji automaticky vloží na místo s kurzorem."
107
108 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:13
109 msgid "Number of recent clipboard items"
110 msgstr "Počet posledních zkopírovaných položek"
111
112 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:14
113 msgid "Number of recent clipboard items shown in clipboard menu."
114 msgstr "Počet posledních zkopírovaných položek zobrazený v menu schránky."
115
116 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:15
117 msgid "Clipboard content filter pattern"
118 msgstr ""
119
120 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:16
121 msgid ""
122 "Regex filter pattern whereas all clipboard items matching this pattern will "
123 "be filtered and not added to clipboard history."
124 msgstr ""
125
126 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:17
127 msgid "Lookup dictionary for application using different paste keybindings"
128 msgstr ""
129
130 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:18
131 msgid ""
132 "A lookup dictionary for applications using different paste keybindings than "
133 "Ctrl + V. Pattern of each string in this array is path-of-app|keybinding"
134 msgstr ""
135
136 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:19
137 msgid "Active plugins"
138 msgstr "Aktivní pluginy"
139
140 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:20
141 msgid "List of active plugins."
142 msgstr "Seznam aktivních pluginů"
143
144 #: ../data/preferences.ui.h:1
145 msgid "Diodon Preferences"
146 msgstr "Nastavení aplikace Diodon"
147
148 #: ../data/preferences.ui.h:2
149 msgid "_Use clipboard (Ctrl+C)"
150 msgstr "Po_užít schránku (Ctrl+C)"
151
152 #: ../data/preferences.ui.h:4
153 msgid "Use _primary selection"
154 msgstr "_Použít primární výběr"
155
156 #: ../data/preferences.ui.h:6
157 msgid "Add _images to clipboard history"
158 msgstr ""
159
160 #: ../data/preferences.ui.h:8
161 msgid "_Keep clipboard content"
162 msgstr "_Uchovat obsah schránky"
163
164 #: ../data/preferences.ui.h:10
165 msgid "S_ynchronize clipboards"
166 msgstr "S_ynchronizovat schránky."
167
168 #: ../data/preferences.ui.h:12
169 msgid "_Automatically paste selected item"
170 msgstr "_Automaticky vložit vybranou položku"
171
172 #: ../data/preferences.ui.h:14
173 msgid "Number of recent clipboard items to be shown in clipboard menu."
174 msgstr "Počet posledních zkopírovaných položek k zobrazení v menu schránky."
175
176 #: ../data/preferences.ui.h:15
177 msgid "Number of recent items"
178 msgstr "Počet posledních položek"
179
180 #: ../data/preferences.ui.h:16 ../unity-scope-diodon/unity-scope-diodon.vala:75
181 msgid "Clipboard"
182 msgstr "Schránka"
183
184 #: ../data/preferences.ui.h:17
185 msgid ""
186 "Please register custom shortcut with\n"
187 "your desktop environment.\n"
188 "Use /usr/bin/diodon as command."
189 msgstr ""
190
191 #: ../data/preferences.ui.h:20
192 msgid "More information"
193 msgstr ""
194
195 #: ../data/preferences.ui.h:21
196 msgid "Hotkeys"
197 msgstr ""
198
199 #: ../data/preferences.ui.h:22
200 msgid "Plugins"
201 msgstr "Pluginy"
202
203 #: ../libdiodon/clipboard-menu.vala:46
204 msgid "<Empty>"
205 msgstr "<Prázdná>"
206
207 #: ../libdiodon/clipboard-menu.vala:53
208 msgid "Privacy mode is enabled. No new items will be added to history!"
209 msgstr ""
210
211 #: ../plugins/indicator/indicator.plugin.in.h:1
212 msgid "Application Indicator"
213 msgstr "Indikátor aplikace"
214
215 #: ../plugins/indicator/indicator.plugin.in.h:2
216 msgid "Access clipboard history with an application indicator."
217 msgstr "Přistupujte k historii schránky přes indikátor aplikací."
218
219 #: ../plugins/indicator/indicator.plugin.in.h:3
220 msgid "Copyright © 2011 Diodon Team"
221 msgstr ""
222
223 #: ../unity-scope-diodon/clipboard.scope.in.in.h:1
224 msgid "Clipboard History"
225 msgstr "Historie schránky"
226
227 #: ../unity-scope-diodon/clipboard.scope.in.in.h:2
228 msgid ""
229 "This is an Ubuntu search plugin that enables information from Diodon to be "
230 "searched and displayed in the Dash underneath the Clipboard header."
231 msgstr ""
232
233 #: ../unity-scope-diodon/clipboard.scope.in.in.h:3
234 msgid "Search clipboard"
235 msgstr "Hledat ve schránce"
236
237 #: ../unity-scope-diodon/clipboard.scope.in.in.h:4
238 #: ../unity-scope-diodon/unity-scope-diodon.vala:79
239 #: ../unity-scope-diodon/unity-scope-diodon.vala:104
240 msgid "Text"
241 msgstr "Text"
242
243 #: ../unity-scope-diodon/clipboard.scope.in.in.h:5
244 #: ../unity-scope-diodon/unity-scope-diodon.vala:84
245 #: ../unity-scope-diodon/unity-scope-diodon.vala:105
246 msgid "Files"
247 msgstr "Soubory"
248
249 #: ../unity-scope-diodon/clipboard.scope.in.in.h:6
250 #: ../unity-scope-diodon/unity-scope-diodon.vala:89
251 #: ../unity-scope-diodon/unity-scope-diodon.vala:106
252 msgid "Images"
253 msgstr "Obrázky"
254
255 #: ../unity-scope-diodon/clipboard.scope.in.in.h:7
256 #: ../unity-scope-diodon/unity-scope-diodon.vala:101
257 msgid "Category"
258 msgstr "Kategorie"
259
260 #: ../unity-scope-diodon/clipboard.scope.in.in.h:8
261 msgid "Text;Files;Images"
262 msgstr ""
263
264 #: ../unity-scope-diodon/clipboard.scope.in.in.h:9
265 msgid "Last 24 hours;Last 7 days;Last 30 days;Last year;"
266 msgstr ""
267
268 #: ../unity-scope-diodon/unity-scope-diodon.vala:45
269 msgid "Search Clipboard"
270 msgstr ""
271
272 #: ../unity-scope-diodon/unity-scope-diodon.vala:110
273 #: ../unity-scope-diodon/unity-scope-diodon.vala:231
274 msgid "Date copied"
275 msgstr ""
276
277 #: ../unity-scope-diodon/unity-scope-diodon.vala:112
278 msgid "Last 24 hours"
279 msgstr ""
280
281 #: ../unity-scope-diodon/unity-scope-diodon.vala:113
282 msgid "Last 7 days"
283 msgstr ""
284
285 #: ../unity-scope-diodon/unity-scope-diodon.vala:114
286 msgid "Last 30 days"
287 msgstr ""
288
289 #: ../unity-scope-diodon/unity-scope-diodon.vala:115
290 msgid "Last year"
291 msgstr ""
292
293 #: ../unity-scope-diodon/unity-scope-diodon.vala:216
294 msgid "Paste"
295 msgstr ""
296
297 #: ../unity-scope-diodon/unity-scope-diodon.vala:224
298 msgid "Origin"
299 msgstr ""
0 msgid ""
1 msgstr ""
2 "Project-Id-Version: Diodon 0.0.1\n"
3 "Report-Msgid-Bugs-To: \n"
4 "POT-Creation-Date: 2017-06-05 14:18+0200\n"
5 "PO-Revision-Date: 2016-05-07 14:06+0000\n"
6 "Last-Translator: UweS <Unknown>\n"
7 "Language-Team: \n"
8 "MIME-Version: 1.0\n"
9 "Content-Type: text/plain; charset=UTF-8\n"
10 "Content-Transfer-Encoding: 8bit\n"
11 "X-Launchpad-Export-Date: 2017-06-06 05:55+0000\n"
12 "X-Generator: Launchpad (build 18399)\n"
13 "Language: de\n"
14
15 #: ../data/diodon.desktop.in.h:1
16 msgid "Clipboard Manager"
17 msgstr "Zwischenablage-Verwaltung"
18
19 #: ../data/diodon.desktop.in.h:2
20 msgid "GTK+ Clipboard Manager"
21 msgstr "GTK+-Zwischenablage-Verwaltung"
22
23 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:1
24 msgid "Use clipboard (Ctrl+C)"
25 msgstr "Zwischenablage verwenden (Strg+C)"
26
27 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:2
28 #: ../data/preferences.ui.h:3
29 msgid ""
30 "Adds content which is copied to the clipboard with e.g. Ctrl + C to the "
31 "clipboard history."
32 msgstr ""
33 "Daten, die z. B. mit Strg+C in die Zwischenablage kopiert werden, werden in "
34 "der Zwischenablage-Chronik gespeichert."
35
36 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:3
37 msgid "Use primary selection"
38 msgstr "Primärauswahl verwenden"
39
40 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:4
41 #: ../data/preferences.ui.h:5
42 msgid ""
43 "Adds the primary selection (an area of the screen which is selected with the "
44 "mouse) to the clipboard history. Enabling will start process which "
45 "continually checks what is selected. This might discharge your battery "
46 "quicker."
47 msgstr ""
48 "Die Primärauswahlen (mit der Maus ausgewählte Bildschirminhalte) werden in "
49 "der Zwischenablage-Chronik gespeichert. Bei Einschalten dieser Option wird "
50 "ein Prozess gestartet, der kontinuierlich verfolgt, welche Inhalte Sie "
51 "auswählen. Daher entlädt Ihr Notebook-Akku sich möglicherweise schneller."
52
53 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:5
54 msgid "Add images to clipboard history"
55 msgstr "Bilder der Zwischenablage-Chronik hinzufügen"
56
57 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:6
58 #: ../data/preferences.ui.h:7
59 msgid ""
60 "Add images copied to clipboard to clipboard history (e.g. when you right "
61 "click on an image in your browser and choose copy image). Enabling this "
62 "option will increase memory consumption. Images already added to clipboard "
63 "history will remain even when disabled."
64 msgstr ""
65 "In die Zwischenablage kopierte Bilder (etwa indem Sie im Browser mit der "
66 "rechten Maustaste auf ein Bild geklickt und »Grafik kopieren« wählen haben) "
67 "werden in der Zwischenablage-Chronik gespeichert. Ist diese Option "
68 "eingeschaltet, vergrößert sich Diodons Arbeitsspeicherbedarf. Bilder, die "
69 "bereits in der Zwischenablage-Chronik gespeichert sind, verbleiben auch dann "
70 "dort, wenn diese Option ausgeschaltet wird."
71
72 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:7
73 msgid "Synchronize clipboards"
74 msgstr "Zwischenablagen abgleichen"
75
76 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:8
77 #: ../data/preferences.ui.h:11
78 msgid ""
79 "Synchronizes the selection (an area of the screen which is selected with the "
80 "mouse) and the clipboard so that anything in the selection is immediately "
81 "available in the clipboard and vice versa e.g. for pasting with Ctrl + V and "
82 "the middle mouse button."
83 msgstr ""
84 "Gleicht die Auswahl (ein mit der Maus ausgewählter Bereich des Bildschirms) "
85 "mit der Zwischenablage ab, sodass die Auswahl sofort in der Zwischenablage "
86 "verfügbar ist und andersherum, z. B. zum Einfügen mit Strg + V oder mit der "
87 "mittleren Maustaste."
88
89 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:9
90 msgid "Keep clipboard content"
91 msgstr "Inhalt der Zwischenablage erhalten"
92
93 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:10
94 #: ../data/preferences.ui.h:9
95 msgid ""
96 "Prevents an empty clipboard. For instance when an application exits, the "
97 "clipboard would usually be emptied."
98 msgstr ""
99 "Verhindert eine leere Zwischenablage. Üblicherweise wird beim Schließen "
100 "eines Programms der Inhalt der Zwischenablage gelöscht."
101
102 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:11
103 msgid "Automatically paste selected item"
104 msgstr "Gewählten Eintrag sofort einfügen"
105
106 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:12
107 #: ../data/preferences.ui.h:13
108 msgid ""
109 "Automatically paste selected item instead of just copying it to the "
110 "clipboard."
111 msgstr ""
112 "Gewählte Einträge werden sofort eingefügt, anstatt nur in die Zwischenablage "
113 "kopiert zu werden."
114
115 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:13
116 msgid "Number of recent clipboard items"
117 msgstr "Einträge in der Zwischenablage-Chronik"
118
119 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:14
120 msgid "Number of recent clipboard items shown in clipboard menu."
121 msgstr "Anzahl der im Zwischenablage-Menü angezeigten Einträge"
122
123 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:15
124 msgid "Clipboard content filter pattern"
125 msgstr "Filterregel für Zwischenablageninhalte"
126
127 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:16
128 msgid ""
129 "Regex filter pattern whereas all clipboard items matching this pattern will "
130 "be filtered and not added to clipboard history."
131 msgstr ""
132 "Regex-Filterregel; Zwischenablageninhalte, die dieser Regel entsprechen, "
133 "werden ausgefiltert und nicht in die Zwischenablagen-Chronik aufgenommen"
134
135 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:17
136 msgid "Lookup dictionary for application using different paste keybindings"
137 msgstr ""
138 "Verzeichnis mit Anwendungen, die abweichende Tastenbelegungen für das "
139 "Einfügen nutzen"
140
141 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:18
142 msgid ""
143 "A lookup dictionary for applications using different paste keybindings than "
144 "Ctrl + V. Pattern of each string in this array is path-of-app|keybinding"
145 msgstr ""
146 "Verzeichnis von Anwendungen, die andere Tastenbelegungen als Strg + V für "
147 "das Einfügen nutzen. Die Zeichenketten dieses Arrays sind nach dem Muster "
148 "pfad-zur-anwendung|tastenbelegung aufgebaut"
149
150 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:19
151 msgid "Active plugins"
152 msgstr "Aktive Erweiterungen"
153
154 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:20
155 msgid "List of active plugins."
156 msgstr "Liste der aktiven Erweiterungen"
157
158 #: ../data/preferences.ui.h:1
159 msgid "Diodon Preferences"
160 msgstr "Diodon-Einstellungen"
161
162 #: ../data/preferences.ui.h:2
163 msgid "_Use clipboard (Ctrl+C)"
164 msgstr "_Zwischenablage (Ctrl+C) in der Chronik speichern"
165
166 #: ../data/preferences.ui.h:4
167 msgid "Use _primary selection"
168 msgstr "_Primärauswahl in der Chronik speichern"
169
170 #: ../data/preferences.ui.h:6
171 msgid "Add _images to clipboard history"
172 msgstr "_Bilder der Zwischenablage-Chronik hinzufügen"
173
174 #: ../data/preferences.ui.h:8
175 msgid "_Keep clipboard content"
176 msgstr "Inhalt der Zwischenablage _erhalten"
177
178 #: ../data/preferences.ui.h:10
179 msgid "S_ynchronize clipboards"
180 msgstr "Zwischenablagen _abgleichen"
181
182 #: ../data/preferences.ui.h:12
183 msgid "_Automatically paste selected item"
184 msgstr "Gewählten Eintrag _sofort einfügen"
185
186 #: ../data/preferences.ui.h:14
187 msgid "Number of recent clipboard items to be shown in clipboard menu."
188 msgstr "Anzahl der im Zwischenablage-Menü angezeigten Einträge"
189
190 #: ../data/preferences.ui.h:15
191 msgid "Number of recent items"
192 msgstr "Einträge in der Chronik"
193
194 #: ../data/preferences.ui.h:16 ../unity-scope-diodon/unity-scope-diodon.vala:75
195 msgid "Clipboard"
196 msgstr "Zwischenablage"
197
198 #: ../data/preferences.ui.h:17
199 msgid ""
200 "Please register custom shortcut with\n"
201 "your desktop environment.\n"
202 "Use /usr/bin/diodon as command."
203 msgstr ""
204 "Tragen Sie das selbst gewählte Tastenkürzel \n"
205 "in Ihrer Desktop-Umgebung ein.\n"
206 "Verwenden Sie den Befehl /usr/bin/diodon."
207
208 #: ../data/preferences.ui.h:20
209 msgid "More information"
210 msgstr "Weitere Informationen"
211
212 #: ../data/preferences.ui.h:21
213 msgid "Hotkeys"
214 msgstr "Tastenkürzel"
215
216 #: ../data/preferences.ui.h:22
217 msgid "Plugins"
218 msgstr "Erweiterungen"
219
220 #: ../libdiodon/clipboard-menu.vala:46
221 msgid "<Empty>"
222 msgstr "<Leer>"
223
224 #: ../libdiodon/clipboard-menu.vala:53
225 msgid "Privacy mode is enabled. No new items will be added to history!"
226 msgstr ""
227
228 #: ../plugins/indicator/indicator.plugin.in.h:1
229 msgid "Application Indicator"
230 msgstr "Indikator-Applet"
231
232 #: ../plugins/indicator/indicator.plugin.in.h:2
233 msgid "Access clipboard history with an application indicator."
234 msgstr "Auf die Zwischenablage-Chronik mit einem Indikator-Applet zugreifen."
235
236 #: ../plugins/indicator/indicator.plugin.in.h:3
237 msgid "Copyright © 2011 Diodon Team"
238 msgstr "Copyright © 2011 Diodon-Team"
239
240 #: ../unity-scope-diodon/clipboard.scope.in.in.h:1
241 msgid "Clipboard History"
242 msgstr "Zwischenablage-Chronik"
243
244 #: ../unity-scope-diodon/clipboard.scope.in.in.h:2
245 msgid ""
246 "This is an Ubuntu search plugin that enables information from Diodon to be "
247 "searched and displayed in the Dash underneath the Clipboard header."
248 msgstr ""
249 "Dies ist ein Ubuntu-Such-Erweiterung, die das Suchen und Anzeigen von "
250 "Informationen aus Diodon im Dash unter der Zwischenablage-Kopfzeile "
251 "ermöglicht."
252
253 #: ../unity-scope-diodon/clipboard.scope.in.in.h:3
254 msgid "Search clipboard"
255 msgstr "Zwischenablage durchsuchen"
256
257 #: ../unity-scope-diodon/clipboard.scope.in.in.h:4
258 #: ../unity-scope-diodon/unity-scope-diodon.vala:79
259 #: ../unity-scope-diodon/unity-scope-diodon.vala:104
260 msgid "Text"
261 msgstr "Text"
262
263 #: ../unity-scope-diodon/clipboard.scope.in.in.h:5
264 #: ../unity-scope-diodon/unity-scope-diodon.vala:84
265 #: ../unity-scope-diodon/unity-scope-diodon.vala:105
266 msgid "Files"
267 msgstr "Dateien"
268
269 #: ../unity-scope-diodon/clipboard.scope.in.in.h:6
270 #: ../unity-scope-diodon/unity-scope-diodon.vala:89
271 #: ../unity-scope-diodon/unity-scope-diodon.vala:106
272 msgid "Images"
273 msgstr "Bilder"
274
275 #: ../unity-scope-diodon/clipboard.scope.in.in.h:7
276 #: ../unity-scope-diodon/unity-scope-diodon.vala:101
277 msgid "Category"
278 msgstr "Kategorie"
279
280 #: ../unity-scope-diodon/clipboard.scope.in.in.h:8
281 msgid "Text;Files;Images"
282 msgstr "Text;Dateien;Bilder"
283
284 #: ../unity-scope-diodon/clipboard.scope.in.in.h:9
285 msgid "Last 24 hours;Last 7 days;Last 30 days;Last year;"
286 msgstr "Letzte 24 Stunden;Letze 7 Tage;Letze 30 Tage;Letztes Jahr"
287
288 #: ../unity-scope-diodon/unity-scope-diodon.vala:45
289 msgid "Search Clipboard"
290 msgstr "Zwischenablage durchsuchen"
291
292 #: ../unity-scope-diodon/unity-scope-diodon.vala:110
293 #: ../unity-scope-diodon/unity-scope-diodon.vala:231
294 msgid "Date copied"
295 msgstr "Kopierdatum"
296
297 #: ../unity-scope-diodon/unity-scope-diodon.vala:112
298 msgid "Last 24 hours"
299 msgstr "Letzte 24 Stunden"
300
301 #: ../unity-scope-diodon/unity-scope-diodon.vala:113
302 msgid "Last 7 days"
303 msgstr "Letzte 7 Tage"
304
305 #: ../unity-scope-diodon/unity-scope-diodon.vala:114
306 msgid "Last 30 days"
307 msgstr "Letzte 30 Tage"
308
309 #: ../unity-scope-diodon/unity-scope-diodon.vala:115
310 msgid "Last year"
311 msgstr "Letztes Jahr"
312
313 #: ../unity-scope-diodon/unity-scope-diodon.vala:216
314 msgid "Paste"
315 msgstr "Einfügen"
316
317 #: ../unity-scope-diodon/unity-scope-diodon.vala:224
318 msgid "Origin"
319 msgstr "Herkunft"
0 # SOME DESCRIPTIVE TITLE.
1 # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
2 # This file is distributed under the same license as the PACKAGE package.
3 # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
4 #
5 #, fuzzy
6 msgid ""
7 msgstr ""
8 "Project-Id-Version: PACKAGE VERSION\n"
9 "Report-Msgid-Bugs-To: \n"
10 "POT-Creation-Date: 2017-06-05 14:18+0200\n"
11 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
12 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
13 "Language-Team: LANGUAGE <LL@li.org>\n"
14 "Language: \n"
15 "MIME-Version: 1.0\n"
16 "Content-Type: text/plain; charset=UTF-8\n"
17 "Content-Transfer-Encoding: 8bit\n"
18
19 #: ../data/diodon.desktop.in.h:1
20 msgid "Clipboard Manager"
21 msgstr ""
22
23 #: ../data/diodon.desktop.in.h:2
24 msgid "GTK+ Clipboard Manager"
25 msgstr ""
26
27 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:1
28 msgid "Use clipboard (Ctrl+C)"
29 msgstr ""
30
31 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:2
32 #: ../data/preferences.ui.h:3
33 msgid ""
34 "Adds content which is copied to the clipboard with e.g. Ctrl + C to the "
35 "clipboard history."
36 msgstr ""
37
38 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:3
39 msgid "Use primary selection"
40 msgstr ""
41
42 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:4
43 #: ../data/preferences.ui.h:5
44 msgid ""
45 "Adds the primary selection (an area of the screen which is selected with the "
46 "mouse) to the clipboard history. Enabling will start process which "
47 "continually checks what is selected. This might discharge your battery "
48 "quicker."
49 msgstr ""
50
51 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:5
52 msgid "Add images to clipboard history"
53 msgstr ""
54
55 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:6
56 #: ../data/preferences.ui.h:7
57 msgid ""
58 "Add images copied to clipboard to clipboard history (e.g. when you right "
59 "click on an image in your browser and choose copy image). Enabling this "
60 "option will increase memory consumption. Images already added to clipboard "
61 "history will remain even when disabled."
62 msgstr ""
63
64 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:7
65 msgid "Synchronize clipboards"
66 msgstr ""
67
68 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:8
69 #: ../data/preferences.ui.h:11
70 msgid ""
71 "Synchronizes the selection (an area of the screen which is selected with the "
72 "mouse) and the clipboard so that anything in the selection is immediately "
73 "available in the clipboard and vice versa e.g. for pasting with Ctrl + V and "
74 "the middle mouse button."
75 msgstr ""
76
77 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:9
78 msgid "Keep clipboard content"
79 msgstr ""
80
81 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:10
82 #: ../data/preferences.ui.h:9
83 msgid ""
84 "Prevents an empty clipboard. For instance when an application exits, the "
85 "clipboard would usually be emptied."
86 msgstr ""
87
88 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:11
89 msgid "Automatically paste selected item"
90 msgstr ""
91
92 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:12
93 #: ../data/preferences.ui.h:13
94 msgid ""
95 "Automatically paste selected item instead of just copying it to the "
96 "clipboard."
97 msgstr ""
98
99 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:13
100 msgid "Number of recent clipboard items"
101 msgstr ""
102
103 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:14
104 msgid "Number of recent clipboard items shown in clipboard menu."
105 msgstr ""
106
107 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:15
108 msgid "Clipboard content filter pattern"
109 msgstr ""
110
111 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:16
112 msgid ""
113 "Regex filter pattern whereas all clipboard items matching this pattern will "
114 "be filtered and not added to clipboard history."
115 msgstr ""
116
117 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:17
118 msgid "Lookup dictionary for application using different paste keybindings"
119 msgstr ""
120
121 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:18
122 msgid ""
123 "A lookup dictionary for applications using different paste keybindings than "
124 "Ctrl + V. Pattern of each string in this array is path-of-app|keybinding"
125 msgstr ""
126
127 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:19
128 msgid "Active plugins"
129 msgstr ""
130
131 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:20
132 msgid "List of active plugins."
133 msgstr ""
134
135 #: ../data/preferences.ui.h:1
136 msgid "Diodon Preferences"
137 msgstr ""
138
139 #: ../data/preferences.ui.h:2
140 msgid "_Use clipboard (Ctrl+C)"
141 msgstr ""
142
143 #: ../data/preferences.ui.h:4
144 msgid "Use _primary selection"
145 msgstr ""
146
147 #: ../data/preferences.ui.h:6
148 msgid "Add _images to clipboard history"
149 msgstr ""
150
151 #: ../data/preferences.ui.h:8
152 msgid "_Keep clipboard content"
153 msgstr ""
154
155 #: ../data/preferences.ui.h:10
156 msgid "S_ynchronize clipboards"
157 msgstr ""
158
159 #: ../data/preferences.ui.h:12
160 msgid "_Automatically paste selected item"
161 msgstr ""
162
163 #: ../data/preferences.ui.h:14
164 msgid "Number of recent clipboard items to be shown in clipboard menu."
165 msgstr ""
166
167 #: ../data/preferences.ui.h:15
168 msgid "Number of recent items"
169 msgstr ""
170
171 #: ../data/preferences.ui.h:16 ../unity-scope-diodon/unity-scope-diodon.vala:75
172 msgid "Clipboard"
173 msgstr ""
174
175 #: ../data/preferences.ui.h:17
176 msgid ""
177 "Please register custom shortcut with\n"
178 "your desktop environment.\n"
179 "Use /usr/bin/diodon as command."
180 msgstr ""
181
182 #: ../data/preferences.ui.h:20
183 msgid "More information"
184 msgstr ""
185
186 #: ../data/preferences.ui.h:21
187 msgid "Hotkeys"
188 msgstr ""
189
190 #: ../data/preferences.ui.h:22
191 msgid "Plugins"
192 msgstr ""
193
194 #: ../libdiodon/clipboard-menu.vala:46
195 msgid "<Empty>"
196 msgstr ""
197
198 #: ../libdiodon/clipboard-menu.vala:53
199 msgid "Privacy mode is enabled. No new items will be added to history!"
200 msgstr ""
201
202 #: ../plugins/indicator/indicator.plugin.in.h:1
203 msgid "Application Indicator"
204 msgstr ""
205
206 #: ../plugins/indicator/indicator.plugin.in.h:2
207 msgid "Access clipboard history with an application indicator."
208 msgstr ""
209
210 #: ../plugins/indicator/indicator.plugin.in.h:3
211 msgid "Copyright © 2011 Diodon Team"
212 msgstr ""
213
214 #: ../unity-scope-diodon/clipboard.scope.in.in.h:1
215 msgid "Clipboard History"
216 msgstr ""
217
218 #: ../unity-scope-diodon/clipboard.scope.in.in.h:2
219 msgid ""
220 "This is an Ubuntu search plugin that enables information from Diodon to be "
221 "searched and displayed in the Dash underneath the Clipboard header."
222 msgstr ""
223
224 #: ../unity-scope-diodon/clipboard.scope.in.in.h:3
225 msgid "Search clipboard"
226 msgstr ""
227
228 #: ../unity-scope-diodon/clipboard.scope.in.in.h:4
229 #: ../unity-scope-diodon/unity-scope-diodon.vala:79
230 #: ../unity-scope-diodon/unity-scope-diodon.vala:104
231 msgid "Text"
232 msgstr ""
233
234 #: ../unity-scope-diodon/clipboard.scope.in.in.h:5
235 #: ../unity-scope-diodon/unity-scope-diodon.vala:84
236 #: ../unity-scope-diodon/unity-scope-diodon.vala:105
237 msgid "Files"
238 msgstr ""
239
240 #: ../unity-scope-diodon/clipboard.scope.in.in.h:6
241 #: ../unity-scope-diodon/unity-scope-diodon.vala:89
242 #: ../unity-scope-diodon/unity-scope-diodon.vala:106
243 msgid "Images"
244 msgstr ""
245
246 #: ../unity-scope-diodon/clipboard.scope.in.in.h:7
247 #: ../unity-scope-diodon/unity-scope-diodon.vala:101
248 msgid "Category"
249 msgstr ""
250
251 #: ../unity-scope-diodon/clipboard.scope.in.in.h:8
252 msgid "Text;Files;Images"
253 msgstr ""
254
255 #: ../unity-scope-diodon/clipboard.scope.in.in.h:9
256 msgid "Last 24 hours;Last 7 days;Last 30 days;Last year;"
257 msgstr ""
258
259 #: ../unity-scope-diodon/unity-scope-diodon.vala:45
260 msgid "Search Clipboard"
261 msgstr ""
262
263 #: ../unity-scope-diodon/unity-scope-diodon.vala:110
264 #: ../unity-scope-diodon/unity-scope-diodon.vala:231
265 msgid "Date copied"
266 msgstr ""
267
268 #: ../unity-scope-diodon/unity-scope-diodon.vala:112
269 msgid "Last 24 hours"
270 msgstr ""
271
272 #: ../unity-scope-diodon/unity-scope-diodon.vala:113
273 msgid "Last 7 days"
274 msgstr ""
275
276 #: ../unity-scope-diodon/unity-scope-diodon.vala:114
277 msgid "Last 30 days"
278 msgstr ""
279
280 #: ../unity-scope-diodon/unity-scope-diodon.vala:115
281 msgid "Last year"
282 msgstr ""
283
284 #: ../unity-scope-diodon/unity-scope-diodon.vala:216
285 msgid "Paste"
286 msgstr ""
287
288 #: ../unity-scope-diodon/unity-scope-diodon.vala:224
289 msgid "Origin"
290 msgstr ""
0 # English (United Kingdom) translation for diodon
1 # Copyright (c) 2012 Rosetta Contributors and Canonical Ltd 2012
2 # This file is distributed under the same license as the diodon package.
3 # FIRST AUTHOR <EMAIL@ADDRESS>, 2012.
4 #
5 msgid ""
6 msgstr ""
7 "Project-Id-Version: diodon\n"
8 "Report-Msgid-Bugs-To: \n"
9 "POT-Creation-Date: 2017-06-05 14:18+0200\n"
10 "PO-Revision-Date: 2013-12-29 00:12+0000\n"
11 "Last-Translator: Oliver Sauder <os@esite.ch>\n"
12 "Language-Team: English (United Kingdom) <en_GB@li.org>\n"
13 "MIME-Version: 1.0\n"
14 "Content-Type: text/plain; charset=UTF-8\n"
15 "Content-Transfer-Encoding: 8bit\n"
16 "X-Launchpad-Export-Date: 2017-06-06 05:56+0000\n"
17 "X-Generator: Launchpad (build 18399)\n"
18 "Language: \n"
19
20 #: ../data/diodon.desktop.in.h:1
21 msgid "Clipboard Manager"
22 msgstr "Clipboard Manager"
23
24 #: ../data/diodon.desktop.in.h:2
25 msgid "GTK+ Clipboard Manager"
26 msgstr "GTK+ Clipboard Manager"
27
28 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:1
29 msgid "Use clipboard (Ctrl+C)"
30 msgstr "Use clipboard (Ctrl+C)"
31
32 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:2
33 #: ../data/preferences.ui.h:3
34 msgid ""
35 "Adds content which is copied to the clipboard with e.g. Ctrl + C to the "
36 "clipboard history."
37 msgstr ""
38
39 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:3
40 msgid "Use primary selection"
41 msgstr "Use primary selection"
42
43 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:4
44 #: ../data/preferences.ui.h:5
45 msgid ""
46 "Adds the primary selection (an area of the screen which is selected with the "
47 "mouse) to the clipboard history. Enabling will start process which "
48 "continually checks what is selected. This might discharge your battery "
49 "quicker."
50 msgstr ""
51
52 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:5
53 msgid "Add images to clipboard history"
54 msgstr ""
55
56 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:6
57 #: ../data/preferences.ui.h:7
58 msgid ""
59 "Add images copied to clipboard to clipboard history (e.g. when you right "
60 "click on an image in your browser and choose copy image). Enabling this "
61 "option will increase memory consumption. Images already added to clipboard "
62 "history will remain even when disabled."
63 msgstr ""
64
65 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:7
66 msgid "Synchronize clipboards"
67 msgstr "Synchronise clipboards"
68
69 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:8
70 #: ../data/preferences.ui.h:11
71 msgid ""
72 "Synchronizes the selection (an area of the screen which is selected with the "
73 "mouse) and the clipboard so that anything in the selection is immediately "
74 "available in the clipboard and vice versa e.g. for pasting with Ctrl + V and "
75 "the middle mouse button."
76 msgstr ""
77 "Synchronises the selection (an area of the screen which is selected with the "
78 "mouse) and the clipboard so that anything in the selection is immediately "
79 "available in the clipboard and vice versa e.g. for pasting with Ctrl + V and "
80 "the middle mouse button."
81
82 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:9
83 msgid "Keep clipboard content"
84 msgstr "Keep clipboard content"
85
86 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:10
87 #: ../data/preferences.ui.h:9
88 msgid ""
89 "Prevents an empty clipboard. For instance when an application exits, the "
90 "clipboard would usually be emptied."
91 msgstr ""
92 "Prevents an empty clipboard. For instance when an application exits, the "
93 "clipboard would usually be emptied."
94
95 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:11
96 msgid "Automatically paste selected item"
97 msgstr "Automatically paste selected item"
98
99 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:12
100 #: ../data/preferences.ui.h:13
101 msgid ""
102 "Automatically paste selected item instead of just copying it to the "
103 "clipboard."
104 msgstr ""
105 "Automatically paste selected item instead of just copying it to the "
106 "clipboard."
107
108 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:13
109 msgid "Number of recent clipboard items"
110 msgstr ""
111
112 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:14
113 msgid "Number of recent clipboard items shown in clipboard menu."
114 msgstr ""
115
116 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:15
117 msgid "Clipboard content filter pattern"
118 msgstr ""
119
120 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:16
121 msgid ""
122 "Regex filter pattern whereas all clipboard items matching this pattern will "
123 "be filtered and not added to clipboard history."
124 msgstr ""
125
126 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:17
127 msgid "Lookup dictionary for application using different paste keybindings"
128 msgstr ""
129
130 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:18
131 msgid ""
132 "A lookup dictionary for applications using different paste keybindings than "
133 "Ctrl + V. Pattern of each string in this array is path-of-app|keybinding"
134 msgstr ""
135
136 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:19
137 msgid "Active plugins"
138 msgstr "Active plugins"
139
140 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:20
141 msgid "List of active plugins."
142 msgstr "List of active plugins."
143
144 #: ../data/preferences.ui.h:1
145 msgid "Diodon Preferences"
146 msgstr "Diodon Preferences"
147
148 #: ../data/preferences.ui.h:2
149 msgid "_Use clipboard (Ctrl+C)"
150 msgstr "_Use clipboard (Ctrl+C)"
151
152 #: ../data/preferences.ui.h:4
153 msgid "Use _primary selection"
154 msgstr "Use _primary selection"
155
156 #: ../data/preferences.ui.h:6
157 msgid "Add _images to clipboard history"
158 msgstr ""
159
160 #: ../data/preferences.ui.h:8
161 msgid "_Keep clipboard content"
162 msgstr "_Keep clipboard content"
163
164 #: ../data/preferences.ui.h:10
165 msgid "S_ynchronize clipboards"
166 msgstr "S_ynchronise clipboards"
167
168 #: ../data/preferences.ui.h:12
169 msgid "_Automatically paste selected item"
170 msgstr "_Automatically paste selected item"
171
172 #: ../data/preferences.ui.h:14
173 msgid "Number of recent clipboard items to be shown in clipboard menu."
174 msgstr ""
175
176 #: ../data/preferences.ui.h:15
177 msgid "Number of recent items"
178 msgstr ""
179
180 #: ../data/preferences.ui.h:16 ../unity-scope-diodon/unity-scope-diodon.vala:75
181 msgid "Clipboard"
182 msgstr "Clipboard"
183
184 #: ../data/preferences.ui.h:17
185 msgid ""
186 "Please register custom shortcut with\n"
187 "your desktop environment.\n"
188 "Use /usr/bin/diodon as command."
189 msgstr ""
190
191 #: ../data/preferences.ui.h:20
192 msgid "More information"
193 msgstr ""
194
195 #: ../data/preferences.ui.h:21
196 msgid "Hotkeys"
197 msgstr ""
198
199 #: ../data/preferences.ui.h:22
200 msgid "Plugins"
201 msgstr "Plugins"
202
203 #: ../libdiodon/clipboard-menu.vala:46
204 msgid "<Empty>"
205 msgstr "<Empty>"
206
207 #: ../libdiodon/clipboard-menu.vala:53
208 msgid "Privacy mode is enabled. No new items will be added to history!"
209 msgstr ""
210
211 #: ../plugins/indicator/indicator.plugin.in.h:1
212 msgid "Application Indicator"
213 msgstr ""
214
215 #: ../plugins/indicator/indicator.plugin.in.h:2
216 msgid "Access clipboard history with an application indicator."
217 msgstr ""
218
219 #: ../plugins/indicator/indicator.plugin.in.h:3
220 msgid "Copyright © 2011 Diodon Team"
221 msgstr ""
222
223 #: ../unity-scope-diodon/clipboard.scope.in.in.h:1
224 msgid "Clipboard History"
225 msgstr ""
226
227 #: ../unity-scope-diodon/clipboard.scope.in.in.h:2
228 msgid ""
229 "This is an Ubuntu search plugin that enables information from Diodon to be "
230 "searched and displayed in the Dash underneath the Clipboard header."
231 msgstr ""
232
233 #: ../unity-scope-diodon/clipboard.scope.in.in.h:3
234 msgid "Search clipboard"
235 msgstr ""
236
237 #: ../unity-scope-diodon/clipboard.scope.in.in.h:4
238 #: ../unity-scope-diodon/unity-scope-diodon.vala:79
239 #: ../unity-scope-diodon/unity-scope-diodon.vala:104
240 msgid "Text"
241 msgstr ""
242
243 #: ../unity-scope-diodon/clipboard.scope.in.in.h:5
244 #: ../unity-scope-diodon/unity-scope-diodon.vala:84
245 #: ../unity-scope-diodon/unity-scope-diodon.vala:105
246 msgid "Files"
247 msgstr ""
248
249 #: ../unity-scope-diodon/clipboard.scope.in.in.h:6
250 #: ../unity-scope-diodon/unity-scope-diodon.vala:89
251 #: ../unity-scope-diodon/unity-scope-diodon.vala:106
252 msgid "Images"
253 msgstr ""
254
255 #: ../unity-scope-diodon/clipboard.scope.in.in.h:7
256 #: ../unity-scope-diodon/unity-scope-diodon.vala:101
257 msgid "Category"
258 msgstr ""
259
260 #: ../unity-scope-diodon/clipboard.scope.in.in.h:8
261 msgid "Text;Files;Images"
262 msgstr ""
263
264 #: ../unity-scope-diodon/clipboard.scope.in.in.h:9
265 msgid "Last 24 hours;Last 7 days;Last 30 days;Last year;"
266 msgstr ""
267
268 #: ../unity-scope-diodon/unity-scope-diodon.vala:45
269 msgid "Search Clipboard"
270 msgstr ""
271
272 #: ../unity-scope-diodon/unity-scope-diodon.vala:110
273 #: ../unity-scope-diodon/unity-scope-diodon.vala:231
274 msgid "Date copied"
275 msgstr ""
276
277 #: ../unity-scope-diodon/unity-scope-diodon.vala:112
278 msgid "Last 24 hours"
279 msgstr ""
280
281 #: ../unity-scope-diodon/unity-scope-diodon.vala:113
282 msgid "Last 7 days"
283 msgstr ""
284
285 #: ../unity-scope-diodon/unity-scope-diodon.vala:114
286 msgid "Last 30 days"
287 msgstr ""
288
289 #: ../unity-scope-diodon/unity-scope-diodon.vala:115
290 msgid "Last year"
291 msgstr ""
292
293 #: ../unity-scope-diodon/unity-scope-diodon.vala:216
294 msgid "Paste"
295 msgstr ""
296
297 #: ../unity-scope-diodon/unity-scope-diodon.vala:224
298 msgid "Origin"
299 msgstr ""
0 # Spanish translation for diodon
1 # Copyright (c) 2011 Rosetta Contributors and Canonical Ltd 2011
2 # This file is distributed under the same license as the diodon package.
3 # FIRST AUTHOR <EMAIL@ADDRESS>, 2011.
4 #
5 msgid ""
6 msgstr ""
7 "Project-Id-Version: diodon\n"
8 "Report-Msgid-Bugs-To: \n"
9 "POT-Creation-Date: 2017-06-05 14:18+0200\n"
10 "PO-Revision-Date: 2018-03-01 12:55+0000\n"
11 "Last-Translator: Marcos <ciltocruz@hotmail.com>\n"
12 "Language-Team: Spanish <es@li.org>\n"
13 "MIME-Version: 1.0\n"
14 "Content-Type: text/plain; charset=UTF-8\n"
15 "Content-Transfer-Encoding: 8bit\n"
16 "X-Launchpad-Export-Date: 2018-03-02 05:31+0000\n"
17 "X-Generator: Launchpad (build 18561)\n"
18 "Language: es\n"
19
20 #: ../data/diodon.desktop.in.h:1
21 msgid "Clipboard Manager"
22 msgstr "Gestor del portapapeles"
23
24 #: ../data/diodon.desktop.in.h:2
25 msgid "GTK+ Clipboard Manager"
26 msgstr "Gestor del portapapeles GTK+"
27
28 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:1
29 msgid "Use clipboard (Ctrl+C)"
30 msgstr "Usar portapapeles (Ctrl+C)"
31
32 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:2
33 #: ../data/preferences.ui.h:3
34 msgid ""
35 "Adds content which is copied to the clipboard with e.g. Ctrl + C to the "
36 "clipboard history."
37 msgstr ""
38 "Añade el contenido copiado en el portapapeles mediante, p. ej., Ctrl+C, al "
39 "historial del portapapeles."
40
41 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:3
42 msgid "Use primary selection"
43 msgstr "Usar selección primaria"
44
45 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:4
46 #: ../data/preferences.ui.h:5
47 msgid ""
48 "Adds the primary selection (an area of the screen which is selected with the "
49 "mouse) to the clipboard history. Enabling will start process which "
50 "continually checks what is selected. This might discharge your battery "
51 "quicker."
52 msgstr ""
53 "Agrega lo seleccionado con el ratón al historial del portapapeles. Habilitar "
54 "comenzará un proceso que continuamente observa lo que selecciona. Esto "
55 "podría descargar su batería más rápido."
56
57 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:5
58 msgid "Add images to clipboard history"
59 msgstr "Añadir imágenes al historial del portapapeles"
60
61 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:6
62 #: ../data/preferences.ui.h:7
63 msgid ""
64 "Add images copied to clipboard to clipboard history (e.g. when you right "
65 "click on an image in your browser and choose copy image). Enabling this "
66 "option will increase memory consumption. Images already added to clipboard "
67 "history will remain even when disabled."
68 msgstr ""
69 "Añadir imágenes al historial del portapapeles, (p.e. cuando haces click "
70 "derecho sobre una imagen en tu navegador y seleccionas copiar imagen). Esta "
71 "opción aumenta el consumo de memoria. Las imágenes ya agregadas al historial "
72 "del portapapeles permanecerán incluso cuando estén deshabilitadas."
73
74 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:7
75 msgid "Synchronize clipboards"
76 msgstr "Sincronizar portapapeles"
77
78 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:8
79 #: ../data/preferences.ui.h:11
80 msgid ""
81 "Synchronizes the selection (an area of the screen which is selected with the "
82 "mouse) and the clipboard so that anything in the selection is immediately "
83 "available in the clipboard and vice versa e.g. for pasting with Ctrl + V and "
84 "the middle mouse button."
85 msgstr ""
86 "Sincroniza la selección (un área de la pantalla seleccionada con el ratón) y "
87 "el portapapeles de forma que cualquier cosa en la selección esté "
88 "inmediatamente disponible en el portapapeles y viceversa, por ejemplo para "
89 "pegar con Ctrl + V y el botón central del ratón."
90
91 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:9
92 msgid "Keep clipboard content"
93 msgstr "Mantener el contenido del portapapeles"
94
95 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:10
96 #: ../data/preferences.ui.h:9
97 msgid ""
98 "Prevents an empty clipboard. For instance when an application exits, the "
99 "clipboard would usually be emptied."
100 msgstr ""
101 "Evita que el portapapeles quede vacío. Por ejemplo, cuando una aplicación se "
102 "cierra, por lo general el portapapeles puede vaciarse."
103
104 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:11
105 msgid "Automatically paste selected item"
106 msgstr "Pegar automáticamente el elemento seleccionado"
107
108 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:12
109 #: ../data/preferences.ui.h:13
110 msgid ""
111 "Automatically paste selected item instead of just copying it to the "
112 "clipboard."
113 msgstr ""
114 "Pegar automáticamente el elemento seleccionado en lugar de copiarlo al "
115 "portapapeles."
116
117 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:13
118 msgid "Number of recent clipboard items"
119 msgstr "Número de elementos recientes del portapapeles"
120
121 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:14
122 msgid "Number of recent clipboard items shown in clipboard menu."
123 msgstr ""
124 "Número de elementos recientes del portapapeles que se muestran en el menú "
125 "del portapapeles."
126
127 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:15
128 msgid "Clipboard content filter pattern"
129 msgstr ""
130
131 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:16
132 msgid ""
133 "Regex filter pattern whereas all clipboard items matching this pattern will "
134 "be filtered and not added to clipboard history."
135 msgstr ""
136
137 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:17
138 msgid "Lookup dictionary for application using different paste keybindings"
139 msgstr ""
140
141 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:18
142 msgid ""
143 "A lookup dictionary for applications using different paste keybindings than "
144 "Ctrl + V. Pattern of each string in this array is path-of-app|keybinding"
145 msgstr ""
146
147 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:19
148 msgid "Active plugins"
149 msgstr "Complementos activos"
150
151 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:20
152 msgid "List of active plugins."
153 msgstr "Lista de complementos activos."
154
155 #: ../data/preferences.ui.h:1
156 msgid "Diodon Preferences"
157 msgstr "Preferencias de Diodon"
158
159 #: ../data/preferences.ui.h:2
160 msgid "_Use clipboard (Ctrl+C)"
161 msgstr "_Usar portapapeles (Ctrl+C)"
162
163 #: ../data/preferences.ui.h:4
164 msgid "Use _primary selection"
165 msgstr "Usa_r selección primaria"
166
167 #: ../data/preferences.ui.h:6
168 msgid "Add _images to clipboard history"
169 msgstr "Agregar _imágenes al historial del portapapeles"
170
171 #: ../data/preferences.ui.h:8
172 msgid "_Keep clipboard content"
173 msgstr "_Mantener el contenido del portapapeles"
174
175 #: ../data/preferences.ui.h:10
176 msgid "S_ynchronize clipboards"
177 msgstr "Si_ncronizar portapapeles"
178
179 #: ../data/preferences.ui.h:12
180 msgid "_Automatically paste selected item"
181 msgstr "Pegar _automáticamente el elemento seleccionado"
182
183 #: ../data/preferences.ui.h:14
184 msgid "Number of recent clipboard items to be shown in clipboard menu."
185 msgstr ""
186 "Número de elementos recientes del portapapeles que se mostrarán en el menú "
187 "del portapapeles."
188
189 #: ../data/preferences.ui.h:15
190 msgid "Number of recent items"
191 msgstr "N.º de elementos recientes"
192
193 #: ../data/preferences.ui.h:16 ../unity-scope-diodon/unity-scope-diodon.vala:75
194 msgid "Clipboard"
195 msgstr "Portapapeles"
196
197 #: ../data/preferences.ui.h:17
198 msgid ""
199 "Please register custom shortcut with\n"
200 "your desktop environment.\n"
201 "Use /usr/bin/diodon as command."
202 msgstr ""
203 "Registre un atajo personalizado con\n"
204 "los atajos de teclado.\n"
205 "Use / usr/bin/diodon como comando para reconocer diodon."
206
207 #: ../data/preferences.ui.h:20
208 msgid "More information"
209 msgstr "Más información"
210
211 #: ../data/preferences.ui.h:21
212 msgid "Hotkeys"
213 msgstr "Atajos de teclado"
214
215 #: ../data/preferences.ui.h:22
216 msgid "Plugins"
217 msgstr "Complementos"
218
219 #: ../libdiodon/clipboard-menu.vala:46
220 msgid "<Empty>"
221 msgstr "<Vacío>"
222
223 #: ../libdiodon/clipboard-menu.vala:53
224 msgid "Privacy mode is enabled. No new items will be added to history!"
225 msgstr ""
226 "El modo de privacidad está habilitado. ¡No se agregarán nuevos elementos al "
227 "portapapeles!"
228
229 #: ../plugins/indicator/indicator.plugin.in.h:1
230 msgid "Application Indicator"
231 msgstr "Indicador de aplicación"
232
233 #: ../plugins/indicator/indicator.plugin.in.h:2
234 msgid "Access clipboard history with an application indicator."
235 msgstr ""
236 "Acceder al historial del portapapeles mediante un indicador de aplicación."
237
238 #: ../plugins/indicator/indicator.plugin.in.h:3
239 msgid "Copyright © 2011 Diodon Team"
240 msgstr "Copyright © 2011 Equipo de Diodon"
241
242 #: ../unity-scope-diodon/clipboard.scope.in.in.h:1
243 msgid "Clipboard History"
244 msgstr "Histórico del portapapeles"
245
246 #: ../unity-scope-diodon/clipboard.scope.in.in.h:2
247 msgid ""
248 "This is an Ubuntu search plugin that enables information from Diodon to be "
249 "searched and displayed in the Dash underneath the Clipboard header."
250 msgstr ""
251 "Este es un complemento de búsqueda de Ubuntu que permite buscar y mostrar "
252 "información de Diodon bajo la cabecera Portapapeles."
253
254 #: ../unity-scope-diodon/clipboard.scope.in.in.h:3
255 msgid "Search clipboard"
256 msgstr "Buscar en el portapapeles"
257
258 #: ../unity-scope-diodon/clipboard.scope.in.in.h:4
259 #: ../unity-scope-diodon/unity-scope-diodon.vala:79
260 #: ../unity-scope-diodon/unity-scope-diodon.vala:104
261 msgid "Text"
262 msgstr "Texto"
263
264 #: ../unity-scope-diodon/clipboard.scope.in.in.h:5
265 #: ../unity-scope-diodon/unity-scope-diodon.vala:84
266 #: ../unity-scope-diodon/unity-scope-diodon.vala:105
267 msgid "Files"
268 msgstr "Archivos"
269
270 #: ../unity-scope-diodon/clipboard.scope.in.in.h:6
271 #: ../unity-scope-diodon/unity-scope-diodon.vala:89
272 #: ../unity-scope-diodon/unity-scope-diodon.vala:106
273 msgid "Images"
274 msgstr "Imágenes"
275
276 #: ../unity-scope-diodon/clipboard.scope.in.in.h:7
277 #: ../unity-scope-diodon/unity-scope-diodon.vala:101
278 msgid "Category"
279 msgstr "Categoría"
280
281 #: ../unity-scope-diodon/clipboard.scope.in.in.h:8
282 msgid "Text;Files;Images"
283 msgstr "Texto;Archivos;Imágenes"
284
285 #: ../unity-scope-diodon/clipboard.scope.in.in.h:9
286 msgid "Last 24 hours;Last 7 days;Last 30 days;Last year;"
287 msgstr "Últimas 24 horas;Últimos 7 días;Últimos 30 días;El año pasado;"
288
289 #: ../unity-scope-diodon/unity-scope-diodon.vala:45
290 msgid "Search Clipboard"
291 msgstr "Buscar en el portapapeles"
292
293 #: ../unity-scope-diodon/unity-scope-diodon.vala:110
294 #: ../unity-scope-diodon/unity-scope-diodon.vala:231
295 msgid "Date copied"
296 msgstr "Fecha de copia"
297
298 #: ../unity-scope-diodon/unity-scope-diodon.vala:112
299 msgid "Last 24 hours"
300 msgstr "Últimas 24 horas"
301
302 #: ../unity-scope-diodon/unity-scope-diodon.vala:113
303 msgid "Last 7 days"
304 msgstr "Últimos 7 días"
305
306 #: ../unity-scope-diodon/unity-scope-diodon.vala:114
307 msgid "Last 30 days"
308 msgstr "Últimos 30 días"
309
310 #: ../unity-scope-diodon/unity-scope-diodon.vala:115
311 msgid "Last year"
312 msgstr "Último año"
313
314 #: ../unity-scope-diodon/unity-scope-diodon.vala:216
315 msgid "Paste"
316 msgstr "Pegar"
317
318 #: ../unity-scope-diodon/unity-scope-diodon.vala:224
319 msgid "Origin"
320 msgstr "Origen"
0 # Estonian translation for diodon
1 # Copyright (c) 2011 Rosetta Contributors and Canonical Ltd 2011
2 # This file is distributed under the same license as the diodon package.
3 # FIRST AUTHOR <EMAIL@ADDRESS>, 2011.
4 #
5 msgid ""
6 msgstr ""
7 "Project-Id-Version: diodon\n"
8 "Report-Msgid-Bugs-To: \n"
9 "POT-Creation-Date: 2017-06-05 14:18+0200\n"
10 "PO-Revision-Date: 2016-01-15 05:46+0000\n"
11 "Last-Translator: Oliver Sauder <os@esite.ch>\n"
12 "Language-Team: Estonian <et@li.org>\n"
13 "MIME-Version: 1.0\n"
14 "Content-Type: text/plain; charset=UTF-8\n"
15 "Content-Transfer-Encoding: 8bit\n"
16 "X-Launchpad-Export-Date: 2017-06-06 05:55+0000\n"
17 "X-Generator: Launchpad (build 18399)\n"
18 "Language: et\n"
19
20 #: ../data/diodon.desktop.in.h:1
21 msgid "Clipboard Manager"
22 msgstr "Lõikepuhvrihaldur"
23
24 #: ../data/diodon.desktop.in.h:2
25 msgid "GTK+ Clipboard Manager"
26 msgstr "GTK+ lõikepuhvrihaldur"
27
28 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:1
29 msgid "Use clipboard (Ctrl+C)"
30 msgstr "Lõikepuhvri kasutamine (Ctrl+C)"
31
32 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:2
33 #: ../data/preferences.ui.h:3
34 msgid ""
35 "Adds content which is copied to the clipboard with e.g. Ctrl + C to the "
36 "clipboard history."
37 msgstr ""
38
39 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:3
40 msgid "Use primary selection"
41 msgstr "Kasuta esimest valikut"
42
43 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:4
44 #: ../data/preferences.ui.h:5
45 msgid ""
46 "Adds the primary selection (an area of the screen which is selected with the "
47 "mouse) to the clipboard history. Enabling will start process which "
48 "continually checks what is selected. This might discharge your battery "
49 "quicker."
50 msgstr ""
51
52 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:5
53 msgid "Add images to clipboard history"
54 msgstr "Lisa pilte lõikelauapuhvri ajalukku"
55
56 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:6
57 #: ../data/preferences.ui.h:7
58 msgid ""
59 "Add images copied to clipboard to clipboard history (e.g. when you right "
60 "click on an image in your browser and choose copy image). Enabling this "
61 "option will increase memory consumption. Images already added to clipboard "
62 "history will remain even when disabled."
63 msgstr ""
64 "Lisa puhvrisse kopeeritud pildid lõikepuhvri ajalukku (nt kui teed oma "
65 "brauseris pildil paremkliki oma ja valid pildi kopeerimise). Selle "
66 "parameetri lubamine suurendab mälukasutust. Varem lõikepuhvri ajalukku "
67 "valitud pildid jäävad alles isegi siis, kui see parameeter on keelatud."
68
69 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:7
70 msgid "Synchronize clipboards"
71 msgstr "Sünkrooni lõikepuhvrid"
72
73 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:8
74 #: ../data/preferences.ui.h:11
75 msgid ""
76 "Synchronizes the selection (an area of the screen which is selected with the "
77 "mouse) and the clipboard so that anything in the selection is immediately "
78 "available in the clipboard and vice versa e.g. for pasting with Ctrl + V and "
79 "the middle mouse button."
80 msgstr ""
81
82 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:9
83 msgid "Keep clipboard content"
84 msgstr "Lõikepuhvri sisu säilitamine"
85
86 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:10
87 #: ../data/preferences.ui.h:9
88 msgid ""
89 "Prevents an empty clipboard. For instance when an application exits, the "
90 "clipboard would usually be emptied."
91 msgstr ""
92 "Hoiab ära kopeerpuhvri tühjendamise. Näiteks, kui väljuda mõnest "
93 "programmist, siis tühjendatakse üldjuhul lõikelauapuhver selle programmi "
94 "asjadest."
95
96 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:11
97 msgid "Automatically paste selected item"
98 msgstr "Valitud kirje automaatne asetamine"
99
100 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:12
101 #: ../data/preferences.ui.h:13
102 msgid ""
103 "Automatically paste selected item instead of just copying it to the "
104 "clipboard."
105 msgstr ""
106
107 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:13
108 msgid "Number of recent clipboard items"
109 msgstr "Hiljutiste lõikelauapuhvri kirjete arv"
110
111 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:14
112 msgid "Number of recent clipboard items shown in clipboard menu."
113 msgstr "Menüüs näidatavate hiljutiste lõikelauapuhvri kirjete arv."
114
115 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:15
116 msgid "Clipboard content filter pattern"
117 msgstr ""
118
119 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:16
120 msgid ""
121 "Regex filter pattern whereas all clipboard items matching this pattern will "
122 "be filtered and not added to clipboard history."
123 msgstr ""
124
125 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:17
126 msgid "Lookup dictionary for application using different paste keybindings"
127 msgstr ""
128
129 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:18
130 msgid ""
131 "A lookup dictionary for applications using different paste keybindings than "
132 "Ctrl + V. Pattern of each string in this array is path-of-app|keybinding"
133 msgstr ""
134
135 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:19
136 msgid "Active plugins"
137 msgstr "Aktiivsed pluginad"
138
139 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:20
140 msgid "List of active plugins."
141 msgstr "Aktiivsete pluginate nimekiri"
142
143 #: ../data/preferences.ui.h:1
144 msgid "Diodon Preferences"
145 msgstr "Diodoni eelistused"
146
147 #: ../data/preferences.ui.h:2
148 msgid "_Use clipboard (Ctrl+C)"
149 msgstr "_Lõikepuhvri (Ctrl+C) kasutamine"
150
151 #: ../data/preferences.ui.h:4
152 msgid "Use _primary selection"
153 msgstr "Valitud _teksti kasutamine"
154
155 #: ../data/preferences.ui.h:6
156 msgid "Add _images to clipboard history"
157 msgstr ""
158
159 #: ../data/preferences.ui.h:8
160 msgid "_Keep clipboard content"
161 msgstr "Lõikepuhvri s_isu säilitamine"
162
163 #: ../data/preferences.ui.h:10
164 msgid "S_ynchronize clipboards"
165 msgstr "Lõikepuhvrite _sünkimine"
166
167 #: ../data/preferences.ui.h:12
168 msgid "_Automatically paste selected item"
169 msgstr "Valitud kirje _automaatne asetamine"
170
171 #: ../data/preferences.ui.h:14
172 msgid "Number of recent clipboard items to be shown in clipboard menu."
173 msgstr "Menüüs näidatavate hiljutiste lõikelauapuhvrite valikute arv."
174
175 #: ../data/preferences.ui.h:15
176 msgid "Number of recent items"
177 msgstr ""
178
179 #: ../data/preferences.ui.h:16 ../unity-scope-diodon/unity-scope-diodon.vala:75
180 msgid "Clipboard"
181 msgstr "Lõikepuhver"
182
183 #: ../data/preferences.ui.h:17
184 msgid ""
185 "Please register custom shortcut with\n"
186 "your desktop environment.\n"
187 "Use /usr/bin/diodon as command."
188 msgstr ""
189
190 #: ../data/preferences.ui.h:20
191 msgid "More information"
192 msgstr ""
193
194 #: ../data/preferences.ui.h:21
195 msgid "Hotkeys"
196 msgstr ""
197
198 #: ../data/preferences.ui.h:22
199 msgid "Plugins"
200 msgstr "Pluginad"
201
202 #: ../libdiodon/clipboard-menu.vala:46
203 msgid "<Empty>"
204 msgstr "<Tühi>"
205
206 #: ../libdiodon/clipboard-menu.vala:53
207 msgid "Privacy mode is enabled. No new items will be added to history!"
208 msgstr ""
209
210 #: ../plugins/indicator/indicator.plugin.in.h:1
211 msgid "Application Indicator"
212 msgstr ""
213
214 #: ../plugins/indicator/indicator.plugin.in.h:2
215 msgid "Access clipboard history with an application indicator."
216 msgstr ""
217
218 #: ../plugins/indicator/indicator.plugin.in.h:3
219 msgid "Copyright © 2011 Diodon Team"
220 msgstr ""
221
222 #: ../unity-scope-diodon/clipboard.scope.in.in.h:1
223 msgid "Clipboard History"
224 msgstr ""
225
226 #: ../unity-scope-diodon/clipboard.scope.in.in.h:2
227 msgid ""
228 "This is an Ubuntu search plugin that enables information from Diodon to be "
229 "searched and displayed in the Dash underneath the Clipboard header."
230 msgstr ""
231
232 #: ../unity-scope-diodon/clipboard.scope.in.in.h:3
233 msgid "Search clipboard"
234 msgstr ""
235
236 #: ../unity-scope-diodon/clipboard.scope.in.in.h:4
237 #: ../unity-scope-diodon/unity-scope-diodon.vala:79
238 #: ../unity-scope-diodon/unity-scope-diodon.vala:104
239 msgid "Text"
240 msgstr ""
241
242 #: ../unity-scope-diodon/clipboard.scope.in.in.h:5
243 #: ../unity-scope-diodon/unity-scope-diodon.vala:84
244 #: ../unity-scope-diodon/unity-scope-diodon.vala:105
245 msgid "Files"
246 msgstr ""
247
248 #: ../unity-scope-diodon/clipboard.scope.in.in.h:6
249 #: ../unity-scope-diodon/unity-scope-diodon.vala:89
250 #: ../unity-scope-diodon/unity-scope-diodon.vala:106
251 msgid "Images"
252 msgstr ""
253
254 #: ../unity-scope-diodon/clipboard.scope.in.in.h:7
255 #: ../unity-scope-diodon/unity-scope-diodon.vala:101
256 msgid "Category"
257 msgstr ""
258
259 #: ../unity-scope-diodon/clipboard.scope.in.in.h:8
260 msgid "Text;Files;Images"
261 msgstr ""
262
263 #: ../unity-scope-diodon/clipboard.scope.in.in.h:9
264 msgid "Last 24 hours;Last 7 days;Last 30 days;Last year;"
265 msgstr ""
266
267 #: ../unity-scope-diodon/unity-scope-diodon.vala:45
268 msgid "Search Clipboard"
269 msgstr ""
270
271 #: ../unity-scope-diodon/unity-scope-diodon.vala:110
272 #: ../unity-scope-diodon/unity-scope-diodon.vala:231
273 msgid "Date copied"
274 msgstr ""
275
276 #: ../unity-scope-diodon/unity-scope-diodon.vala:112
277 msgid "Last 24 hours"
278 msgstr ""
279
280 #: ../unity-scope-diodon/unity-scope-diodon.vala:113
281 msgid "Last 7 days"
282 msgstr ""
283
284 #: ../unity-scope-diodon/unity-scope-diodon.vala:114
285 msgid "Last 30 days"
286 msgstr ""
287
288 #: ../unity-scope-diodon/unity-scope-diodon.vala:115
289 msgid "Last year"
290 msgstr ""
291
292 #: ../unity-scope-diodon/unity-scope-diodon.vala:216
293 msgid "Paste"
294 msgstr ""
295
296 #: ../unity-scope-diodon/unity-scope-diodon.vala:224
297 msgid "Origin"
298 msgstr ""
0 # Finnish translation for diodon
1 # Copyright (c) 2011 Rosetta Contributors and Canonical Ltd 2011
2 # This file is distributed under the same license as the diodon package.
3 # FIRST AUTHOR <EMAIL@ADDRESS>, 2011.
4 #
5 msgid ""
6 msgstr ""
7 "Project-Id-Version: diodon\n"
8 "Report-Msgid-Bugs-To: \n"
9 "POT-Creation-Date: 2017-06-05 14:18+0200\n"
10 "PO-Revision-Date: 2017-04-06 13:50+0000\n"
11 "Last-Translator: rainland <reino.kinner@aalto.fi>\n"
12 "Language-Team: Finnish <fi@li.org>\n"
13 "MIME-Version: 1.0\n"
14 "Content-Type: text/plain; charset=UTF-8\n"
15 "Content-Transfer-Encoding: 8bit\n"
16 "X-Launchpad-Export-Date: 2017-06-06 05:55+0000\n"
17 "X-Generator: Launchpad (build 18399)\n"
18 "Language: fi\n"
19
20 #: ../data/diodon.desktop.in.h:1
21 msgid "Clipboard Manager"
22 msgstr "Leikepöydän hallinta"
23
24 #: ../data/diodon.desktop.in.h:2
25 msgid "GTK+ Clipboard Manager"
26 msgstr "GTK+-pohjainen leikepöydän hallinta"
27
28 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:1
29 msgid "Use clipboard (Ctrl+C)"
30 msgstr "Käytä leikepöytää (Ctrl+C)"
31
32 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:2
33 #: ../data/preferences.ui.h:3
34 msgid ""
35 "Adds content which is copied to the clipboard with e.g. Ctrl + C to the "
36 "clipboard history."
37 msgstr ""
38 "Lisää leikepöytään kopioidun sisällön esim. näppäinkomennolla Ctrl + C "
39 "leikepöydän historiaan."
40
41 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:3
42 msgid "Use primary selection"
43 msgstr "Käytä ensisijaista valintaa"
44
45 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:4
46 #: ../data/preferences.ui.h:5
47 msgid ""
48 "Adds the primary selection (an area of the screen which is selected with the "
49 "mouse) to the clipboard history. Enabling will start process which "
50 "continually checks what is selected. This might discharge your battery "
51 "quicker."
52 msgstr ""
53 "Lisää ensisijaisen valinna (maalattu alue) leikepöydän historiaan. Valinta "
54 "aloittaa prosessin, joka tarkistaa toistuvasti valinnan. Tämä valinta "
55 "saattaa kuluttaa virtaa enemmän."
56
57 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:5
58 msgid "Add images to clipboard history"
59 msgstr "Lisää kuvat leikepöydän historiaan"
60
61 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:6
62 #: ../data/preferences.ui.h:7
63 msgid ""
64 "Add images copied to clipboard to clipboard history (e.g. when you right "
65 "click on an image in your browser and choose copy image). Enabling this "
66 "option will increase memory consumption. Images already added to clipboard "
67 "history will remain even when disabled."
68 msgstr ""
69 "Lisää kopioidut kuvat leikepöydälle (ja sen historiaan) (esim. silloin, kun "
70 "painat kuvaa oikealla hiiren näppäimellä ja valitset 'kopioi'). Tämä valinta "
71 "lisää muistinkäyttöä. Aikaisemmin lisätyt kuvat säilyvät historiassa vaikka "
72 "valinta poistettaisiin."
73
74 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:7
75 msgid "Synchronize clipboards"
76 msgstr "Synkronoi leikepöydät"
77
78 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:8
79 #: ../data/preferences.ui.h:11
80 msgid ""
81 "Synchronizes the selection (an area of the screen which is selected with the "
82 "mouse) and the clipboard so that anything in the selection is immediately "
83 "available in the clipboard and vice versa e.g. for pasting with Ctrl + V and "
84 "the middle mouse button."
85 msgstr ""
86 "Synkronoi valinnan (maalattu alue) ja leikepöydän niin, että kaikki, mikä on "
87 "valittuna on heti tavoiteltavissa leikepöydältä ja päinvastoin (esim. "
88 "liittämällä Ctrl + V ja hiiren oikea näppäin)."
89
90 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:9
91 msgid "Keep clipboard content"
92 msgstr "Pidä leikepöydän sisältö"
93
94 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:10
95 #: ../data/preferences.ui.h:9
96 msgid ""
97 "Prevents an empty clipboard. For instance when an application exits, the "
98 "clipboard would usually be emptied."
99 msgstr ""
100 "Estää tyhjän leikepöydän. Esimerkkitapaus: kun sovellus sulkeutuu, "
101 "leikepöytä saattaisi yleensä tyhjentyä."
102
103 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:11
104 msgid "Automatically paste selected item"
105 msgstr "Liitä valittu kohde automaattisesti"
106
107 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:12
108 #: ../data/preferences.ui.h:13
109 msgid ""
110 "Automatically paste selected item instead of just copying it to the "
111 "clipboard."
112 msgstr ""
113 "Liitä valittu kohde automaattisesti sen sijaan, että kohde vain kopioidaan "
114 "leikepöydälle."
115
116 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:13
117 msgid "Number of recent clipboard items"
118 msgstr "Viimeaikaisten leikepöydän osien lukumäärä"
119
120 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:14
121 msgid "Number of recent clipboard items shown in clipboard menu."
122 msgstr ""
123 "Viimeaikaisten leikepöydän osien lukumäärä joka näytetään "
124 "leikepöytävalikossa."
125
126 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:15
127 msgid "Clipboard content filter pattern"
128 msgstr "Leikepöydän sisällön suodattimen kaava"
129
130 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:16
131 msgid ""
132 "Regex filter pattern whereas all clipboard items matching this pattern will "
133 "be filtered and not added to clipboard history."
134 msgstr ""
135 "Säännöllisen lausekkeen suodatin missä kaikki leikepöydän kohdat, jotka "
136 "vastaavat tätä malliin, suodatetaan eikä niitä lisätä leikepöydän historiaan."
137
138 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:17
139 msgid "Lookup dictionary for application using different paste keybindings"
140 msgstr ""
141 "Hakusanakirja sovellukselle, joka käyttää eri liittämisen näppäinkomentoja."
142
143 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:18
144 msgid ""
145 "A lookup dictionary for applications using different paste keybindings than "
146 "Ctrl + V. Pattern of each string in this array is path-of-app|keybinding"
147 msgstr ""
148 "Hakusanakirja sovellukselle, joka käyttää jotain muuta liittämisen "
149 "näppäinkomento kuin Ctrl + V. Jokaisen merkkijonon malli tässä taulukossa on "
150 "sovelluksen-polku|pikanäppäin"
151
152 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:19
153 msgid "Active plugins"
154 msgstr "Käytössä olevat liitännäiset"
155
156 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:20
157 msgid "List of active plugins."
158 msgstr "Luettelo käytössä olevista liitännäisistä."
159
160 #: ../data/preferences.ui.h:1
161 msgid "Diodon Preferences"
162 msgstr "Diodonin asetukset"
163
164 #: ../data/preferences.ui.h:2
165 msgid "_Use clipboard (Ctrl+C)"
166 msgstr "_Käytä leikepöytää (Ctrl+C)"
167
168 #: ../data/preferences.ui.h:4
169 msgid "Use _primary selection"
170 msgstr "Käytä _ensisijaista valintaa"
171
172 #: ../data/preferences.ui.h:6
173 msgid "Add _images to clipboard history"
174 msgstr "Lisää ku_vat leikepöydän historiaan"
175
176 #: ../data/preferences.ui.h:8
177 msgid "_Keep clipboard content"
178 msgstr "_Säilytä leikepöydän sisältö"
179
180 #: ../data/preferences.ui.h:10
181 msgid "S_ynchronize clipboards"
182 msgstr "S_ynkronoi leikepöydät"
183
184 #: ../data/preferences.ui.h:12
185 msgid "_Automatically paste selected item"
186 msgstr "_Liitä valittu kohde automaattisesti"
187
188 #: ../data/preferences.ui.h:14
189 msgid "Number of recent clipboard items to be shown in clipboard menu."
190 msgstr "Leikepöytävalikossa näytettävien kohteiden lukumäärä."
191
192 #: ../data/preferences.ui.h:15
193 msgid "Number of recent items"
194 msgstr "Kohteiden lukumäärä"
195
196 #: ../data/preferences.ui.h:16 ../unity-scope-diodon/unity-scope-diodon.vala:75
197 msgid "Clipboard"
198 msgstr "Leikepöytä"
199
200 #: ../data/preferences.ui.h:17
201 msgid ""
202 "Please register custom shortcut with\n"
203 "your desktop environment.\n"
204 "Use /usr/bin/diodon as command."
205 msgstr ""
206 "Rekisteröi mukautettu pikanäppäin\n"
207 "työpöytäympäristössäsi.\n"
208 "Käytä komentona /usr/bin/diodon"
209
210 #: ../data/preferences.ui.h:20
211 msgid "More information"
212 msgstr "Lisätietoja"
213
214 #: ../data/preferences.ui.h:21
215 msgid "Hotkeys"
216 msgstr "Pikanäppäimet"
217
218 #: ../data/preferences.ui.h:22
219 msgid "Plugins"
220 msgstr "Liitännäiset"
221
222 #: ../libdiodon/clipboard-menu.vala:46
223 msgid "<Empty>"
224 msgstr "<Tyhjä>"
225
226 #: ../libdiodon/clipboard-menu.vala:53
227 msgid "Privacy mode is enabled. No new items will be added to history!"
228 msgstr ""
229
230 #: ../plugins/indicator/indicator.plugin.in.h:1
231 msgid "Application Indicator"
232 msgstr "Sovellusilmaisin"
233
234 #: ../plugins/indicator/indicator.plugin.in.h:2
235 msgid "Access clipboard history with an application indicator."
236 msgstr "Käytä leikepöydän historiaa sovellusilmaisimella."
237
238 #: ../plugins/indicator/indicator.plugin.in.h:3
239 msgid "Copyright © 2011 Diodon Team"
240 msgstr "Tekijänoikeus © 2011 Diodon-kehittäjät"
241
242 #: ../unity-scope-diodon/clipboard.scope.in.in.h:1
243 msgid "Clipboard History"
244 msgstr "Leikepöydän historia"
245
246 #: ../unity-scope-diodon/clipboard.scope.in.in.h:2
247 msgid ""
248 "This is an Ubuntu search plugin that enables information from Diodon to be "
249 "searched and displayed in the Dash underneath the Clipboard header."
250 msgstr ""
251 "Tämä on Ubuntun hakuliitännäinen, jolla tietoja Diodon-ohjelmasta voidaan "
252 "hakea ja näyttää Unity-valikossa Leikepöytä-osiossa."
253
254 #: ../unity-scope-diodon/clipboard.scope.in.in.h:3
255 msgid "Search clipboard"
256 msgstr "Etsi leikepöydältä"
257
258 #: ../unity-scope-diodon/clipboard.scope.in.in.h:4
259 #: ../unity-scope-diodon/unity-scope-diodon.vala:79
260 #: ../unity-scope-diodon/unity-scope-diodon.vala:104
261 msgid "Text"
262 msgstr "Teksti"
263
264 #: ../unity-scope-diodon/clipboard.scope.in.in.h:5
265 #: ../unity-scope-diodon/unity-scope-diodon.vala:84
266 #: ../unity-scope-diodon/unity-scope-diodon.vala:105
267 msgid "Files"
268 msgstr "Tiedostot"
269
270 #: ../unity-scope-diodon/clipboard.scope.in.in.h:6
271 #: ../unity-scope-diodon/unity-scope-diodon.vala:89
272 #: ../unity-scope-diodon/unity-scope-diodon.vala:106
273 msgid "Images"
274 msgstr "Kuvat"
275
276 #: ../unity-scope-diodon/clipboard.scope.in.in.h:7
277 #: ../unity-scope-diodon/unity-scope-diodon.vala:101
278 msgid "Category"
279 msgstr "Luokka"
280
281 #: ../unity-scope-diodon/clipboard.scope.in.in.h:8
282 msgid "Text;Files;Images"
283 msgstr "Teksti;Tiedostot;Kuvat"
284
285 #: ../unity-scope-diodon/clipboard.scope.in.in.h:9
286 msgid "Last 24 hours;Last 7 days;Last 30 days;Last year;"
287 msgstr ""
288 "Viimeiset 24 tuntia;Viimeiset 7 päivää;Viimeiset 30 päivää;Viime vuonna;"
289
290 #: ../unity-scope-diodon/unity-scope-diodon.vala:45
291 msgid "Search Clipboard"
292 msgstr "Etsi leikepöydältä"
293
294 #: ../unity-scope-diodon/unity-scope-diodon.vala:110
295 #: ../unity-scope-diodon/unity-scope-diodon.vala:231
296 msgid "Date copied"
297 msgstr "Kopioimispäivä"
298
299 #: ../unity-scope-diodon/unity-scope-diodon.vala:112
300 msgid "Last 24 hours"
301 msgstr "Viimeiset 24 tuntia"
302
303 #: ../unity-scope-diodon/unity-scope-diodon.vala:113
304 msgid "Last 7 days"
305 msgstr "Viimeiset 7 päivää"
306
307 #: ../unity-scope-diodon/unity-scope-diodon.vala:114
308 msgid "Last 30 days"
309 msgstr "Viimeiset 30 päivää"
310
311 #: ../unity-scope-diodon/unity-scope-diodon.vala:115
312 msgid "Last year"
313 msgstr "Viime vuonna"
314
315 #: ../unity-scope-diodon/unity-scope-diodon.vala:216
316 msgid "Paste"
317 msgstr "Liitä"
318
319 #: ../unity-scope-diodon/unity-scope-diodon.vala:224
320 msgid "Origin"
321 msgstr "Alkuperä"
0 # French translation for diodon
1 # Copyright (c) 2011 Rosetta Contributors and Canonical Ltd 2011
2 # This file is distributed under the same license as the diodon package.
3 # FIRST AUTHOR <EMAIL@ADDRESS>, 2011.
4 #
5 msgid ""
6 msgstr ""
7 "Project-Id-Version: diodon\n"
8 "Report-Msgid-Bugs-To: \n"
9 "POT-Creation-Date: 2017-06-05 14:18+0200\n"
10 "PO-Revision-Date: 2017-04-19 12:08+0000\n"
11 "Last-Translator: Olivier Febwin <febwin@free.fr>\n"
12 "Language-Team: French <fr@li.org>\n"
13 "MIME-Version: 1.0\n"
14 "Content-Type: text/plain; charset=UTF-8\n"
15 "Content-Transfer-Encoding: 8bit\n"
16 "X-Launchpad-Export-Date: 2017-06-06 05:55+0000\n"
17 "X-Generator: Launchpad (build 18399)\n"
18 "Language: fr\n"
19
20 #: ../data/diodon.desktop.in.h:1
21 msgid "Clipboard Manager"
22 msgstr "Gestionnaire de presse-papier"
23
24 #: ../data/diodon.desktop.in.h:2
25 msgid "GTK+ Clipboard Manager"
26 msgstr "Gestionnaire de presse-papier GTK+"
27
28 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:1
29 msgid "Use clipboard (Ctrl+C)"
30 msgstr "Utiliser le presse-papier (Ctrl+C)"
31
32 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:2
33 #: ../data/preferences.ui.h:3
34 msgid ""
35 "Adds content which is copied to the clipboard with e.g. Ctrl + C to the "
36 "clipboard history."
37 msgstr ""
38 "Ajouter du contenu déja dans le presse-papiers à l'historique du presse-"
39 "papiers en faisant par exemple Ctrl + C."
40
41 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:3
42 msgid "Use primary selection"
43 msgstr "Utiliser la sélection courante"
44
45 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:4
46 #: ../data/preferences.ui.h:5
47 msgid ""
48 "Adds the primary selection (an area of the screen which is selected with the "
49 "mouse) to the clipboard history. Enabling will start process which "
50 "continually checks what is selected. This might discharge your battery "
51 "quicker."
52 msgstr ""
53
54 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:5
55 msgid "Add images to clipboard history"
56 msgstr "Ajouter les images à l'historique du presse-papiers"
57
58 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:6
59 #: ../data/preferences.ui.h:7
60 msgid ""
61 "Add images copied to clipboard to clipboard history (e.g. when you right "
62 "click on an image in your browser and choose copy image). Enabling this "
63 "option will increase memory consumption. Images already added to clipboard "
64 "history will remain even when disabled."
65 msgstr ""
66 "Ajouter les images copiées dans le presse-papiers à l'historique du presse-"
67 "papiers (Par exemple, lorsque vous faite un clic droit sur une image dans "
68 "votre navigateur et sélectionner Copier Image). Activer cette option "
69 "augmente l'utilisation de la mémoire. Les image déjà ajoutées à l'historique "
70 "du presse-papiers y restent même après désactivation de l'option."
71
72 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:7
73 msgid "Synchronize clipboards"
74 msgstr "Synchroniser les presse-papiers"
75
76 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:8
77 #: ../data/preferences.ui.h:11
78 msgid ""
79 "Synchronizes the selection (an area of the screen which is selected with the "
80 "mouse) and the clipboard so that anything in the selection is immediately "
81 "available in the clipboard and vice versa e.g. for pasting with Ctrl + V and "
82 "the middle mouse button."
83 msgstr ""
84 "Synchroniser la sélection (une zone de l'écran qui est sélectionné avec la "
85 "souris) et le presse-papiers de sorte que rien dans la sélection ne soit "
86 "disponible immédiatement dans le presse-papiers, et vice versa, par exemple "
87 "pour coller avec Ctrl + V et le bouton du milieu."
88
89 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:9
90 msgid "Keep clipboard content"
91 msgstr "Conserver le contenu du presse-papier"
92
93 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:10
94 #: ../data/preferences.ui.h:9
95 msgid ""
96 "Prevents an empty clipboard. For instance when an application exits, the "
97 "clipboard would usually be emptied."
98 msgstr ""
99 "Empêcher le presse-papier d'être vidé. Par exemple, lorsqu'une application "
100 "se ferme, elle vide automatiquement le presse-papier"
101
102 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:11
103 msgid "Automatically paste selected item"
104 msgstr "Coller automatiquement l'élément sélectionné"
105
106 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:12
107 #: ../data/preferences.ui.h:13
108 msgid ""
109 "Automatically paste selected item instead of just copying it to the "
110 "clipboard."
111 msgstr ""
112 "Coller automatiquement l'élément sélectionné au lieu de le copier simplement "
113 "dans le presse-papier."
114
115 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:13
116 msgid "Number of recent clipboard items"
117 msgstr "Nombre d'éléments récents dans le presse-papiers"
118
119 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:14
120 msgid "Number of recent clipboard items shown in clipboard menu."
121 msgstr ""
122 "Nombre d'éléments récents dans le presse-papiers à afficher dans le menu du "
123 "presse-papiers"
124
125 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:15
126 msgid "Clipboard content filter pattern"
127 msgstr ""
128
129 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:16
130 msgid ""
131 "Regex filter pattern whereas all clipboard items matching this pattern will "
132 "be filtered and not added to clipboard history."
133 msgstr ""
134
135 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:17
136 msgid "Lookup dictionary for application using different paste keybindings"
137 msgstr ""
138
139 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:18
140 msgid ""
141 "A lookup dictionary for applications using different paste keybindings than "
142 "Ctrl + V. Pattern of each string in this array is path-of-app|keybinding"
143 msgstr ""
144
145 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:19
146 msgid "Active plugins"
147 msgstr "Greffons actifs"
148
149 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:20
150 msgid "List of active plugins."
151 msgstr "Liste des greffons actifs"
152
153 #: ../data/preferences.ui.h:1
154 msgid "Diodon Preferences"
155 msgstr "Préférences de Diodon"
156
157 #: ../data/preferences.ui.h:2
158 msgid "_Use clipboard (Ctrl+C)"
159 msgstr "Utiliser le presse-papier (Ctrl+C)"
160
161 #: ../data/preferences.ui.h:4
162 msgid "Use _primary selection"
163 msgstr "Utiliser la sélection primaire"
164
165 #: ../data/preferences.ui.h:6
166 msgid "Add _images to clipboard history"
167 msgstr "Ajouter les _images à l'historique"
168
169 #: ../data/preferences.ui.h:8
170 msgid "_Keep clipboard content"
171 msgstr "_Conserver le contenu du presse-papier"
172
173 #: ../data/preferences.ui.h:10
174 msgid "S_ynchronize clipboards"
175 msgstr "Synchroniser les presse-papiers"
176
177 #: ../data/preferences.ui.h:12
178 msgid "_Automatically paste selected item"
179 msgstr "_Coller automatiquement l'élément sélectionné"
180
181 #: ../data/preferences.ui.h:14
182 msgid "Number of recent clipboard items to be shown in clipboard menu."
183 msgstr "Nombre d'éléments récents à afficher dans le menu."
184
185 #: ../data/preferences.ui.h:15
186 msgid "Number of recent items"
187 msgstr "Nombre d'éléments récents"
188
189 #: ../data/preferences.ui.h:16 ../unity-scope-diodon/unity-scope-diodon.vala:75
190 msgid "Clipboard"
191 msgstr "Presse-papier"
192
193 #: ../data/preferences.ui.h:17
194 msgid ""
195 "Please register custom shortcut with\n"
196 "your desktop environment.\n"
197 "Use /usr/bin/diodon as command."
198 msgstr ""
199
200 #: ../data/preferences.ui.h:20
201 msgid "More information"
202 msgstr "Plus d'informations"
203
204 #: ../data/preferences.ui.h:21
205 msgid "Hotkeys"
206 msgstr "Raccourcis"
207
208 #: ../data/preferences.ui.h:22
209 msgid "Plugins"
210 msgstr "Extensions"
211
212 #: ../libdiodon/clipboard-menu.vala:46
213 msgid "<Empty>"
214 msgstr "<Vide>"
215
216 #: ../libdiodon/clipboard-menu.vala:53
217 msgid "Privacy mode is enabled. No new items will be added to history!"
218 msgstr ""
219
220 #: ../plugins/indicator/indicator.plugin.in.h:1
221 msgid "Application Indicator"
222 msgstr "Indicateur"
223
224 #: ../plugins/indicator/indicator.plugin.in.h:2
225 msgid "Access clipboard history with an application indicator."
226 msgstr "Accéder au presse-papier à l'aide d'un indicateur."
227
228 #: ../plugins/indicator/indicator.plugin.in.h:3
229 msgid "Copyright © 2011 Diodon Team"
230 msgstr "Copyright © 2011 Équipe Diodon"
231
232 #: ../unity-scope-diodon/clipboard.scope.in.in.h:1
233 msgid "Clipboard History"
234 msgstr "Historique du presse-papiers"
235
236 #: ../unity-scope-diodon/clipboard.scope.in.in.h:2
237 msgid ""
238 "This is an Ubuntu search plugin that enables information from Diodon to be "
239 "searched and displayed in the Dash underneath the Clipboard header."
240 msgstr ""
241 "Il s'agit d'une extension de recherche Ubuntu qui permet depuis le tableau "
242 "de bord dans la section Presse-Papiers de rechercher parmi les éléments de "
243 "Diodon."
244
245 #: ../unity-scope-diodon/clipboard.scope.in.in.h:3
246 msgid "Search clipboard"
247 msgstr "Rechercher dans le presse-papier"
248
249 #: ../unity-scope-diodon/clipboard.scope.in.in.h:4
250 #: ../unity-scope-diodon/unity-scope-diodon.vala:79
251 #: ../unity-scope-diodon/unity-scope-diodon.vala:104
252 msgid "Text"
253 msgstr "Texte"
254
255 #: ../unity-scope-diodon/clipboard.scope.in.in.h:5
256 #: ../unity-scope-diodon/unity-scope-diodon.vala:84
257 #: ../unity-scope-diodon/unity-scope-diodon.vala:105
258 msgid "Files"
259 msgstr "Fichiers"
260
261 #: ../unity-scope-diodon/clipboard.scope.in.in.h:6
262 #: ../unity-scope-diodon/unity-scope-diodon.vala:89
263 #: ../unity-scope-diodon/unity-scope-diodon.vala:106
264 msgid "Images"
265 msgstr "Images"
266
267 #: ../unity-scope-diodon/clipboard.scope.in.in.h:7
268 #: ../unity-scope-diodon/unity-scope-diodon.vala:101
269 msgid "Category"
270 msgstr "Catégorie"
271
272 #: ../unity-scope-diodon/clipboard.scope.in.in.h:8
273 msgid "Text;Files;Images"
274 msgstr "Textes;Fichiers;Images"
275
276 #: ../unity-scope-diodon/clipboard.scope.in.in.h:9
277 msgid "Last 24 hours;Last 7 days;Last 30 days;Last year;"
278 msgstr ""
279 "Dernières 24h;7 jours précédents;30 jours précédents; dernière année;"
280
281 #: ../unity-scope-diodon/unity-scope-diodon.vala:45
282 msgid "Search Clipboard"
283 msgstr "Rechercher dans le presse-papiers"
284
285 #: ../unity-scope-diodon/unity-scope-diodon.vala:110
286 #: ../unity-scope-diodon/unity-scope-diodon.vala:231
287 msgid "Date copied"
288 msgstr "Date de copie"
289
290 #: ../unity-scope-diodon/unity-scope-diodon.vala:112
291 msgid "Last 24 hours"
292 msgstr "Dernières 24h"
293
294 #: ../unity-scope-diodon/unity-scope-diodon.vala:113
295 msgid "Last 7 days"
296 msgstr "7 jours précédents"
297
298 #: ../unity-scope-diodon/unity-scope-diodon.vala:114
299 msgid "Last 30 days"
300 msgstr "30 jours précédents"
301
302 #: ../unity-scope-diodon/unity-scope-diodon.vala:115
303 msgid "Last year"
304 msgstr "L'an dernier"
305
306 #: ../unity-scope-diodon/unity-scope-diodon.vala:216
307 msgid "Paste"
308 msgstr "Coller"
309
310 #: ../unity-scope-diodon/unity-scope-diodon.vala:224
311 msgid "Origin"
312 msgstr "Origine"
0 # Galician translation for diodon
1 # Copyright (c) 2013 Rosetta Contributors and Canonical Ltd 2013
2 # This file is distributed under the same license as the diodon package.
3 # FIRST AUTHOR <EMAIL@ADDRESS>, 2013.
4 #
5 msgid ""
6 msgstr ""
7 "Project-Id-Version: diodon\n"
8 "Report-Msgid-Bugs-To: \n"
9 "POT-Creation-Date: 2017-06-05 14:18+0200\n"
10 "PO-Revision-Date: 2014-08-02 02:19+0000\n"
11 "Last-Translator: Manuel Xosé Lemos <Unknown>\n"
12 "Language-Team: Galician <gl@li.org>\n"
13 "MIME-Version: 1.0\n"
14 "Content-Type: text/plain; charset=UTF-8\n"
15 "Content-Transfer-Encoding: 8bit\n"
16 "X-Launchpad-Export-Date: 2017-06-06 05:55+0000\n"
17 "X-Generator: Launchpad (build 18399)\n"
18 "Language: gl\n"
19
20 #: ../data/diodon.desktop.in.h:1
21 msgid "Clipboard Manager"
22 msgstr "Xestor do portapapeis"
23
24 #: ../data/diodon.desktop.in.h:2
25 msgid "GTK+ Clipboard Manager"
26 msgstr "Xestor do portapapeis en GTK+"
27
28 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:1
29 msgid "Use clipboard (Ctrl+C)"
30 msgstr "Usar portapapeis (Ctrl+C)"
31
32 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:2
33 #: ../data/preferences.ui.h:3
34 msgid ""
35 "Adds content which is copied to the clipboard with e.g. Ctrl + C to the "
36 "clipboard history."
37 msgstr ""
38 "Engade contido copiado ao portapapeis, por exemplo con Ctrl+C, ao historial "
39 "do portapapeis."
40
41 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:3
42 msgid "Use primary selection"
43 msgstr "Usar selección primaria"
44
45 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:4
46 #: ../data/preferences.ui.h:5
47 msgid ""
48 "Adds the primary selection (an area of the screen which is selected with the "
49 "mouse) to the clipboard history. Enabling will start process which "
50 "continually checks what is selected. This might discharge your battery "
51 "quicker."
52 msgstr ""
53 "Engade a selección primaria (unha área da pantalla seleccionada co rato) ao "
54 "historial do portapapeis. Ao activar esta opción iniciarase un proceso que "
55 "comproba continuamente o seleccionado. Isto pode descargar a batería "
56 "rápidamente."
57
58 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:5
59 msgid "Add images to clipboard history"
60 msgstr "Engadir imaxes ao historial do portapapeis"
61
62 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:6
63 #: ../data/preferences.ui.h:7
64 msgid ""
65 "Add images copied to clipboard to clipboard history (e.g. when you right "
66 "click on an image in your browser and choose copy image). Enabling this "
67 "option will increase memory consumption. Images already added to clipboard "
68 "history will remain even when disabled."
69 msgstr ""
70 "Engade as imaxes copiadas ao historial do portapapeis (por exemplo cando fai "
71 "clic dereito nunha imaxe do navegador e selecciona copiar imaxe). Activar "
72 "esta opción incrementará o consumo de memoria. As imaxes engadidas ao "
73 "historial do portapapeis permanecerán incluso se despois de desactivar esta "
74 "opción."
75
76 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:7
77 msgid "Synchronize clipboards"
78 msgstr "Sincronizar portapapeis"
79
80 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:8
81 #: ../data/preferences.ui.h:11
82 msgid ""
83 "Synchronizes the selection (an area of the screen which is selected with the "
84 "mouse) and the clipboard so that anything in the selection is immediately "
85 "available in the clipboard and vice versa e.g. for pasting with Ctrl + V and "
86 "the middle mouse button."
87 msgstr ""
88 "Sincroniza a selección (unha área da pantalla seleccionada co rato) e o "
89 "portapapeis de forma que calquera cousa da selección estea inmediatamente "
90 "dispoñíbel no portapapeis e viceversa, por exemplo para pegar con Ctrl+V e o "
91 "botón central do rato."
92
93 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:9
94 msgid "Keep clipboard content"
95 msgstr "Manter o contido do portapapeis"
96
97 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:10
98 #: ../data/preferences.ui.h:9
99 msgid ""
100 "Prevents an empty clipboard. For instance when an application exits, the "
101 "clipboard would usually be emptied."
102 msgstr ""
103 "Evita que o portapapeis quede baleiro. Por exemplo, cando un aplicativo se "
104 "pecha, a miúdo o portapapeis quedará baleiro."
105
106 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:11
107 msgid "Automatically paste selected item"
108 msgstr "Pegar automaticamente o elemento seleccionado"
109
110 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:12
111 #: ../data/preferences.ui.h:13
112 msgid ""
113 "Automatically paste selected item instead of just copying it to the "
114 "clipboard."
115 msgstr ""
116 "Pega automaticamente o elemento seleccionado no canto de copialo ao "
117 "portapapeis."
118
119 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:13
120 msgid "Number of recent clipboard items"
121 msgstr "Número de elementos no portapapeis"
122
123 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:14
124 msgid "Number of recent clipboard items shown in clipboard menu."
125 msgstr "Número de elementos recentes que se mostrarán no menú do portapapeis"
126
127 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:15
128 msgid "Clipboard content filter pattern"
129 msgstr ""
130
131 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:16
132 msgid ""
133 "Regex filter pattern whereas all clipboard items matching this pattern will "
134 "be filtered and not added to clipboard history."
135 msgstr ""
136
137 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:17
138 msgid "Lookup dictionary for application using different paste keybindings"
139 msgstr ""
140
141 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:18
142 msgid ""
143 "A lookup dictionary for applications using different paste keybindings than "
144 "Ctrl + V. Pattern of each string in this array is path-of-app|keybinding"
145 msgstr ""
146
147 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:19
148 msgid "Active plugins"
149 msgstr "Engadidos activos"
150
151 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:20
152 msgid "List of active plugins."
153 msgstr "LIsta de engadidos activos."
154
155 #: ../data/preferences.ui.h:1
156 msgid "Diodon Preferences"
157 msgstr "Preferencias de Diodon"
158
159 #: ../data/preferences.ui.h:2
160 msgid "_Use clipboard (Ctrl+C)"
161 msgstr "_Usar portapapeis (Ctrl+C)"
162
163 #: ../data/preferences.ui.h:4
164 msgid "Use _primary selection"
165 msgstr "Usa_r selección primaria"
166
167 #: ../data/preferences.ui.h:6
168 msgid "Add _images to clipboard history"
169 msgstr "Engadir _imaxes ao historial do porpapeis"
170
171 #: ../data/preferences.ui.h:8
172 msgid "_Keep clipboard content"
173 msgstr "_Manter o contido no portapapeis"
174
175 #: ../data/preferences.ui.h:10
176 msgid "S_ynchronize clipboards"
177 msgstr "S_incronizar portapapeis"
178
179 #: ../data/preferences.ui.h:12
180 msgid "_Automatically paste selected item"
181 msgstr "Pegar _automaticamente o elemento seleccionado"
182
183 #: ../data/preferences.ui.h:14
184 msgid "Number of recent clipboard items to be shown in clipboard menu."
185 msgstr ""
186 "Número de elementos recentes do portapapeis que se mostrarán no menú do "
187 "portapapeis"
188
189 #: ../data/preferences.ui.h:15
190 msgid "Number of recent items"
191 msgstr "Número de elementos recentes"
192
193 #: ../data/preferences.ui.h:16 ../unity-scope-diodon/unity-scope-diodon.vala:75
194 msgid "Clipboard"
195 msgstr "Portapapeis"
196
197 #: ../data/preferences.ui.h:17
198 msgid ""
199 "Please register custom shortcut with\n"
200 "your desktop environment.\n"
201 "Use /usr/bin/diodon as command."
202 msgstr ""
203
204 #: ../data/preferences.ui.h:20
205 msgid "More information"
206 msgstr ""
207
208 #: ../data/preferences.ui.h:21
209 msgid "Hotkeys"
210 msgstr ""
211
212 #: ../data/preferences.ui.h:22
213 msgid "Plugins"
214 msgstr "Complementos"
215
216 #: ../libdiodon/clipboard-menu.vala:46
217 msgid "<Empty>"
218 msgstr "<Baleiro>"
219
220 #: ../libdiodon/clipboard-menu.vala:53
221 msgid "Privacy mode is enabled. No new items will be added to history!"
222 msgstr ""
223
224 #: ../plugins/indicator/indicator.plugin.in.h:1
225 msgid "Application Indicator"
226 msgstr "Indicador de aplicativo"
227
228 #: ../plugins/indicator/indicator.plugin.in.h:2
229 msgid "Access clipboard history with an application indicator."
230 msgstr ""
231 "Acceder ao historial do portapapeis mediante un indicador de aplicativo."
232
233 #: ../plugins/indicator/indicator.plugin.in.h:3
234 msgid "Copyright © 2011 Diodon Team"
235 msgstr "Copyright © 2011 Equipo de Diodon"
236
237 #: ../unity-scope-diodon/clipboard.scope.in.in.h:1
238 msgid "Clipboard History"
239 msgstr "Historial do portapapeis"
240
241 #: ../unity-scope-diodon/clipboard.scope.in.in.h:2
242 msgid ""
243 "This is an Ubuntu search plugin that enables information from Diodon to be "
244 "searched and displayed in the Dash underneath the Clipboard header."
245 msgstr ""
246
247 #: ../unity-scope-diodon/clipboard.scope.in.in.h:3
248 msgid "Search clipboard"
249 msgstr "Buscar no portapapeis"
250
251 #: ../unity-scope-diodon/clipboard.scope.in.in.h:4
252 #: ../unity-scope-diodon/unity-scope-diodon.vala:79
253 #: ../unity-scope-diodon/unity-scope-diodon.vala:104
254 msgid "Text"
255 msgstr "Texto"
256
257 #: ../unity-scope-diodon/clipboard.scope.in.in.h:5
258 #: ../unity-scope-diodon/unity-scope-diodon.vala:84
259 #: ../unity-scope-diodon/unity-scope-diodon.vala:105
260 msgid "Files"
261 msgstr "Ficheiros"
262
263 #: ../unity-scope-diodon/clipboard.scope.in.in.h:6
264 #: ../unity-scope-diodon/unity-scope-diodon.vala:89
265 #: ../unity-scope-diodon/unity-scope-diodon.vala:106
266 msgid "Images"
267 msgstr "Imaxes"
268
269 #: ../unity-scope-diodon/clipboard.scope.in.in.h:7
270 #: ../unity-scope-diodon/unity-scope-diodon.vala:101
271 msgid "Category"
272 msgstr "Categoría"
273
274 #: ../unity-scope-diodon/clipboard.scope.in.in.h:8
275 msgid "Text;Files;Images"
276 msgstr "Texto;Ficheiros;Imaxes"
277
278 #: ../unity-scope-diodon/clipboard.scope.in.in.h:9
279 msgid "Last 24 hours;Last 7 days;Last 30 days;Last year;"
280 msgstr "Últimas 24 horas;Últimos 7 días;Últimos 30 días;Último ano;"
281
282 #: ../unity-scope-diodon/unity-scope-diodon.vala:45
283 msgid "Search Clipboard"
284 msgstr "Buscar no portapapeis"
285
286 #: ../unity-scope-diodon/unity-scope-diodon.vala:110
287 #: ../unity-scope-diodon/unity-scope-diodon.vala:231
288 msgid "Date copied"
289 msgstr "Data copiada"
290
291 #: ../unity-scope-diodon/unity-scope-diodon.vala:112
292 msgid "Last 24 hours"
293 msgstr "Últimas 24 horas"
294
295 #: ../unity-scope-diodon/unity-scope-diodon.vala:113
296 msgid "Last 7 days"
297 msgstr "Últimos 7 días"
298
299 #: ../unity-scope-diodon/unity-scope-diodon.vala:114
300 msgid "Last 30 days"
301 msgstr "Últimos 30 días"
302
303 #: ../unity-scope-diodon/unity-scope-diodon.vala:115
304 msgid "Last year"
305 msgstr "Último ano"
306
307 #: ../unity-scope-diodon/unity-scope-diodon.vala:216
308 msgid "Paste"
309 msgstr "Pegar"
310
311 #: ../unity-scope-diodon/unity-scope-diodon.vala:224
312 msgid "Origin"
313 msgstr "Orixe"
0 # Hungarian translation for diodon
1 # Copyright (c) 2014 Rosetta Contributors and Canonical Ltd 2014
2 # This file is distributed under the same license as the diodon package.
3 # FIRST AUTHOR <EMAIL@ADDRESS>, 2014.
4 #
5 msgid ""
6 msgstr ""
7 "Project-Id-Version: diodon\n"
8 "Report-Msgid-Bugs-To: \n"
9 "POT-Creation-Date: 2017-06-05 14:18+0200\n"
10 "PO-Revision-Date: 2014-07-16 22:54+0000\n"
11 "Last-Translator: mktiti <markuskrisztian1@gmail.com>\n"
12 "Language-Team: Hungarian <hu@li.org>\n"
13 "MIME-Version: 1.0\n"
14 "Content-Type: text/plain; charset=UTF-8\n"
15 "Content-Transfer-Encoding: 8bit\n"
16 "X-Launchpad-Export-Date: 2017-06-06 05:55+0000\n"
17 "X-Generator: Launchpad (build 18399)\n"
18 "Language: hu\n"
19
20 #: ../data/diodon.desktop.in.h:1
21 msgid "Clipboard Manager"
22 msgstr "Vágólapkezelő"
23
24 #: ../data/diodon.desktop.in.h:2
25 msgid "GTK+ Clipboard Manager"
26 msgstr "GTK+ Vágólapkezelő"
27
28 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:1
29 msgid "Use clipboard (Ctrl+C)"
30 msgstr "Vágólap használata (Ctrl+C)"
31
32 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:2
33 #: ../data/preferences.ui.h:3
34 msgid ""
35 "Adds content which is copied to the clipboard with e.g. Ctrl + C to the "
36 "clipboard history."
37 msgstr ""
38 "A vágólap előzményekhez adja a vágólapra (például Ctrl+C-vel) másolt "
39 "tartalmat."
40
41 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:3
42 msgid "Use primary selection"
43 msgstr "Elsődleges kijelölés használata"
44
45 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:4
46 #: ../data/preferences.ui.h:5
47 msgid ""
48 "Adds the primary selection (an area of the screen which is selected with the "
49 "mouse) to the clipboard history. Enabling will start process which "
50 "continually checks what is selected. This might discharge your battery "
51 "quicker."
52 msgstr ""
53 "Hozzáadja az elsődleges kijelölés tartalmát (a kijelző egérrel kijelölt "
54 "részét) a vágólap előzményekhez. Engedélyezése olyan folyamatot fog "
55 "elindítani, ami folyamatosan figyeli, hogy mi van kijelölve. Ez könnyebben "
56 "lemerítheti az akkumulátort."
57
58 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:5
59 msgid "Add images to clipboard history"
60 msgstr "Képek hozzáadása a vágólap előzményekhez"
61
62 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:6
63 #: ../data/preferences.ui.h:7
64 msgid ""
65 "Add images copied to clipboard to clipboard history (e.g. when you right "
66 "click on an image in your browser and choose copy image). Enabling this "
67 "option will increase memory consumption. Images already added to clipboard "
68 "history will remain even when disabled."
69 msgstr ""
70 "Hozzáadja a vágólapra másolt képeket a vágólap előzményekhez (például amikor "
71 "jobb egérgombbal kattint egy képre a böngészőjében és a \"kép másolásá\"-t "
72 "választja). Ezen opció engedélyezése megnöveli a memóriahasználatot. A már a "
73 "vágólap előzményekhez adott képek letiltása után is ott maradnak."
74
75 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:7
76 msgid "Synchronize clipboards"
77 msgstr "Vágólapok szinkronizálása"
78
79 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:8
80 #: ../data/preferences.ui.h:11
81 msgid ""
82 "Synchronizes the selection (an area of the screen which is selected with the "
83 "mouse) and the clipboard so that anything in the selection is immediately "
84 "available in the clipboard and vice versa e.g. for pasting with Ctrl + V and "
85 "the middle mouse button."
86 msgstr ""
87 "Szinkronizálja a kijelölést (a kijelző egérrel kijelölt részét) és a "
88 "vágólapot, így a kijelölésből bármi azonnal elérhető a vágólapon és "
89 "fordítva, például Ctrl+V-vel vagy a középső egérgombbal való beszúrásra."
90
91 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:9
92 msgid "Keep clipboard content"
93 msgstr "A vágólap tartalmának megtartása"
94
95 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:10
96 #: ../data/preferences.ui.h:9
97 msgid ""
98 "Prevents an empty clipboard. For instance when an application exits, the "
99 "clipboard would usually be emptied."
100 msgstr ""
101 "Megakadályozza, hogy a vágólap kiürüljön. Például amikor egy alkalmazás "
102 "bezárul, a vágólap tartalma általában kitörlődne."
103
104 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:11
105 msgid "Automatically paste selected item"
106 msgstr "A kiválasztott elem automatikus beillesztése"
107
108 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:12
109 #: ../data/preferences.ui.h:13
110 msgid ""
111 "Automatically paste selected item instead of just copying it to the "
112 "clipboard."
113 msgstr ""
114 "A kiválasztott elem automatikus beillesztése az egyszerű vágólapra való "
115 "másolás helyett."
116
117 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:13
118 msgid "Number of recent clipboard items"
119 msgstr "A vágólapon lévő friss elemek száma"
120
121 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:14
122 msgid "Number of recent clipboard items shown in clipboard menu."
123 msgstr "A vágólapon lévő, vágólap menüben megjelenő friss elemek száma"
124
125 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:15
126 msgid "Clipboard content filter pattern"
127 msgstr ""
128
129 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:16
130 msgid ""
131 "Regex filter pattern whereas all clipboard items matching this pattern will "
132 "be filtered and not added to clipboard history."
133 msgstr ""
134
135 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:17
136 msgid "Lookup dictionary for application using different paste keybindings"
137 msgstr ""
138
139 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:18
140 msgid ""
141 "A lookup dictionary for applications using different paste keybindings than "
142 "Ctrl + V. Pattern of each string in this array is path-of-app|keybinding"
143 msgstr ""
144
145 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:19
146 msgid "Active plugins"
147 msgstr "Aktív bővítmények"
148
149 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:20
150 msgid "List of active plugins."
151 msgstr "Az aktív bővítmények listája"
152
153 #: ../data/preferences.ui.h:1
154 msgid "Diodon Preferences"
155 msgstr "Diodon Beállítások"
156
157 #: ../data/preferences.ui.h:2
158 msgid "_Use clipboard (Ctrl+C)"
159 msgstr "Vágólap _használata (Ctrl+C)"
160
161 #: ../data/preferences.ui.h:4
162 msgid "Use _primary selection"
163 msgstr "_Elsődleges kijelölés használata"
164
165 #: ../data/preferences.ui.h:6
166 msgid "Add _images to clipboard history"
167 msgstr "_Képek hozzáadása a vágólap előzményekhez"
168
169 #: ../data/preferences.ui.h:8
170 msgid "_Keep clipboard content"
171 msgstr "Vágólap tartalom _megtartása"
172
173 #: ../data/preferences.ui.h:10
174 msgid "S_ynchronize clipboards"
175 msgstr "Vágólapok _szinkronizálása"
176
177 #: ../data/preferences.ui.h:12
178 msgid "_Automatically paste selected item"
179 msgstr "A kijelölt elemek _automatikus beillesztése"
180
181 #: ../data/preferences.ui.h:14
182 msgid "Number of recent clipboard items to be shown in clipboard menu."
183 msgstr "A vágólap menüben megjelenítendő friss vágólapi elemek száma."
184
185 #: ../data/preferences.ui.h:15
186 msgid "Number of recent items"
187 msgstr "Friss elemek száma"
188
189 #: ../data/preferences.ui.h:16 ../unity-scope-diodon/unity-scope-diodon.vala:75
190 msgid "Clipboard"
191 msgstr "Vágólap"
192
193 #: ../data/preferences.ui.h:17
194 msgid ""
195 "Please register custom shortcut with\n"
196 "your desktop environment.\n"
197 "Use /usr/bin/diodon as command."
198 msgstr ""
199
200 #: ../data/preferences.ui.h:20
201 msgid "More information"
202 msgstr ""
203
204 #: ../data/preferences.ui.h:21
205 msgid "Hotkeys"
206 msgstr ""
207
208 #: ../data/preferences.ui.h:22
209 msgid "Plugins"
210 msgstr "Bővítmények"
211
212 #: ../libdiodon/clipboard-menu.vala:46
213 msgid "<Empty>"
214 msgstr "<Üres>"
215
216 #: ../libdiodon/clipboard-menu.vala:53
217 msgid "Privacy mode is enabled. No new items will be added to history!"
218 msgstr ""
219
220 #: ../plugins/indicator/indicator.plugin.in.h:1
221 msgid "Application Indicator"
222 msgstr "Alkalmazás Indikátor"
223
224 #: ../plugins/indicator/indicator.plugin.in.h:2
225 msgid "Access clipboard history with an application indicator."
226 msgstr "Vágólap előzmények elérése alkalmazás indikátorral."
227
228 #: ../plugins/indicator/indicator.plugin.in.h:3
229 msgid "Copyright © 2011 Diodon Team"
230 msgstr "Copyright @ 2011 Diodon Team"
231
232 #: ../unity-scope-diodon/clipboard.scope.in.in.h:1
233 msgid "Clipboard History"
234 msgstr "Vágólap Előzmények"
235
236 #: ../unity-scope-diodon/clipboard.scope.in.in.h:2
237 msgid ""
238 "This is an Ubuntu search plugin that enables information from Diodon to be "
239 "searched and displayed in the Dash underneath the Clipboard header."
240 msgstr ""
241 "Ez egy Ubuntu kereső bővítmény, amivel a Diodonból származó információk "
242 "kereshetők és megjeleníthetők a Dashben, a Vágólap fejléc alatt."
243
244 #: ../unity-scope-diodon/clipboard.scope.in.in.h:3
245 msgid "Search clipboard"
246 msgstr "Keresés a vágólapon"
247
248 #: ../unity-scope-diodon/clipboard.scope.in.in.h:4
249 #: ../unity-scope-diodon/unity-scope-diodon.vala:79
250 #: ../unity-scope-diodon/unity-scope-diodon.vala:104
251 msgid "Text"
252 msgstr "Szöveg"
253
254 #: ../unity-scope-diodon/clipboard.scope.in.in.h:5
255 #: ../unity-scope-diodon/unity-scope-diodon.vala:84
256 #: ../unity-scope-diodon/unity-scope-diodon.vala:105
257 msgid "Files"
258 msgstr "Fájlok"
259
260 #: ../unity-scope-diodon/clipboard.scope.in.in.h:6
261 #: ../unity-scope-diodon/unity-scope-diodon.vala:89
262 #: ../unity-scope-diodon/unity-scope-diodon.vala:106
263 msgid "Images"
264 msgstr "Képek"
265
266 #: ../unity-scope-diodon/clipboard.scope.in.in.h:7
267 #: ../unity-scope-diodon/unity-scope-diodon.vala:101
268 msgid "Category"
269 msgstr "Kategória"
270
271 #: ../unity-scope-diodon/clipboard.scope.in.in.h:8
272 msgid "Text;Files;Images"
273 msgstr "Szöveg;Fájlok;Képek"
274
275 #: ../unity-scope-diodon/clipboard.scope.in.in.h:9
276 msgid "Last 24 hours;Last 7 days;Last 30 days;Last year;"
277 msgstr "Elmúlt 24 óra;Elmúlt 7 nap;Elmúlt 30 nap;Elmúlt év;"
278
279 #: ../unity-scope-diodon/unity-scope-diodon.vala:45
280 msgid "Search Clipboard"
281 msgstr "Keresés a Vágólapon"
282
283 #: ../unity-scope-diodon/unity-scope-diodon.vala:110
284 #: ../unity-scope-diodon/unity-scope-diodon.vala:231
285 msgid "Date copied"
286 msgstr "A másolás dátuma"
287
288 #: ../unity-scope-diodon/unity-scope-diodon.vala:112
289 msgid "Last 24 hours"
290 msgstr "Elmúlt 24 óra"
291
292 #: ../unity-scope-diodon/unity-scope-diodon.vala:113
293 msgid "Last 7 days"
294 msgstr "Elmúlt 7 nap"
295
296 #: ../unity-scope-diodon/unity-scope-diodon.vala:114
297 msgid "Last 30 days"
298 msgstr "Elmúlt 30 nap"
299
300 #: ../unity-scope-diodon/unity-scope-diodon.vala:115
301 msgid "Last year"
302 msgstr "Tavaly"
303
304 #: ../unity-scope-diodon/unity-scope-diodon.vala:216
305 msgid "Paste"
306 msgstr "Beillesztés"
307
308 #: ../unity-scope-diodon/unity-scope-diodon.vala:224
309 msgid "Origin"
310 msgstr "Származás"
0 # Italian translation for diodon
1 # Copyright (c) 2011 Rosetta Contributors and Canonical Ltd 2011
2 # This file is distributed under the same license as the diodon package.
3 # FIRST AUTHOR <EMAIL@ADDRESS>, 2011.
4 #
5 msgid ""
6 msgstr ""
7 "Project-Id-Version: diodon\n"
8 "Report-Msgid-Bugs-To: \n"
9 "POT-Creation-Date: 2017-06-05 14:18+0200\n"
10 "PO-Revision-Date: 2013-12-29 00:12+0000\n"
11 "Last-Translator: Oliver Sauder <os@esite.ch>\n"
12 "Language-Team: Italian <it@li.org>\n"
13 "MIME-Version: 1.0\n"
14 "Content-Type: text/plain; charset=UTF-8\n"
15 "Content-Transfer-Encoding: 8bit\n"
16 "X-Launchpad-Export-Date: 2017-06-06 05:55+0000\n"
17 "X-Generator: Launchpad (build 18399)\n"
18 "Language: it\n"
19
20 #: ../data/diodon.desktop.in.h:1
21 msgid "Clipboard Manager"
22 msgstr "Gestore degli appunti"
23
24 #: ../data/diodon.desktop.in.h:2
25 msgid "GTK+ Clipboard Manager"
26 msgstr "GTK+ Clipboard Manager"
27
28 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:1
29 msgid "Use clipboard (Ctrl+C)"
30 msgstr "Utilizza gli appunti (Ctrl + C)"
31
32 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:2
33 #: ../data/preferences.ui.h:3
34 msgid ""
35 "Adds content which is copied to the clipboard with e.g. Ctrl + C to the "
36 "clipboard history."
37 msgstr ""
38
39 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:3
40 msgid "Use primary selection"
41 msgstr ""
42
43 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:4
44 #: ../data/preferences.ui.h:5
45 msgid ""
46 "Adds the primary selection (an area of the screen which is selected with the "
47 "mouse) to the clipboard history. Enabling will start process which "
48 "continually checks what is selected. This might discharge your battery "
49 "quicker."
50 msgstr ""
51
52 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:5
53 msgid "Add images to clipboard history"
54 msgstr ""
55
56 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:6
57 #: ../data/preferences.ui.h:7
58 msgid ""
59 "Add images copied to clipboard to clipboard history (e.g. when you right "
60 "click on an image in your browser and choose copy image). Enabling this "
61 "option will increase memory consumption. Images already added to clipboard "
62 "history will remain even when disabled."
63 msgstr ""
64
65 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:7
66 msgid "Synchronize clipboards"
67 msgstr "Sincronizza gli appunti"
68
69 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:8
70 #: ../data/preferences.ui.h:11
71 msgid ""
72 "Synchronizes the selection (an area of the screen which is selected with the "
73 "mouse) and the clipboard so that anything in the selection is immediately "
74 "available in the clipboard and vice versa e.g. for pasting with Ctrl + V and "
75 "the middle mouse button."
76 msgstr ""
77 "Sincronizza la selezione (la zona dello schermo evidenziata con il mouse) e "
78 "gli appunti in modo che qualsiasi cosa nella selezione è immediatamente "
79 "disponibile negli appunti e viceversa, ad esempio, per incollare con Ctrl + "
80 "V e il tasto centrale del mouse."
81
82 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:9
83 msgid "Keep clipboard content"
84 msgstr "Mantieni il contenuto degli appunti."
85
86 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:10
87 #: ../data/preferences.ui.h:9
88 msgid ""
89 "Prevents an empty clipboard. For instance when an application exits, the "
90 "clipboard would usually be emptied."
91 msgstr ""
92 "Impedisce la cancellazione degli appunti. Per esempio quando un applicazione "
93 "viene chiusa, gli appunti di solito vengono eliminati."
94
95 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:11
96 msgid "Automatically paste selected item"
97 msgstr "Incolla automaticamente gli elementi selezionati"
98
99 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:12
100 #: ../data/preferences.ui.h:13
101 msgid ""
102 "Automatically paste selected item instead of just copying it to the "
103 "clipboard."
104 msgstr ""
105 "Incolla automaticamente gli elementi selezionati invece che copiarli "
106 "solamente negli appunti."
107
108 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:13
109 msgid "Number of recent clipboard items"
110 msgstr ""
111
112 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:14
113 msgid "Number of recent clipboard items shown in clipboard menu."
114 msgstr ""
115
116 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:15
117 msgid "Clipboard content filter pattern"
118 msgstr ""
119
120 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:16
121 msgid ""
122 "Regex filter pattern whereas all clipboard items matching this pattern will "
123 "be filtered and not added to clipboard history."
124 msgstr ""
125
126 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:17
127 msgid "Lookup dictionary for application using different paste keybindings"
128 msgstr ""
129
130 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:18
131 msgid ""
132 "A lookup dictionary for applications using different paste keybindings than "
133 "Ctrl + V. Pattern of each string in this array is path-of-app|keybinding"
134 msgstr ""
135
136 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:19
137 msgid "Active plugins"
138 msgstr "Plugin attivi"
139
140 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:20
141 msgid "List of active plugins."
142 msgstr "Lista degli plugin attivi."
143
144 #: ../data/preferences.ui.h:1
145 msgid "Diodon Preferences"
146 msgstr "Preferenze di Diodon"
147
148 #: ../data/preferences.ui.h:2
149 msgid "_Use clipboard (Ctrl+C)"
150 msgstr "_Copia gli appunti (Ctrl+C)"
151
152 #: ../data/preferences.ui.h:4
153 msgid "Use _primary selection"
154 msgstr "Usa la selezione _primaria"
155
156 #: ../data/preferences.ui.h:6
157 msgid "Add _images to clipboard history"
158 msgstr ""
159
160 #: ../data/preferences.ui.h:8
161 msgid "_Keep clipboard content"
162 msgstr "_Mantieni il contenuto degli appunti"
163
164 #: ../data/preferences.ui.h:10
165 msgid "S_ynchronize clipboards"
166 msgstr "_Sincronizza appunti"
167
168 #: ../data/preferences.ui.h:12
169 msgid "_Automatically paste selected item"
170 msgstr "Incolla _automaticamente gli elementi selezionati"
171
172 #: ../data/preferences.ui.h:14
173 msgid "Number of recent clipboard items to be shown in clipboard menu."
174 msgstr ""
175
176 #: ../data/preferences.ui.h:15
177 msgid "Number of recent items"
178 msgstr ""
179
180 #: ../data/preferences.ui.h:16 ../unity-scope-diodon/unity-scope-diodon.vala:75
181 msgid "Clipboard"
182 msgstr "Appunti"
183
184 #: ../data/preferences.ui.h:17
185 msgid ""
186 "Please register custom shortcut with\n"
187 "your desktop environment.\n"
188 "Use /usr/bin/diodon as command."
189 msgstr ""
190
191 #: ../data/preferences.ui.h:20
192 msgid "More information"
193 msgstr ""
194
195 #: ../data/preferences.ui.h:21
196 msgid "Hotkeys"
197 msgstr ""
198
199 #: ../data/preferences.ui.h:22
200 msgid "Plugins"
201 msgstr "Plugin"
202
203 #: ../libdiodon/clipboard-menu.vala:46
204 msgid "<Empty>"
205 msgstr "<Vuoto>"
206
207 #: ../libdiodon/clipboard-menu.vala:53
208 msgid "Privacy mode is enabled. No new items will be added to history!"
209 msgstr ""
210
211 #: ../plugins/indicator/indicator.plugin.in.h:1
212 msgid "Application Indicator"
213 msgstr ""
214
215 #: ../plugins/indicator/indicator.plugin.in.h:2
216 msgid "Access clipboard history with an application indicator."
217 msgstr ""
218
219 #: ../plugins/indicator/indicator.plugin.in.h:3
220 msgid "Copyright © 2011 Diodon Team"
221 msgstr ""
222
223 #: ../unity-scope-diodon/clipboard.scope.in.in.h:1
224 msgid "Clipboard History"
225 msgstr ""
226
227 #: ../unity-scope-diodon/clipboard.scope.in.in.h:2
228 msgid ""
229 "This is an Ubuntu search plugin that enables information from Diodon to be "
230 "searched and displayed in the Dash underneath the Clipboard header."
231 msgstr ""
232
233 #: ../unity-scope-diodon/clipboard.scope.in.in.h:3
234 msgid "Search clipboard"
235 msgstr ""
236
237 #: ../unity-scope-diodon/clipboard.scope.in.in.h:4
238 #: ../unity-scope-diodon/unity-scope-diodon.vala:79
239 #: ../unity-scope-diodon/unity-scope-diodon.vala:104
240 msgid "Text"
241 msgstr ""
242
243 #: ../unity-scope-diodon/clipboard.scope.in.in.h:5
244 #: ../unity-scope-diodon/unity-scope-diodon.vala:84
245 #: ../unity-scope-diodon/unity-scope-diodon.vala:105
246 msgid "Files"
247 msgstr ""
248
249 #: ../unity-scope-diodon/clipboard.scope.in.in.h:6
250 #: ../unity-scope-diodon/unity-scope-diodon.vala:89
251 #: ../unity-scope-diodon/unity-scope-diodon.vala:106
252 msgid "Images"
253 msgstr ""
254
255 #: ../unity-scope-diodon/clipboard.scope.in.in.h:7
256 #: ../unity-scope-diodon/unity-scope-diodon.vala:101
257 msgid "Category"
258 msgstr ""
259
260 #: ../unity-scope-diodon/clipboard.scope.in.in.h:8
261 msgid "Text;Files;Images"
262 msgstr ""
263
264 #: ../unity-scope-diodon/clipboard.scope.in.in.h:9
265 msgid "Last 24 hours;Last 7 days;Last 30 days;Last year;"
266 msgstr ""
267
268 #: ../unity-scope-diodon/unity-scope-diodon.vala:45
269 msgid "Search Clipboard"
270 msgstr ""
271
272 #: ../unity-scope-diodon/unity-scope-diodon.vala:110
273 #: ../unity-scope-diodon/unity-scope-diodon.vala:231
274 msgid "Date copied"
275 msgstr ""
276
277 #: ../unity-scope-diodon/unity-scope-diodon.vala:112
278 msgid "Last 24 hours"
279 msgstr ""
280
281 #: ../unity-scope-diodon/unity-scope-diodon.vala:113
282 msgid "Last 7 days"
283 msgstr ""
284
285 #: ../unity-scope-diodon/unity-scope-diodon.vala:114
286 msgid "Last 30 days"
287 msgstr ""
288
289 #: ../unity-scope-diodon/unity-scope-diodon.vala:115
290 msgid "Last year"
291 msgstr ""
292
293 #: ../unity-scope-diodon/unity-scope-diodon.vala:216
294 msgid "Paste"
295 msgstr ""
296
297 #: ../unity-scope-diodon/unity-scope-diodon.vala:224
298 msgid "Origin"
299 msgstr ""
0 # Japanese translation for diodon
1 # Copyright (c) 2013 Rosetta Contributors and Canonical Ltd 2013
2 # This file is distributed under the same license as the diodon package.
3 # FIRST AUTHOR <EMAIL@ADDRESS>, 2013.
4 #
5 msgid ""
6 msgstr ""
7 "Project-Id-Version: diodon\n"
8 "Report-Msgid-Bugs-To: \n"
9 "POT-Creation-Date: 2017-06-05 14:18+0200\n"
10 "PO-Revision-Date: 2014-03-21 00:52+0000\n"
11 "Last-Translator: ub <xenolith0bytetestcomgreen@gmail.com>\n"
12 "Language-Team: Japanese <ja@li.org>\n"
13 "MIME-Version: 1.0\n"
14 "Content-Type: text/plain; charset=UTF-8\n"
15 "Content-Transfer-Encoding: 8bit\n"
16 "X-Launchpad-Export-Date: 2017-06-06 05:55+0000\n"
17 "X-Generator: Launchpad (build 18399)\n"
18 "Language: ja\n"
19
20 #: ../data/diodon.desktop.in.h:1
21 msgid "Clipboard Manager"
22 msgstr "クリップボードマネージャー"
23
24 #: ../data/diodon.desktop.in.h:2
25 msgid "GTK+ Clipboard Manager"
26 msgstr "GTK+クリップボードマネージャー"
27
28 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:1
29 msgid "Use clipboard (Ctrl+C)"
30 msgstr "クリップボードを使用 (Ctrl+C)"
31
32 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:2
33 #: ../data/preferences.ui.h:3
34 msgid ""
35 "Adds content which is copied to the clipboard with e.g. Ctrl + C to the "
36 "clipboard history."
37 msgstr "Ctrl + C でクリップボードにコピーした内容をクリップボード履歴に追加。"
38
39 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:3
40 msgid "Use primary selection"
41 msgstr "選択を使用"
42
43 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:4
44 #: ../data/preferences.ui.h:5
45 msgid ""
46 "Adds the primary selection (an area of the screen which is selected with the "
47 "mouse) to the clipboard history. Enabling will start process which "
48 "continually checks what is selected. This might discharge your battery "
49 "quicker."
50 msgstr ""
51
52 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:5
53 msgid "Add images to clipboard history"
54 msgstr "クリップボード履歴に画像を追加"
55
56 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:6
57 #: ../data/preferences.ui.h:7
58 msgid ""
59 "Add images copied to clipboard to clipboard history (e.g. when you right "
60 "click on an image in your browser and choose copy image). Enabling this "
61 "option will increase memory consumption. Images already added to clipboard "
62 "history will remain even when disabled."
63 msgstr ""
64 "クリップボードにコピーした画像をクリップボード履歴に追加します(ブラウザで画像を右クリックしてコピーを選択したとき)。このオプションを有効にするとメモリ消"
65 "費が多くなります。クリップボード履歴に追加した画像はこの機能を無効にしても残ります。"
66
67 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:7
68 msgid "Synchronize clipboards"
69 msgstr "クリップボードの同期"
70
71 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:8
72 #: ../data/preferences.ui.h:11
73 msgid ""
74 "Synchronizes the selection (an area of the screen which is selected with the "
75 "mouse) and the clipboard so that anything in the selection is immediately "
76 "available in the clipboard and vice versa e.g. for pasting with Ctrl + V and "
77 "the middle mouse button."
78 msgstr ""
79
80 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:9
81 msgid "Keep clipboard content"
82 msgstr "クリップボードを記憶"
83
84 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:10
85 #: ../data/preferences.ui.h:9
86 msgid ""
87 "Prevents an empty clipboard. For instance when an application exits, the "
88 "clipboard would usually be emptied."
89 msgstr "アプリケーションを終了した時にクリップボードを空にせず記憶します。"
90
91 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:11
92 msgid "Automatically paste selected item"
93 msgstr "選択したアイテムを自動ペースト"
94
95 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:12
96 #: ../data/preferences.ui.h:13
97 msgid ""
98 "Automatically paste selected item instead of just copying it to the "
99 "clipboard."
100 msgstr "選択したアイテムをクリップボードに送らず自動的にペーストします。"
101
102 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:13
103 msgid "Number of recent clipboard items"
104 msgstr "最近のクリップボードアイテムの数"
105
106 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:14
107 msgid "Number of recent clipboard items shown in clipboard menu."
108 msgstr "クリップボードメニューで表示される最近のクリップボードアイテムの数。"
109
110 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:15
111 msgid "Clipboard content filter pattern"
112 msgstr ""
113
114 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:16
115 msgid ""
116 "Regex filter pattern whereas all clipboard items matching this pattern will "
117 "be filtered and not added to clipboard history."
118 msgstr ""
119
120 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:17
121 msgid "Lookup dictionary for application using different paste keybindings"
122 msgstr ""
123
124 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:18
125 msgid ""
126 "A lookup dictionary for applications using different paste keybindings than "
127 "Ctrl + V. Pattern of each string in this array is path-of-app|keybinding"
128 msgstr ""
129
130 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:19
131 msgid "Active plugins"
132 msgstr "有効なプラグイン"
133
134 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:20
135 msgid "List of active plugins."
136 msgstr "有効なプラグインの一覧です。"
137
138 #: ../data/preferences.ui.h:1
139 msgid "Diodon Preferences"
140 msgstr "Diodon 設定"
141
142 #: ../data/preferences.ui.h:2
143 msgid "_Use clipboard (Ctrl+C)"
144 msgstr "クリップボード(Ctrl+C)を使用(_U)"
145
146 #: ../data/preferences.ui.h:4
147 msgid "Use _primary selection"
148 msgstr "選択を使用(_P)"
149
150 #: ../data/preferences.ui.h:6
151 msgid "Add _images to clipboard history"
152 msgstr "クリップボード履歴に画像を追加_(I)"
153
154 #: ../data/preferences.ui.h:8
155 msgid "_Keep clipboard content"
156 msgstr "クリップボードを記憶(_K)"
157
158 #: ../data/preferences.ui.h:10
159 msgid "S_ynchronize clipboards"
160 msgstr "クリップボードを同期(_Y)"
161
162 #: ../data/preferences.ui.h:12
163 msgid "_Automatically paste selected item"
164 msgstr "選択したアイテムを自動ペースト(_A)"
165
166 #: ../data/preferences.ui.h:14
167 msgid "Number of recent clipboard items to be shown in clipboard menu."
168 msgstr "クリップボードメニューで表示される最近のクリップボードアイテムの数。"
169
170 #: ../data/preferences.ui.h:15
171 msgid "Number of recent items"
172 msgstr ""
173
174 #: ../data/preferences.ui.h:16 ../unity-scope-diodon/unity-scope-diodon.vala:75
175 msgid "Clipboard"
176 msgstr "クリップボード"
177
178 #: ../data/preferences.ui.h:17
179 msgid ""
180 "Please register custom shortcut with\n"
181 "your desktop environment.\n"
182 "Use /usr/bin/diodon as command."
183 msgstr ""
184
185 #: ../data/preferences.ui.h:20
186 msgid "More information"
187 msgstr ""
188
189 #: ../data/preferences.ui.h:21
190 msgid "Hotkeys"
191 msgstr ""
192
193 #: ../data/preferences.ui.h:22
194 msgid "Plugins"
195 msgstr "プラグイン"
196
197 #: ../libdiodon/clipboard-menu.vala:46
198 msgid "<Empty>"
199 msgstr "<空>"
200
201 #: ../libdiodon/clipboard-menu.vala:53
202 msgid "Privacy mode is enabled. No new items will be added to history!"
203 msgstr ""
204
205 #: ../plugins/indicator/indicator.plugin.in.h:1
206 msgid "Application Indicator"
207 msgstr "アプリケーションインジケーター"
208
209 #: ../plugins/indicator/indicator.plugin.in.h:2
210 msgid "Access clipboard history with an application indicator."
211 msgstr "クリップボードのアクセスにアプリケーションインジケーターを使用します。"
212
213 #: ../plugins/indicator/indicator.plugin.in.h:3
214 msgid "Copyright © 2011 Diodon Team"
215 msgstr "Copyright © 2011 Diodon Team"
216
217 #: ../unity-scope-diodon/clipboard.scope.in.in.h:1
218 msgid "Clipboard History"
219 msgstr ""
220
221 #: ../unity-scope-diodon/clipboard.scope.in.in.h:2
222 msgid ""
223 "This is an Ubuntu search plugin that enables information from Diodon to be "
224 "searched and displayed in the Dash underneath the Clipboard header."
225 msgstr ""
226
227 #: ../unity-scope-diodon/clipboard.scope.in.in.h:3
228 msgid "Search clipboard"
229 msgstr "クリップボード検索"
230
231 #: ../unity-scope-diodon/clipboard.scope.in.in.h:4
232 #: ../unity-scope-diodon/unity-scope-diodon.vala:79
233 #: ../unity-scope-diodon/unity-scope-diodon.vala:104
234 msgid "Text"
235 msgstr ""
236
237 #: ../unity-scope-diodon/clipboard.scope.in.in.h:5
238 #: ../unity-scope-diodon/unity-scope-diodon.vala:84
239 #: ../unity-scope-diodon/unity-scope-diodon.vala:105
240 msgid "Files"
241 msgstr ""
242
243 #: ../unity-scope-diodon/clipboard.scope.in.in.h:6
244 #: ../unity-scope-diodon/unity-scope-diodon.vala:89
245 #: ../unity-scope-diodon/unity-scope-diodon.vala:106
246 msgid "Images"
247 msgstr ""
248
249 #: ../unity-scope-diodon/clipboard.scope.in.in.h:7
250 #: ../unity-scope-diodon/unity-scope-diodon.vala:101
251 msgid "Category"
252 msgstr ""
253
254 #: ../unity-scope-diodon/clipboard.scope.in.in.h:8
255 msgid "Text;Files;Images"
256 msgstr ""
257
258 #: ../unity-scope-diodon/clipboard.scope.in.in.h:9
259 msgid "Last 24 hours;Last 7 days;Last 30 days;Last year;"
260 msgstr ""
261
262 #: ../unity-scope-diodon/unity-scope-diodon.vala:45
263 msgid "Search Clipboard"
264 msgstr ""
265
266 #: ../unity-scope-diodon/unity-scope-diodon.vala:110
267 #: ../unity-scope-diodon/unity-scope-diodon.vala:231
268 msgid "Date copied"
269 msgstr ""
270
271 #: ../unity-scope-diodon/unity-scope-diodon.vala:112
272 msgid "Last 24 hours"
273 msgstr ""
274
275 #: ../unity-scope-diodon/unity-scope-diodon.vala:113
276 msgid "Last 7 days"
277 msgstr ""
278
279 #: ../unity-scope-diodon/unity-scope-diodon.vala:114
280 msgid "Last 30 days"
281 msgstr ""
282
283 #: ../unity-scope-diodon/unity-scope-diodon.vala:115
284 msgid "Last year"
285 msgstr ""
286
287 #: ../unity-scope-diodon/unity-scope-diodon.vala:216
288 msgid "Paste"
289 msgstr ""
290
291 #: ../unity-scope-diodon/unity-scope-diodon.vala:224
292 msgid "Origin"
293 msgstr ""
0 # Lithuanian translation for diodon
1 # Copyright (c) 2011 Rosetta Contributors and Canonical Ltd 2011
2 # This file is distributed under the same license as the diodon package.
3 # FIRST AUTHOR <EMAIL@ADDRESS>, 2011.
4 #
5 msgid ""
6 msgstr ""
7 "Project-Id-Version: diodon\n"
8 "Report-Msgid-Bugs-To: \n"
9 "POT-Creation-Date: 2017-06-05 14:18+0200\n"
10 "PO-Revision-Date: 2013-12-29 00:13+0000\n"
11 "Last-Translator: Oliver Sauder <os@esite.ch>\n"
12 "Language-Team: Lithuanian <lt@li.org>\n"
13 "MIME-Version: 1.0\n"
14 "Content-Type: text/plain; charset=UTF-8\n"
15 "Content-Transfer-Encoding: 8bit\n"
16 "X-Launchpad-Export-Date: 2017-06-06 05:55+0000\n"
17 "X-Generator: Launchpad (build 18399)\n"
18 "Language: lt\n"
19
20 #: ../data/diodon.desktop.in.h:1
21 msgid "Clipboard Manager"
22 msgstr "Iškarpinės tvarkytuvė"
23
24 #: ../data/diodon.desktop.in.h:2
25 msgid "GTK+ Clipboard Manager"
26 msgstr "GTK+ iškarpinės tvarkytuvė"
27
28 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:1
29 msgid "Use clipboard (Ctrl+C)"
30 msgstr "Naudoti iškarpinę (Vald+C)"
31
32 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:2
33 #: ../data/preferences.ui.h:3
34 msgid ""
35 "Adds content which is copied to the clipboard with e.g. Ctrl + C to the "
36 "clipboard history."
37 msgstr ""
38
39 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:3
40 msgid "Use primary selection"
41 msgstr "Naudoti žymimo teksto iškarpinę (primary selection)"
42
43 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:4
44 #: ../data/preferences.ui.h:5
45 msgid ""
46 "Adds the primary selection (an area of the screen which is selected with the "
47 "mouse) to the clipboard history. Enabling will start process which "
48 "continually checks what is selected. This might discharge your battery "
49 "quicker."
50 msgstr ""
51
52 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:5
53 msgid "Add images to clipboard history"
54 msgstr ""
55
56 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:6
57 #: ../data/preferences.ui.h:7
58 msgid ""
59 "Add images copied to clipboard to clipboard history (e.g. when you right "
60 "click on an image in your browser and choose copy image). Enabling this "
61 "option will increase memory consumption. Images already added to clipboard "
62 "history will remain even when disabled."
63 msgstr ""
64
65 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:7
66 msgid "Synchronize clipboards"
67 msgstr "Sinchronizuoti iškarpines"
68
69 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:8
70 #: ../data/preferences.ui.h:11
71 msgid ""
72 "Synchronizes the selection (an area of the screen which is selected with the "
73 "mouse) and the clipboard so that anything in the selection is immediately "
74 "available in the clipboard and vice versa e.g. for pasting with Ctrl + V and "
75 "the middle mouse button."
76 msgstr ""
77 "Sinchronizuoja žymėjimą (ekrano plotą, kuris yra pažymėtas pele) ir "
78 "iškarpinę, kad bet kas pažymėta iš karto būtų prieinama iškarpinėje ir "
79 "atvirkščiai, pavyzdžiui, įterpimui su Vald + V ir viduriniuoju pelės klavišu."
80
81 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:9
82 msgid "Keep clipboard content"
83 msgstr "Išlaikyti iškarpinės turinį"
84
85 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:10
86 #: ../data/preferences.ui.h:9
87 msgid ""
88 "Prevents an empty clipboard. For instance when an application exits, the "
89 "clipboard would usually be emptied."
90 msgstr ""
91 "Išvengia tuščios iškarpinės. Pavyzdžiui, kai programa baigia darbą, "
92 "iškarpinė paprastai būna išvaloma."
93
94 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:11
95 msgid "Automatically paste selected item"
96 msgstr "Automatiškai įdėti parinktą iškarpinės elementą"
97
98 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:12
99 #: ../data/preferences.ui.h:13
100 msgid ""
101 "Automatically paste selected item instead of just copying it to the "
102 "clipboard."
103 msgstr ""
104 "Automatiškai įdėti pažymėtą elementą vietoje tik nukopijavimo į iškarpinę."
105
106 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:13
107 msgid "Number of recent clipboard items"
108 msgstr ""
109
110 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:14
111 msgid "Number of recent clipboard items shown in clipboard menu."
112 msgstr ""
113
114 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:15
115 msgid "Clipboard content filter pattern"
116 msgstr ""
117
118 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:16
119 msgid ""
120 "Regex filter pattern whereas all clipboard items matching this pattern will "
121 "be filtered and not added to clipboard history."
122 msgstr ""
123
124 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:17
125 msgid "Lookup dictionary for application using different paste keybindings"
126 msgstr ""
127
128 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:18
129 msgid ""
130 "A lookup dictionary for applications using different paste keybindings than "
131 "Ctrl + V. Pattern of each string in this array is path-of-app|keybinding"
132 msgstr ""
133
134 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:19
135 msgid "Active plugins"
136 msgstr "Įjungti papildiniai"
137
138 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:20
139 msgid "List of active plugins."
140 msgstr "Aktyvių papildinių sąrašas."
141
142 #: ../data/preferences.ui.h:1
143 msgid "Diodon Preferences"
144 msgstr "Diodon programos nustatymai"
145
146 #: ../data/preferences.ui.h:2
147 msgid "_Use clipboard (Ctrl+C)"
148 msgstr "Naudoti _iškarpinę (Vald+C)"
149
150 #: ../data/preferences.ui.h:4
151 msgid "Use _primary selection"
152 msgstr ""
153
154 #: ../data/preferences.ui.h:6
155 msgid "Add _images to clipboard history"
156 msgstr ""
157
158 #: ../data/preferences.ui.h:8
159 msgid "_Keep clipboard content"
160 msgstr "Iš_laikyti iškarpinės turinį"
161
162 #: ../data/preferences.ui.h:10
163 msgid "S_ynchronize clipboards"
164 msgstr "_Sinchronizuoti iškarpines"
165
166 #: ../data/preferences.ui.h:12
167 msgid "_Automatically paste selected item"
168 msgstr "_Automatiškai įdėti parinktą iškarpinės elementą"
169
170 #: ../data/preferences.ui.h:14
171 msgid "Number of recent clipboard items to be shown in clipboard menu."
172 msgstr ""
173
174 #: ../data/preferences.ui.h:15
175 msgid "Number of recent items"
176 msgstr ""
177
178 #: ../data/preferences.ui.h:16 ../unity-scope-diodon/unity-scope-diodon.vala:75
179 msgid "Clipboard"
180 msgstr "Iškarpinė"
181
182 #: ../data/preferences.ui.h:17
183 msgid ""
184 "Please register custom shortcut with\n"
185 "your desktop environment.\n"
186 "Use /usr/bin/diodon as command."
187 msgstr ""
188
189 #: ../data/preferences.ui.h:20
190 msgid "More information"
191 msgstr ""
192
193 #: ../data/preferences.ui.h:21
194 msgid "Hotkeys"
195 msgstr ""
196
197 #: ../data/preferences.ui.h:22
198 msgid "Plugins"
199 msgstr "Papildiniai"
200
201 #: ../libdiodon/clipboard-menu.vala:46
202 msgid "<Empty>"
203 msgstr "<Tuščia>"
204
205 #: ../libdiodon/clipboard-menu.vala:53
206 msgid "Privacy mode is enabled. No new items will be added to history!"
207 msgstr ""
208
209 #: ../plugins/indicator/indicator.plugin.in.h:1
210 msgid "Application Indicator"
211 msgstr ""
212
213 #: ../plugins/indicator/indicator.plugin.in.h:2
214 msgid "Access clipboard history with an application indicator."
215 msgstr ""
216
217 #: ../plugins/indicator/indicator.plugin.in.h:3
218 msgid "Copyright © 2011 Diodon Team"
219 msgstr ""
220
221 #: ../unity-scope-diodon/clipboard.scope.in.in.h:1
222 msgid "Clipboard History"
223 msgstr ""
224
225 #: ../unity-scope-diodon/clipboard.scope.in.in.h:2
226 msgid ""
227 "This is an Ubuntu search plugin that enables information from Diodon to be "
228 "searched and displayed in the Dash underneath the Clipboard header."
229 msgstr ""
230
231 #: ../unity-scope-diodon/clipboard.scope.in.in.h:3
232 msgid "Search clipboard"
233 msgstr ""
234
235 #: ../unity-scope-diodon/clipboard.scope.in.in.h:4
236 #: ../unity-scope-diodon/unity-scope-diodon.vala:79
237 #: ../unity-scope-diodon/unity-scope-diodon.vala:104
238 msgid "Text"
239 msgstr ""
240
241 #: ../unity-scope-diodon/clipboard.scope.in.in.h:5
242 #: ../unity-scope-diodon/unity-scope-diodon.vala:84
243 #: ../unity-scope-diodon/unity-scope-diodon.vala:105
244 msgid "Files"
245 msgstr ""
246
247 #: ../unity-scope-diodon/clipboard.scope.in.in.h:6
248 #: ../unity-scope-diodon/unity-scope-diodon.vala:89
249 #: ../unity-scope-diodon/unity-scope-diodon.vala:106
250 msgid "Images"
251 msgstr ""
252
253 #: ../unity-scope-diodon/clipboard.scope.in.in.h:7
254 #: ../unity-scope-diodon/unity-scope-diodon.vala:101
255 msgid "Category"
256 msgstr ""
257
258 #: ../unity-scope-diodon/clipboard.scope.in.in.h:8
259 msgid "Text;Files;Images"
260 msgstr ""
261
262 #: ../unity-scope-diodon/clipboard.scope.in.in.h:9
263 msgid "Last 24 hours;Last 7 days;Last 30 days;Last year;"
264 msgstr ""
265
266 #: ../unity-scope-diodon/unity-scope-diodon.vala:45
267 msgid "Search Clipboard"
268 msgstr ""
269
270 #: ../unity-scope-diodon/unity-scope-diodon.vala:110
271 #: ../unity-scope-diodon/unity-scope-diodon.vala:231
272 msgid "Date copied"
273 msgstr ""
274
275 #: ../unity-scope-diodon/unity-scope-diodon.vala:112
276 msgid "Last 24 hours"
277 msgstr ""
278
279 #: ../unity-scope-diodon/unity-scope-diodon.vala:113
280 msgid "Last 7 days"
281 msgstr ""
282
283 #: ../unity-scope-diodon/unity-scope-diodon.vala:114
284 msgid "Last 30 days"
285 msgstr ""
286
287 #: ../unity-scope-diodon/unity-scope-diodon.vala:115
288 msgid "Last year"
289 msgstr ""
290
291 #: ../unity-scope-diodon/unity-scope-diodon.vala:216
292 msgid "Paste"
293 msgstr ""
294
295 #: ../unity-scope-diodon/unity-scope-diodon.vala:224
296 msgid "Origin"
297 msgstr ""
0 # Norwegian Bokmal translation for diodon
1 # Copyright (c) 2011 Rosetta Contributors and Canonical Ltd 2011
2 # This file is distributed under the same license as the diodon package.
3 # FIRST AUTHOR <EMAIL@ADDRESS>, 2011.
4 #
5 msgid ""
6 msgstr ""
7 "Project-Id-Version: diodon\n"
8 "Report-Msgid-Bugs-To: \n"
9 "POT-Creation-Date: 2017-06-05 14:18+0200\n"
10 "PO-Revision-Date: 2014-06-16 06:01+0000\n"
11 "Last-Translator: Thor K. H. <nitrolinken@gmail.com>\n"
12 "Language-Team: Norwegian Bokmal <nb@li.org>\n"
13 "MIME-Version: 1.0\n"
14 "Content-Type: text/plain; charset=UTF-8\n"
15 "Content-Transfer-Encoding: 8bit\n"
16 "X-Launchpad-Export-Date: 2017-06-06 05:55+0000\n"
17 "X-Generator: Launchpad (build 18399)\n"
18 "Language: nb\n"
19
20 #: ../data/diodon.desktop.in.h:1
21 msgid "Clipboard Manager"
22 msgstr "Utklippstavle-behandler"
23
24 #: ../data/diodon.desktop.in.h:2
25 msgid "GTK+ Clipboard Manager"
26 msgstr "GTK+ håndtering av utklippstavle"
27
28 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:1
29 msgid "Use clipboard (Ctrl+C)"
30 msgstr "Bruk utklippstavle (Ctrl+C)"
31
32 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:2
33 #: ../data/preferences.ui.h:3
34 msgid ""
35 "Adds content which is copied to the clipboard with e.g. Ctrl + C to the "
36 "clipboard history."
37 msgstr ""
38
39 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:3
40 msgid "Use primary selection"
41 msgstr ""
42
43 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:4
44 #: ../data/preferences.ui.h:5
45 msgid ""
46 "Adds the primary selection (an area of the screen which is selected with the "
47 "mouse) to the clipboard history. Enabling will start process which "
48 "continually checks what is selected. This might discharge your battery "
49 "quicker."
50 msgstr ""
51
52 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:5
53 msgid "Add images to clipboard history"
54 msgstr ""
55
56 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:6
57 #: ../data/preferences.ui.h:7
58 msgid ""
59 "Add images copied to clipboard to clipboard history (e.g. when you right "
60 "click on an image in your browser and choose copy image). Enabling this "
61 "option will increase memory consumption. Images already added to clipboard "
62 "history will remain even when disabled."
63 msgstr ""
64
65 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:7
66 msgid "Synchronize clipboards"
67 msgstr ""
68
69 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:8
70 #: ../data/preferences.ui.h:11
71 msgid ""
72 "Synchronizes the selection (an area of the screen which is selected with the "
73 "mouse) and the clipboard so that anything in the selection is immediately "
74 "available in the clipboard and vice versa e.g. for pasting with Ctrl + V and "
75 "the middle mouse button."
76 msgstr ""
77 "Synkroniserer utvalget (et område på skjermen som er valgt med musen) og "
78 "utklippstavlen slik at alt i utvalget er umiddelbart tilgjengelig i "
79 "utklippstavlen og vice versa f.eks når man limer inn med Ctrl + V og midtre "
80 "museknapp."
81
82 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:9
83 msgid "Keep clipboard content"
84 msgstr ""
85
86 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:10
87 #: ../data/preferences.ui.h:9
88 msgid ""
89 "Prevents an empty clipboard. For instance when an application exits, the "
90 "clipboard would usually be emptied."
91 msgstr ""
92 "Hindrer en tom utklippstavle. For eksempel når en applikasjon avsluttes, "
93 "ville utklippstavlen vanligvis blitt tømt."
94
95 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:11
96 msgid "Automatically paste selected item"
97 msgstr ""
98
99 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:12
100 #: ../data/preferences.ui.h:13
101 msgid ""
102 "Automatically paste selected item instead of just copying it to the "
103 "clipboard."
104 msgstr ""
105
106 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:13
107 msgid "Number of recent clipboard items"
108 msgstr ""
109
110 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:14
111 msgid "Number of recent clipboard items shown in clipboard menu."
112 msgstr ""
113
114 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:15
115 msgid "Clipboard content filter pattern"
116 msgstr ""
117
118 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:16
119 msgid ""
120 "Regex filter pattern whereas all clipboard items matching this pattern will "
121 "be filtered and not added to clipboard history."
122 msgstr ""
123
124 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:17
125 msgid "Lookup dictionary for application using different paste keybindings"
126 msgstr ""
127
128 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:18
129 msgid ""
130 "A lookup dictionary for applications using different paste keybindings than "
131 "Ctrl + V. Pattern of each string in this array is path-of-app|keybinding"
132 msgstr ""
133
134 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:19
135 msgid "Active plugins"
136 msgstr ""
137
138 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:20
139 msgid "List of active plugins."
140 msgstr ""
141
142 #: ../data/preferences.ui.h:1
143 msgid "Diodon Preferences"
144 msgstr "Innstillinger for Diodon"
145
146 #: ../data/preferences.ui.h:2
147 msgid "_Use clipboard (Ctrl+C)"
148 msgstr "Bruk _utklippstavle"
149
150 #: ../data/preferences.ui.h:4
151 msgid "Use _primary selection"
152 msgstr "Bruk _primærvalg"
153
154 #: ../data/preferences.ui.h:6
155 msgid "Add _images to clipboard history"
156 msgstr ""
157
158 #: ../data/preferences.ui.h:8
159 msgid "_Keep clipboard content"
160 msgstr "Behold ut_klippstavlens innhold"
161
162 #: ../data/preferences.ui.h:10
163 msgid "S_ynchronize clipboards"
164 msgstr "S_ynkroniser utklippstavler"
165
166 #: ../data/preferences.ui.h:12
167 msgid "_Automatically paste selected item"
168 msgstr ""
169
170 #: ../data/preferences.ui.h:14
171 msgid "Number of recent clipboard items to be shown in clipboard menu."
172 msgstr ""
173
174 #: ../data/preferences.ui.h:15
175 msgid "Number of recent items"
176 msgstr ""
177
178 #: ../data/preferences.ui.h:16 ../unity-scope-diodon/unity-scope-diodon.vala:75
179 msgid "Clipboard"
180 msgstr "Utklippstavle"
181
182 #: ../data/preferences.ui.h:17
183 msgid ""
184 "Please register custom shortcut with\n"
185 "your desktop environment.\n"
186 "Use /usr/bin/diodon as command."
187 msgstr ""
188
189 #: ../data/preferences.ui.h:20
190 msgid "More information"
191 msgstr ""
192
193 #: ../data/preferences.ui.h:21
194 msgid "Hotkeys"
195 msgstr ""
196
197 #: ../data/preferences.ui.h:22
198 msgid "Plugins"
199 msgstr ""
200
201 #: ../libdiodon/clipboard-menu.vala:46
202 msgid "<Empty>"
203 msgstr "<Tom>"
204
205 #: ../libdiodon/clipboard-menu.vala:53
206 msgid "Privacy mode is enabled. No new items will be added to history!"
207 msgstr ""
208
209 #: ../plugins/indicator/indicator.plugin.in.h:1
210 msgid "Application Indicator"
211 msgstr ""
212
213 #: ../plugins/indicator/indicator.plugin.in.h:2
214 msgid "Access clipboard history with an application indicator."
215 msgstr ""
216
217 #: ../plugins/indicator/indicator.plugin.in.h:3
218 msgid "Copyright © 2011 Diodon Team"
219 msgstr ""
220
221 #: ../unity-scope-diodon/clipboard.scope.in.in.h:1
222 msgid "Clipboard History"
223 msgstr ""
224
225 #: ../unity-scope-diodon/clipboard.scope.in.in.h:2
226 msgid ""
227 "This is an Ubuntu search plugin that enables information from Diodon to be "
228 "searched and displayed in the Dash underneath the Clipboard header."
229 msgstr ""
230
231 #: ../unity-scope-diodon/clipboard.scope.in.in.h:3
232 msgid "Search clipboard"
233 msgstr ""
234
235 #: ../unity-scope-diodon/clipboard.scope.in.in.h:4
236 #: ../unity-scope-diodon/unity-scope-diodon.vala:79
237 #: ../unity-scope-diodon/unity-scope-diodon.vala:104
238 msgid "Text"
239 msgstr ""
240
241 #: ../unity-scope-diodon/clipboard.scope.in.in.h:5
242 #: ../unity-scope-diodon/unity-scope-diodon.vala:84
243 #: ../unity-scope-diodon/unity-scope-diodon.vala:105
244 msgid "Files"
245 msgstr ""
246
247 #: ../unity-scope-diodon/clipboard.scope.in.in.h:6
248 #: ../unity-scope-diodon/unity-scope-diodon.vala:89
249 #: ../unity-scope-diodon/unity-scope-diodon.vala:106
250 msgid "Images"
251 msgstr ""
252
253 #: ../unity-scope-diodon/clipboard.scope.in.in.h:7
254 #: ../unity-scope-diodon/unity-scope-diodon.vala:101
255 msgid "Category"
256 msgstr ""
257
258 #: ../unity-scope-diodon/clipboard.scope.in.in.h:8
259 msgid "Text;Files;Images"
260 msgstr ""
261
262 #: ../unity-scope-diodon/clipboard.scope.in.in.h:9
263 msgid "Last 24 hours;Last 7 days;Last 30 days;Last year;"
264 msgstr ""
265
266 #: ../unity-scope-diodon/unity-scope-diodon.vala:45
267 msgid "Search Clipboard"
268 msgstr ""
269
270 #: ../unity-scope-diodon/unity-scope-diodon.vala:110
271 #: ../unity-scope-diodon/unity-scope-diodon.vala:231
272 msgid "Date copied"
273 msgstr ""
274
275 #: ../unity-scope-diodon/unity-scope-diodon.vala:112
276 msgid "Last 24 hours"
277 msgstr ""
278
279 #: ../unity-scope-diodon/unity-scope-diodon.vala:113
280 msgid "Last 7 days"
281 msgstr ""
282
283 #: ../unity-scope-diodon/unity-scope-diodon.vala:114
284 msgid "Last 30 days"
285 msgstr ""
286
287 #: ../unity-scope-diodon/unity-scope-diodon.vala:115
288 msgid "Last year"
289 msgstr ""
290
291 #: ../unity-scope-diodon/unity-scope-diodon.vala:216
292 msgid "Paste"
293 msgstr ""
294
295 #: ../unity-scope-diodon/unity-scope-diodon.vala:224
296 msgid "Origin"
297 msgstr ""
0 # Dutch translation for diodon
1 # Copyright (c) 2013 Rosetta Contributors and Canonical Ltd 2013
2 # This file is distributed under the same license as the diodon package.
3 # FIRST AUTHOR <EMAIL@ADDRESS>, 2013.
4 #
5 msgid ""
6 msgstr ""
7 "Project-Id-Version: diodon\n"
8 "Report-Msgid-Bugs-To: \n"
9 "POT-Creation-Date: 2017-06-05 14:18+0200\n"
10 "PO-Revision-Date: 2016-02-07 21:28+0000\n"
11 "Last-Translator: rob <linuxned@gmail.com>\n"
12 "Language-Team: Dutch <nl@li.org>\n"
13 "MIME-Version: 1.0\n"
14 "Content-Type: text/plain; charset=UTF-8\n"
15 "Content-Transfer-Encoding: 8bit\n"
16 "X-Launchpad-Export-Date: 2017-06-06 05:55+0000\n"
17 "X-Generator: Launchpad (build 18399)\n"
18 "Language: nl\n"
19
20 #: ../data/diodon.desktop.in.h:1
21 msgid "Clipboard Manager"
22 msgstr "Klembordbeheer"
23
24 #: ../data/diodon.desktop.in.h:2
25 msgid "GTK+ Clipboard Manager"
26 msgstr "GTK+-klembordbeheer"
27
28 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:1
29 msgid "Use clipboard (Ctrl+C)"
30 msgstr "Klembord gebruiken (Ctrl+C)"
31
32 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:2
33 #: ../data/preferences.ui.h:3
34 msgid ""
35 "Adds content which is copied to the clipboard with e.g. Ctrl + C to the "
36 "clipboard history."
37 msgstr ""
38 "Voegt items die gekopieerd zijn naar het klembord met bijvoorbeeld Ctrl + C, "
39 "toe aan de klembordgeschiedenis."
40
41 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:3
42 msgid "Use primary selection"
43 msgstr "Primaire selectie gebruiken"
44
45 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:4
46 #: ../data/preferences.ui.h:5
47 msgid ""
48 "Adds the primary selection (an area of the screen which is selected with the "
49 "mouse) to the clipboard history. Enabling will start process which "
50 "continually checks what is selected. This might discharge your battery "
51 "quicker."
52 msgstr ""
53 "Voegt de primaire selectie (een gebied van het scherm dat geselecteerd is "
54 "met de muis) toe aan de klembordgeschiedenis. Wanneer u dit inschakelt zal "
55 "er een proces gestart worden dat voortdurend controleert wat er geselecteerd "
56 "is. Hierdoor kan uw accu mogelijk sneller leeg raken."
57
58 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:5
59 msgid "Add images to clipboard history"
60 msgstr "Afbeeldingen toevoegen aan de klembordgeschiedenis"
61
62 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:6
63 #: ../data/preferences.ui.h:7
64 msgid ""
65 "Add images copied to clipboard to clipboard history (e.g. when you right "
66 "click on an image in your browser and choose copy image). Enabling this "
67 "option will increase memory consumption. Images already added to clipboard "
68 "history will remain even when disabled."
69 msgstr ""
70 "Voegt afbeeldingen die gekopieerd zijn naar het klembord (bijvoorbeeld "
71 "wanneer u met rechts klikt op een afbeelding in uw browser en vervolgens "
72 "kopiëren selecteert) toe aan de klembordgeschiedenis. Wanneer u deze optie "
73 "inschakelt zal het geheugengebruik groter worden. Afbeeldingen die reeds "
74 "toegevoegd zijn aan de klembordgeschiedenis zullen behouden blijven, zelfs "
75 "wanneer deze optie uitgeschakeld staat."
76
77 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:7
78 msgid "Synchronize clipboards"
79 msgstr "Klemborden synchroniseren"
80
81 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:8
82 #: ../data/preferences.ui.h:11
83 msgid ""
84 "Synchronizes the selection (an area of the screen which is selected with the "
85 "mouse) and the clipboard so that anything in the selection is immediately "
86 "available in the clipboard and vice versa e.g. for pasting with Ctrl + V and "
87 "the middle mouse button."
88 msgstr ""
89 "Synchroniseert de selectie (een gebied van het scherm dat geselecteerd is "
90 "met de muis) en het klembord zodat de selectie direct beschikbaar is in het "
91 "klembord en vice versa, bijvoorbeeld voor het plakken via Ctrl + V en de "
92 "middelste muisknop."
93
94 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:9
95 msgid "Keep clipboard content"
96 msgstr "Klembordinhoud behouden"
97
98 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:10
99 #: ../data/preferences.ui.h:9
100 msgid ""
101 "Prevents an empty clipboard. For instance when an application exits, the "
102 "clipboard would usually be emptied."
103 msgstr ""
104 "Voorkomt een leeg klembord. Wanneer een toepassing bijvoorbeeld afgesloten "
105 "wordt, dan wordt het klembord gewoonlijk gewist."
106
107 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:11
108 msgid "Automatically paste selected item"
109 msgstr "Geselecteerd onderdeel automatisch plakken"
110
111 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:12
112 #: ../data/preferences.ui.h:13
113 msgid ""
114 "Automatically paste selected item instead of just copying it to the "
115 "clipboard."
116 msgstr ""
117 "Geselecteerde onderdeel automatisch plakken in plaats van het alleen te "
118 "kopiëren naar het klembord."
119
120 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:13
121 msgid "Number of recent clipboard items"
122 msgstr "Aantal recente klemborditems"
123
124 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:14
125 msgid "Number of recent clipboard items shown in clipboard menu."
126 msgstr "Aantal getoonde recente klemborditems in het klembordmenu."
127
128 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:15
129 msgid "Clipboard content filter pattern"
130 msgstr "Klembordinhoudfilterpatroon"
131
132 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:16
133 msgid ""
134 "Regex filter pattern whereas all clipboard items matching this pattern will "
135 "be filtered and not added to clipboard history."
136 msgstr ""
137 "Alle klemborditems die overeenkomen met dit filterpatroon zullen niet "
138 "toegevoegd worden aan de klembordgeschiedenis."
139
140 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:17
141 msgid "Lookup dictionary for application using different paste keybindings"
142 msgstr ""
143 "Opzoeklijst met mogelijkheden voor toepassingen die een andere "
144 "toetsencombinatie gebruiken voor het plakken"
145
146 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:18
147 msgid ""
148 "A lookup dictionary for applications using different paste keybindings than "
149 "Ctrl + V. Pattern of each string in this array is path-of-app|keybinding"
150 msgstr ""
151 "Opzoeklijst met mogelijkheden voor toepassingen die een andere "
152 "toetsencombinatie gebruiken voor het plakken dan Ctrl + V. Patroon van elke "
153 "regel in deze lijst is path-of-app|keybinding"
154
155 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:19
156 msgid "Active plugins"
157 msgstr "Actieve plug-ins"
158
159 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:20
160 msgid "List of active plugins."
161 msgstr "Lijst met actieve plug-ins"
162
163 #: ../data/preferences.ui.h:1
164 msgid "Diodon Preferences"
165 msgstr "Diodon-voorkeuren"
166
167 #: ../data/preferences.ui.h:2
168 msgid "_Use clipboard (Ctrl+C)"
169 msgstr "Klembord gebr_uiken (Ctrl+C)"
170
171 #: ../data/preferences.ui.h:4
172 msgid "Use _primary selection"
173 msgstr "_Primaire selectie gebruiken"
174
175 #: ../data/preferences.ui.h:6
176 msgid "Add _images to clipboard history"
177 msgstr "Afbeeld_ingen toevoegen aan klembordgeschiedenis"
178
179 #: ../data/preferences.ui.h:8
180 msgid "_Keep clipboard content"
181 msgstr "_Klembordinhoud behouden"
182
183 #: ../data/preferences.ui.h:10
184 msgid "S_ynchronize clipboards"
185 msgstr "Klemborden s_ynchroniseren"
186
187 #: ../data/preferences.ui.h:12
188 msgid "_Automatically paste selected item"
189 msgstr "Geselecteerde onderdeel _automatisch plakken"
190
191 #: ../data/preferences.ui.h:14
192 msgid "Number of recent clipboard items to be shown in clipboard menu."
193 msgstr "Aantal recente klemborditems om te tonen in het klembordmenu."
194
195 #: ../data/preferences.ui.h:15
196 msgid "Number of recent items"
197 msgstr "Aantal recente items"
198
199 #: ../data/preferences.ui.h:16 ../unity-scope-diodon/unity-scope-diodon.vala:75
200 msgid "Clipboard"
201 msgstr "Klembord"
202
203 #: ../data/preferences.ui.h:17
204 msgid ""
205 "Please register custom shortcut with\n"
206 "your desktop environment.\n"
207 "Use /usr/bin/diodon as command."
208 msgstr ""
209 "Registreer a.u.b. de aangepaste snelkoppeling bij\n"
210 "uw werkomgeving.\n"
211 "Gebruik hiervoor de opdracht /usr/bin/diodon."
212
213 #: ../data/preferences.ui.h:20
214 msgid "More information"
215 msgstr "Meer informatie"
216
217 #: ../data/preferences.ui.h:21
218 msgid "Hotkeys"
219 msgstr "Sneltoetsen"
220
221 #: ../data/preferences.ui.h:22
222 msgid "Plugins"
223 msgstr "Plug-ins"
224
225 #: ../libdiodon/clipboard-menu.vala:46
226 msgid "<Empty>"
227 msgstr "<Leeg>"
228
229 #: ../libdiodon/clipboard-menu.vala:53
230 msgid "Privacy mode is enabled. No new items will be added to history!"
231 msgstr ""
232
233 #: ../plugins/indicator/indicator.plugin.in.h:1
234 msgid "Application Indicator"
235 msgstr "Toepassingsindicator"
236
237 #: ../plugins/indicator/indicator.plugin.in.h:2
238 msgid "Access clipboard history with an application indicator."
239 msgstr "Toegang tot de klembordgeschiedenis via een toepassingsindicator."
240
241 #: ../plugins/indicator/indicator.plugin.in.h:3
242 msgid "Copyright © 2011 Diodon Team"
243 msgstr "Copyright © 2011 Diodon-team"
244
245 #: ../unity-scope-diodon/clipboard.scope.in.in.h:1
246 msgid "Clipboard History"
247 msgstr "Klembordgeschiedenis"
248
249 #: ../unity-scope-diodon/clipboard.scope.in.in.h:2
250 msgid ""
251 "This is an Ubuntu search plugin that enables information from Diodon to be "
252 "searched and displayed in the Dash underneath the Clipboard header."
253 msgstr ""
254 "Dit is een Ubuntu-zoekplug-in waarmee naar informatie van Diodon gezocht kan "
255 "worden en die dan wordt getoond in de Snelzoeker onder de klembordkopregel."
256
257 #: ../unity-scope-diodon/clipboard.scope.in.in.h:3
258 msgid "Search clipboard"
259 msgstr "Klembord doorzoeken"
260
261 #: ../unity-scope-diodon/clipboard.scope.in.in.h:4
262 #: ../unity-scope-diodon/unity-scope-diodon.vala:79
263 #: ../unity-scope-diodon/unity-scope-diodon.vala:104
264 msgid "Text"
265 msgstr "Tekst"
266
267 #: ../unity-scope-diodon/clipboard.scope.in.in.h:5
268 #: ../unity-scope-diodon/unity-scope-diodon.vala:84
269 #: ../unity-scope-diodon/unity-scope-diodon.vala:105
270 msgid "Files"
271 msgstr "Bestanden"
272
273 #: ../unity-scope-diodon/clipboard.scope.in.in.h:6
274 #: ../unity-scope-diodon/unity-scope-diodon.vala:89
275 #: ../unity-scope-diodon/unity-scope-diodon.vala:106
276 msgid "Images"
277 msgstr "Afbeeldingen"
278
279 #: ../unity-scope-diodon/clipboard.scope.in.in.h:7
280 #: ../unity-scope-diodon/unity-scope-diodon.vala:101
281 msgid "Category"
282 msgstr "Categorie"
283
284 #: ../unity-scope-diodon/clipboard.scope.in.in.h:8
285 msgid "Text;Files;Images"
286 msgstr "Tekst;Bestanden;Afbeeldingen"
287
288 #: ../unity-scope-diodon/clipboard.scope.in.in.h:9
289 msgid "Last 24 hours;Last 7 days;Last 30 days;Last year;"
290 msgstr "Laatste 24 uur;Laatste 7 dagen;Laatste 30 dagen;Laatste jaar;"
291
292 #: ../unity-scope-diodon/unity-scope-diodon.vala:45
293 msgid "Search Clipboard"
294 msgstr "Klembord doorzoeken"
295
296 #: ../unity-scope-diodon/unity-scope-diodon.vala:110
297 #: ../unity-scope-diodon/unity-scope-diodon.vala:231
298 msgid "Date copied"
299 msgstr "Kopiedatum"
300
301 #: ../unity-scope-diodon/unity-scope-diodon.vala:112
302 msgid "Last 24 hours"
303 msgstr "Laatste 24 uur"
304
305 #: ../unity-scope-diodon/unity-scope-diodon.vala:113
306 msgid "Last 7 days"
307 msgstr "Laatste 7 dagen"
308
309 #: ../unity-scope-diodon/unity-scope-diodon.vala:114
310 msgid "Last 30 days"
311 msgstr "Laatste 30 dagen"
312
313 #: ../unity-scope-diodon/unity-scope-diodon.vala:115
314 msgid "Last year"
315 msgstr "Laatste jaar"
316
317 #: ../unity-scope-diodon/unity-scope-diodon.vala:216
318 msgid "Paste"
319 msgstr "Plakken"
320
321 #: ../unity-scope-diodon/unity-scope-diodon.vala:224
322 msgid "Origin"
323 msgstr "Vindplaats:"
0 # Polish translation for diodon
1 # Copyright (c) 2013 Rosetta Contributors and Canonical Ltd 2013
2 # This file is distributed under the same license as the diodon package.
3 # FIRST AUTHOR <EMAIL@ADDRESS>, 2013.
4 #
5 msgid ""
6 msgstr ""
7 "Project-Id-Version: diodon\n"
8 "Report-Msgid-Bugs-To: \n"
9 "POT-Creation-Date: 2017-06-05 14:18+0200\n"
10 "PO-Revision-Date: 2014-03-09 07:57+0000\n"
11 "Last-Translator: Michał Olber <michal.olber@osworld.pl>\n"
12 "Language-Team: Polish <pl@li.org>\n"
13 "MIME-Version: 1.0\n"
14 "Content-Type: text/plain; charset=UTF-8\n"
15 "Content-Transfer-Encoding: 8bit\n"
16 "X-Launchpad-Export-Date: 2017-06-06 05:55+0000\n"
17 "X-Generator: Launchpad (build 18399)\n"
18 "Language: pl\n"
19
20 #: ../data/diodon.desktop.in.h:1
21 msgid "Clipboard Manager"
22 msgstr "Menadżer Schowka"
23
24 #: ../data/diodon.desktop.in.h:2
25 msgid "GTK+ Clipboard Manager"
26 msgstr "Menadżer schowka GTK+"
27
28 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:1
29 msgid "Use clipboard (Ctrl+C)"
30 msgstr "Użyj schowka (Ctrl+C)"
31
32 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:2
33 #: ../data/preferences.ui.h:3
34 msgid ""
35 "Adds content which is copied to the clipboard with e.g. Ctrl + C to the "
36 "clipboard history."
37 msgstr ""
38
39 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:3
40 msgid "Use primary selection"
41 msgstr "Używaj podstawowego zaznaczenia"
42
43 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:4
44 #: ../data/preferences.ui.h:5
45 msgid ""
46 "Adds the primary selection (an area of the screen which is selected with the "
47 "mouse) to the clipboard history. Enabling will start process which "
48 "continually checks what is selected. This might discharge your battery "
49 "quicker."
50 msgstr ""
51
52 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:5
53 msgid "Add images to clipboard history"
54 msgstr ""
55
56 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:6
57 #: ../data/preferences.ui.h:7
58 msgid ""
59 "Add images copied to clipboard to clipboard history (e.g. when you right "
60 "click on an image in your browser and choose copy image). Enabling this "
61 "option will increase memory consumption. Images already added to clipboard "
62 "history will remain even when disabled."
63 msgstr ""
64
65 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:7
66 msgid "Synchronize clipboards"
67 msgstr "Synchronizuj schowki"
68
69 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:8
70 #: ../data/preferences.ui.h:11
71 msgid ""
72 "Synchronizes the selection (an area of the screen which is selected with the "
73 "mouse) and the clipboard so that anything in the selection is immediately "
74 "available in the clipboard and vice versa e.g. for pasting with Ctrl + V and "
75 "the middle mouse button."
76 msgstr ""
77 "Synchronizuj zaznaczony obszar (obszar na ekranie, który jest zaznaczony "
78 "przy pomocy myszy) i schowek, dzięki czemu wszystko w tym obszarze jest "
79 "natychmiast dostępne w schowku systemowym i odwrotnie."
80
81 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:9
82 msgid "Keep clipboard content"
83 msgstr "Zachowaj zawartość schowka systemowego"
84
85 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:10
86 #: ../data/preferences.ui.h:9
87 msgid ""
88 "Prevents an empty clipboard. For instance when an application exits, the "
89 "clipboard would usually be emptied."
90 msgstr ""
91
92 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:11
93 msgid "Automatically paste selected item"
94 msgstr "Wkleja automatycznie zaznaczone wpisy"
95
96 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:12
97 #: ../data/preferences.ui.h:13
98 msgid ""
99 "Automatically paste selected item instead of just copying it to the "
100 "clipboard."
101 msgstr ""
102 "Wkleja automatycznie zaznaczone wpisy, zamiast je tylko kopiować do schowka"
103
104 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:13
105 msgid "Number of recent clipboard items"
106 msgstr ""
107
108 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:14
109 msgid "Number of recent clipboard items shown in clipboard menu."
110 msgstr ""
111
112 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:15
113 msgid "Clipboard content filter pattern"
114 msgstr ""
115
116 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:16
117 msgid ""
118 "Regex filter pattern whereas all clipboard items matching this pattern will "
119 "be filtered and not added to clipboard history."
120 msgstr ""
121
122 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:17
123 msgid "Lookup dictionary for application using different paste keybindings"
124 msgstr ""
125
126 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:18
127 msgid ""
128 "A lookup dictionary for applications using different paste keybindings than "
129 "Ctrl + V. Pattern of each string in this array is path-of-app|keybinding"
130 msgstr ""
131
132 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:19
133 msgid "Active plugins"
134 msgstr "Aktywne wtyczki"
135
136 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:20
137 msgid "List of active plugins."
138 msgstr "Lista aktywnych wtyczek"
139
140 #: ../data/preferences.ui.h:1
141 msgid "Diodon Preferences"
142 msgstr "Właściwości programu"
143
144 #: ../data/preferences.ui.h:2
145 msgid "_Use clipboard (Ctrl+C)"
146 msgstr "Używaj _schowka systemowego"
147
148 #: ../data/preferences.ui.h:4
149 msgid "Use _primary selection"
150 msgstr "Używaj _podstawowego zaznaczenia"
151
152 #: ../data/preferences.ui.h:6
153 msgid "Add _images to clipboard history"
154 msgstr ""
155
156 #: ../data/preferences.ui.h:8
157 msgid "_Keep clipboard content"
158 msgstr "_Zachowaj zawartość schowka"
159
160 #: ../data/preferences.ui.h:10
161 msgid "S_ynchronize clipboards"
162 msgstr "S_ynchronizuj schowki"
163
164 #: ../data/preferences.ui.h:12
165 msgid "_Automatically paste selected item"
166 msgstr "Wkleja automatycznie zaznaczony wpis"
167
168 #: ../data/preferences.ui.h:14
169 msgid "Number of recent clipboard items to be shown in clipboard menu."
170 msgstr ""
171
172 #: ../data/preferences.ui.h:15
173 msgid "Number of recent items"
174 msgstr ""
175
176 #: ../data/preferences.ui.h:16 ../unity-scope-diodon/unity-scope-diodon.vala:75
177 msgid "Clipboard"
178 msgstr "Schowek"
179
180 #: ../data/preferences.ui.h:17
181 msgid ""
182 "Please register custom shortcut with\n"
183 "your desktop environment.\n"
184 "Use /usr/bin/diodon as command."
185 msgstr ""
186
187 #: ../data/preferences.ui.h:20
188 msgid "More information"
189 msgstr ""
190
191 #: ../data/preferences.ui.h:21
192 msgid "Hotkeys"
193 msgstr ""
194
195 #: ../data/preferences.ui.h:22
196 msgid "Plugins"
197 msgstr "Wtyczki"
198
199 #: ../libdiodon/clipboard-menu.vala:46
200 msgid "<Empty>"
201 msgstr "<Pusty>"
202
203 #: ../libdiodon/clipboard-menu.vala:53
204 msgid "Privacy mode is enabled. No new items will be added to history!"
205 msgstr ""
206
207 #: ../plugins/indicator/indicator.plugin.in.h:1
208 msgid "Application Indicator"
209 msgstr "Application Indicator"
210
211 #: ../plugins/indicator/indicator.plugin.in.h:2
212 msgid "Access clipboard history with an application indicator."
213 msgstr "Dostęp do historii schowka z użyciem panelu aplikacji"
214
215 #: ../plugins/indicator/indicator.plugin.in.h:3
216 msgid "Copyright © 2011 Diodon Team"
217 msgstr "Prawa autorskie © 2011 Diodon Team"
218
219 #: ../unity-scope-diodon/clipboard.scope.in.in.h:1
220 msgid "Clipboard History"
221 msgstr ""
222
223 #: ../unity-scope-diodon/clipboard.scope.in.in.h:2
224 msgid ""
225 "This is an Ubuntu search plugin that enables information from Diodon to be "
226 "searched and displayed in the Dash underneath the Clipboard header."
227 msgstr ""
228
229 #: ../unity-scope-diodon/clipboard.scope.in.in.h:3
230 msgid "Search clipboard"
231 msgstr "Przeszukaj schowek systemowy"
232
233 #: ../unity-scope-diodon/clipboard.scope.in.in.h:4
234 #: ../unity-scope-diodon/unity-scope-diodon.vala:79
235 #: ../unity-scope-diodon/unity-scope-diodon.vala:104
236 msgid "Text"
237 msgstr ""
238
239 #: ../unity-scope-diodon/clipboard.scope.in.in.h:5
240 #: ../unity-scope-diodon/unity-scope-diodon.vala:84
241 #: ../unity-scope-diodon/unity-scope-diodon.vala:105
242 msgid "Files"
243 msgstr ""
244
245 #: ../unity-scope-diodon/clipboard.scope.in.in.h:6
246 #: ../unity-scope-diodon/unity-scope-diodon.vala:89
247 #: ../unity-scope-diodon/unity-scope-diodon.vala:106
248 msgid "Images"
249 msgstr ""
250
251 #: ../unity-scope-diodon/clipboard.scope.in.in.h:7
252 #: ../unity-scope-diodon/unity-scope-diodon.vala:101
253 msgid "Category"
254 msgstr ""
255
256 #: ../unity-scope-diodon/clipboard.scope.in.in.h:8
257 msgid "Text;Files;Images"
258 msgstr ""
259
260 #: ../unity-scope-diodon/clipboard.scope.in.in.h:9
261 msgid "Last 24 hours;Last 7 days;Last 30 days;Last year;"
262 msgstr ""
263
264 #: ../unity-scope-diodon/unity-scope-diodon.vala:45
265 msgid "Search Clipboard"
266 msgstr ""
267
268 #: ../unity-scope-diodon/unity-scope-diodon.vala:110
269 #: ../unity-scope-diodon/unity-scope-diodon.vala:231
270 msgid "Date copied"
271 msgstr ""
272
273 #: ../unity-scope-diodon/unity-scope-diodon.vala:112
274 msgid "Last 24 hours"
275 msgstr ""
276
277 #: ../unity-scope-diodon/unity-scope-diodon.vala:113
278 msgid "Last 7 days"
279 msgstr ""
280
281 #: ../unity-scope-diodon/unity-scope-diodon.vala:114
282 msgid "Last 30 days"
283 msgstr ""
284
285 #: ../unity-scope-diodon/unity-scope-diodon.vala:115
286 msgid "Last year"
287 msgstr ""
288
289 #: ../unity-scope-diodon/unity-scope-diodon.vala:216
290 msgid "Paste"
291 msgstr ""
292
293 #: ../unity-scope-diodon/unity-scope-diodon.vala:224
294 msgid "Origin"
295 msgstr ""
0 # Portuguese translation for diodon
1 # Copyright (c) 2014 Rosetta Contributors and Canonical Ltd 2014
2 # This file is distributed under the same license as the diodon package.
3 # FIRST AUTHOR <EMAIL@ADDRESS>, 2014.
4 #
5 msgid ""
6 msgstr ""
7 "Project-Id-Version: diodon\n"
8 "Report-Msgid-Bugs-To: \n"
9 "POT-Creation-Date: 2017-06-05 14:18+0200\n"
10 "PO-Revision-Date: 2014-05-22 17:26+0000\n"
11 "Last-Translator: Pedro Sardinha <Unknown>\n"
12 "Language-Team: Portuguese <pt@li.org>\n"
13 "MIME-Version: 1.0\n"
14 "Content-Type: text/plain; charset=UTF-8\n"
15 "Content-Transfer-Encoding: 8bit\n"
16 "X-Launchpad-Export-Date: 2017-06-06 05:55+0000\n"
17 "X-Generator: Launchpad (build 18399)\n"
18 "Language: pt\n"
19
20 #: ../data/diodon.desktop.in.h:1
21 msgid "Clipboard Manager"
22 msgstr "Gestor da Área de Transferência"
23
24 #: ../data/diodon.desktop.in.h:2
25 msgid "GTK+ Clipboard Manager"
26 msgstr "Gestor da Área de Transferência GTK+"
27
28 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:1
29 msgid "Use clipboard (Ctrl+C)"
30 msgstr "Usar a área de transferência (Ctrl+C)"
31
32 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:2
33 #: ../data/preferences.ui.h:3
34 msgid ""
35 "Adds content which is copied to the clipboard with e.g. Ctrl + C to the "
36 "clipboard history."
37 msgstr ""
38 "Adiciona à área de transferência conteúdo que é copiado com, p. e., Ctrl+C "
39 "ao seu histórico."
40
41 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:3
42 msgid "Use primary selection"
43 msgstr "Usar a selecção primária"
44
45 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:4
46 #: ../data/preferences.ui.h:5
47 msgid ""
48 "Adds the primary selection (an area of the screen which is selected with the "
49 "mouse) to the clipboard history. Enabling will start process which "
50 "continually checks what is selected. This might discharge your battery "
51 "quicker."
52 msgstr ""
53 "Adiciona a selecção primária (uma área do ecrã que é seleccionada com o "
54 "rato) ao histórico da área de transferência. Activar esta opção, iniciará o "
55 "processo que continuamente verifica o que é seleccionado. Isto pode acentuar "
56 "a descarga da bateria."
57
58 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:5
59 msgid "Add images to clipboard history"
60 msgstr "Adicionar imagens ao histórico da área de transferência"
61
62 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:6
63 #: ../data/preferences.ui.h:7
64 msgid ""
65 "Add images copied to clipboard to clipboard history (e.g. when you right "
66 "click on an image in your browser and choose copy image). Enabling this "
67 "option will increase memory consumption. Images already added to clipboard "
68 "history will remain even when disabled."
69 msgstr ""
70 "Adiciona imagens copiadas para a área de transferência ao seu histórico (p. "
71 "e., quando copia uma imagem a partir do seu navegador). Activar esta opção, "
72 "aumenta o consumo da memória. As imagens já no histórico, permanecerão mesmo "
73 "que desactive esta opção."
74
75 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:7
76 msgid "Synchronize clipboards"
77 msgstr "Sincronizar áreas de transferência"
78
79 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:8
80 #: ../data/preferences.ui.h:11
81 msgid ""
82 "Synchronizes the selection (an area of the screen which is selected with the "
83 "mouse) and the clipboard so that anything in the selection is immediately "
84 "available in the clipboard and vice versa e.g. for pasting with Ctrl + V and "
85 "the middle mouse button."
86 msgstr ""
87 "Sincroniza a selecção (uma área do ecrã que é seleccionada com o rato) e a "
88 "área de transferência, assim, qualquer elemento seleccionado, está "
89 "imediatamente acessível na área de transferência e vice versa. P. e., para "
90 "colar com Ctrl+V e o botão do meio do rato."
91
92 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:9
93 msgid "Keep clipboard content"
94 msgstr "Manter o conteúdo da área de transferência"
95
96 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:10
97 #: ../data/preferences.ui.h:9
98 msgid ""
99 "Prevents an empty clipboard. For instance when an application exits, the "
100 "clipboard would usually be emptied."
101 msgstr ""
102 "Previne a área de transferência vazia. P. e., quando uma aplicação é "
103 "fechada, normalmente a área de transferência é limpa."
104
105 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:11
106 msgid "Automatically paste selected item"
107 msgstr "Colar automaticamente o item seleccionado"
108
109 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:12
110 #: ../data/preferences.ui.h:13
111 msgid ""
112 "Automatically paste selected item instead of just copying it to the "
113 "clipboard."
114 msgstr ""
115 "Cola automaticamente o item seleccionado em vez de apenas o copiar para a "
116 "área de transferência."
117
118 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:13
119 msgid "Number of recent clipboard items"
120 msgstr "Número de itens recentes na área de transferência"
121
122 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:14
123 msgid "Number of recent clipboard items shown in clipboard menu."
124 msgstr "Número de itens recentes mostrados no menu da área de transferência."
125
126 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:15
127 msgid "Clipboard content filter pattern"
128 msgstr ""
129
130 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:16
131 msgid ""
132 "Regex filter pattern whereas all clipboard items matching this pattern will "
133 "be filtered and not added to clipboard history."
134 msgstr ""
135
136 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:17
137 msgid "Lookup dictionary for application using different paste keybindings"
138 msgstr ""
139
140 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:18
141 msgid ""
142 "A lookup dictionary for applications using different paste keybindings than "
143 "Ctrl + V. Pattern of each string in this array is path-of-app|keybinding"
144 msgstr ""
145
146 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:19
147 msgid "Active plugins"
148 msgstr "Extensões activas"
149
150 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:20
151 msgid "List of active plugins."
152 msgstr "Lista das extensões activas"
153
154 #: ../data/preferences.ui.h:1
155 msgid "Diodon Preferences"
156 msgstr "Preferências do Diodon"
157
158 #: ../data/preferences.ui.h:2
159 msgid "_Use clipboard (Ctrl+C)"
160 msgstr "_Utilizar a área de transferência"
161
162 #: ../data/preferences.ui.h:4
163 msgid "Use _primary selection"
164 msgstr "Utilizar a selecção _primária"
165
166 #: ../data/preferences.ui.h:6
167 msgid "Add _images to clipboard history"
168 msgstr "Adicionar _imagens ao histórico da área de transferência"
169
170 #: ../data/preferences.ui.h:8
171 msgid "_Keep clipboard content"
172 msgstr "_Manter o conteúdo da área de transferência"
173
174 #: ../data/preferences.ui.h:10
175 msgid "S_ynchronize clipboards"
176 msgstr "S_incronizar as áreas de transferência"
177
178 #: ../data/preferences.ui.h:12
179 msgid "_Automatically paste selected item"
180 msgstr "_Colar automaticamente o item seleccionado"
181
182 #: ../data/preferences.ui.h:14
183 msgid "Number of recent clipboard items to be shown in clipboard menu."
184 msgstr ""
185 "Número de itens recentes a serem mostrados no menu da área de transferência."
186
187 #: ../data/preferences.ui.h:15
188 msgid "Number of recent items"
189 msgstr "Número de itens recentes"
190
191 #: ../data/preferences.ui.h:16 ../unity-scope-diodon/unity-scope-diodon.vala:75
192 msgid "Clipboard"
193 msgstr "Área de Transferência"
194
195 #: ../data/preferences.ui.h:17
196 msgid ""
197 "Please register custom shortcut with\n"
198 "your desktop environment.\n"
199 "Use /usr/bin/diodon as command."
200 msgstr ""
201
202 #: ../data/preferences.ui.h:20
203 msgid "More information"
204 msgstr ""
205
206 #: ../data/preferences.ui.h:21
207 msgid "Hotkeys"
208 msgstr ""
209
210 #: ../data/preferences.ui.h:22
211 msgid "Plugins"
212 msgstr "Extensões"
213
214 #: ../libdiodon/clipboard-menu.vala:46
215 msgid "<Empty>"
216 msgstr "<Vazio>"
217
218 #: ../libdiodon/clipboard-menu.vala:53
219 msgid "Privacy mode is enabled. No new items will be added to history!"
220 msgstr ""
221
222 #: ../plugins/indicator/indicator.plugin.in.h:1
223 msgid "Application Indicator"
224 msgstr "Indicador da Aplicação"
225
226 #: ../plugins/indicator/indicator.plugin.in.h:2
227 msgid "Access clipboard history with an application indicator."
228 msgstr ""
229 "Aceder ao histórico da área de transferência pelo indicador da aplicação."
230
231 #: ../plugins/indicator/indicator.plugin.in.h:3
232 msgid "Copyright © 2011 Diodon Team"
233 msgstr "Direitos de Autor © 2011 Diodon Team"
234
235 #: ../unity-scope-diodon/clipboard.scope.in.in.h:1
236 msgid "Clipboard History"
237 msgstr "Histórico da Área de Transferência"
238
239 #: ../unity-scope-diodon/clipboard.scope.in.in.h:2
240 msgid ""
241 "This is an Ubuntu search plugin that enables information from Diodon to be "
242 "searched and displayed in the Dash underneath the Clipboard header."
243 msgstr ""
244
245 #: ../unity-scope-diodon/clipboard.scope.in.in.h:3
246 msgid "Search clipboard"
247 msgstr "Procurar na área de transferência"
248
249 #: ../unity-scope-diodon/clipboard.scope.in.in.h:4
250 #: ../unity-scope-diodon/unity-scope-diodon.vala:79
251 #: ../unity-scope-diodon/unity-scope-diodon.vala:104
252 msgid "Text"
253 msgstr "Texto"
254
255 #: ../unity-scope-diodon/clipboard.scope.in.in.h:5
256 #: ../unity-scope-diodon/unity-scope-diodon.vala:84
257 #: ../unity-scope-diodon/unity-scope-diodon.vala:105
258 msgid "Files"
259 msgstr "Ficheiros"
260
261 #: ../unity-scope-diodon/clipboard.scope.in.in.h:6
262 #: ../unity-scope-diodon/unity-scope-diodon.vala:89
263 #: ../unity-scope-diodon/unity-scope-diodon.vala:106
264 msgid "Images"
265 msgstr "Imagens"
266
267 #: ../unity-scope-diodon/clipboard.scope.in.in.h:7
268 #: ../unity-scope-diodon/unity-scope-diodon.vala:101
269 msgid "Category"
270 msgstr "Categori­a"
271
272 #: ../unity-scope-diodon/clipboard.scope.in.in.h:8
273 msgid "Text;Files;Images"
274 msgstr "Texto;Ficheiros;Imagens"
275
276 #: ../unity-scope-diodon/clipboard.scope.in.in.h:9
277 msgid "Last 24 hours;Last 7 days;Last 30 days;Last year;"
278 msgstr "Últimas 24 horas;Últimos 7 dias;Últimos 30 dias;Último ano;"
279
280 #: ../unity-scope-diodon/unity-scope-diodon.vala:45
281 msgid "Search Clipboard"
282 msgstr "Pesquisar na Área de Transferência"
283
284 #: ../unity-scope-diodon/unity-scope-diodon.vala:110
285 #: ../unity-scope-diodon/unity-scope-diodon.vala:231
286 msgid "Date copied"
287 msgstr "Data copiada"
288
289 #: ../unity-scope-diodon/unity-scope-diodon.vala:112
290 msgid "Last 24 hours"
291 msgstr "Últimas 24 horas"
292
293 #: ../unity-scope-diodon/unity-scope-diodon.vala:113
294 msgid "Last 7 days"
295 msgstr "Últimos 7 dias"
296
297 #: ../unity-scope-diodon/unity-scope-diodon.vala:114
298 msgid "Last 30 days"
299 msgstr "Últimos 30 dias"
300
301 #: ../unity-scope-diodon/unity-scope-diodon.vala:115
302 msgid "Last year"
303 msgstr "Último ano"
304
305 #: ../unity-scope-diodon/unity-scope-diodon.vala:216
306 msgid "Paste"
307 msgstr "Colar"
308
309 #: ../unity-scope-diodon/unity-scope-diodon.vala:224
310 msgid "Origin"
311 msgstr "Origem"
0 # Brazilian Portuguese translation for diodon
1 # Copyright (c) 2011 Rosetta Contributors and Canonical Ltd 2011
2 # This file is distributed under the same license as the diodon package.
3 # FIRST AUTHOR <EMAIL@ADDRESS>, 2011.
4 #
5 msgid ""
6 msgstr ""
7 "Project-Id-Version: diodon\n"
8 "Report-Msgid-Bugs-To: \n"
9 "POT-Creation-Date: 2017-06-05 14:18+0200\n"
10 "PO-Revision-Date: 2013-12-29 00:09+0000\n"
11 "Last-Translator: Oliver Sauder <os@esite.ch>\n"
12 "Language-Team: Brazilian Portuguese <pt_BR@li.org>\n"
13 "MIME-Version: 1.0\n"
14 "Content-Type: text/plain; charset=UTF-8\n"
15 "Content-Transfer-Encoding: 8bit\n"
16 "X-Launchpad-Export-Date: 2017-06-06 05:56+0000\n"
17 "X-Generator: Launchpad (build 18399)\n"
18 "Language: pt_BR\n"
19
20 #: ../data/diodon.desktop.in.h:1
21 msgid "Clipboard Manager"
22 msgstr "Gerenciador de área de transferência"
23
24 #: ../data/diodon.desktop.in.h:2
25 msgid "GTK+ Clipboard Manager"
26 msgstr "Gerenciador de área de transferência em GTK+"
27
28 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:1
29 msgid "Use clipboard (Ctrl+C)"
30 msgstr "Usar área de transferênica (Ctrl+C)"
31
32 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:2
33 #: ../data/preferences.ui.h:3
34 msgid ""
35 "Adds content which is copied to the clipboard with e.g. Ctrl + C to the "
36 "clipboard history."
37 msgstr ""
38
39 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:3
40 msgid "Use primary selection"
41 msgstr "Usar seleção primária"
42
43 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:4
44 #: ../data/preferences.ui.h:5
45 msgid ""
46 "Adds the primary selection (an area of the screen which is selected with the "
47 "mouse) to the clipboard history. Enabling will start process which "
48 "continually checks what is selected. This might discharge your battery "
49 "quicker."
50 msgstr ""
51
52 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:5
53 msgid "Add images to clipboard history"
54 msgstr ""
55
56 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:6
57 #: ../data/preferences.ui.h:7
58 msgid ""
59 "Add images copied to clipboard to clipboard history (e.g. when you right "
60 "click on an image in your browser and choose copy image). Enabling this "
61 "option will increase memory consumption. Images already added to clipboard "
62 "history will remain even when disabled."
63 msgstr ""
64
65 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:7
66 msgid "Synchronize clipboards"
67 msgstr "Sincronizar áreas de transferênica"
68
69 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:8
70 #: ../data/preferences.ui.h:11
71 msgid ""
72 "Synchronizes the selection (an area of the screen which is selected with the "
73 "mouse) and the clipboard so that anything in the selection is immediately "
74 "available in the clipboard and vice versa e.g. for pasting with Ctrl + V and "
75 "the middle mouse button."
76 msgstr ""
77 "Sincroniza a seleção (uma área da tela que foi selecionada com o mouse) e a "
78 "área de transferência para que tudo na seleção seja imediatamente disponível "
79 "na memória e vice versa."
80
81 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:9
82 msgid "Keep clipboard content"
83 msgstr "Manter o conteúdo da área de transferência."
84
85 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:10
86 #: ../data/preferences.ui.h:9
87 msgid ""
88 "Prevents an empty clipboard. For instance when an application exits, the "
89 "clipboard would usually be emptied."
90 msgstr ""
91 "Impede uma área de transferência vazia. Por exemplo, quando um aplicativo é "
92 "encerrado, a área de transferência normalmente seria esvaziado."
93
94 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:11
95 msgid "Automatically paste selected item"
96 msgstr "Cola o item selecionado automaticamente"
97
98 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:12
99 #: ../data/preferences.ui.h:13
100 msgid ""
101 "Automatically paste selected item instead of just copying it to the "
102 "clipboard."
103 msgstr ""
104 "Automaticamente cola o item selecionado ao invés de copiar para a área de "
105 "transferência."
106
107 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:13
108 msgid "Number of recent clipboard items"
109 msgstr ""
110
111 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:14
112 msgid "Number of recent clipboard items shown in clipboard menu."
113 msgstr ""
114
115 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:15
116 msgid "Clipboard content filter pattern"
117 msgstr ""
118
119 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:16
120 msgid ""
121 "Regex filter pattern whereas all clipboard items matching this pattern will "
122 "be filtered and not added to clipboard history."
123 msgstr ""
124
125 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:17
126 msgid "Lookup dictionary for application using different paste keybindings"
127 msgstr ""
128
129 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:18
130 msgid ""
131 "A lookup dictionary for applications using different paste keybindings than "
132 "Ctrl + V. Pattern of each string in this array is path-of-app|keybinding"
133 msgstr ""
134
135 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:19
136 msgid "Active plugins"
137 msgstr "Plug-ins ativos"
138
139 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:20
140 msgid "List of active plugins."
141 msgstr "Lista de plug-ins ativos"
142
143 #: ../data/preferences.ui.h:1
144 msgid "Diodon Preferences"
145 msgstr "Preferênciad do Diodon"
146
147 #: ../data/preferences.ui.h:2
148 msgid "_Use clipboard (Ctrl+C)"
149 msgstr "_Usar área de transferência (Ctrl+C)"
150
151 #: ../data/preferences.ui.h:4
152 msgid "Use _primary selection"
153 msgstr "Usar seleção _primária"
154
155 #: ../data/preferences.ui.h:6
156 msgid "Add _images to clipboard history"
157 msgstr ""
158
159 #: ../data/preferences.ui.h:8
160 msgid "_Keep clipboard content"
161 msgstr "_Manter conteúdo da área de transferência"
162
163 #: ../data/preferences.ui.h:10
164 msgid "S_ynchronize clipboards"
165 msgstr "S_incronizar áreas de transferência"
166
167 #: ../data/preferences.ui.h:12
168 msgid "_Automatically paste selected item"
169 msgstr "Colar _automaticamente item selecionado"
170
171 #: ../data/preferences.ui.h:14
172 msgid "Number of recent clipboard items to be shown in clipboard menu."
173 msgstr ""
174
175 #: ../data/preferences.ui.h:15
176 msgid "Number of recent items"
177 msgstr ""
178
179 #: ../data/preferences.ui.h:16 ../unity-scope-diodon/unity-scope-diodon.vala:75
180 msgid "Clipboard"
181 msgstr "Área de transferência"
182
183 #: ../data/preferences.ui.h:17
184 msgid ""
185 "Please register custom shortcut with\n"
186 "your desktop environment.\n"
187 "Use /usr/bin/diodon as command."
188 msgstr ""
189
190 #: ../data/preferences.ui.h:20
191 msgid "More information"
192 msgstr ""
193
194 #: ../data/preferences.ui.h:21
195 msgid "Hotkeys"
196 msgstr ""
197
198 #: ../data/preferences.ui.h:22
199 msgid "Plugins"
200 msgstr "Plug-ins"
201
202 #: ../libdiodon/clipboard-menu.vala:46
203 msgid "<Empty>"
204 msgstr "<Vazio>"
205
206 #: ../libdiodon/clipboard-menu.vala:53
207 msgid "Privacy mode is enabled. No new items will be added to history!"
208 msgstr ""
209
210 #: ../plugins/indicator/indicator.plugin.in.h:1
211 msgid "Application Indicator"
212 msgstr ""
213
214 #: ../plugins/indicator/indicator.plugin.in.h:2
215 msgid "Access clipboard history with an application indicator."
216 msgstr ""
217
218 #: ../plugins/indicator/indicator.plugin.in.h:3
219 msgid "Copyright © 2011 Diodon Team"
220 msgstr ""
221
222 #: ../unity-scope-diodon/clipboard.scope.in.in.h:1
223 msgid "Clipboard History"
224 msgstr ""
225
226 #: ../unity-scope-diodon/clipboard.scope.in.in.h:2
227 msgid ""
228 "This is an Ubuntu search plugin that enables information from Diodon to be "
229 "searched and displayed in the Dash underneath the Clipboard header."
230 msgstr ""
231
232 #: ../unity-scope-diodon/clipboard.scope.in.in.h:3
233 msgid "Search clipboard"
234 msgstr ""
235
236 #: ../unity-scope-diodon/clipboard.scope.in.in.h:4
237 #: ../unity-scope-diodon/unity-scope-diodon.vala:79
238 #: ../unity-scope-diodon/unity-scope-diodon.vala:104
239 msgid "Text"
240 msgstr ""
241
242 #: ../unity-scope-diodon/clipboard.scope.in.in.h:5
243 #: ../unity-scope-diodon/unity-scope-diodon.vala:84
244 #: ../unity-scope-diodon/unity-scope-diodon.vala:105
245 msgid "Files"
246 msgstr ""
247
248 #: ../unity-scope-diodon/clipboard.scope.in.in.h:6
249 #: ../unity-scope-diodon/unity-scope-diodon.vala:89
250 #: ../unity-scope-diodon/unity-scope-diodon.vala:106
251 msgid "Images"
252 msgstr ""
253
254 #: ../unity-scope-diodon/clipboard.scope.in.in.h:7
255 #: ../unity-scope-diodon/unity-scope-diodon.vala:101
256 msgid "Category"
257 msgstr ""
258
259 #: ../unity-scope-diodon/clipboard.scope.in.in.h:8
260 msgid "Text;Files;Images"
261 msgstr ""
262
263 #: ../unity-scope-diodon/clipboard.scope.in.in.h:9
264 msgid "Last 24 hours;Last 7 days;Last 30 days;Last year;"
265 msgstr ""
266
267 #: ../unity-scope-diodon/unity-scope-diodon.vala:45
268 msgid "Search Clipboard"
269 msgstr ""
270
271 #: ../unity-scope-diodon/unity-scope-diodon.vala:110
272 #: ../unity-scope-diodon/unity-scope-diodon.vala:231
273 msgid "Date copied"
274 msgstr ""
275
276 #: ../unity-scope-diodon/unity-scope-diodon.vala:112
277 msgid "Last 24 hours"
278 msgstr ""
279
280 #: ../unity-scope-diodon/unity-scope-diodon.vala:113
281 msgid "Last 7 days"
282 msgstr ""
283
284 #: ../unity-scope-diodon/unity-scope-diodon.vala:114
285 msgid "Last 30 days"
286 msgstr ""
287
288 #: ../unity-scope-diodon/unity-scope-diodon.vala:115
289 msgid "Last year"
290 msgstr ""
291
292 #: ../unity-scope-diodon/unity-scope-diodon.vala:216
293 msgid "Paste"
294 msgstr ""
295
296 #: ../unity-scope-diodon/unity-scope-diodon.vala:224
297 msgid "Origin"
298 msgstr ""
0 # Romanian translation for diodon
1 # Copyright (c) 2014 Rosetta Contributors and Canonical Ltd 2014
2 # This file is distributed under the same license as the diodon package.
3 # FIRST AUTHOR <EMAIL@ADDRESS>, 2014.
4 #
5 msgid ""
6 msgstr ""
7 "Project-Id-Version: diodon\n"
8 "Report-Msgid-Bugs-To: \n"
9 "POT-Creation-Date: 2017-06-05 14:18+0200\n"
10 "PO-Revision-Date: 2014-04-22 06:04+0000\n"
11 "Last-Translator: Marian Vasile <marianvasile1972@gmail.com>\n"
12 "Language-Team: Romanian <ro@li.org>\n"
13 "MIME-Version: 1.0\n"
14 "Content-Type: text/plain; charset=UTF-8\n"
15 "Content-Transfer-Encoding: 8bit\n"
16 "X-Launchpad-Export-Date: 2017-06-06 05:56+0000\n"
17 "X-Generator: Launchpad (build 18399)\n"
18 "Language: ro\n"
19
20 #: ../data/diodon.desktop.in.h:1
21 msgid "Clipboard Manager"
22 msgstr "Administrator clipboard"
23
24 #: ../data/diodon.desktop.in.h:2
25 msgid "GTK+ Clipboard Manager"
26 msgstr "Administrator clipboard pentru mediul GTK+"
27
28 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:1
29 msgid "Use clipboard (Ctrl+C)"
30 msgstr "Utilizează clipboard (Ctrl+C)"
31
32 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:2
33 #: ../data/preferences.ui.h:3
34 msgid ""
35 "Adds content which is copied to the clipboard with e.g. Ctrl + C to the "
36 "clipboard history."
37 msgstr ""
38 "Adaugă conținutul care este copiat în clipboard cu de ex. Ctrl + C la "
39 "istoricul acțiunilor."
40
41 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:3
42 msgid "Use primary selection"
43 msgstr "Utilizează selecția primară"
44
45 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:4
46 #: ../data/preferences.ui.h:5
47 msgid ""
48 "Adds the primary selection (an area of the screen which is selected with the "
49 "mouse) to the clipboard history. Enabling will start process which "
50 "continually checks what is selected. This might discharge your battery "
51 "quicker."
52 msgstr ""
53 "Adaugă selecția primară (o zonă a ecranului care este selectată cu mouse-ul) "
54 "la istoricul clipboard-ului. La activare se va porni un proces care verifică "
55 "continuu dacă există ceva selectat. Din această cauză este posibil ca "
56 "bateria să se descarce mai repede."
57
58 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:5
59 msgid "Add images to clipboard history"
60 msgstr "Adaugă imagini la istoricul clipboard-ului."
61
62 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:6
63 #: ../data/preferences.ui.h:7
64 msgid ""
65 "Add images copied to clipboard to clipboard history (e.g. when you right "
66 "click on an image in your browser and choose copy image). Enabling this "
67 "option will increase memory consumption. Images already added to clipboard "
68 "history will remain even when disabled."
69 msgstr ""
70 "Adaugă imaginile copiate în clipboard la istoricul acțiunilor (de ex. la "
71 "efectuarea unui clic dreapta pe o imagine în navigatorul de Internet urmată "
72 "de selectarea opțiunii copiere imagine). La activarea acestei opțiuni crește "
73 "consumul de memorie. Imaginile adăugate la istoricul acțiunilor vor rămâne "
74 "și după dezactivarea funcției."
75
76 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:7
77 msgid "Synchronize clipboards"
78 msgstr "Sincronizează clipboard-urile"
79
80 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:8
81 #: ../data/preferences.ui.h:11
82 msgid ""
83 "Synchronizes the selection (an area of the screen which is selected with the "
84 "mouse) and the clipboard so that anything in the selection is immediately "
85 "available in the clipboard and vice versa e.g. for pasting with Ctrl + V and "
86 "the middle mouse button."
87 msgstr ""
88 "Sincronizează selecția (o zonă a ecranului care este selectată cu mouse-ul) "
89 "și clipboard-ul astfel încât orice lucru din selecție este disponibil "
90 "imediat în clipboard și vice versa, de exemplu lipirea cu Ctrl + V și "
91 "butonul din mijloc al mouse-ului."
92
93 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:9
94 msgid "Keep clipboard content"
95 msgstr "Păstrează conținutul clipboard-ului"
96
97 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:10
98 #: ../data/preferences.ui.h:9
99 msgid ""
100 "Prevents an empty clipboard. For instance when an application exits, the "
101 "clipboard would usually be emptied."
102 msgstr ""
103 "Nu permite un clipboard golit. De exemplu la închiderea unei aplicații, de "
104 "regulă clipboard-ul este golit."
105
106 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:11
107 msgid "Automatically paste selected item"
108 msgstr "Lipește automat elementul selectat"
109
110 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:12
111 #: ../data/preferences.ui.h:13
112 msgid ""
113 "Automatically paste selected item instead of just copying it to the "
114 "clipboard."
115 msgstr "Lipește automat elementul selectat în loc de a-l copia în clipboard."
116
117 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:13
118 msgid "Number of recent clipboard items"
119 msgstr "Numărul elementelor recente din clipboard"
120
121 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:14
122 msgid "Number of recent clipboard items shown in clipboard menu."
123 msgstr ""
124 "Numărul elementelor recente din clipboard arătat în meniul clipboard-ului."
125
126 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:15
127 msgid "Clipboard content filter pattern"
128 msgstr ""
129
130 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:16
131 msgid ""
132 "Regex filter pattern whereas all clipboard items matching this pattern will "
133 "be filtered and not added to clipboard history."
134 msgstr ""
135
136 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:17
137 msgid "Lookup dictionary for application using different paste keybindings"
138 msgstr ""
139
140 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:18
141 msgid ""
142 "A lookup dictionary for applications using different paste keybindings than "
143 "Ctrl + V. Pattern of each string in this array is path-of-app|keybinding"
144 msgstr ""
145
146 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:19
147 msgid "Active plugins"
148 msgstr "Module active"
149
150 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:20
151 msgid "List of active plugins."
152 msgstr "Lista modulelor active."
153
154 #: ../data/preferences.ui.h:1
155 msgid "Diodon Preferences"
156 msgstr "Preferințe Diodon"
157
158 #: ../data/preferences.ui.h:2
159 msgid "_Use clipboard (Ctrl+C)"
160 msgstr "_Utilizează clipboard-ul"
161
162 #: ../data/preferences.ui.h:4
163 msgid "Use _primary selection"
164 msgstr "Utilizează selecția _primară"
165
166 #: ../data/preferences.ui.h:6
167 msgid "Add _images to clipboard history"
168 msgstr "Adaugă _imagini la istoricul clipboard-ului"
169
170 #: ../data/preferences.ui.h:8
171 msgid "_Keep clipboard content"
172 msgstr "_Păstrează conținutul clipboard-ului"
173
174 #: ../data/preferences.ui.h:10
175 msgid "S_ynchronize clipboards"
176 msgstr "Sincroni_zează clipboard-urile"
177
178 #: ../data/preferences.ui.h:12
179 msgid "_Automatically paste selected item"
180 msgstr "Lipește _automat elementul selectat"
181
182 #: ../data/preferences.ui.h:14
183 msgid "Number of recent clipboard items to be shown in clipboard menu."
184 msgstr "Numărul elementelor recente arătate în meniul clipboard-ului."
185
186 #: ../data/preferences.ui.h:15
187 msgid "Number of recent items"
188 msgstr "Numărul elementelor recente"
189
190 #: ../data/preferences.ui.h:16 ../unity-scope-diodon/unity-scope-diodon.vala:75
191 msgid "Clipboard"
192 msgstr "Clipboard"
193
194 #: ../data/preferences.ui.h:17
195 msgid ""
196 "Please register custom shortcut with\n"
197 "your desktop environment.\n"
198 "Use /usr/bin/diodon as command."
199 msgstr ""
200
201 #: ../data/preferences.ui.h:20
202 msgid "More information"
203 msgstr ""
204
205 #: ../data/preferences.ui.h:21
206 msgid "Hotkeys"
207 msgstr ""
208
209 #: ../data/preferences.ui.h:22
210 msgid "Plugins"
211 msgstr "Module"
212
213 #: ../libdiodon/clipboard-menu.vala:46
214 msgid "<Empty>"
215 msgstr "<Gol>"
216
217 #: ../libdiodon/clipboard-menu.vala:53
218 msgid "Privacy mode is enabled. No new items will be added to history!"
219 msgstr ""
220
221 #: ../plugins/indicator/indicator.plugin.in.h:1
222 msgid "Application Indicator"
223 msgstr "Indicator aplicație"
224
225 #: ../plugins/indicator/indicator.plugin.in.h:2
226 msgid "Access clipboard history with an application indicator."
227 msgstr "Accesați istoricul clipboard-ului printr-un indicator al aplicației."
228
229 #: ../plugins/indicator/indicator.plugin.in.h:3
230 msgid "Copyright © 2011 Diodon Team"
231 msgstr "Drepturi de autor © 2011 Diodon Team"
232
233 #: ../unity-scope-diodon/clipboard.scope.in.in.h:1
234 msgid "Clipboard History"
235 msgstr "Istoric clipboard"
236
237 #: ../unity-scope-diodon/clipboard.scope.in.in.h:2
238 msgid ""
239 "This is an Ubuntu search plugin that enables information from Diodon to be "
240 "searched and displayed in the Dash underneath the Clipboard header."
241 msgstr ""
242 "Acesta este un modul de căutare Ubuntu care permite căutarea de informații "
243 "în Diodon și afișarea rezultatelor în Panoul principal, în cuprinsul "
244 "antetului Clipboard."
245
246 #: ../unity-scope-diodon/clipboard.scope.in.in.h:3
247 msgid "Search clipboard"
248 msgstr "Caută în clipboard"
249
250 #: ../unity-scope-diodon/clipboard.scope.in.in.h:4
251 #: ../unity-scope-diodon/unity-scope-diodon.vala:79
252 #: ../unity-scope-diodon/unity-scope-diodon.vala:104
253 msgid "Text"
254 msgstr "Text"
255
256 #: ../unity-scope-diodon/clipboard.scope.in.in.h:5
257 #: ../unity-scope-diodon/unity-scope-diodon.vala:84
258 #: ../unity-scope-diodon/unity-scope-diodon.vala:105
259 msgid "Files"
260 msgstr "Fișiere"
261
262 #: ../unity-scope-diodon/clipboard.scope.in.in.h:6
263 #: ../unity-scope-diodon/unity-scope-diodon.vala:89
264 #: ../unity-scope-diodon/unity-scope-diodon.vala:106
265 msgid "Images"
266 msgstr "Imagini"
267
268 #: ../unity-scope-diodon/clipboard.scope.in.in.h:7
269 #: ../unity-scope-diodon/unity-scope-diodon.vala:101
270 msgid "Category"
271 msgstr "Categorie"
272
273 #: ../unity-scope-diodon/clipboard.scope.in.in.h:8
274 msgid "Text;Files;Images"
275 msgstr "Text;Fișiere;Imagini"
276
277 #: ../unity-scope-diodon/clipboard.scope.in.in.h:9
278 msgid "Last 24 hours;Last 7 days;Last 30 days;Last year;"
279 msgstr "Ultimele 24 de ore;Ultimele 7 zile;Ultimele 30 de zile;Ultimul an;"
280
281 #: ../unity-scope-diodon/unity-scope-diodon.vala:45
282 msgid "Search Clipboard"
283 msgstr "Caută în clipboard"
284
285 #: ../unity-scope-diodon/unity-scope-diodon.vala:110
286 #: ../unity-scope-diodon/unity-scope-diodon.vala:231
287 msgid "Date copied"
288 msgstr "Data copierii"
289
290 #: ../unity-scope-diodon/unity-scope-diodon.vala:112
291 msgid "Last 24 hours"
292 msgstr "Ultimele 24 de ore"
293
294 #: ../unity-scope-diodon/unity-scope-diodon.vala:113
295 msgid "Last 7 days"
296 msgstr "Ultimele 7 zile"
297
298 #: ../unity-scope-diodon/unity-scope-diodon.vala:114
299 msgid "Last 30 days"
300 msgstr "Ultimele 30 de zile"
301
302 #: ../unity-scope-diodon/unity-scope-diodon.vala:115
303 msgid "Last year"
304 msgstr "Ultimul an"
305
306 #: ../unity-scope-diodon/unity-scope-diodon.vala:216
307 msgid "Paste"
308 msgstr "Lipire"
309
310 #: ../unity-scope-diodon/unity-scope-diodon.vala:224
311 msgid "Origin"
312 msgstr "Origine"
0 # Russian translation for diodon
1 # Copyright (c) 2011 Rosetta Contributors and Canonical Ltd 2011
2 # This file is distributed under the same license as the diodon package.
3 # FIRST AUTHOR <EMAIL@ADDRESS>, 2011.
4 #
5 msgid ""
6 msgstr ""
7 "Project-Id-Version: diodon\n"
8 "Report-Msgid-Bugs-To: \n"
9 "POT-Creation-Date: 2017-06-05 14:18+0200\n"
10 "PO-Revision-Date: 2017-08-09 21:07+0000\n"
11 "Last-Translator: Volos_86 <Unknown>\n"
12 "Language-Team: Russian <ru@li.org>\n"
13 "MIME-Version: 1.0\n"
14 "Content-Type: text/plain; charset=UTF-8\n"
15 "Content-Transfer-Encoding: 8bit\n"
16 "X-Launchpad-Export-Date: 2017-08-10 05:49+0000\n"
17 "X-Generator: Launchpad (build 18446)\n"
18 "Language: ru\n"
19
20 #: ../data/diodon.desktop.in.h:1
21 msgid "Clipboard Manager"
22 msgstr "Менеджер буфера обмена"
23
24 #: ../data/diodon.desktop.in.h:2
25 msgid "GTK+ Clipboard Manager"
26 msgstr "Менеджер буфера обмена на базе GTK+"
27
28 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:1
29 msgid "Use clipboard (Ctrl+C)"
30 msgstr "Использовать буфер обмена (Ctrl+C)"
31
32 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:2
33 #: ../data/preferences.ui.h:3
34 msgid ""
35 "Adds content which is copied to the clipboard with e.g. Ctrl + C to the "
36 "clipboard history."
37 msgstr "Хранить в истории данные из буфера обмена (Ctrl+C)"
38
39 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:3
40 msgid "Use primary selection"
41 msgstr "Использовать выделение мышкой"
42
43 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:4
44 #: ../data/preferences.ui.h:5
45 msgid ""
46 "Adds the primary selection (an area of the screen which is selected with the "
47 "mouse) to the clipboard history. Enabling will start process which "
48 "continually checks what is selected. This might discharge your battery "
49 "quicker."
50 msgstr ""
51 "Добавляет первичное выделение (область экрана выделанный с помощью мыши) в "
52 "историю буфера обмена. Включение запустит процесс который постоянно "
53 "проверяет, что выбрано. Это может заставить вашу батарею разряжаться быстрее."
54
55 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:5
56 msgid "Add images to clipboard history"
57 msgstr "Использовать изображения"
58
59 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:6
60 #: ../data/preferences.ui.h:7
61 msgid ""
62 "Add images copied to clipboard to clipboard history (e.g. when you right "
63 "click on an image in your browser and choose copy image). Enabling this "
64 "option will increase memory consumption. Images already added to clipboard "
65 "history will remain even when disabled."
66 msgstr ""
67 "Добавить в историю буфера обмена изображения, скопированные в буфер обмена "
68 "(например щелчком правой кнопкой на изображении в браузере и выбором "
69 "«Скопировать изображение»). Активация этого параметра увеличит потребление "
70 "памяти. Изображения, уже добавленные в историю буфера обмена, останутся там, "
71 "даже если вы отключите этот параметр."
72
73 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:7
74 msgid "Synchronize clipboards"
75 msgstr "Синхронизировать буферы обмена"
76
77 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:8
78 #: ../data/preferences.ui.h:11
79 msgid ""
80 "Synchronizes the selection (an area of the screen which is selected with the "
81 "mouse) and the clipboard so that anything in the selection is immediately "
82 "available in the clipboard and vice versa e.g. for pasting with Ctrl + V and "
83 "the middle mouse button."
84 msgstr ""
85 "Синхронизирует буфер выделения и буфер обмена, так что любой выделенный "
86 "текст становится доступным для вставки через Ctrl+V и наоборот."
87
88 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:9
89 msgid "Keep clipboard content"
90 msgstr "Хранить содержимое буфера обмена"
91
92 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:10
93 #: ../data/preferences.ui.h:9
94 msgid ""
95 "Prevents an empty clipboard. For instance when an application exits, the "
96 "clipboard would usually be emptied."
97 msgstr ""
98 "Предотвращает очистку буфера обмена. Обычно, когда приложение закрывается, "
99 "оно очищает за собой буфер обмена."
100
101 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:11
102 msgid "Automatically paste selected item"
103 msgstr "Автоматически вставлять выделенный объект"
104
105 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:12
106 #: ../data/preferences.ui.h:13
107 msgid ""
108 "Automatically paste selected item instead of just copying it to the "
109 "clipboard."
110 msgstr ""
111 "Автоматически вставлять выделенный объект вместо копирования в буфер обмена."
112
113 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:13
114 msgid "Number of recent clipboard items"
115 msgstr "Размер истории обмена"
116
117 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:14
118 msgid "Number of recent clipboard items shown in clipboard menu."
119 msgstr "Количество элементов буфера обмена для отображения в меню истории"
120
121 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:15
122 msgid "Clipboard content filter pattern"
123 msgstr "Паттерн фильтрации содержимого буфера обмена."
124
125 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:16
126 msgid ""
127 "Regex filter pattern whereas all clipboard items matching this pattern will "
128 "be filtered and not added to clipboard history."
129 msgstr ""
130 "Фильтр на основе Regex-паттерна. Все элементы которые соответствуют этому "
131 "паттерну будут отфильтрованы и не добавлены в историю буфера обмена."
132
133 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:17
134 msgid "Lookup dictionary for application using different paste keybindings"
135 msgstr "Lookup dictionary for application using different paste keybindings"
136
137 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:18
138 msgid ""
139 "A lookup dictionary for applications using different paste keybindings than "
140 "Ctrl + V. Pattern of each string in this array is path-of-app|keybinding"
141 msgstr ""
142 "A lookup dictionary for applications using different paste keybindings than "
143 "Ctrl + V. Pattern of each string in this array is path-of-app|keybinding"
144
145 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:19
146 msgid "Active plugins"
147 msgstr "Активные модули"
148
149 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:20
150 msgid "List of active plugins."
151 msgstr "Список активных модулей"
152
153 #: ../data/preferences.ui.h:1
154 msgid "Diodon Preferences"
155 msgstr "Настройка Diodon"
156
157 #: ../data/preferences.ui.h:2
158 msgid "_Use clipboard (Ctrl+C)"
159 msgstr "Использовать _буфер обмена (Ctrl+C)"
160
161 #: ../data/preferences.ui.h:4
162 msgid "Use _primary selection"
163 msgstr "Использовать выделение _мышкой"
164
165 #: ../data/preferences.ui.h:6
166 msgid "Add _images to clipboard history"
167 msgstr "Добавлять _изображения в историю буфера обмена"
168
169 #: ../data/preferences.ui.h:8
170 msgid "_Keep clipboard content"
171 msgstr "_Хранить содержимое буфера обмена"
172
173 #: ../data/preferences.ui.h:10
174 msgid "S_ynchronize clipboards"
175 msgstr "_Синхронизировать буферы обмена"
176
177 #: ../data/preferences.ui.h:12
178 msgid "_Automatically paste selected item"
179 msgstr "_Автоматически вставлять выделенный объект"
180
181 #: ../data/preferences.ui.h:14
182 msgid "Number of recent clipboard items to be shown in clipboard menu."
183 msgstr ""
184 "Количество последних объектов буфера обмена, отображаемое в меню буфера "
185 "обмена."
186
187 #: ../data/preferences.ui.h:15
188 msgid "Number of recent items"
189 msgstr "Количество последних объектов"
190
191 #: ../data/preferences.ui.h:16 ../unity-scope-diodon/unity-scope-diodon.vala:75
192 msgid "Clipboard"
193 msgstr "Буфер обмена"
194
195 #: ../data/preferences.ui.h:17
196 msgid ""
197 "Please register custom shortcut with\n"
198 "your desktop environment.\n"
199 "Use /usr/bin/diodon as command."
200 msgstr ""
201 "Пожалуйста, зарегистрируйте сочетание клавиш в своём окружении рабочего "
202 "стола. Используйте путь /usr/bin/diodon как команду запуска."
203
204 #: ../data/preferences.ui.h:20
205 msgid "More information"
206 msgstr "Подробнее"
207
208 #: ../data/preferences.ui.h:21
209 msgid "Hotkeys"
210 msgstr "Комбинации клавиш"
211
212 #: ../data/preferences.ui.h:22
213 msgid "Plugins"
214 msgstr "Модули"
215
216 #: ../libdiodon/clipboard-menu.vala:46
217 msgid "<Empty>"
218 msgstr "<Пусто>"
219
220 #: ../libdiodon/clipboard-menu.vala:53
221 msgid "Privacy mode is enabled. No new items will be added to history!"
222 msgstr "Приватный режим включен."
223
224 #: ../plugins/indicator/indicator.plugin.in.h:1
225 msgid "Application Indicator"
226 msgstr "Приложение-индикатор"
227
228 #: ../plugins/indicator/indicator.plugin.in.h:2
229 msgid "Access clipboard history with an application indicator."
230 msgstr ""
231 "Доступ к журналу событий буфера обмена с помощью приложения индикатора."
232
233 #: ../plugins/indicator/indicator.plugin.in.h:3
234 msgid "Copyright © 2011 Diodon Team"
235 msgstr "Copyright © 2011 Diodon Team"
236
237 #: ../unity-scope-diodon/clipboard.scope.in.in.h:1
238 msgid "Clipboard History"
239 msgstr "История Буфера обмена"
240
241 #: ../unity-scope-diodon/clipboard.scope.in.in.h:2
242 msgid ""
243 "This is an Ubuntu search plugin that enables information from Diodon to be "
244 "searched and displayed in the Dash underneath the Clipboard header."
245 msgstr ""
246 "Это поисковый плагин для Ubuntu он включает информацию про Diodon в Ubuntu "
247 "Dash, после чего она может быть там найдена и отображенна."
248
249 #: ../unity-scope-diodon/clipboard.scope.in.in.h:3
250 msgid "Search clipboard"
251 msgstr "Поиск в буфере обмена"
252
253 #: ../unity-scope-diodon/clipboard.scope.in.in.h:4
254 #: ../unity-scope-diodon/unity-scope-diodon.vala:79
255 #: ../unity-scope-diodon/unity-scope-diodon.vala:104
256 msgid "Text"
257 msgstr "Текст"
258
259 #: ../unity-scope-diodon/clipboard.scope.in.in.h:5
260 #: ../unity-scope-diodon/unity-scope-diodon.vala:84
261 #: ../unity-scope-diodon/unity-scope-diodon.vala:105
262 msgid "Files"
263 msgstr "Файлы"
264
265 #: ../unity-scope-diodon/clipboard.scope.in.in.h:6
266 #: ../unity-scope-diodon/unity-scope-diodon.vala:89
267 #: ../unity-scope-diodon/unity-scope-diodon.vala:106
268 msgid "Images"
269 msgstr "Изображения"
270
271 #: ../unity-scope-diodon/clipboard.scope.in.in.h:7
272 #: ../unity-scope-diodon/unity-scope-diodon.vala:101
273 msgid "Category"
274 msgstr "Категория"
275
276 #: ../unity-scope-diodon/clipboard.scope.in.in.h:8
277 msgid "Text;Files;Images"
278 msgstr "Текст;Файлы;Изображения"
279
280 #: ../unity-scope-diodon/clipboard.scope.in.in.h:9
281 msgid "Last 24 hours;Last 7 days;Last 30 days;Last year;"
282 msgstr "Последние 24 часа;Последние 7 дней;Последние 30 дней;Последний год;"
283
284 #: ../unity-scope-diodon/unity-scope-diodon.vala:45
285 msgid "Search Clipboard"
286 msgstr "Поиск в буфере обмена"
287
288 #: ../unity-scope-diodon/unity-scope-diodon.vala:110
289 #: ../unity-scope-diodon/unity-scope-diodon.vala:231
290 msgid "Date copied"
291 msgstr "Дата скопирована"
292
293 #: ../unity-scope-diodon/unity-scope-diodon.vala:112
294 msgid "Last 24 hours"
295 msgstr "Последние 24 часа"
296
297 #: ../unity-scope-diodon/unity-scope-diodon.vala:113
298 msgid "Last 7 days"
299 msgstr "Последние 7 дней"
300
301 #: ../unity-scope-diodon/unity-scope-diodon.vala:114
302 msgid "Last 30 days"
303 msgstr "Последние 30 дней"
304
305 #: ../unity-scope-diodon/unity-scope-diodon.vala:115
306 msgid "Last year"
307 msgstr "За последний год"
308
309 #: ../unity-scope-diodon/unity-scope-diodon.vala:216
310 msgid "Paste"
311 msgstr "Вставить"
312
313 #: ../unity-scope-diodon/unity-scope-diodon.vala:224
314 msgid "Origin"
315 msgstr "Origin"
0 # Northern Sami translation for diodon
1 # Copyright (c) 2012 Rosetta Contributors and Canonical Ltd 2012
2 # This file is distributed under the same license as the diodon package.
3 # FIRST AUTHOR <EMAIL@ADDRESS>, 2012.
4 #
5 msgid ""
6 msgstr ""
7 "Project-Id-Version: diodon\n"
8 "Report-Msgid-Bugs-To: \n"
9 "POT-Creation-Date: 2017-06-05 14:18+0200\n"
10 "PO-Revision-Date: 2013-12-29 00:12+0000\n"
11 "Last-Translator: Oliver Sauder <os@esite.ch>\n"
12 "Language-Team: Northern Sami <se@li.org>\n"
13 "MIME-Version: 1.0\n"
14 "Content-Type: text/plain; charset=UTF-8\n"
15 "Content-Transfer-Encoding: 8bit\n"
16 "X-Launchpad-Export-Date: 2017-06-06 05:56+0000\n"
17 "X-Generator: Launchpad (build 18399)\n"
18 "Language: se\n"
19
20 #: ../data/diodon.desktop.in.h:1
21 msgid "Clipboard Manager"
22 msgstr "Čuohpusgirjigieđahalli"
23
24 #: ../data/diodon.desktop.in.h:2
25 msgid "GTK+ Clipboard Manager"
26 msgstr "GTK+ Čuohpusgirjigieđahalli"
27
28 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:1
29 msgid "Use clipboard (Ctrl+C)"
30 msgstr "Geavat čuohpusgirji (Ctrl+C)"
31
32 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:2
33 #: ../data/preferences.ui.h:3
34 msgid ""
35 "Adds content which is copied to the clipboard with e.g. Ctrl + C to the "
36 "clipboard history."
37 msgstr ""
38
39 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:3
40 msgid "Use primary selection"
41 msgstr ""
42
43 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:4
44 #: ../data/preferences.ui.h:5
45 msgid ""
46 "Adds the primary selection (an area of the screen which is selected with the "
47 "mouse) to the clipboard history. Enabling will start process which "
48 "continually checks what is selected. This might discharge your battery "
49 "quicker."
50 msgstr ""
51
52 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:5
53 msgid "Add images to clipboard history"
54 msgstr ""
55
56 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:6
57 #: ../data/preferences.ui.h:7
58 msgid ""
59 "Add images copied to clipboard to clipboard history (e.g. when you right "
60 "click on an image in your browser and choose copy image). Enabling this "
61 "option will increase memory consumption. Images already added to clipboard "
62 "history will remain even when disabled."
63 msgstr ""
64
65 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:7
66 msgid "Synchronize clipboards"
67 msgstr ""
68
69 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:8
70 #: ../data/preferences.ui.h:11
71 msgid ""
72 "Synchronizes the selection (an area of the screen which is selected with the "
73 "mouse) and the clipboard so that anything in the selection is immediately "
74 "available in the clipboard and vice versa e.g. for pasting with Ctrl + V and "
75 "the middle mouse button."
76 msgstr ""
77
78 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:9
79 msgid "Keep clipboard content"
80 msgstr ""
81
82 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:10
83 #: ../data/preferences.ui.h:9
84 msgid ""
85 "Prevents an empty clipboard. For instance when an application exits, the "
86 "clipboard would usually be emptied."
87 msgstr ""
88
89 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:11
90 msgid "Automatically paste selected item"
91 msgstr ""
92
93 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:12
94 #: ../data/preferences.ui.h:13
95 msgid ""
96 "Automatically paste selected item instead of just copying it to the "
97 "clipboard."
98 msgstr ""
99
100 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:13
101 msgid "Number of recent clipboard items"
102 msgstr ""
103
104 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:14
105 msgid "Number of recent clipboard items shown in clipboard menu."
106 msgstr ""
107
108 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:15
109 msgid "Clipboard content filter pattern"
110 msgstr ""
111
112 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:16
113 msgid ""
114 "Regex filter pattern whereas all clipboard items matching this pattern will "
115 "be filtered and not added to clipboard history."
116 msgstr ""
117
118 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:17
119 msgid "Lookup dictionary for application using different paste keybindings"
120 msgstr ""
121
122 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:18
123 msgid ""
124 "A lookup dictionary for applications using different paste keybindings than "
125 "Ctrl + V. Pattern of each string in this array is path-of-app|keybinding"
126 msgstr ""
127
128 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:19
129 msgid "Active plugins"
130 msgstr ""
131
132 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:20
133 msgid "List of active plugins."
134 msgstr ""
135
136 #: ../data/preferences.ui.h:1
137 msgid "Diodon Preferences"
138 msgstr "Diodon Oidimat"
139
140 #: ../data/preferences.ui.h:2
141 msgid "_Use clipboard (Ctrl+C)"
142 msgstr ""
143
144 #: ../data/preferences.ui.h:4
145 msgid "Use _primary selection"
146 msgstr ""
147
148 #: ../data/preferences.ui.h:6
149 msgid "Add _images to clipboard history"
150 msgstr ""
151
152 #: ../data/preferences.ui.h:8
153 msgid "_Keep clipboard content"
154 msgstr ""
155
156 #: ../data/preferences.ui.h:10
157 msgid "S_ynchronize clipboards"
158 msgstr ""
159
160 #: ../data/preferences.ui.h:12
161 msgid "_Automatically paste selected item"
162 msgstr ""
163
164 #: ../data/preferences.ui.h:14
165 msgid "Number of recent clipboard items to be shown in clipboard menu."
166 msgstr ""
167
168 #: ../data/preferences.ui.h:15
169 msgid "Number of recent items"
170 msgstr ""
171
172 #: ../data/preferences.ui.h:16 ../unity-scope-diodon/unity-scope-diodon.vala:75
173 msgid "Clipboard"
174 msgstr "Čuohpusgirji"
175
176 #: ../data/preferences.ui.h:17
177 msgid ""
178 "Please register custom shortcut with\n"
179 "your desktop environment.\n"
180 "Use /usr/bin/diodon as command."
181 msgstr ""
182
183 #: ../data/preferences.ui.h:20
184 msgid "More information"
185 msgstr ""
186
187 #: ../data/preferences.ui.h:21
188 msgid "Hotkeys"
189 msgstr ""
190
191 #: ../data/preferences.ui.h:22
192 msgid "Plugins"
193 msgstr "Lassemoduvllat"
194
195 #: ../libdiodon/clipboard-menu.vala:46
196 msgid "<Empty>"
197 msgstr "<guorus>"
198
199 #: ../libdiodon/clipboard-menu.vala:53
200 msgid "Privacy mode is enabled. No new items will be added to history!"
201 msgstr ""
202
203 #: ../plugins/indicator/indicator.plugin.in.h:1
204 msgid "Application Indicator"
205 msgstr ""
206
207 #: ../plugins/indicator/indicator.plugin.in.h:2
208 msgid "Access clipboard history with an application indicator."
209 msgstr ""
210
211 #: ../plugins/indicator/indicator.plugin.in.h:3
212 msgid "Copyright © 2011 Diodon Team"
213 msgstr ""
214
215 #: ../unity-scope-diodon/clipboard.scope.in.in.h:1
216 msgid "Clipboard History"
217 msgstr ""
218
219 #: ../unity-scope-diodon/clipboard.scope.in.in.h:2
220 msgid ""
221 "This is an Ubuntu search plugin that enables information from Diodon to be "
222 "searched and displayed in the Dash underneath the Clipboard header."
223 msgstr ""
224
225 #: ../unity-scope-diodon/clipboard.scope.in.in.h:3
226 msgid "Search clipboard"
227 msgstr ""
228
229 #: ../unity-scope-diodon/clipboard.scope.in.in.h:4
230 #: ../unity-scope-diodon/unity-scope-diodon.vala:79
231 #: ../unity-scope-diodon/unity-scope-diodon.vala:104
232 msgid "Text"
233 msgstr ""
234
235 #: ../unity-scope-diodon/clipboard.scope.in.in.h:5
236 #: ../unity-scope-diodon/unity-scope-diodon.vala:84
237 #: ../unity-scope-diodon/unity-scope-diodon.vala:105
238 msgid "Files"
239 msgstr ""
240
241 #: ../unity-scope-diodon/clipboard.scope.in.in.h:6
242 #: ../unity-scope-diodon/unity-scope-diodon.vala:89
243 #: ../unity-scope-diodon/unity-scope-diodon.vala:106
244 msgid "Images"
245 msgstr ""
246
247 #: ../unity-scope-diodon/clipboard.scope.in.in.h:7
248 #: ../unity-scope-diodon/unity-scope-diodon.vala:101
249 msgid "Category"
250 msgstr ""
251
252 #: ../unity-scope-diodon/clipboard.scope.in.in.h:8
253 msgid "Text;Files;Images"
254 msgstr ""
255
256 #: ../unity-scope-diodon/clipboard.scope.in.in.h:9
257 msgid "Last 24 hours;Last 7 days;Last 30 days;Last year;"
258 msgstr ""
259
260 #: ../unity-scope-diodon/unity-scope-diodon.vala:45
261 msgid "Search Clipboard"
262 msgstr ""
263
264 #: ../unity-scope-diodon/unity-scope-diodon.vala:110
265 #: ../unity-scope-diodon/unity-scope-diodon.vala:231
266 msgid "Date copied"
267 msgstr ""
268
269 #: ../unity-scope-diodon/unity-scope-diodon.vala:112
270 msgid "Last 24 hours"
271 msgstr ""
272
273 #: ../unity-scope-diodon/unity-scope-diodon.vala:113
274 msgid "Last 7 days"
275 msgstr ""
276
277 #: ../unity-scope-diodon/unity-scope-diodon.vala:114
278 msgid "Last 30 days"
279 msgstr ""
280
281 #: ../unity-scope-diodon/unity-scope-diodon.vala:115
282 msgid "Last year"
283 msgstr ""
284
285 #: ../unity-scope-diodon/unity-scope-diodon.vala:216
286 msgid "Paste"
287 msgstr ""
288
289 #: ../unity-scope-diodon/unity-scope-diodon.vala:224
290 msgid "Origin"
291 msgstr ""
0 # Slovak translation for diodon
1 # Copyright (c) 2011 Rosetta Contributors and Canonical Ltd 2011
2 # This file is distributed under the same license as the diodon package.
3 # FIRST AUTHOR <EMAIL@ADDRESS>, 2011.
4 #
5 msgid ""
6 msgstr ""
7 "Project-Id-Version: diodon\n"
8 "Report-Msgid-Bugs-To: \n"
9 "POT-Creation-Date: 2017-06-05 14:18+0200\n"
10 "PO-Revision-Date: 2011-09-07 17:45+0000\n"
11 "Last-Translator: Oliver Sauder <os@esite.ch>\n"
12 "Language-Team: Slovak <sk@li.org>\n"
13 "MIME-Version: 1.0\n"
14 "Content-Type: text/plain; charset=UTF-8\n"
15 "Content-Transfer-Encoding: 8bit\n"
16 "X-Launchpad-Export-Date: 2017-06-06 05:56+0000\n"
17 "X-Generator: Launchpad (build 18399)\n"
18 "Language: sk\n"
19
20 #: ../data/diodon.desktop.in.h:1
21 msgid "Clipboard Manager"
22 msgstr "Správca schránky"
23
24 #: ../data/diodon.desktop.in.h:2
25 msgid "GTK+ Clipboard Manager"
26 msgstr ""
27
28 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:1
29 msgid "Use clipboard (Ctrl+C)"
30 msgstr ""
31
32 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:2
33 #: ../data/preferences.ui.h:3
34 msgid ""
35 "Adds content which is copied to the clipboard with e.g. Ctrl + C to the "
36 "clipboard history."
37 msgstr ""
38
39 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:3
40 msgid "Use primary selection"
41 msgstr ""
42
43 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:4
44 #: ../data/preferences.ui.h:5
45 msgid ""
46 "Adds the primary selection (an area of the screen which is selected with the "
47 "mouse) to the clipboard history. Enabling will start process which "
48 "continually checks what is selected. This might discharge your battery "
49 "quicker."
50 msgstr ""
51
52 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:5
53 msgid "Add images to clipboard history"
54 msgstr ""
55
56 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:6
57 #: ../data/preferences.ui.h:7
58 msgid ""
59 "Add images copied to clipboard to clipboard history (e.g. when you right "
60 "click on an image in your browser and choose copy image). Enabling this "
61 "option will increase memory consumption. Images already added to clipboard "
62 "history will remain even when disabled."
63 msgstr ""
64
65 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:7
66 msgid "Synchronize clipboards"
67 msgstr ""
68
69 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:8
70 #: ../data/preferences.ui.h:11
71 msgid ""
72 "Synchronizes the selection (an area of the screen which is selected with the "
73 "mouse) and the clipboard so that anything in the selection is immediately "
74 "available in the clipboard and vice versa e.g. for pasting with Ctrl + V and "
75 "the middle mouse button."
76 msgstr ""
77 "Synchronizuje výber (oblasť obrazovky, kt. je vyznačená myšou) a schránku, "
78 "takže všetko, čo vyberiete myšou je okamžite prístupné v schránke pre "
79 "vloženie pomocou Ctrl+V a stredným tlačidlom myši."
80
81 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:9
82 msgid "Keep clipboard content"
83 msgstr ""
84
85 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:10
86 #: ../data/preferences.ui.h:9
87 msgid ""
88 "Prevents an empty clipboard. For instance when an application exits, the "
89 "clipboard would usually be emptied."
90 msgstr ""
91 "Zabráni vyprázdneniu schránky. Napríklad pri keď sa aplikácia ukončí, "
92 "schránka sa obvykle vyprázdni."
93
94 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:11
95 msgid "Automatically paste selected item"
96 msgstr ""
97
98 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:12
99 #: ../data/preferences.ui.h:13
100 msgid ""
101 "Automatically paste selected item instead of just copying it to the "
102 "clipboard."
103 msgstr ""
104
105 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:13
106 msgid "Number of recent clipboard items"
107 msgstr ""
108
109 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:14
110 msgid "Number of recent clipboard items shown in clipboard menu."
111 msgstr ""
112
113 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:15
114 msgid "Clipboard content filter pattern"
115 msgstr ""
116
117 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:16
118 msgid ""
119 "Regex filter pattern whereas all clipboard items matching this pattern will "
120 "be filtered and not added to clipboard history."
121 msgstr ""
122
123 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:17
124 msgid "Lookup dictionary for application using different paste keybindings"
125 msgstr ""
126
127 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:18
128 msgid ""
129 "A lookup dictionary for applications using different paste keybindings than "
130 "Ctrl + V. Pattern of each string in this array is path-of-app|keybinding"
131 msgstr ""
132
133 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:19
134 msgid "Active plugins"
135 msgstr ""
136
137 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:20
138 msgid "List of active plugins."
139 msgstr ""
140
141 #: ../data/preferences.ui.h:1
142 msgid "Diodon Preferences"
143 msgstr "Diodon nastavenia"
144
145 #: ../data/preferences.ui.h:2
146 msgid "_Use clipboard (Ctrl+C)"
147 msgstr "Po_užiť schránku (Ctrl+C)"
148
149 #: ../data/preferences.ui.h:4
150 msgid "Use _primary selection"
151 msgstr "Použiť _primárny výber"
152
153 #: ../data/preferences.ui.h:6
154 msgid "Add _images to clipboard history"
155 msgstr ""
156
157 #: ../data/preferences.ui.h:8
158 msgid "_Keep clipboard content"
159 msgstr "Ponechať obsah schrán_ky"
160
161 #: ../data/preferences.ui.h:10
162 msgid "S_ynchronize clipboards"
163 msgstr "S_ynchronizovať schránky"
164
165 #: ../data/preferences.ui.h:12
166 msgid "_Automatically paste selected item"
167 msgstr ""
168
169 #: ../data/preferences.ui.h:14
170 msgid "Number of recent clipboard items to be shown in clipboard menu."
171 msgstr ""
172
173 #: ../data/preferences.ui.h:15
174 msgid "Number of recent items"
175 msgstr ""
176
177 #: ../data/preferences.ui.h:16 ../unity-scope-diodon/unity-scope-diodon.vala:75
178 msgid "Clipboard"
179 msgstr "Schránka"
180
181 #: ../data/preferences.ui.h:17
182 msgid ""
183 "Please register custom shortcut with\n"
184 "your desktop environment.\n"
185 "Use /usr/bin/diodon as command."
186 msgstr ""
187
188 #: ../data/preferences.ui.h:20
189 msgid "More information"
190 msgstr ""
191
192 #: ../data/preferences.ui.h:21
193 msgid "Hotkeys"
194 msgstr ""
195
196 #: ../data/preferences.ui.h:22
197 msgid "Plugins"
198 msgstr ""
199
200 #: ../libdiodon/clipboard-menu.vala:46
201 msgid "<Empty>"
202 msgstr "<Prázdne>"
203
204 #: ../libdiodon/clipboard-menu.vala:53
205 msgid "Privacy mode is enabled. No new items will be added to history!"
206 msgstr ""
207
208 #: ../plugins/indicator/indicator.plugin.in.h:1
209 msgid "Application Indicator"
210 msgstr ""
211
212 #: ../plugins/indicator/indicator.plugin.in.h:2
213 msgid "Access clipboard history with an application indicator."
214 msgstr ""
215
216 #: ../plugins/indicator/indicator.plugin.in.h:3
217 msgid "Copyright © 2011 Diodon Team"
218 msgstr ""
219
220 #: ../unity-scope-diodon/clipboard.scope.in.in.h:1
221 msgid "Clipboard History"
222 msgstr ""
223
224 #: ../unity-scope-diodon/clipboard.scope.in.in.h:2
225 msgid ""
226 "This is an Ubuntu search plugin that enables information from Diodon to be "
227 "searched and displayed in the Dash underneath the Clipboard header."
228 msgstr ""
229
230 #: ../unity-scope-diodon/clipboard.scope.in.in.h:3
231 msgid "Search clipboard"
232 msgstr ""
233
234 #: ../unity-scope-diodon/clipboard.scope.in.in.h:4
235 #: ../unity-scope-diodon/unity-scope-diodon.vala:79
236 #: ../unity-scope-diodon/unity-scope-diodon.vala:104
237 msgid "Text"
238 msgstr ""
239
240 #: ../unity-scope-diodon/clipboard.scope.in.in.h:5
241 #: ../unity-scope-diodon/unity-scope-diodon.vala:84
242 #: ../unity-scope-diodon/unity-scope-diodon.vala:105
243 msgid "Files"
244 msgstr ""
245
246 #: ../unity-scope-diodon/clipboard.scope.in.in.h:6
247 #: ../unity-scope-diodon/unity-scope-diodon.vala:89
248 #: ../unity-scope-diodon/unity-scope-diodon.vala:106
249 msgid "Images"
250 msgstr ""
251
252 #: ../unity-scope-diodon/clipboard.scope.in.in.h:7
253 #: ../unity-scope-diodon/unity-scope-diodon.vala:101
254 msgid "Category"
255 msgstr ""
256
257 #: ../unity-scope-diodon/clipboard.scope.in.in.h:8
258 msgid "Text;Files;Images"
259 msgstr ""
260
261 #: ../unity-scope-diodon/clipboard.scope.in.in.h:9
262 msgid "Last 24 hours;Last 7 days;Last 30 days;Last year;"
263 msgstr ""
264
265 #: ../unity-scope-diodon/unity-scope-diodon.vala:45
266 msgid "Search Clipboard"
267 msgstr ""
268
269 #: ../unity-scope-diodon/unity-scope-diodon.vala:110
270 #: ../unity-scope-diodon/unity-scope-diodon.vala:231
271 msgid "Date copied"
272 msgstr ""
273
274 #: ../unity-scope-diodon/unity-scope-diodon.vala:112
275 msgid "Last 24 hours"
276 msgstr ""
277
278 #: ../unity-scope-diodon/unity-scope-diodon.vala:113
279 msgid "Last 7 days"
280 msgstr ""
281
282 #: ../unity-scope-diodon/unity-scope-diodon.vala:114
283 msgid "Last 30 days"
284 msgstr ""
285
286 #: ../unity-scope-diodon/unity-scope-diodon.vala:115
287 msgid "Last year"
288 msgstr ""
289
290 #: ../unity-scope-diodon/unity-scope-diodon.vala:216
291 msgid "Paste"
292 msgstr ""
293
294 #: ../unity-scope-diodon/unity-scope-diodon.vala:224
295 msgid "Origin"
296 msgstr ""
0 # Swedish translation for diodon
1 # Copyright (c) 2011 Rosetta Contributors and Canonical Ltd 2011
2 # This file is distributed under the same license as the diodon package.
3 # FIRST AUTHOR <EMAIL@ADDRESS>, 2011.
4 #
5 msgid ""
6 msgstr ""
7 "Project-Id-Version: diodon\n"
8 "Report-Msgid-Bugs-To: \n"
9 "POT-Creation-Date: 2017-06-05 14:18+0200\n"
10 "PO-Revision-Date: 2017-06-05 12:30+0000\n"
11 "Last-Translator: Åke Engelbrektson <Unknown>\n"
12 "Language-Team: Swedish\n"
13 "MIME-Version: 1.0\n"
14 "Content-Type: text/plain; charset=UTF-8\n"
15 "Content-Transfer-Encoding: 8bit\n"
16 "X-Launchpad-Export-Date: 2017-06-06 05:56+0000\n"
17 "X-Generator: Launchpad (build 18399)\n"
18 "Language: sv\n"
19
20 #: ../data/diodon.desktop.in.h:1
21 msgid "Clipboard Manager"
22 msgstr "Urklipphanterare"
23
24 #: ../data/diodon.desktop.in.h:2
25 msgid "GTK+ Clipboard Manager"
26 msgstr "GTK+ Urklipphanterare"
27
28 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:1
29 msgid "Use clipboard (Ctrl+C)"
30 msgstr "Använd urklipp (Ctrl-C)"
31
32 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:2
33 #: ../data/preferences.ui.h:3
34 msgid ""
35 "Adds content which is copied to the clipboard with e.g. Ctrl + C to the "
36 "clipboard history."
37 msgstr ""
38 "Lägg till innehåll som kopieras till urklipp med t.ex. Ctrl + C, i "
39 "urklippshistoriken."
40
41 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:3
42 msgid "Use primary selection"
43 msgstr "Använd primär markering"
44
45 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:4
46 #: ../data/preferences.ui.h:5
47 msgid ""
48 "Adds the primary selection (an area of the screen which is selected with the "
49 "mouse) to the clipboard history. Enabling will start process which "
50 "continually checks what is selected. This might discharge your battery "
51 "quicker."
52 msgstr ""
53 "Lägger till primär markering (område på skärmen som markerats med musen) "
54 "till urklippshistoriken. Aktivering startar en process som kontinuerligt "
55 "kontrollerar vad som markeras. Detta kan ladda ur ditt batteri snabbare."
56
57 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:5
58 msgid "Add images to clipboard history"
59 msgstr "Lägg till bilder i urklippshistoriken"
60
61 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:6
62 #: ../data/preferences.ui.h:7
63 msgid ""
64 "Add images copied to clipboard to clipboard history (e.g. when you right "
65 "click on an image in your browser and choose copy image). Enabling this "
66 "option will increase memory consumption. Images already added to clipboard "
67 "history will remain even when disabled."
68 msgstr ""
69 "Lägger till bilder från urklipp i urklippshistoriken (t.ex när du "
70 "högerklickar på en bild i webbläsaren och väljer \"Kopiera bild\"). "
71 "Aktivering av detta alternativ, ökar minnesanvändningen. Bilder som redan "
72 "finns i urklippshistoriken, kvarstår även vid inaktivering."
73
74 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:7
75 msgid "Synchronize clipboards"
76 msgstr "Synkronisera urklipp"
77
78 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:8
79 #: ../data/preferences.ui.h:11
80 msgid ""
81 "Synchronizes the selection (an area of the screen which is selected with the "
82 "mouse) and the clipboard so that anything in the selection is immediately "
83 "available in the clipboard and vice versa e.g. for pasting with Ctrl + V and "
84 "the middle mouse button."
85 msgstr ""
86 "Synkroniserar markeringen (område på skärmen som markerats med musen) och "
87 "urklipp så att allt i markeringen blir tillgängligt i urklipp, och tvärt om. "
88 "T.ex. för inklistring med Ctrl + V eller med mushjulsknappen."
89
90 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:9
91 msgid "Keep clipboard content"
92 msgstr "Spara urklippsinnehållet"
93
94 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:10
95 #: ../data/preferences.ui.h:9
96 msgid ""
97 "Prevents an empty clipboard. For instance when an application exits, the "
98 "clipboard would usually be emptied."
99 msgstr ""
100 "Förhindrar tomt urklipp. När ett program avslutas, töms vanligtvis urklipp."
101
102 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:11
103 msgid "Automatically paste selected item"
104 msgstr "Klistra automatiskt in markerat objekt"
105
106 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:12
107 #: ../data/preferences.ui.h:13
108 msgid ""
109 "Automatically paste selected item instead of just copying it to the "
110 "clipboard."
111 msgstr ""
112 "Klistra automatisk in markerat objekt istället för att bara kopiera det till "
113 "urklipp."
114
115 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:13
116 msgid "Number of recent clipboard items"
117 msgstr "Antal tidigare urklippsobjekt"
118
119 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:14
120 msgid "Number of recent clipboard items shown in clipboard menu."
121 msgstr "Antal tidigare urklippsobjekt som visas i urklippsmenyn."
122
123 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:15
124 msgid "Clipboard content filter pattern"
125 msgstr "Filtreringsmönster för urklippsinnehåll"
126
127 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:16
128 msgid ""
129 "Regex filter pattern whereas all clipboard items matching this pattern will "
130 "be filtered and not added to clipboard history."
131 msgstr ""
132 "Alla urklippsobjekt som matchar detta regex-filter, sållas bort och läggs "
133 "inte till i urklippshistoriken."
134
135 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:17
136 msgid "Lookup dictionary for application using different paste keybindings"
137 msgstr ""
138 "Uppslagsbok för program som använder andra tangentbindningar, för "
139 "inklistring."
140
141 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:18
142 msgid ""
143 "A lookup dictionary for applications using different paste keybindings than "
144 "Ctrl + V. Pattern of each string in this array is path-of-app|keybinding"
145 msgstr ""
146 "En uppslagsbok för program som använder andra tangentbindningar än Ctrl + V, "
147 "för inklistring. Mönstret för varje sträng i denna matris är programsökväg | "
148 "tangentbindning"
149
150 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:19
151 msgid "Active plugins"
152 msgstr "Aktiva instick"
153
154 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:20
155 msgid "List of active plugins."
156 msgstr "Lista över aktiva instick."
157
158 #: ../data/preferences.ui.h:1
159 msgid "Diodon Preferences"
160 msgstr "Diodon-inställningar"
161
162 #: ../data/preferences.ui.h:2
163 msgid "_Use clipboard (Ctrl+C)"
164 msgstr "_Använd urklipp (Ctrl+C)"
165
166 #: ../data/preferences.ui.h:4
167 msgid "Use _primary selection"
168 msgstr "Använd _primär markering"
169
170 #: ../data/preferences.ui.h:6
171 msgid "Add _images to clipboard history"
172 msgstr "Lägg till _bilder i urklippshistoriken"
173
174 #: ../data/preferences.ui.h:8
175 msgid "_Keep clipboard content"
176 msgstr "_Spara urklippsinnehållet"
177
178 #: ../data/preferences.ui.h:10
179 msgid "S_ynchronize clipboards"
180 msgstr "S_ynkronisera urklipp"
181
182 #: ../data/preferences.ui.h:12
183 msgid "_Automatically paste selected item"
184 msgstr "_Klistra automatiskt in markerat objekt"
185
186 #: ../data/preferences.ui.h:14
187 msgid "Number of recent clipboard items to be shown in clipboard menu."
188 msgstr "Antal tidigare urklippsobjekt som skall visas i urklippsmenyn."
189
190 #: ../data/preferences.ui.h:15
191 msgid "Number of recent items"
192 msgstr "Antal tidigare objekt"
193
194 #: ../data/preferences.ui.h:16 ../unity-scope-diodon/unity-scope-diodon.vala:75
195 msgid "Clipboard"
196 msgstr "Urklipp"
197
198 #: ../data/preferences.ui.h:17
199 msgid ""
200 "Please register custom shortcut with\n"
201 "your desktop environment.\n"
202 "Use /usr/bin/diodon as command."
203 msgstr ""
204 "Registrera en anpassad genväg i\n"
205 "din skrivbordsmiljö.\n"
206 "Använd /usr/bin/diodon som kommando."
207
208 #: ../data/preferences.ui.h:20
209 msgid "More information"
210 msgstr "Mer information"
211
212 #: ../data/preferences.ui.h:21
213 msgid "Hotkeys"
214 msgstr "Snabbtangenter"
215
216 #: ../data/preferences.ui.h:22
217 msgid "Plugins"
218 msgstr "Insticksmoduler"
219
220 #: ../libdiodon/clipboard-menu.vala:46
221 msgid "<Empty>"
222 msgstr "<Tom>"
223
224 #: ../libdiodon/clipboard-menu.vala:53
225 msgid "Privacy mode is enabled. No new items will be added to history!"
226 msgstr "Sekretessläge är aktiverat. Inga nya poster läggs till i historiken!"
227
228 #: ../plugins/indicator/indicator.plugin.in.h:1
229 msgid "Application Indicator"
230 msgstr "Programindikator"
231
232 #: ../plugins/indicator/indicator.plugin.in.h:2
233 msgid "Access clipboard history with an application indicator."
234 msgstr "Öppna urklippshistoriken med en programindikator."
235
236 #: ../plugins/indicator/indicator.plugin.in.h:3
237 msgid "Copyright © 2011 Diodon Team"
238 msgstr "Copyright © 2011 Diodon Team"
239
240 #: ../unity-scope-diodon/clipboard.scope.in.in.h:1
241 msgid "Clipboard History"
242 msgstr "Urklippshistorik"
243
244 #: ../unity-scope-diodon/clipboard.scope.in.in.h:2
245 msgid ""
246 "This is an Ubuntu search plugin that enables information from Diodon to be "
247 "searched and displayed in the Dash underneath the Clipboard header."
248 msgstr ""
249 "Detta är ett Ubuntu sökinstick som medger att information från Diodon "
250 "genomsöks och visas i Dash, under urklippsrubriken."
251
252 #: ../unity-scope-diodon/clipboard.scope.in.in.h:3
253 msgid "Search clipboard"
254 msgstr "Sök i urklipp"
255
256 #: ../unity-scope-diodon/clipboard.scope.in.in.h:4
257 #: ../unity-scope-diodon/unity-scope-diodon.vala:79
258 #: ../unity-scope-diodon/unity-scope-diodon.vala:104
259 msgid "Text"
260 msgstr "Text"
261
262 #: ../unity-scope-diodon/clipboard.scope.in.in.h:5
263 #: ../unity-scope-diodon/unity-scope-diodon.vala:84
264 #: ../unity-scope-diodon/unity-scope-diodon.vala:105
265 msgid "Files"
266 msgstr "Filer"
267
268 #: ../unity-scope-diodon/clipboard.scope.in.in.h:6
269 #: ../unity-scope-diodon/unity-scope-diodon.vala:89
270 #: ../unity-scope-diodon/unity-scope-diodon.vala:106
271 msgid "Images"
272 msgstr "Bilder"
273
274 #: ../unity-scope-diodon/clipboard.scope.in.in.h:7
275 #: ../unity-scope-diodon/unity-scope-diodon.vala:101
276 msgid "Category"
277 msgstr "Kategori"
278
279 #: ../unity-scope-diodon/clipboard.scope.in.in.h:8
280 msgid "Text;Files;Images"
281 msgstr "Text;Filer;Bilder"
282
283 #: ../unity-scope-diodon/clipboard.scope.in.in.h:9
284 msgid "Last 24 hours;Last 7 days;Last 30 days;Last year;"
285 msgstr ""
286 "Senaste 24 timmarna;Senaste 7 dagarna;Senaste 30 dagarna;Senaste året"
287
288 #: ../unity-scope-diodon/unity-scope-diodon.vala:45
289 msgid "Search Clipboard"
290 msgstr "Sök i urklipp"
291
292 #: ../unity-scope-diodon/unity-scope-diodon.vala:110
293 #: ../unity-scope-diodon/unity-scope-diodon.vala:231
294 msgid "Date copied"
295 msgstr "Kopieringsdatum"
296
297 #: ../unity-scope-diodon/unity-scope-diodon.vala:112
298 msgid "Last 24 hours"
299 msgstr "Senaste 24 timmarna"
300
301 #: ../unity-scope-diodon/unity-scope-diodon.vala:113
302 msgid "Last 7 days"
303 msgstr "Senaste 7 dagarna"
304
305 #: ../unity-scope-diodon/unity-scope-diodon.vala:114
306 msgid "Last 30 days"
307 msgstr "Senaste 30 dagarna"
308
309 #: ../unity-scope-diodon/unity-scope-diodon.vala:115
310 msgid "Last year"
311 msgstr "Senaste året"
312
313 #: ../unity-scope-diodon/unity-scope-diodon.vala:216
314 msgid "Paste"
315 msgstr "Klistra in"
316
317 #: ../unity-scope-diodon/unity-scope-diodon.vala:224
318 msgid "Origin"
319 msgstr "Ursprung"
0 # English (United Kingdom) translation for diodon
1 # Copyright (c) 2012 Rosetta Contributors and Canonical Ltd 2012
2 # This file is distributed under the same license as the diodon package.
3 # FIRST AUTHOR <EMAIL@ADDRESS>, 2012.
4 #
5 msgid ""
6 msgstr ""
7 "Project-Id-Version: diodon\n"
8 "Report-Msgid-Bugs-To: \n"
9 "POT-Creation-Date: 2017-06-05 14:18+0200\n"
10 "PO-Revision-Date: 2014-03-27 08:54+0000\n"
11 "Last-Translator: recepchakan <Unknown>\n"
12 "Language-Team: English (United Kingdom) <en_GB@li.org>\n"
13 "MIME-Version: 1.0\n"
14 "Content-Type: text/plain; charset=UTF-8\n"
15 "Content-Transfer-Encoding: 8bit\n"
16 "X-Launchpad-Export-Date: 2017-06-06 05:56+0000\n"
17 "X-Generator: Launchpad (build 18399)\n"
18 "Language: \n"
19 "X-Language: tr_TR\n"
20 "X-Source-Language: en\n"
21
22 #: ../data/diodon.desktop.in.h:1
23 msgid "Clipboard Manager"
24 msgstr "Pano Yöneticisi"
25
26 #: ../data/diodon.desktop.in.h:2
27 msgid "GTK+ Clipboard Manager"
28 msgstr "GTK+ Pano Yöneticisi"
29
30 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:1
31 msgid "Use clipboard (Ctrl+C)"
32 msgstr "Panoyu kullan (Ctrl+C)"
33
34 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:2
35 #: ../data/preferences.ui.h:3
36 msgid ""
37 "Adds content which is copied to the clipboard with e.g. Ctrl + C to the "
38 "clipboard history."
39 msgstr ""
40 "Panoya kopyalanan nesneleri (Ctrl + C ile örnek olarak) pano geçmişine "
41 "kopyalar."
42
43 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:3
44 msgid "Use primary selection"
45 msgstr "Seçilen metni panoya kopyala"
46
47 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:4
48 #: ../data/preferences.ui.h:5
49 msgid ""
50 "Adds the primary selection (an area of the screen which is selected with the "
51 "mouse) to the clipboard history. Enabling will start process which "
52 "continually checks what is selected. This might discharge your battery "
53 "quicker."
54 msgstr ""
55 "Birincil secimi (ekranda fare ile seçilen kısmı) panoya geçmişine kopyalar. "
56 "Aktif edildiğinde sürekli olarak seçtiğiniz bölge kontrol edilir. Bu "
57 "bataryanızın daha hızlı tükenmesine yol açabilir."
58
59 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:5
60 msgid "Add images to clipboard history"
61 msgstr "Resimleri pano geçmişine ekle"
62
63 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:6
64 #: ../data/preferences.ui.h:7
65 msgid ""
66 "Add images copied to clipboard to clipboard history (e.g. when you right "
67 "click on an image in your browser and choose copy image). Enabling this "
68 "option will increase memory consumption. Images already added to clipboard "
69 "history will remain even when disabled."
70 msgstr ""
71 "Eklenen resmi pano geçmişine kopyalar (Örnek: İnternet tarayıcınızda bir "
72 "resmi sağ tuşla tıklayıp kopyala dediğinizde ). Bu seçeneğin "
73 "etkinleştirilmesi bellek tüketimini artıracaktır. Devre dışı bırakıldığında "
74 "daha önce panoya geçmişine eklenen görüntüler bile kalır."
75
76 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:7
77 msgid "Synchronize clipboards"
78 msgstr "Senkronize panolar"
79
80 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:8
81 #: ../data/preferences.ui.h:11
82 msgid ""
83 "Synchronizes the selection (an area of the screen which is selected with the "
84 "mouse) and the clipboard so that anything in the selection is immediately "
85 "available in the clipboard and vice versa e.g. for pasting with Ctrl + V and "
86 "the middle mouse button."
87 msgstr "Aktif edildiğinde, fare ile seçilen yerin hemen önüne yapıştırır."
88
89 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:9
90 msgid "Keep clipboard content"
91 msgstr "Pano içeriyini tut"
92
93 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:10
94 #: ../data/preferences.ui.h:9
95 msgid ""
96 "Prevents an empty clipboard. For instance when an application exits, the "
97 "clipboard would usually be emptied."
98 msgstr "Genelde bir uygulama kapatıldıktan sonra panoyu temizler."
99
100 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:11
101 msgid "Automatically paste selected item"
102 msgstr "Seçilen nesneyi otomatik yapıştır"
103
104 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:12
105 #: ../data/preferences.ui.h:13
106 msgid ""
107 "Automatically paste selected item instead of just copying it to the "
108 "clipboard."
109 msgstr "Panodan seçilen nesneyi son konuma otomatik olarak yapıştırır."
110
111 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:13
112 msgid "Number of recent clipboard items"
113 msgstr "Panoda tutulan nesne sayısı."
114
115 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:14
116 msgid "Number of recent clipboard items shown in clipboard menu."
117 msgstr "Panoda listelenecek nesne sayısı."
118
119 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:15
120 msgid "Clipboard content filter pattern"
121 msgstr ""
122
123 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:16
124 msgid ""
125 "Regex filter pattern whereas all clipboard items matching this pattern will "
126 "be filtered and not added to clipboard history."
127 msgstr ""
128
129 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:17
130 msgid "Lookup dictionary for application using different paste keybindings"
131 msgstr ""
132
133 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:18
134 msgid ""
135 "A lookup dictionary for applications using different paste keybindings than "
136 "Ctrl + V. Pattern of each string in this array is path-of-app|keybinding"
137 msgstr ""
138
139 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:19
140 msgid "Active plugins"
141 msgstr "Aktive eklentiler"
142
143 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:20
144 msgid "List of active plugins."
145 msgstr "Aktive eklentileri listele."
146
147 #: ../data/preferences.ui.h:1
148 msgid "Diodon Preferences"
149 msgstr "Tercihler"
150
151 #: ../data/preferences.ui.h:2
152 msgid "_Use clipboard (Ctrl+C)"
153 msgstr "_Panoyu kullan (Ctrl+C)"
154
155 #: ../data/preferences.ui.h:4
156 msgid "Use _primary selection"
157 msgstr "_Birincil seçim kullanın"
158
159 #: ../data/preferences.ui.h:6
160 msgid "Add _images to clipboard history"
161 msgstr "_Resimleri pano geçmişine ekle"
162
163 #: ../data/preferences.ui.h:8
164 msgid "_Keep clipboard content"
165 msgstr "_Pano içeriğini tut"
166
167 #: ../data/preferences.ui.h:10
168 msgid "S_ynchronize clipboards"
169 msgstr "S_enkronize panolar"
170
171 #: ../data/preferences.ui.h:12
172 msgid "_Automatically paste selected item"
173 msgstr "S_eçilen nesneyi otomatik yapıştır"
174
175 #: ../data/preferences.ui.h:14
176 msgid "Number of recent clipboard items to be shown in clipboard menu."
177 msgstr "Panoda tutulacak nesnelerin sayısı."
178
179 #: ../data/preferences.ui.h:15
180 msgid "Number of recent items"
181 msgstr "Geçmiş nesne sayısı"
182
183 #: ../data/preferences.ui.h:16 ../unity-scope-diodon/unity-scope-diodon.vala:75
184 msgid "Clipboard"
185 msgstr "Pano"
186
187 #: ../data/preferences.ui.h:17
188 msgid ""
189 "Please register custom shortcut with\n"
190 "your desktop environment.\n"
191 "Use /usr/bin/diodon as command."
192 msgstr ""
193
194 #: ../data/preferences.ui.h:20
195 msgid "More information"
196 msgstr ""
197
198 #: ../data/preferences.ui.h:21
199 msgid "Hotkeys"
200 msgstr ""
201
202 #: ../data/preferences.ui.h:22
203 msgid "Plugins"
204 msgstr "Eklentiler"
205
206 #: ../libdiodon/clipboard-menu.vala:46
207 msgid "<Empty>"
208 msgstr "<Boş>"
209
210 #: ../libdiodon/clipboard-menu.vala:53
211 msgid "Privacy mode is enabled. No new items will be added to history!"
212 msgstr ""
213
214 #: ../plugins/indicator/indicator.plugin.in.h:1
215 msgid "Application Indicator"
216 msgstr "Uygulama Göstergesi"
217
218 #: ../plugins/indicator/indicator.plugin.in.h:2
219 msgid "Access clipboard history with an application indicator."
220 msgstr "Uygulama göstergesi ile pano geçmişine erişim."
221
222 #: ../plugins/indicator/indicator.plugin.in.h:3
223 msgid "Copyright © 2011 Diodon Team"
224 msgstr "Copyright © 2011 Diodon Team"
225
226 #: ../unity-scope-diodon/clipboard.scope.in.in.h:1
227 msgid "Clipboard History"
228 msgstr "Pano gecmişi"
229
230 #: ../unity-scope-diodon/clipboard.scope.in.in.h:2
231 msgid ""
232 "This is an Ubuntu search plugin that enables information from Diodon to be "
233 "searched and displayed in the Dash underneath the Clipboard header."
234 msgstr ""
235 "Ubuntu arama eklentisi, Seçke altından ki Pano başlığı ile arama ve "
236 "listeleme yapar."
237
238 #: ../unity-scope-diodon/clipboard.scope.in.in.h:3
239 msgid "Search clipboard"
240 msgstr "Panoda ara"
241
242 #: ../unity-scope-diodon/clipboard.scope.in.in.h:4
243 #: ../unity-scope-diodon/unity-scope-diodon.vala:79
244 #: ../unity-scope-diodon/unity-scope-diodon.vala:104
245 msgid "Text"
246 msgstr "Metin"
247
248 #: ../unity-scope-diodon/clipboard.scope.in.in.h:5
249 #: ../unity-scope-diodon/unity-scope-diodon.vala:84
250 #: ../unity-scope-diodon/unity-scope-diodon.vala:105
251 msgid "Files"
252 msgstr "Dosyalar"
253
254 #: ../unity-scope-diodon/clipboard.scope.in.in.h:6
255 #: ../unity-scope-diodon/unity-scope-diodon.vala:89
256 #: ../unity-scope-diodon/unity-scope-diodon.vala:106
257 msgid "Images"
258 msgstr "Resimler"
259
260 #: ../unity-scope-diodon/clipboard.scope.in.in.h:7
261 #: ../unity-scope-diodon/unity-scope-diodon.vala:101
262 msgid "Category"
263 msgstr "Kategori"
264
265 #: ../unity-scope-diodon/clipboard.scope.in.in.h:8
266 msgid "Text;Files;Images"
267 msgstr "Metin;Dosyalar;Resimler"
268
269 #: ../unity-scope-diodon/clipboard.scope.in.in.h:9
270 msgid "Last 24 hours;Last 7 days;Last 30 days;Last year;"
271 msgstr "Son 24 saat;Son 7 gün;Son 30 gün;Son yıl;"
272
273 #: ../unity-scope-diodon/unity-scope-diodon.vala:45
274 msgid "Search Clipboard"
275 msgstr "Panoda Ara"
276
277 #: ../unity-scope-diodon/unity-scope-diodon.vala:110
278 #: ../unity-scope-diodon/unity-scope-diodon.vala:231
279 msgid "Date copied"
280 msgstr "Tarih kopyalandı"
281
282 #: ../unity-scope-diodon/unity-scope-diodon.vala:112
283 msgid "Last 24 hours"
284 msgstr "Son 24 saat"
285
286 #: ../unity-scope-diodon/unity-scope-diodon.vala:113
287 msgid "Last 7 days"
288 msgstr "Son 7 gün"
289
290 #: ../unity-scope-diodon/unity-scope-diodon.vala:114
291 msgid "Last 30 days"
292 msgstr "Son 30 gün"
293
294 #: ../unity-scope-diodon/unity-scope-diodon.vala:115
295 msgid "Last year"
296 msgstr "Son 1 yıl"
297
298 #: ../unity-scope-diodon/unity-scope-diodon.vala:216
299 msgid "Paste"
300 msgstr "Yapıştır"
301
302 #: ../unity-scope-diodon/unity-scope-diodon.vala:224
303 msgid "Origin"
304 msgstr "Kaynak"
0 # Ukrainian translation for diodon
1 # Copyright (c) 2011 Rosetta Contributors and Canonical Ltd 2011
2 # This file is distributed under the same license as the diodon package.
3 # FIRST AUTHOR <EMAIL@ADDRESS>, 2011.
4 #
5 msgid ""
6 msgstr ""
7 "Project-Id-Version: diodon\n"
8 "Report-Msgid-Bugs-To: \n"
9 "POT-Creation-Date: 2017-06-05 14:18+0200\n"
10 "PO-Revision-Date: 2016-02-06 11:55+0000\n"
11 "Last-Translator: Микола Ткач <Stuartlittle1970@gmail.com>\n"
12 "Language-Team: Ukrainian <uk@li.org>\n"
13 "MIME-Version: 1.0\n"
14 "Content-Type: text/plain; charset=UTF-8\n"
15 "Content-Transfer-Encoding: 8bit\n"
16 "X-Launchpad-Export-Date: 2017-06-06 05:56+0000\n"
17 "X-Generator: Launchpad (build 18399)\n"
18 "Language: uk\n"
19
20 #: ../data/diodon.desktop.in.h:1
21 msgid "Clipboard Manager"
22 msgstr "Менеджер буферу обміну"
23
24 #: ../data/diodon.desktop.in.h:2
25 msgid "GTK+ Clipboard Manager"
26 msgstr "GTK+ Менеджер буферу обміну"
27
28 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:1
29 msgid "Use clipboard (Ctrl+C)"
30 msgstr "Використовувати буфер (Ctrl+C)"
31
32 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:2
33 #: ../data/preferences.ui.h:3
34 msgid ""
35 "Adds content which is copied to the clipboard with e.g. Ctrl + C to the "
36 "clipboard history."
37 msgstr "Зберігати в історії дані з буферу обміну (Ctrl+C)"
38
39 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:3
40 msgid "Use primary selection"
41 msgstr "Використовувати виділення"
42
43 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:4
44 #: ../data/preferences.ui.h:5
45 msgid ""
46 "Adds the primary selection (an area of the screen which is selected with the "
47 "mouse) to the clipboard history. Enabling will start process which "
48 "continually checks what is selected. This might discharge your battery "
49 "quicker."
50 msgstr ""
51
52 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:5
53 msgid "Add images to clipboard history"
54 msgstr "Використовувати зображення"
55
56 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:6
57 #: ../data/preferences.ui.h:7
58 msgid ""
59 "Add images copied to clipboard to clipboard history (e.g. when you right "
60 "click on an image in your browser and choose copy image). Enabling this "
61 "option will increase memory consumption. Images already added to clipboard "
62 "history will remain even when disabled."
63 msgstr ""
64
65 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:7
66 msgid "Synchronize clipboards"
67 msgstr "Синхронізувати буфери обміну"
68
69 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:8
70 #: ../data/preferences.ui.h:11
71 msgid ""
72 "Synchronizes the selection (an area of the screen which is selected with the "
73 "mouse) and the clipboard so that anything in the selection is immediately "
74 "available in the clipboard and vice versa e.g. for pasting with Ctrl + V and "
75 "the middle mouse button."
76 msgstr ""
77 "Синхронізує виділення (частина екрану, що виділена за допомогою миші) і "
78 "буфер, так що виділення відразу доступні у буфері і навпаки, напр. для "
79 "вставлення комбінацією клавіш Ctrl + V і середньою клавішею миши."
80
81 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:9
82 msgid "Keep clipboard content"
83 msgstr "Зберігати вміст буферу обміну"
84
85 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:10
86 #: ../data/preferences.ui.h:9
87 msgid ""
88 "Prevents an empty clipboard. For instance when an application exits, the "
89 "clipboard would usually be emptied."
90 msgstr ""
91 "Запобігає спустошенню буферу обміну. Наприклад, коли програма закривається, "
92 "буфер зазвичай очищається."
93
94 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:11
95 msgid "Automatically paste selected item"
96 msgstr "Автоматично вставляти вибраний запис"
97
98 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:12
99 #: ../data/preferences.ui.h:13
100 msgid ""
101 "Automatically paste selected item instead of just copying it to the "
102 "clipboard."
103 msgstr ""
104 "Автоматично вставляти вибраний запис замість того, щоб копіювати його в "
105 "буфер обміну."
106
107 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:13
108 msgid "Number of recent clipboard items"
109 msgstr "Розмір історії обміну"
110
111 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:14
112 msgid "Number of recent clipboard items shown in clipboard menu."
113 msgstr "Кількість елементів буферу обміну для відображення у меню історії"
114
115 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:15
116 msgid "Clipboard content filter pattern"
117 msgstr ""
118
119 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:16
120 msgid ""
121 "Regex filter pattern whereas all clipboard items matching this pattern will "
122 "be filtered and not added to clipboard history."
123 msgstr ""
124
125 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:17
126 msgid "Lookup dictionary for application using different paste keybindings"
127 msgstr ""
128
129 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:18
130 msgid ""
131 "A lookup dictionary for applications using different paste keybindings than "
132 "Ctrl + V. Pattern of each string in this array is path-of-app|keybinding"
133 msgstr ""
134
135 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:19
136 msgid "Active plugins"
137 msgstr "Активні додатки"
138
139 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:20
140 msgid "List of active plugins."
141 msgstr "Список активних додатків"
142
143 #: ../data/preferences.ui.h:1
144 msgid "Diodon Preferences"
145 msgstr "Налашування Diodon"
146
147 #: ../data/preferences.ui.h:2
148 msgid "_Use clipboard (Ctrl+C)"
149 msgstr "_Використати буфер (Ctrl+C)"
150
151 #: ../data/preferences.ui.h:4
152 msgid "Use _primary selection"
153 msgstr "Використовувати _основний вибір"
154
155 #: ../data/preferences.ui.h:6
156 msgid "Add _images to clipboard history"
157 msgstr "Використовувати _зображення"
158
159 #: ../data/preferences.ui.h:8
160 msgid "_Keep clipboard content"
161 msgstr "_Зберігати вмістиме буферу"
162
163 #: ../data/preferences.ui.h:10
164 msgid "S_ynchronize clipboards"
165 msgstr "С_инхронізація буферів"
166
167 #: ../data/preferences.ui.h:12
168 msgid "_Automatically paste selected item"
169 msgstr "_Автоматично вставляти вибрані записи"
170
171 #: ../data/preferences.ui.h:14
172 msgid "Number of recent clipboard items to be shown in clipboard menu."
173 msgstr ""
174
175 #: ../data/preferences.ui.h:15
176 msgid "Number of recent items"
177 msgstr ""
178
179 #: ../data/preferences.ui.h:16 ../unity-scope-diodon/unity-scope-diodon.vala:75
180 msgid "Clipboard"
181 msgstr "Буфер Обміну"
182
183 #: ../data/preferences.ui.h:17
184 msgid ""
185 "Please register custom shortcut with\n"
186 "your desktop environment.\n"
187 "Use /usr/bin/diodon as command."
188 msgstr ""
189
190 #: ../data/preferences.ui.h:20
191 msgid "More information"
192 msgstr "Докладніше"
193
194 #: ../data/preferences.ui.h:21
195 msgid "Hotkeys"
196 msgstr "\"Гарячі\" клавіші"
197
198 #: ../data/preferences.ui.h:22
199 msgid "Plugins"
200 msgstr "Додатки"
201
202 #: ../libdiodon/clipboard-menu.vala:46
203 msgid "<Empty>"
204 msgstr "<Порожньо>"
205
206 #: ../libdiodon/clipboard-menu.vala:53
207 msgid "Privacy mode is enabled. No new items will be added to history!"
208 msgstr ""
209
210 #: ../plugins/indicator/indicator.plugin.in.h:1
211 msgid "Application Indicator"
212 msgstr "Застосунок-індикатор"
213
214 #: ../plugins/indicator/indicator.plugin.in.h:2
215 msgid "Access clipboard history with an application indicator."
216 msgstr ""
217 "Доступ до журналу подій буферу обміну за допомогою застосунку індикатора."
218
219 #: ../plugins/indicator/indicator.plugin.in.h:3
220 msgid "Copyright © 2011 Diodon Team"
221 msgstr "Авторське право © 2011 Diodon Team"
222
223 #: ../unity-scope-diodon/clipboard.scope.in.in.h:1
224 msgid "Clipboard History"
225 msgstr "Історія буферу обміну"
226
227 #: ../unity-scope-diodon/clipboard.scope.in.in.h:2
228 msgid ""
229 "This is an Ubuntu search plugin that enables information from Diodon to be "
230 "searched and displayed in the Dash underneath the Clipboard header."
231 msgstr ""
232
233 #: ../unity-scope-diodon/clipboard.scope.in.in.h:3
234 msgid "Search clipboard"
235 msgstr "Пошук в буфері обміну"
236
237 #: ../unity-scope-diodon/clipboard.scope.in.in.h:4
238 #: ../unity-scope-diodon/unity-scope-diodon.vala:79
239 #: ../unity-scope-diodon/unity-scope-diodon.vala:104
240 msgid "Text"
241 msgstr "Текст"
242
243 #: ../unity-scope-diodon/clipboard.scope.in.in.h:5
244 #: ../unity-scope-diodon/unity-scope-diodon.vala:84
245 #: ../unity-scope-diodon/unity-scope-diodon.vala:105
246 msgid "Files"
247 msgstr "Файли"
248
249 #: ../unity-scope-diodon/clipboard.scope.in.in.h:6
250 #: ../unity-scope-diodon/unity-scope-diodon.vala:89
251 #: ../unity-scope-diodon/unity-scope-diodon.vala:106
252 msgid "Images"
253 msgstr "Зображення"
254
255 #: ../unity-scope-diodon/clipboard.scope.in.in.h:7
256 #: ../unity-scope-diodon/unity-scope-diodon.vala:101
257 msgid "Category"
258 msgstr "Категорія"
259
260 #: ../unity-scope-diodon/clipboard.scope.in.in.h:8
261 msgid "Text;Files;Images"
262 msgstr "Текст;Файли;Зображення"
263
264 #: ../unity-scope-diodon/clipboard.scope.in.in.h:9
265 msgid "Last 24 hours;Last 7 days;Last 30 days;Last year;"
266 msgstr ""
267 "Останні 24 години;Останні 7 днів;Останні 30 днів;Протягом останнього року;"
268
269 #: ../unity-scope-diodon/unity-scope-diodon.vala:45
270 msgid "Search Clipboard"
271 msgstr "Пошук в буфері обміну"
272
273 #: ../unity-scope-diodon/unity-scope-diodon.vala:110
274 #: ../unity-scope-diodon/unity-scope-diodon.vala:231
275 msgid "Date copied"
276 msgstr ""
277
278 #: ../unity-scope-diodon/unity-scope-diodon.vala:112
279 msgid "Last 24 hours"
280 msgstr "Останні 24 години"
281
282 #: ../unity-scope-diodon/unity-scope-diodon.vala:113
283 msgid "Last 7 days"
284 msgstr "Останні 7 днів"
285
286 #: ../unity-scope-diodon/unity-scope-diodon.vala:114
287 msgid "Last 30 days"
288 msgstr "Останні 30 днів"
289
290 #: ../unity-scope-diodon/unity-scope-diodon.vala:115
291 msgid "Last year"
292 msgstr "Протягом останнього року"
293
294 #: ../unity-scope-diodon/unity-scope-diodon.vala:216
295 msgid "Paste"
296 msgstr "Вставити"
297
298 #: ../unity-scope-diodon/unity-scope-diodon.vala:224
299 msgid "Origin"
300 msgstr ""
0 #! /usr/bin/env python
1 # encoding: utf-8
2
3 bld.new_task_gen (
4 features = 'intltool_po',
5 appname = 'diodon')
6
0 # Chinese (Simplified) translation for diodon
1 # Copyright (c) 2012 Rosetta Contributors and Canonical Ltd 2012
2 # This file is distributed under the same license as the diodon package.
3 # FIRST AUTHOR <EMAIL@ADDRESS>, 2012.
4 #
5 msgid ""
6 msgstr ""
7 "Project-Id-Version: diodon\n"
8 "Report-Msgid-Bugs-To: \n"
9 "POT-Creation-Date: 2017-06-05 14:18+0200\n"
10 "PO-Revision-Date: 2013-12-29 00:12+0000\n"
11 "Last-Translator: Oliver Sauder <os@esite.ch>\n"
12 "Language-Team: Chinese (Simplified) <zh_CN@li.org>\n"
13 "MIME-Version: 1.0\n"
14 "Content-Type: text/plain; charset=UTF-8\n"
15 "Content-Transfer-Encoding: 8bit\n"
16 "X-Launchpad-Export-Date: 2017-06-06 05:56+0000\n"
17 "X-Generator: Launchpad (build 18399)\n"
18 "Language: \n"
19
20 #: ../data/diodon.desktop.in.h:1
21 msgid "Clipboard Manager"
22 msgstr "剪贴板管理器"
23
24 #: ../data/diodon.desktop.in.h:2
25 msgid "GTK+ Clipboard Manager"
26 msgstr "GTK+ 剪贴板管理器"
27
28 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:1
29 msgid "Use clipboard (Ctrl+C)"
30 msgstr "使用剪贴板(Ctrl+C)"
31
32 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:2
33 #: ../data/preferences.ui.h:3
34 msgid ""
35 "Adds content which is copied to the clipboard with e.g. Ctrl + C to the "
36 "clipboard history."
37 msgstr ""
38
39 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:3
40 msgid "Use primary selection"
41 msgstr ""
42
43 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:4
44 #: ../data/preferences.ui.h:5
45 msgid ""
46 "Adds the primary selection (an area of the screen which is selected with the "
47 "mouse) to the clipboard history. Enabling will start process which "
48 "continually checks what is selected. This might discharge your battery "
49 "quicker."
50 msgstr ""
51
52 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:5
53 msgid "Add images to clipboard history"
54 msgstr ""
55
56 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:6
57 #: ../data/preferences.ui.h:7
58 msgid ""
59 "Add images copied to clipboard to clipboard history (e.g. when you right "
60 "click on an image in your browser and choose copy image). Enabling this "
61 "option will increase memory consumption. Images already added to clipboard "
62 "history will remain even when disabled."
63 msgstr ""
64
65 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:7
66 msgid "Synchronize clipboards"
67 msgstr "同步剪贴板"
68
69 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:8
70 #: ../data/preferences.ui.h:11
71 msgid ""
72 "Synchronizes the selection (an area of the screen which is selected with the "
73 "mouse) and the clipboard so that anything in the selection is immediately "
74 "available in the clipboard and vice versa e.g. for pasting with Ctrl + V and "
75 "the middle mouse button."
76 msgstr ""
77
78 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:9
79 msgid "Keep clipboard content"
80 msgstr "保留剪贴板内容"
81
82 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:10
83 #: ../data/preferences.ui.h:9
84 msgid ""
85 "Prevents an empty clipboard. For instance when an application exits, the "
86 "clipboard would usually be emptied."
87 msgstr "预防剪贴板为空。例如当一个应用程序存在时,剪贴板通常会被清空。"
88
89 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:11
90 msgid "Automatically paste selected item"
91 msgstr "自动粘贴已选条目"
92
93 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:12
94 #: ../data/preferences.ui.h:13
95 msgid ""
96 "Automatically paste selected item instead of just copying it to the "
97 "clipboard."
98 msgstr "自动粘贴已选条目,不只是复制到剪贴板。"
99
100 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:13
101 msgid "Number of recent clipboard items"
102 msgstr ""
103
104 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:14
105 msgid "Number of recent clipboard items shown in clipboard menu."
106 msgstr ""
107
108 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:15
109 msgid "Clipboard content filter pattern"
110 msgstr ""
111
112 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:16
113 msgid ""
114 "Regex filter pattern whereas all clipboard items matching this pattern will "
115 "be filtered and not added to clipboard history."
116 msgstr ""
117
118 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:17
119 msgid "Lookup dictionary for application using different paste keybindings"
120 msgstr ""
121
122 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:18
123 msgid ""
124 "A lookup dictionary for applications using different paste keybindings than "
125 "Ctrl + V. Pattern of each string in this array is path-of-app|keybinding"
126 msgstr ""
127
128 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:19
129 msgid "Active plugins"
130 msgstr "活动插件"
131
132 #: ../data/net.launchpad.Diodon.gschema.xml.in.in.h:20
133 msgid "List of active plugins."
134 msgstr "活动插件列表。"
135
136 #: ../data/preferences.ui.h:1
137 msgid "Diodon Preferences"
138 msgstr "Diodon 首选项"
139
140 #: ../data/preferences.ui.h:2
141 msgid "_Use clipboard (Ctrl+C)"
142 msgstr "使用剪贴板(Ctrl+C)(_U)"
143
144 #: ../data/preferences.ui.h:4
145 msgid "Use _primary selection"
146 msgstr ""
147
148 #: ../data/preferences.ui.h:6
149 msgid "Add _images to clipboard history"
150 msgstr ""
151
152 #: ../data/preferences.ui.h:8
153 msgid "_Keep clipboard content"
154 msgstr "保留剪贴板内容(_K)"
155
156 #: ../data/preferences.ui.h:10
157 msgid "S_ynchronize clipboards"
158 msgstr "同步剪贴板(_Y)"
159
160 #: ../data/preferences.ui.h:12
161 msgid "_Automatically paste selected item"
162 msgstr "自动粘贴所选条目(_A)"
163
164 #: ../data/preferences.ui.h:14
165 msgid "Number of recent clipboard items to be shown in clipboard menu."
166 msgstr ""
167
168 #: ../data/preferences.ui.h:15
169 msgid "Number of recent items"
170 msgstr ""
171
172 #: ../data/preferences.ui.h:16 ../unity-scope-diodon/unity-scope-diodon.vala:75
173 msgid "Clipboard"
174 msgstr "剪贴板"
175
176 #: ../data/preferences.ui.h:17
177 msgid ""
178 "Please register custom shortcut with\n"
179 "your desktop environment.\n"
180 "Use /usr/bin/diodon as command."
181 msgstr ""
182
183 #: ../data/preferences.ui.h:20
184 msgid "More information"
185 msgstr ""
186
187 #: ../data/preferences.ui.h:21
188 msgid "Hotkeys"
189 msgstr ""
190
191 #: ../data/preferences.ui.h:22
192 msgid "Plugins"
193 msgstr "插件"
194
195 #: ../libdiodon/clipboard-menu.vala:46
196 msgid "<Empty>"
197 msgstr "<空>"
198
199 #: ../libdiodon/clipboard-menu.vala:53
200 msgid "Privacy mode is enabled. No new items will be added to history!"
201 msgstr ""
202
203 #: ../plugins/indicator/indicator.plugin.in.h:1
204 msgid "Application Indicator"
205 msgstr ""
206
207 #: ../plugins/indicator/indicator.plugin.in.h:2
208 msgid "Access clipboard history with an application indicator."
209 msgstr ""
210
211 #: ../plugins/indicator/indicator.plugin.in.h:3
212 msgid "Copyright © 2011 Diodon Team"
213 msgstr ""
214
215 #: ../unity-scope-diodon/clipboard.scope.in.in.h:1
216 msgid "Clipboard History"
217 msgstr ""
218
219 #: ../unity-scope-diodon/clipboard.scope.in.in.h:2
220 msgid ""
221 "This is an Ubuntu search plugin that enables information from Diodon to be "
222 "searched and displayed in the Dash underneath the Clipboard header."
223 msgstr ""
224
225 #: ../unity-scope-diodon/clipboard.scope.in.in.h:3
226 msgid "Search clipboard"
227 msgstr ""
228
229 #: ../unity-scope-diodon/clipboard.scope.in.in.h:4
230 #: ../unity-scope-diodon/unity-scope-diodon.vala:79
231 #: ../unity-scope-diodon/unity-scope-diodon.vala:104
232 msgid "Text"
233 msgstr ""
234
235 #: ../unity-scope-diodon/clipboard.scope.in.in.h:5
236 #: ../unity-scope-diodon/unity-scope-diodon.vala:84
237 #: ../unity-scope-diodon/unity-scope-diodon.vala:105
238 msgid "Files"
239 msgstr ""
240
241 #: ../unity-scope-diodon/clipboard.scope.in.in.h:6
242 #: ../unity-scope-diodon/unity-scope-diodon.vala:89
243 #: ../unity-scope-diodon/unity-scope-diodon.vala:106
244 msgid "Images"
245 msgstr ""
246
247 #: ../unity-scope-diodon/clipboard.scope.in.in.h:7
248 #: ../unity-scope-diodon/unity-scope-diodon.vala:101
249 msgid "Category"
250 msgstr ""
251
252 #: ../unity-scope-diodon/clipboard.scope.in.in.h:8
253 msgid "Text;Files;Images"
254 msgstr ""
255
256 #: ../unity-scope-diodon/clipboard.scope.in.in.h:9
257 msgid "Last 24 hours;Last 7 days;Last 30 days;Last year;"
258 msgstr ""
259
260 #: ../unity-scope-diodon/unity-scope-diodon.vala:45
261 msgid "Search Clipboard"
262 msgstr ""
263
264 #: ../unity-scope-diodon/unity-scope-diodon.vala:110
265 #: ../unity-scope-diodon/unity-scope-diodon.vala:231
266 msgid "Date copied"
267 msgstr ""
268
269 #: ../unity-scope-diodon/unity-scope-diodon.vala:112
270 msgid "Last 24 hours"
271 msgstr ""
272
273 #: ../unity-scope-diodon/unity-scope-diodon.vala:113
274 msgid "Last 7 days"
275 msgstr ""
276
277 #: ../unity-scope-diodon/unity-scope-diodon.vala:114
278 msgid "Last 30 days"
279 msgstr ""
280
281 #: ../unity-scope-diodon/unity-scope-diodon.vala:115
282 msgid "Last year"
283 msgstr ""
284
285 #: ../unity-scope-diodon/unity-scope-diodon.vala:216
286 msgid "Paste"
287 msgstr ""
288
289 #: ../unity-scope-diodon/unity-scope-diodon.vala:224
290 msgid "Origin"
291 msgstr ""
0 /*
1 * (C) 2011-2012 Simon Busch <morphis@gravedo.de>
2 *
3 * This library is free software; you can redistribute it and/or
4 * modify it under the terms of the GNU Lesser General Public
5 * License as published by the Free Software Foundation; either
6 * version 2.1 of the License, or (at your option) any later version.
7
8 * This library is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 * Lesser General Public License for more details.
12
13 * You should have received a copy of the GNU Lesser General Public
14 * License along with this library; if not, write to the Free Software
15 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16 */
17
18 using GLib;
19
20 namespace FsoFramework.Test
21 {
22 public errordomain AssertError
23 {
24 UNEXPECTED_VALUE,
25 UNEXPECTED_STATE,
26 }
27
28 public class Assert : GLib.Object
29 {
30 private static string typed_value_to_string<T>( T value )
31 {
32 string result = "";
33
34 Type value_type = typeof(T);
35 if ( value_type.is_value_type() )
36 {
37 if ( value_type.is_a( typeof(string) ) )
38 result = @"$((string) value)";
39 else if ( value_type.is_a( typeof(int32) ) )
40 result = @"$((int32) value)";
41 else if ( value_type.is_a( typeof(uint32) ) )
42 result = @"$((uint32) value)";
43 else if ( value_type.is_a( typeof(int16) ) )
44 result = @"$((int16) value)";
45 else if ( value_type.is_a( typeof(uint16) ) )
46 result = @"$((uint16) value)";
47 else if ( value_type.is_a( typeof(int8) ) )
48 result = @"$((int8) value)";
49 else if ( value_type.is_a( typeof(uint8) ) )
50 result = @"$((uint8) value)";
51 else if ( value_type.is_a( typeof(bool) ) )
52 result = @"$((bool) value)";
53 }
54
55 return result;
56 }
57
58 private static void throw_unexpected_value( string info, string message ) throws AssertError
59 {
60 throw new AssertError.UNEXPECTED_VALUE( info + ( message.length > 0 ? @" : $(message)" : "" ) );
61 }
62
63 /**
64 * Check wether two values of type T are the same. If both values are different an
65 * exception of type AssertError is thrown.
66 *
67 * @param expected Expected value
68 * @param actual Actual value to compare with the expected one
69 * @param message Extra description message if both values are different
70 **/
71 public static void are_equal<T>( T expected, T actual, string message = "" ) throws AssertError
72 {
73
74 if ( expected != actual )
75 {
76 var msg = @"$(typed_value_to_string(expected)) != $(typed_value_to_string(actual))";
77 throw_unexpected_value( @"Actual value is not the same as the expected one: $(msg)", message );
78 }
79 }
80
81 /**
82 * Check wether two values of type string are the same. If both values are different an
83 * exception of type AssertError is thrown.
84 *
85 * @param expected Expected value
86 * @param actual Actual value to compare with the expected one
87 * @param message Extra description message if both values are different
88 **/
89 public static void are_equal_string ( string expected, string actual, string message = "" ) throws AssertError
90 {
91 if ( strcmp( expected, actual ) != 0 )
92 {
93 var msg = @"$(expected) != $(actual)";
94 throw_unexpected_value( @"Actual value is not the same as the expected one: $(msg)", message );
95 }
96 }
97
98 /**
99 * Check wether two values of type T are not the same. If both values are the same an
100 * exception of type AssertError is thrown.
101 *
102 * @param not_expected Not expected value
103 * @param actual Actual value to compare with the not expected one
104 * @param message Extra description message if both values are not different
105 **/
106 public static void are_not_equal<T>( T not_expected, T actual, string message = "" ) throws AssertError
107 {
108 if ( not_expected == actual )
109 {
110 var msg = "$(typed_value_to_string(expected)) == $(typed_value_to_string(actual))";
111 throw_unexpected_value( @"Actual value is the same as the not expected one: $(msg)", message );
112 }
113 }
114
115 /**
116 * Check wether a boolean value is true and throw an exception otherwise.
117 *
118 * @param actual Value to check if it's true or not
119 * @param message Text message to append to error message when assert failed
120 **/
121 public static void is_true( bool actual, string message = "" ) throws AssertError
122 {
123 if ( !actual )
124 throw_unexpected_value( "Supplied value is not true", message );
125 }
126
127 /**
128 * Check wether a boolean value is false and throw an exception otherwise.
129 *
130 * @param actual Value to check if it's false or not
131 * @param message Text message to append to error message when assert failed
132 **/
133 public static void is_false( bool actual, string message = "" ) throws AssertError
134 {
135 if ( actual )
136 throw_unexpected_value( "Supplied value is not false", message );
137 }
138
139 /**
140 * Let test execution fail regardless any condition.
141 *
142 * @param message Text to append to error message
143 **/
144 public static void fail( string message ) throws AssertError
145 {
146 throw new AssertError.UNEXPECTED_STATE( message );
147 }
148
149 /**
150 * Check wether an async operation throws a specific exception.
151 *
152 * @param fbegin Method to start execution of async operation
153 * @param ffinish Method to finish execution of async operation
154 * @param domain Error domain of the exception which should be thrown by the async
155 operation.
156 * @param message Text message to append to error message when specific exception
157 * is not thrown.
158 **/
159 public static void should_throw_async( AsyncBegin fbegin, AsyncFinish ffinish, string domain, string message = "" ) throws AssertError
160 {
161 try
162 {
163 if ( !wait_for_async( 200, fbegin, ffinish ) )
164 throw_unexpected_value( "Execution of async method didn't returns the expected value", message );
165 }
166 catch ( GLib.Error err )
167 {
168 if ( err.domain.to_string() != domain )
169 throw_unexpected_value( @"Didn't receive the expected exception of type $domain", message );
170 return;
171 }
172
173 throw new AssertError.UNEXPECTED_STATE( @"Function didn't throw expected exception" );
174 }
175 }
176 }
177
178 // vim:ts=4:sw=4:expandtab
0 /*
1 * Valadate - Unit testing library for GObject-based libraries.
2 * Copyright (C) 2009-2012 Jan Hudec <bulb@ucw.cz>
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License as published
6 * by the Free Software Foundation, either version 3 of the License, or (at
7 * your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
11 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
12 * License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18 using GLib;
19
20 namespace FsoFramework.Test
21 {
22 public delegate bool Predicate();
23 public delegate void Block();
24 public delegate void AsyncBegin(AsyncReadyCallback callback);
25 public delegate void CancelableAsyncBegin(Cancellable cancel, AsyncReadyCallback callback);
26 public delegate void AsyncFinish(AsyncResult result) throws GLib.Error;
27
28 private class SignalWaiter
29 {
30 public MainLoop loop = new MainLoop(MainContext.default(), true);
31 public bool succeeded = false;
32 public Predicate predicate;
33
34 public SignalWaiter(owned Predicate predicate)
35 {
36 this.predicate = (owned)predicate;
37 }
38
39 public int callback()
40 {
41 if(predicate())
42 {
43 succeeded = true;
44 loop.quit();
45 }
46
47 return 0;
48 }
49
50 public bool abort()
51 {
52 loop.quit();
53 return false;
54 }
55 }
56
57 /**
58 * Wait until a condition becomes true.
59 *
60 * Waits until a condition becomes true. The condition is checked
61 * at the begining and than each time emitter emits signal signame.
62 * This can be used to check asynchronous functionality that uses
63 * signals to signal completion when the first emission does not
64 * necessarily imply the desired state was reached.
65 *
66 * @param timeout Maximum timeout to wait for the emission, in
67 * milliseconds.
68 * @param emitter The object that will emit signal.
69 * @param signame Name of the signal to wait for. May include detail
70 * (in the format used by g_signal_connect).
71 * @param predicate Function that will be called to test whether the
72 * waited-for condition occured. The wait will continue until this
73 * function returns true.
74 * @param block Function that will start the asynchronous operation.
75 * The function will register the signal if it's emitted
76 * synchronously from block, while obviously it cannot notice if it
77 * is emitted before.
78 * @return true if the condition became true, false otherwise.
79 */
80 public bool wait_for_condition(int timeout, Object emitter, string signame, owned Predicate predicate, Block block)
81 {
82 // FIXME: The fixture should push a new context in set_up and
83 // pop it back on clean-up! (But it's GLib 2.21.0+ and
84 // I still have 2.20.4)
85 var waiter = new SignalWaiter((owned)predicate);
86 // Connect to the signal
87 var sh = Signal.connect_swapped(emitter, signame, (Callback)SignalWaiter.callback, waiter);
88 // Run the block to trigger the signal
89 block();
90 // Check whether the condition is not true already
91 waiter.callback();
92 // Plan timeout
93 var t1 = Timeout.add(timeout, waiter.abort);
94 // Run the loop if it was not quit yet.
95 if(waiter.loop.is_running())
96 waiter.loop.run();
97 // Disconnect from singnal
98 SignalHandler.disconnect(emitter, sh);
99 // Cancel timer
100 Source.remove(t1);
101 // Return whether the callback succeeded.
102 return waiter.succeeded;
103 }
104
105 /**
106 * Wait for signal to be emited.
107 *
108 * Waits at most timeout for given signal to be emited and return
109 * whether the signal was emited. Runs main loop while waiting. This
110 * can be used to test asynchronous functionality using signals to
111 * signal completion.
112 *
113 * @param timeout Maximum timeout to wait for the emission, in
114 * milliseconds.
115 * @param emitter The object that will emit signal.
116 * @param signame Name of the signal to wait for. May include detail
117 * (in the format used by g_signal_connect).
118 * @param block Function that will start the asynchronous operation.
119 * The function will register the signal if it's emitted
120 * synchronously from block, while obviously it cannot notice if it
121 * is emitted before.
122 * @return true if the signal was emited, false otherwise.
123 */
124 public bool wait_for_signal(int timeout, Object emitter, string signame, Block block)
125 {
126 bool condition = false;
127 return wait_for_condition(timeout, emitter, signame, () => {
128 if(condition)
129 return true;
130 condition = true;
131 return false;
132 }, block);
133 }
134
135 /**
136 * Wait for an async operation to complete.
137 *
138 * Waits until a async function completes.
139 * @param timeout Maximum timeout to wait for completion, in
140 * milliseconds.
141 * @param async_function The async function to call. The signature
142 * corresponds to function declared as
143 * {{{
144 * async void async_function()
145 * }}}
146 * in Vala.
147 * @param async_finish The finsih part of the async function. It is
148 * assumed it will either assert any problems, or stash the result
149 * somewhere.
150 * @return ture if the function completed and passed the check, false
151 * otherwise.
152 * [[warning:
153 * If it times out, the async function may run to completion when
154 * main loop is entered again later. By that time, the callback data
155 * will be destroyed and the callback will crash.
156 *
157 * This should be avoided by setting new GLib.MainContext for each
158 * test case, but that is only available in development 2.21 GLib.
159 * ]]
160 */
161 public bool wait_for_async(int timeout, AsyncBegin async_function, AsyncFinish async_finish) throws GLib.Error
162 {
163 var loop = new MainLoop(MainContext.default(), true);
164 AsyncResult? result = null;
165 // Plan the async function
166 async_function((o, r) => { result = r; loop.quit(); });
167 // Plan timeout
168 var t1 = Timeout.add(timeout, () => { loop.quit(); return false; });
169 // Run the loop if it was not quit yet.
170 if(loop.is_running())
171 loop.run();
172 // Cancel timer
173 Source.remove(t1);
174 // Check the outcome
175 if(result == null)
176 return false;
177 async_finish(result);
178 return true;
179 }
180
181 /**
182 * Wait for cancellable async operation to complete.
183 *
184 * Calls an async function and waits until it completes, at most
185 * specified time. If it does not complete in time, it cancels the
186 * operation and waits once more the same timeout for the
187 * cancellation (it still fails if the cancellation succeeds).
188 *
189 * @param timeout Maximum timeout to wait for completion, in
190 * milliseconds.
191 * @param async_function The async function to call. The signature
192 * corresponds to function declared as
193 * {{{
194 * async void async_function(GLib.Cancellable cancel)
195 * }}}
196 * in Vala.
197 * @param async_finish The finsih part of the async function. It is
198 * assumed it will either assert any problems, or stash the result
199 * somewhere.
200 * @return ture if the function completed (without being cancelled)
201 * and passed the check, false otherwise.
202 * [[warning:
203 * If the cancel fails and it times out second time, the async
204 * function may run to completion when main loop is entered again
205 * later. By that time, the callback data will be destroyed and the
206 * callback will crash.
207 *
208 * This should be avoided by setting new GLib.MainContext for each
209 * test case, but that is only available in development 2.21 GLib.
210 * ]]
211 */
212 public bool wait_for_cancellable_async(int timeout, CancelableAsyncBegin async_function, AsyncFinish async_finish) throws GLib.Error
213 {
214 var loop = new MainLoop(MainContext.default(), true);
215 AsyncResult? result = null;
216 var cancel = new Cancellable();
217 // Plan the async function
218 async_function(cancel, (o, r) => { result = r; loop.quit(); });
219 // Plan timeouts
220 var t1 = Timeout.add(timeout, () => { cancel.cancel(); return false; });
221 var t2 = Timeout.add(2 * timeout, () => { loop.quit(); return false; });
222 // Run the loop if it was not quit yet.
223 if(loop.is_running())
224 loop.run();
225 // Cancel timers
226 Source.remove(t1);
227 Source.remove(t2);
228 // Check the outcome
229 if(result == null)
230 return false; // The async wasn't called at all.
231 if(cancel.is_cancelled()) // Only succeed if not cancelled
232 return false;
233 async_finish(result);
234 return true;
235 }
236 }
0 /*
1 * (C) 2011-2012 Simon Busch <morphis@gravedo.de>
2 *
3 * This library is free software; you can redistribute it and/or
4 * modify it under the terms of the GNU Lesser General Public
5 * License as published by the Free Software Foundation; either
6 * version 2.1 of the License, or (at your option) any later version.
7
8 * This library is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 * Lesser General Public License for more details.
12
13 * You should have received a copy of the GNU Lesser General Public
14 * License along with this library; if not, write to the Free Software
15 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16 */
17
18 using GLib;
19
20 namespace FsoFramework.Test
21 {
22 private class SignalWrapper
23 {
24 public Object emitter { get; set; }
25 public string signame { get; set; default = ""; }
26 public ulong id { get; set; }
27 public int timeout { get; set; }
28 public int catch_count { get; set; }
29
30 public int callback()
31 {
32 catch_count++;
33 triggered();
34 return 0;
35 }
36
37 public void setup()
38 {
39 id = Signal.connect_swapped( emitter, signame, (Callback) SignalWrapper.callback, this );
40 catch_count = 0;
41 }
42
43 public void release()
44 {
45 SignalHandler.disconnect( emitter, id );
46 }
47
48 public signal void triggered();
49 }
50
51 /**
52 * Wait for one or more signals to arrived when executing a operation which causes
53 * this signals to be triggered. The waiter will return a failure when a timeout is
54 * reached and no or not all signals has triggered.
55 *
56 * Example:
57 * var waiter = new MultiSignalWaiter();
58 * waiter.add_signal( emitter, "signal0" );
59 * var result = waiter.run( () => { triggerSignal0(); } );
60 **/
61 public class MultiSignalWaiter : GLib.Object
62 {
63 private GLib.List<SignalWrapper> signals = new GLib.List<SignalWrapper>();
64 private uint succeeded_count = 0;
65 private MainLoop mainloop;
66
67 /**
68 * Add a signal of an object called emitter to listen for until a timeout is
69 * reached.
70 *
71 * @param emitter Object which emits the signal
72 * @param signame Name of the signal
73 * @param timeout Timeout Specifies the maximum amount of time to wait for the
74 * signal to be triggerd.
75 **/
76 public void add_signal( Object emitter, string signame, int timeout = 200 )
77 {
78 var s = new SignalWrapper() { emitter = emitter, signame = signame, timeout = timeout };
79 s.triggered.connect( () => {
80 succeeded_count++;
81 if ( succeeded_count == signals.length() )
82 mainloop.quit();
83 } );
84 signals.append( s );
85 }
86
87 /**
88 * Run the code block which causes the added signals to be triggered. After block
89 * is executed and timeout is reached or all signals has arrived the result is
90 * returned to the caller.
91 *
92 * @param block Code block to execute
93 * @param timeout Timeout to wait before returning to caller
94 * @return True, if all signals has been triggered. False, if timeout is reached
95 * and not all signals has been triggered.
96 **/
97 public bool run( Block block, int timeout = 200 )
98 {
99 mainloop = new MainLoop(MainContext.default(), true);
100 succeeded_count = 0;
101
102 foreach ( var s in signals )
103 s.setup();
104
105 block();
106 var t1 = Timeout.add( timeout, () => {
107 mainloop.quit();
108 return false;
109 } );
110
111 while ( mainloop.is_running() )
112 mainloop.run();
113
114 bool succeeded = true;
115 foreach ( var s in signals )
116 {
117 s.release();
118 if ( s.catch_count == 0 )
119 succeeded = false;
120 }
121
122 Source.remove( t1 );
123 return succeeded;
124 }
125 }
126 }
127
128 // vim:ts=4:sw=4:expandtab
0 /* testcase.vala
1 *
2 * Copyright (C) 2009-2012 Julien Peeters
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17 *
18 * Author:
19 * Julien Peeters <contact@julienpeeters.fr>
20 *
21 * Copied from libgee/tests/testcase.vala.
22 */
23
24 public abstract class FsoFramework.Test.TestCase : Object
25 {
26 private GLib.TestSuite _suite;
27 private Adaptor[] _adaptors = new Adaptor[0];
28
29 public delegate void TestMethod () throws GLib.Error;
30
31 public TestCase (string name)
32 {
33 this._suite = new GLib.TestSuite (name);
34 }
35
36 public void add_test (string name, owned TestMethod test)
37 {
38 var adaptor = new Adaptor (name, (owned)test, this);
39 this._adaptors += adaptor;
40
41 this._suite.add (new GLib.TestCase (adaptor.name, adaptor.set_up, adaptor.run, adaptor.tear_down, sizeof(Adaptor)));
42 }
43
44 public void add_async_test (string name, AsyncBegin async_begin, AsyncFinish async_finish, int timeout = 200)
45 {
46 var adaptor = new Adaptor (name, () => { }, this);
47 adaptor.is_async = true;
48 adaptor.async_begin = async_begin;
49 adaptor.async_finish = async_finish;
50 adaptor.async_timeout = timeout;
51 this._adaptors += adaptor;
52
53 this._suite.add (new GLib.TestCase (adaptor.name, adaptor.set_up, adaptor.run, adaptor.tear_down, sizeof(Adaptor)));
54 }
55
56 public virtual void set_up ()
57 {
58 }
59
60 public virtual void tear_down ()
61 {
62 }
63
64 public GLib.TestSuite get_suite ()
65 {
66 return this._suite;
67 }
68
69 private class Adaptor
70 {
71 public string name { get; private set; }
72 public int async_timeout { get; set; }
73
74 private unowned TestMethod _test;
75 private TestCase _test_case;
76
77 public bool is_async = false;
78 public unowned AsyncBegin async_begin;
79 public unowned AsyncFinish async_finish;
80
81 public Adaptor (string name, TestMethod test, TestCase test_case)
82 {
83 this._name = name;
84 this._test = test;
85 this._test_case = test_case;
86 }
87
88 public void set_up (void* fixture)
89 {
90 GLib.set_printerr_handler (Adaptor._printerr_func_stack_trace);
91 Log.set_default_handler (this._log_func_stack_trace);
92 this._test_case.set_up ();
93 }
94
95 private static void _printerr_func_stack_trace (string? text)
96 {
97 if (text == null || str_equal (text, ""))
98 return;
99
100 stderr.printf (text);
101
102 /* Print a stack trace since we've hit some major issue */
103 GLib.on_error_stack_trace ("libtool --mode=execute gdb");
104 }
105
106 private void _log_func_stack_trace (string? log_domain, LogLevelFlags log_levels, string message)
107 {
108 Log.default_handler (log_domain, log_levels, message);
109
110 /* Print a stack trace for any message at the warning level or above */
111 if ((log_levels & (LogLevelFlags.LEVEL_WARNING | LogLevelFlags.LEVEL_ERROR | LogLevelFlags.LEVEL_CRITICAL)) != 0)
112 {
113 GLib.on_error_stack_trace ("libtool --mode=execute gdb");
114 }
115 }
116
117 public void run (void* fixture)
118 {
119 if (this.is_async)
120 {
121 try
122 {
123 assert( wait_for_async (async_timeout, this.async_begin, this.async_finish) );
124 }
125 catch (GLib.Error err)
126 {
127 message(@"Got exception while excuting asynchronous test: $(err.message)");
128 GLib.Test.fail();
129 }
130 }
131 else
132 {
133 try
134 {
135 this._test ();
136 }
137 catch (GLib.Error err)
138 {
139 message(@"Got exception while excuting test: $(err.message)");
140 GLib.Test.fail();
141 }
142 }
143 }
144
145 public void tear_down (void* fixture)
146 {
147 this._test_case.tear_down ();
148 }
149 }
150 }
0 /*
1 * Diodon - GTK+ clipboard manager.
2 * Copyright (C) 2015 Diodon Team <diodon-team@lists.launchpad.net>
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published
6 * by the Free Software Foundation, either version 2 of the License, or (at
7 * your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
11 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
12 * License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 *
17 * Author:
18 * Oliver Sauder <os@esite.ch>
19 */
20
21 using FsoFramework.Test;
22
23 namespace Diodon
24 {
25 /**
26 * Testing of TestClipboardConfiguration functionality
27 */
28 class TestClipboardConfiguration : FsoFramework.Test.TestCase
29 {
30 private ClipboardConfiguration configuration;
31
32 public TestClipboardConfiguration()
33 {
34 base("TestClipboardConfiguration");
35 add_test("test_lookup_app_paste_keybinding", test_lookup_app_paste_keybinding);
36 }
37
38 public override void set_up()
39 {
40 this.configuration = new ClipboardConfiguration();
41 this.configuration.app_paste_keybindings = new string[2];
42 this.configuration.app_paste_keybindings[0] = "/some/invalid/pattern";
43 this.configuration.app_paste_keybindings[1] = "/usr/bin/gnome-terminal|<Ctrl><Shift>v";
44 }
45
46 public void test_lookup_app_paste_keybinding() throws GLib.Error
47 {
48 string? key = configuration.lookup_app_paste_keybinding(null);
49 assert(key==null);
50
51 key = configuration.lookup_app_paste_keybinding("/path/not/available");
52 assert(key==null);
53
54 key = configuration.lookup_app_paste_keybinding("/usr/bin/gnome-terminal");
55 Assert.are_equal_string(key, "<Ctrl><Shift>v", "Invalid keybinding");
56
57 uint keyacc;
58 Gdk.ModifierType mods;
59 Gtk.accelerator_parse("<Shift><Ctrl>V", out keyacc, out mods);
60 assert(mods != 0);
61 }
62 }
63 }
64
0 /*
1 * Diodon - GTK+ clipboard manager.
2 * Copyright (C) 2015 Diodon Team <diodon-team@lists.launchpad.net>
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published
6 * by the Free Software Foundation, either version 2 of the License, or (at
7 * your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
11 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
12 * License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 *
17 * Author:
18 * Oliver Sauder <os@esite.ch>
19 */
20
21 namespace Diodon
22 {
23 /**
24 * Testing of Controller functionality
25 */
26 class TestController : FsoFramework.Test.TestCase
27 {
28 private Controller controller;
29
30 public TestController()
31 {
32 base("TestController");
33 add_test("test_filter_item_whitespace", test_filter_item_whitespace);
34 add_test("test_filter_item_whitespace", test_filter_item_none_whitespace);
35 }
36
37 public override void set_up()
38 {
39 ClipboardConfiguration cfg = new ClipboardConfiguration();
40 this.controller = new Controller.with_configuration(cfg, false);
41 }
42
43 public void test_filter_item_whitespace() throws GLib.Error
44 {
45 assert(controller.filter_item(create_text_item(" ")));
46 assert(controller.filter_item(create_text_item(" ")));
47 assert(controller.filter_item(create_text_item(" \n ")));
48 assert(controller.filter_item(create_text_item("\t")));
49 }
50
51 public void test_filter_item_none_whitespace() throws GLib.Error
52 {
53 assert(!controller.filter_item(create_text_item("This is a item\n ")));
54 assert(!controller.filter_item(create_text_item(" \nThis is a item")));
55 assert(!controller.filter_item(create_text_item(" an item ")));
56 assert(!controller.filter_item(create_text_item("this is a item")));
57 }
58
59 private TextClipboardItem create_text_item(string text)
60 {
61 return new TextClipboardItem(ClipboardType.CLIPBOARD, text, null,
62 new DateTime.now_utc());
63 }
64 }
65 }
66
0 /*
1 * Diodon - GTK+ clipboard manager.
2 * Copyright (C) 2013 Diodon Team <diodon-team@lists.launchpad.net>
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published
6 * by the Free Software Foundation, either version 2 of the License, or (at
7 * your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
11 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
12 * License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 *
17 * Author:
18 * Oliver Sauder <os@esite.ch>
19 */
20
21 namespace Diodon
22 {
23 /**
24 * Testing of ImageClipboardItem functionality
25 */
26 class TestImageClipboardItem : FsoFramework.Test.TestCase
27 {
28 public TestImageClipboardItem()
29 {
30 base("TestImageClipboardItem");
31 add_test("test_image_clipboard_item_new_with_payload", test_image_clipboard_item_new_with_payload);
32 }
33
34 public void test_image_clipboard_item_new_with_payload() throws GLib.Error
35 {
36 Gdk.Pixbuf pixbuf = new Gdk.Pixbuf.from_file(Config.TEST_DATA_DIR + "Diodon-64x64.png");
37
38 ImageClipboardItem item1 = new ImageClipboardItem.with_image(ClipboardType.CLIPBOARD, pixbuf, null, new DateTime.now_utc());
39 string checksum1 = item1.get_checksum();
40
41 ImageClipboardItem item2 = new ImageClipboardItem.with_payload(ClipboardType.CLIPBOARD, item1.get_payload(), null, new DateTime.now_utc());
42 string checksum2 = item2.get_checksum();
43
44 FsoFramework.Test.Assert.are_equal_string(checksum1, checksum2, "Images are not the same");
45 }
46 }
47 }
48
0 /*
1 * Diodon - GTK+ clipboard manager.
2 * Copyright (C) 2012 Diodon Team <diodon-team@lists.launchpad.net>
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published
6 * by the Free Software Foundation, either version 2 of the License, or (at
7 * your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
11 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
12 * License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 *
17 * Author:
18 * Oliver Sauder <os@esite.ch>
19 */
20
21 namespace Diodon
22 {
23 public static int main(string[] args)
24 {
25 Test.init(ref args);
26 Gtk.init(ref args);
27
28 TestSuite.get_root().add_suite(new TestImageClipboardItem().get_suite());
29 TestSuite.get_root().add_suite(new TestController().get_suite());
30 TestSuite.get_root().add_suite(new TestClipboardConfiguration().get_suite());
31
32 // run integration tests which needs additional setup of services
33 // when requested by option --integration
34
35 if("--integration" in args) {
36 TestSuite.get_root().add_suite(new TestZeitgeistClipboardStorage().get_suite());
37 }
38
39 return Test.run ();
40 }
41 }
42
0 /*
1 * Diodon - GTK+ clipboard manager.
2 * Copyright (C) 2013 Diodon Team <diodon-team@lists.launchpad.net>
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published
6 * by the Free Software Foundation, either version 2 of the License, or (at
7 * your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
11 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
12 * License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 *
17 * Author:
18 * Oliver Sauder <os@esite.ch>
19 */
20
21 using Zeitgeist;
22
23 namespace Diodon
24 {
25 /**
26 * Testing of ZeitgeistClipboardStorage functionality
27 */
28 class TestZeitgeistClipboardStorage : FsoFramework.Test.TestCase
29 {
30 private ZeitgeistClipboardStorage storage;
31 private Zeitgeist.Log log;
32
33 public TestZeitgeistClipboardStorage()
34 {
35 base("TestZeitgeistClipboardStorage");
36 add_async_test("test_add_text_item",
37 cb => test_add_text_item.begin(cb),
38 res => test_add_text_item.end(res)
39 );
40 add_async_test("test_remove_text_item",
41 cb => test_remove_text_item.begin(cb),
42 res => test_remove_text_item.end(res)
43 );
44 add_async_test("test_get_recent_items",
45 cb => test_get_recent_items.begin(cb),
46 res => test_get_recent_items.end(res)
47 );
48 add_async_test("test_get_recent_items_by_type",
49 cb => test_get_recent_items_by_type.begin(cb),
50 res => test_get_recent_items_by_type.end(res)
51 );
52 add_async_test("test_get_recent_items_image",
53 cb => test_get_recent_items_image.begin(cb),
54 res => test_get_recent_items_image.end(res)
55 );
56 add_async_test("test_get_item_by_checksum",
57 cb => test_get_item_by_checksum.begin(cb),
58 res => test_get_item_by_checksum.end(res)
59 );
60 add_async_test("test_clear",
61 cb => test_clear.begin(cb),
62 res => test_clear.end(res)
63 );
64 // TODO: issue to run DBus service in test
65 //add_async_test("test_get_items_by_search_query",
66 // cb => test_get_items_by_search_query.begin(cb),
67 // res => test_get_items_by_search_query.end(res)
68 //);
69 }
70
71 public override void set_up()
72 {
73 this.log = Zeitgeist.Log.get_default();
74 this.storage = new ZeitgeistClipboardStorage();
75 }
76
77 public async void test_add_text_item() throws FsoFramework.Test.AssertError
78 {
79 TextClipboardItem text_item = new TextClipboardItem(
80 ClipboardType.CLIPBOARD, "test_add_text_item", "/path/to/app", new DateTime.now_utc());
81 yield this.storage.add_item(text_item);
82 yield assert_text_item("test_add_text_item", 1);
83 }
84
85 public async void test_remove_text_item() throws FsoFramework.Test.AssertError
86 {
87 string test_text = "test_remove_text_item";
88 TextClipboardItem text_item = new TextClipboardItem(
89 ClipboardType.CLIPBOARD, test_text, "/path/to/app", new DateTime.now_utc());
90 // add first item
91 yield this.storage.add_item(text_item);
92 yield assert_text_item(test_text, 1);
93
94 // add another one
95 yield this.storage.add_item(text_item);
96 yield assert_text_item(test_text, 2);
97
98 // remove item which should delete all (two) added
99 yield this.storage.remove_item(text_item);
100 yield assert_text_item(test_text, 0);
101 }
102
103 public async void test_get_recent_items() throws FsoFramework.Test.AssertError
104 {
105 const int ITEMS = 10;
106 const int RECENT_ITEMS = 5;
107
108 // add some items
109 for(int i=1; i<=ITEMS; ++i) {
110 yield this.storage.add_item(
111 new TextClipboardItem(ClipboardType.CLIPBOARD, i.to_string(), "/path/to/app", new DateTime.now_utc()));
112 }
113 // add a duplicate to test that duplicates are being ignored
114 yield this.storage.add_item(new TextClipboardItem(ClipboardType.CLIPBOARD,
115 ITEMS.to_string(), "/path/to/app", new DateTime.now_utc()));
116
117 List<IClipboardItem> items = yield this.storage.get_recent_items(RECENT_ITEMS);
118 FsoFramework.Test.Assert.are_equal(items.length(), RECENT_ITEMS,
119 "Invalid number of recent items");
120
121 // recent items should be in reverse order
122 int current_item = ITEMS;
123 foreach(IClipboardItem item in items) {
124 FsoFramework.Test.Assert.is_true(item is TextClipboardItem,
125 "Should be of type TextClipboardItem");
126 FsoFramework.Test.Assert.are_equal_string(item.get_text(),
127 current_item.to_string(), "Invalid clipboard item content");
128 --current_item;
129 }
130
131 // only number of available items should be returned even when asked for more
132 items = yield this.storage.get_recent_items(ITEMS + 1);
133 FsoFramework.Test.Assert.are_equal(items.length(), ITEMS,
134 "Invalid number of recent items");
135 }
136
137 public async void test_get_recent_items_by_type() throws FsoFramework.Test.AssertError, GLib.Error
138 {
139 // add test data
140 yield this.storage.add_item(new TextClipboardItem(ClipboardType.CLIPBOARD, "1", "/path/to/app", new DateTime.now_utc()));
141 yield this.storage.add_item(new FileClipboardItem(ClipboardType.CLIPBOARD,
142 Config.TEST_DATA_DIR + "Diodon-64x64.png", "/path/to/app", new DateTime.now_utc()));
143 Gdk.Pixbuf pixbuf = new Gdk.Pixbuf.from_file(Config.TEST_DATA_DIR + "Diodon-64x64.png");
144 yield this.storage.add_item(new ImageClipboardItem.with_image(ClipboardType.CLIPBOARD,
145 pixbuf, "/path/to/app", new DateTime.now_utc()));
146
147 List<IClipboardItem> items = yield this.storage.get_recent_items(3, new ClipboardCategory[]{ClipboardCategory.IMAGES});
148 FsoFramework.Test.Assert.are_equal(items.length(), 1, "Invalid number of recent items");
149 IClipboardItem item = items.nth_data(0);
150 FsoFramework.Test.Assert.are_equal_string(item.get_label(), "[64x64]", "Invalid image label");
151 }
152
153 public async void test_get_recent_items_image() throws FsoFramework.Test.AssertError, GLib.Error
154 {
155 // add image item
156 Gdk.Pixbuf pixbuf = new Gdk.Pixbuf.from_file(Config.TEST_DATA_DIR + "Diodon-64x64.png");
157 yield this.storage.add_item(new ImageClipboardItem.with_image(ClipboardType.CLIPBOARD,
158 pixbuf, "/path/to/app", new DateTime.now_utc()));
159
160 List<IClipboardItem> items = yield this.storage.get_recent_items(100);
161 FsoFramework.Test.Assert.are_equal(items.length(), 1, "Invalid number of recent items");
162 IClipboardItem item = items.nth_data(0);
163 FsoFramework.Test.Assert.are_equal_string(item.get_label(), "[64x64]", "Invalid image label");
164 }
165
166 public async void test_get_item_by_checksum() throws FsoFramework.Test.AssertError
167 {
168 // add test item
169 TextClipboardItem text_item = new TextClipboardItem(ClipboardType.CLIPBOARD, "checksum", "/path/to/app", new DateTime.now_utc());
170 yield this.storage.add_item(text_item);
171
172 // check item availability
173 IClipboardItem item = yield this.storage.get_item_by_checksum(text_item.get_checksum());
174 FsoFramework.Test.Assert.is_true(item != null, "Item not found");
175 FsoFramework.Test.Assert.are_equal_string("checksum", item.get_text(), "Invalid content");
176
177 // check item which is not available
178 IClipboardItem not_found = yield this.storage.get_item_by_checksum("invalidchecksum");
179 FsoFramework.Test.Assert.is_true(not_found == null, "Item was not null");
180 }
181
182 public async void test_clear() throws FsoFramework.Test.AssertError, GLib.Error
183 {
184 // add test data
185 yield this.storage.add_item(new TextClipboardItem(ClipboardType.CLIPBOARD, "1", "/path/to/app", new DateTime.now_utc()));
186 yield this.storage.add_item(new FileClipboardItem(ClipboardType.CLIPBOARD,
187 Config.TEST_DATA_DIR + "Diodon-64x64.png", "/path/to/app", new DateTime.now_utc()));
188 Gdk.Pixbuf pixbuf = new Gdk.Pixbuf.from_file(Config.TEST_DATA_DIR + "Diodon-64x64.png");
189 yield this.storage.add_item(new ImageClipboardItem.with_image(ClipboardType.CLIPBOARD,
190 pixbuf, "/path/to/app", new DateTime.now_utc()));
191
192 yield this.storage.clear();
193
194 List<IClipboardItem> items = yield this.storage.get_recent_items(3);
195 FsoFramework.Test.Assert.are_equal(0, (int) items.length(), "Items found");
196 }
197
198 // TODO: get this up and running
199 /*public async void test_get_items_by_search_query() throws FsoFramework.Test.AssertError, GLib.Error
200 {
201 yield this.storage.add_item(new TextClipboardItem(ClipboardType.CLIPBOARD, "TestName", "/path/to/app"));
202 yield this.storage.add_item(new TextClipboardItem(ClipboardType.CLIPBOARD, "TestName", "/path/to/app"));
203 yield this.storage.add_item(new TextClipboardItem(ClipboardType.CLIPBOARD, "SampleName", "/path/to/app"));
204
205 Gee.List<IClipboardItem> items = yield this.storage.get_items_by_search_query("name");
206 FsoFramework.Test.Assert.are_equal(2, items.length(), "Invalid number of items found");
207
208 items = yield this.storage.get_items_by_search_query("sample");
209 FsoFramework.Test.Assert.are_equal(1, items.length(), "Invalid number of items found");
210 }*/
211
212 public override void tear_down()
213 {
214 try {
215 FsoFramework.Test.wait_for_async(1000,
216 cb => this.storage.clear.begin(null, cb),
217 res => this.storage.clear.end(res));
218 } catch(GLib.Error e) {
219 warning(e.message);
220 }
221 }
222
223 /**
224 * assert whether text item is added to Zeitgeist Log in assigned quantity
225 */
226 private async void assert_text_item(string text, uint qty) throws FsoFramework.Test.AssertError
227 {
228 GenericArray<Event> templates = new GenericArray<Event>();
229 TimeRange time_range = new TimeRange.anytime();
230 Event template = new Zeitgeist.Event.full (
231 ZG.CREATE_EVENT,
232 ZG.USER_ACTIVITY,
233 null,
234 "application://diodon.desktop", // origin events added by diodon
235 new Subject.full (
236 ZeitgeistClipboardStorage.CLIPBOARD_URI + "*",
237 NFO.PLAIN_TEXT_DOCUMENT,
238 NFO.DATA_CONTAINER,
239 null,
240 null,
241 text,
242 null));
243 templates.add(template);
244
245 try {
246 ResultSet results = yield this.log.find_events(
247 time_range,
248 templates,
249 StorageState.ANY,
250 // not only one resp. qty as the event might be added more than
251 // once resp. qty and in such a case the test should fail
252 1 + qty,
253 ResultType.MOST_RECENT_EVENTS,
254 null);
255
256 FsoFramework.Test.Assert.are_equal(results.size(), qty,
257 "Result size did not match expected quantity");
258
259 } catch(GLib.Error e) {
260 FsoFramework.Test.Assert.fail(e.message);
261 }
262 }
263 }
264 }
265
0 #! /usr/bin/env python
1 # encoding: utf-8
2 # Oliver Sauder, 2010
3
4 import Options
5
6 prog = bld.new_task_gen (
7 features = 'c cprogram test',
8 target = 'diodon-test',
9 vapi_dirs = '../vapi ../libdiodon',
10 uselib = 'GTK GIOUNIX ZEITGEIST',
11 use = 'libdiodon',
12 cflags = ['-include', 'config.h'],
13 packages = 'gtk+-3.0 gio-unix-2.0 config zeitgeist-2.0',
14 source = bld.path.ant_glob (incl='**/*.vala'))
15
0 [Scope]
1 DBusName=@BUSNAME@.Unity.Scope.Clipboard
2 DBusPath=@BUSOBJECTPATH@/unity/scope/clipboard
3 RequiredMetadata=date_copied[s];
4 OptionalMetadata=origin[s];
5 Keywords=clipboard;diodon;
6 _Name=Clipboard History
7 _Description=This is an Ubuntu search plugin that enables information from Diodon to be searched and displayed in the Dash underneath the Clipboard header.
8 _SearchHint=Search clipboard
9 Type=clipboard
10 IsMaster=true
11 Shortcut=b
12 Icon=@DATADIR@/icons/ubuntu-mono-dark/status/16/diodon-panel.svg
13
14 #
15 # Make translation work with Ubuntu's special handling of keyfiles
16 #
17 [Desktop Entry]
18 X-Ubuntu-Gettext-Domain=@GETTEXT_PACKAGE@
19
20 [Category text]
21 _Name=Text
22 Icon=/usr/share/icons/unity-icon-theme/places/svg/group-notes.svg
23 DedupField=uri
24
25 [Category files]
26 _Name=Files
27 Icon=/usr/share/icons/unity-icon-theme/places/svg/group-files.svg
28 DedupField=uri
29
30 [Category images]
31 _Name=Images
32 Icon=/usr/share/icons/unity-icon-theme/places/svg/group-photos.svg
33 DedupField=uri
34
35 [Filter category]
36 _Name=Category
37 Type=filter-checkoption
38 SortType=display-name
39 OptionIDs=text;files;images
40 _OptionNames=Text;Files;Images
41
42 [Filter date_copied]
43 Name=Date copied
44 Type=filter-radiooption
45 OptionIDs=last-24-hours;last-7-days;last-30-days;last-year;
46 _OptionNames=Last 24 hours;Last 7 days;Last 30 days;Last year;
47
0 [com.canonical.Unity.Dash]
1 scopes=['home.scope', 'applications.scope', 'files.scope', 'video.scope', 'music.scope', 'photos.scope', 'social.scope', 'clipboard.scope']
0 [D-BUS Service]
1 Name=@BUSNAME@.Unity.Scope.Clipboard
2 Exec=@LIBDIR_DIODON@/unity-scope-diodon
0 /*
1 * Diodon - GTK+ clipboard manager.
2 * Copyright (C) 2014 Diodon Team <diodon-team@lists.launchpad.net>
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published
6 * by the Free Software Foundation, either version 2 of the License, or (at
7 * your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
11 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
12 * License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 *
17 * Author:
18 * Oliver Sauder <os@esite.ch>
19 */
20
21 namespace Diodon
22 {
23 private static ZeitgeistClipboardStorage storage;
24 const string GROUP_NAME = Config.BUSNAME + ".Unity.Scope.Clipboard";
25 const string UNIQUE_NAME = Config.BUSOBJECTPATH + "/unity/scope/clipboard";
26 const string ICON_PATH = "/usr/share/icons/unity-icon-theme/places/svg/";
27
28 /**
29 * This is the main function providing access to clipboard history through
30 * a unity scope; the scope is defined and exported, a DBUS connector is
31 * created and the main loop is run
32 */
33 public static int main(string[] args)
34 {
35 debug("Start Unity Scope");
36
37 storage = new ZeitgeistClipboardStorage();
38
39 // Create and setup the scope
40 Unity.SimpleScope scope = new Unity.SimpleScope();
41 scope.group_name = GROUP_NAME;
42 scope.unique_name = UNIQUE_NAME;
43 scope.set_search_async_func(search_async);
44 scope.search_hint = _("Search Clipboard");
45 scope.set_preview_func(preview);
46 scope.category_set = populate_categories();
47 scope.filter_set = populate_filters();
48
49 // result needs to be invalidated whenever clipboard history changes
50 storage.on_items_deleted.connect(() => { scope.results_invalidated(Unity.SearchType.DEFAULT); });
51 storage.on_items_inserted.connect(() => { scope.results_invalidated(Unity.SearchType.DEFAULT); });
52
53 Unity.ScopeDBusConnector connector = new Unity.ScopeDBusConnector(scope);
54 try {
55 connector.export();
56 Unity.ScopeDBusConnector.run();
57
58 debug("Unity scope has been closed");
59 } catch(Error error) {
60 warning("Failed to export Unity ScopeDBusConnector': %s",
61 error.message);
62 return 1;
63 }
64
65 return 0;
66 }
67
68 private static Unity.CategorySet populate_categories()
69 {
70 File icon_dir = File.new_for_path (ICON_PATH);
71 Icon catIcon = new ThemedIcon("diodon-panel");
72 Unity.CategorySet cats = new Unity.CategorySet();
73
74 Unity.Category clipboard = new Unity.Category("global", _("Clipboard"),
75 catIcon, Unity.CategoryRenderer.HORIZONTAL_TILE);
76 cats.add(clipboard);
77
78 Unity.Category text = new Unity.Category("text", _("Text"),
79 new FileIcon(icon_dir.get_child("group-notes.svg")),
80 Unity.CategoryRenderer.HORIZONTAL_TILE);
81 cats.add(text);
82
83 Unity.Category files = new Unity.Category("files", _("Files"),
84 new FileIcon(icon_dir.get_child("group-files.svg")),
85 Unity.CategoryRenderer.HORIZONTAL_TILE);
86 cats.add(files);
87
88 Unity.Category images = new Unity.Category("images", _("Images"),
89 new FileIcon(icon_dir.get_child("group-photos.svg")),
90 Unity.CategoryRenderer.HORIZONTAL_TILE);
91 cats.add(images);
92
93 return cats;
94 }
95
96 private static Unity.FilterSet populate_filters()
97 {
98 Unity.FilterSet filters = new Unity.FilterSet();
99
100 Unity.CheckOptionFilter category = new Unity.CheckOptionFilter("category", _("Category"));
101 category.sort_type = Unity.OptionsFilter.SortType.DISPLAY_NAME;
102
103 category.add_option("text", _("Text"));
104 category.add_option("files", _("Files"));
105 category.add_option("images", _("Images"));
106
107 filters.add(category);
108
109 Unity.RadioOptionFilter date_copied = new Unity.RadioOptionFilter("date_copied", _("Date copied"));
110
111 date_copied.add_option("last-24-hours", _("Last 24 hours"));
112 date_copied.add_option("last-7-days", _("Last 7 days"));
113 date_copied.add_option("last-30-days", _("Last 30 days"));
114 date_copied.add_option("last-year", _("Last year"));
115
116 filters.add(date_copied);
117
118 return filters;
119 }
120
121 private static void search_async(Unity.ScopeSearchBase search, Unity.ScopeSearchBaseCallback callback)
122 {
123 Diodon.search.begin(search, () => { callback(search); });
124 }
125
126 private static async void search(Unity.ScopeSearchBase search)
127 {
128 Cancellable? cancellable = search.search_context.cancellable.get_gcancellable();
129 ClipboardCategory[]? cats = get_filter_categories(search.search_context.filter_state);
130 ClipboardTimerange date_copied = get_filter_datecopied(search.search_context.filter_state);
131 List<IClipboardItem> items = yield storage.get_items_by_search_query(
132 search.search_context.search_query, cats, date_copied, cancellable);
133
134 if(!search.search_context.cancellable.is_cancelled()) {
135 foreach(IClipboardItem item in items) {
136 Unity.ScopeResult result = Unity.ScopeResult();
137 string? origin = item.get_origin();
138
139 result.uri = "clipboard:" + item.get_checksum();
140 // TODO see comment ZeitgeistClipboardStorage.CLIPBOARD_URI but
141 // here we actually need clipboard:// uri
142 //result.uri = ZeitgeistClipboardStorage.CLIPBOARD_URI + item.get_checksum();
143 result.title = item.get_label();
144 result.icon_hint = item.get_icon().to_string();
145 result.category = item.get_category();
146 result.result_type = Unity.ResultType.DEFAULT;
147 result.mimetype = item.get_mime_type();
148 result.comment = item.get_text();
149 result.dnd_uri = result.uri;
150
151 result.metadata = new HashTable<string, Variant>(str_hash, str_equal);
152 if(origin != null) {
153 result.metadata.insert("origin", new Variant.string(origin));
154 }
155 DateTime local_date_copied = item.get_date_copied().to_local();
156 result.metadata.insert("date_copied", new Variant.string(local_date_copied.format("%Y-%m-%d %H:%M:%S")));
157
158 search.search_context.result_set.add_result(result);
159 }
160 }
161 }
162
163 /**
164 * Get currently set cateogry filters. Return null if none or all are set.
165 */
166 private static ClipboardCategory[]? get_filter_categories(Unity.FilterSet filter_state)
167 {
168 /* returns null if the filter is disabled / all options selected */
169 Unity.CheckOptionFilter filter = filter_state.get_filter_by_id("category") as Unity.CheckOptionFilter;
170
171 if (filter == null || !filter.filtering) return null;
172
173 ClipboardCategory[] cats = {};
174
175 foreach (ClipboardCategory cat in ClipboardCategory.all())
176 {
177 Unity.FilterOption? option = filter.get_option(cat.to_string());
178 if (option == null || !option.active) continue;
179
180 cats += cat;
181 }
182
183 if (cats.length == ClipboardCategory.all().length) return null;
184
185 return cats;
186 }
187
188 private static ClipboardTimerange get_filter_datecopied(Unity.FilterSet filter_state)
189 {
190 Unity.RadioOptionFilter filter = filter_state.get_filter_by_id("date_copied") as Unity.RadioOptionFilter;
191 Unity.FilterOption? option = filter.get_active_option();
192
193 string date_copied = option == null ? "all" : option.id;
194
195 return ClipboardTimerange.from_string(date_copied);
196 }
197
198 private static Unity.AbstractPreview? preview(Unity.ResultPreviewer previewer)
199 {
200 Unity.ScopeResult result = previewer.result;
201
202 Icon hint_icon = null;
203 try {
204 hint_icon = Icon.new_for_string(result.icon_hint);
205 } catch(Error error) {
206 warning("Could not convert icon_hint to an icon': %s",
207 error.message);
208 hint_icon = ContentType.get_icon("text/plain");
209 }
210
211 debug("Show preview for %s", result.title);
212 Unity.Preview preview = new Unity.GenericPreview(result.title,
213 result.comment, hint_icon);
214 Unity.PreviewAction copy_action = new Unity.PreviewAction.with_uri(result.uri,
215 _("Paste"), null);
216 preview.add_action(copy_action);
217
218 // add metadata
219 if(result.metadata != null) {
220 Variant? orign_variant = result.metadata.lookup("origin");
221 if(orign_variant != null) {
222 Unity.InfoHint origin_info = new Unity.InfoHint.with_variant(
223 "origin", _("Origin"), null, orign_variant);
224 preview.add_info(origin_info);
225 }
226
227 Variant? date_copied_variant = result.metadata.lookup("date_copied");
228 if(date_copied_variant != null) {
229 Unity.InfoHint date_copied_info = new Unity.InfoHint.with_variant(
230 "date_copied", _("Date copied"), null, date_copied_variant);
231 preview.add_info(date_copied_info);
232 }
233 }
234
235 return preview;
236 }
237 }
0 #! /usr/bin/env python
1 # encoding: utf-8
2 # Oliver Sauder, 2010
3
4 import Options
5
6 prog = bld.new_task_gen (
7 features = 'c cprogram',
8 target = 'unity-scope-diodon',
9 vapi_dirs = '../vapi ../libdiodon',
10 uselib = 'GTK UNITY',
11 use = 'libdiodon',
12 cflags = ['-include', 'config.h'],
13 packages = 'gtk+-3.0 unity config',
14 source = 'unity-scope-diodon.vala')
15
16 prog.install_path = bld.env['LIBDIR_DIODON']
17
18 bld.new_task_gen (
19 features = "subst",
20 source= "clipboard.scope.in.in",
21 target= "clipboard.scope.in",
22 BUSNAME = bld.env['BUSNAME'],
23 BUSOBJECTPATH = bld.env['BUSOBJECTPATH'])
24
25 bld.new_task_gen (
26 features = 'intltool_in',
27 podir = '../po',
28 source = 'clipboard.scope.in',
29 flags = ["-d", "-q", "-u", "-c"],
30 install_path = "${DATADIR}/unity/scopes")
31
32 bld.new_task_gen (
33 features = "subst",
34 source= "unity-scope-diodon.service.in",
35 target= "unity-scope-diodon.service",
36 BUSNAME = bld.env['BUSNAME'],
37 LIBDIR_DIODON = bld.env['LIBDIR_DIODON'],
38 install_path = "${DATADIR}/dbus-1/services")
39
40 bld.install_files('${DATADIR}/glib-2.0/schemas', 'unity-scope-diodon.gschema.override')
41
0 /*
1 * Diodon - GTK+ clipboard manager.
2 * Copyright (C) 2010-2013 Diodon Team <diodon-team@lists.launchpad.net>
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License as published
6 * by the Free Software Foundation, either version 2 of the License, or (at
7 * your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
11 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
12 * License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18 [CCode (cprefix = "", lower_case_cprefix = "", cheader_filename = "config.h")]
19 namespace Config
20 {
21 public const bool DEBUG;
22
23 public const string GETTEXT_PACKAGE;
24
25 public const string APPNAME;
26 public const string PACKAGE_NAME;
27 public const string VERSION;
28 public const string COPYRIGHT;
29 public const string WEBSITE;
30
31 public const string BUSNAME;
32 public const string BUSOBJECTPATH;
33
34 public const string LOCALEDIR;
35 public const string SHAREDIR;
36 public const string LIBDIR;
37 public const string PLUGINS_DIR;
38 public const string PLUGINS_DATA_DIR;
39
40 public const string TEST_DATA_DIR;
41 }
42
+164
-0
waf less more
0 #!/usr/bin/env python
1 # encoding: ISO8859-1
2 # Thomas Nagy, 2005-2011
3
4 """
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions
7 are met:
8
9 1. Redistributions of source code must retain the above copyright
10 notice, this list of conditions and the following disclaimer.
11
12 2. Redistributions in binary form must reproduce the above copyright
13 notice, this list of conditions and the following disclaimer in the
14 documentation and/or other materials provided with the distribution.
15
16 3. The name of the author may not be used to endorse or promote products
17 derived from this software without specific prior written permission.
18
19 THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
20 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22 DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
23 INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
27 STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
28 IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 POSSIBILITY OF SUCH DAMAGE.
30 """
31
32 import os, sys
33
34 VERSION="1.6.11"
35 REVISION="x"
36 INSTALL="x"
37 C1='x'
38 C2='x'
39 cwd = os.getcwd()
40 join = os.path.join
41
42 if sys.hexversion<0x206000f:
43 raise ImportError('Python >= 2.6 is required to create the waf file')
44
45 WAF='waf'
46 def b(x):
47 return x
48 if sys.hexversion>0x300000f:
49 WAF='waf3'
50 def b(x):
51 return x.encode()
52
53 def err(m):
54 print(('\033[91mError: %s\033[0m' % m))
55 sys.exit(1)
56
57 def unpack_wafdir(dir):
58 f = open(sys.argv[0],'rb')
59 c = 'corrupt archive (%d)'
60 while 1:
61 line = f.readline()
62 if not line: err('run waf-light from a folder containing waflib')
63 if line == b('#==>\n'):
64 txt = f.readline()
65 if not txt: err(c % 1)
66 if f.readline() != b('#<==\n'): err(c % 2)
67 break
68 if not txt: err(c % 3)
69 txt = txt[1:-1].replace(b(C1), b('\n')).replace(b(C2), b('\r'))
70
71 import shutil, tarfile
72 try: shutil.rmtree(dir)
73 except OSError: pass
74 try:
75 for x in ['Tools', 'extras']:
76 os.makedirs(join(dir, 'waflib', x))
77 except OSError:
78 err("Cannot unpack waf lib into %s\nMove waf into a writeable directory" % dir)
79
80 os.chdir(dir)
81 tmp = 't.bz2'
82 t = open(tmp,'wb')
83 t.write(txt)
84 t.close()
85
86 try:
87 t = tarfile.open(tmp)
88 except:
89 try:
90 os.system('bunzip2 t.bz2')
91 t = tarfile.open('t')
92 tmp = 't'
93 except:
94 os.chdir(cwd)
95 try: shutil.rmtree(dir)
96 except OSError: pass
97 err("Waf cannot be unpacked, check that bzip2 support is present")
98
99 for x in t: t.extract(x)
100 t.close()
101
102 for x in ['Tools', 'extras']:
103 os.chmod(join('waflib',x), 493)
104
105 if sys.hexversion<0x300000f:
106 sys.path = [join(dir, 'waflib')] + sys.path
107 import fixpy2
108 fixpy2.fixdir(dir)
109
110 os.unlink(tmp)
111 os.chdir(cwd)
112
113 try: dir = unicode(dir, 'mbcs')
114 except: pass
115 try:
116 from ctypes import windll
117 windll.kernel32.SetFileAttributesW(dir, 2)
118 except:
119 pass
120
121 def test(dir):
122 try:
123 os.stat(join(dir, 'waflib'))
124 return os.path.abspath(dir)
125 except OSError:
126 pass
127
128 def find_lib():
129 name = sys.argv[0]
130 base = os.path.dirname(os.path.abspath(name))
131
132 #devs use $WAFDIR
133 w=test(os.environ.get('WAFDIR', ''))
134 if w: return w
135
136 #waf-light
137 if name.endswith('waf-light'):
138 w = test(base)
139 if w: return w
140 err('waf-light requires waflib -> export WAFDIR=/folder')
141
142 dirname = '%s-%s-%s' % (WAF, VERSION, REVISION)
143 for i in [INSTALL,'/usr','/usr/local','/opt']:
144 w = test(i + '/lib/' + dirname)
145 if w: return w
146
147 #waf-local
148 dir = join(base, (sys.platform != 'win32' and '.' or '') + dirname)
149 w = test(dir)
150 if w: return w
151
152 #unpack
153 unpack_wafdir(dir)
154 return dir
155
156 wafdir = find_lib()
157 sys.path.insert(0, wafdir)
158
159 if __name__ == '__main__':
160 import waflib.extras.compat15#PRELUDE
161 from waflib import Scripting
162 Scripting.waf_entry_point(cwd, VERSION, wafdir)
163
0 #!/usr/bin/env python
1 # encoding: utf-8
2 # Thomas Nagy, 2005-2010 (ita)
3
4 """
5 Classes related to the build phase (build, clean, install, step, etc)
6
7 The inheritance tree is the following:
8
9 """
10
11 import os, sys, errno, re, shutil
12 try: import cPickle
13 except: import pickle as cPickle
14 from waflib import Runner, TaskGen, Utils, ConfigSet, Task, Logs, Options, Context, Errors
15 import waflib.Node
16
17 CACHE_DIR = 'c4che'
18 """Location of the cache files"""
19
20 CACHE_SUFFIX = '_cache.py'
21 """Suffix for the cache files"""
22
23 INSTALL = 1337
24 """Positive value '->' install, see :py:attr:`waflib.Build.BuildContext.is_install`"""
25
26 UNINSTALL = -1337
27 """Negative value '<-' uninstall, see :py:attr:`waflib.Build.BuildContext.is_install`"""
28
29 SAVED_ATTRS = 'root node_deps raw_deps task_sigs'.split()
30 """Build class members to save between the runs (root, node_deps, raw_deps, task_sigs)"""
31
32 CFG_FILES = 'cfg_files'
33 """Files from the build directory to hash before starting the build (``config.h`` written during the configuration)"""
34
35 POST_AT_ONCE = 0
36 """Post mode: all task generators are posted before the build really starts"""
37
38 POST_LAZY = 1
39 """Post mode: post the task generators group after group"""
40
41 POST_BOTH = 2
42 """Post mode: post the task generators at once, then re-check them for each group"""
43
44 class BuildContext(Context.Context):
45 '''executes the build'''
46
47 cmd = 'build'
48 variant = ''
49
50 def __init__(self, **kw):
51 super(BuildContext, self).__init__(**kw)
52
53 self.is_install = 0
54 """Non-zero value when installing or uninstalling file"""
55
56 self.top_dir = kw.get('top_dir', Context.top_dir)
57
58 self.run_dir = kw.get('run_dir', Context.run_dir)
59
60 self.post_mode = POST_AT_ONCE
61 """post the task generators at once, group-by-group, or both"""
62
63 # output directory - may be set until the nodes are considered
64 self.out_dir = kw.get('out_dir', Context.out_dir)
65
66 self.cache_dir = kw.get('cache_dir', None)
67 if not self.cache_dir:
68 self.cache_dir = self.out_dir + os.sep + CACHE_DIR
69
70 # map names to environments, the '' must be defined
71 self.all_envs = {}
72
73 # ======================================= #
74 # cache variables
75
76 self.task_sigs = {}
77 """Signatures of the tasks (persists between build executions)"""
78
79 self.node_deps = {}
80 """Dict of node dependencies found by :py:meth:`waflib.Task.Task.scan` (persists between build executions)"""
81
82 self.raw_deps = {}
83 """Dict of custom data returned by :py:meth:`waflib.Task.Task.scan` (persists between build executions)"""
84
85 # list of folders that are already scanned
86 # so that we do not need to stat them one more time
87 self.cache_dir_contents = {}
88
89 self.task_gen_cache_names = {}
90
91 self.launch_dir = Context.launch_dir
92
93 self.jobs = Options.options.jobs
94 self.targets = Options.options.targets
95 self.keep = Options.options.keep
96 self.cache_global = Options.cache_global
97 self.nocache = Options.options.nocache
98 self.progress_bar = Options.options.progress_bar
99
100 ############ stuff below has not been reviewed
101
102 # Manual dependencies.
103 self.deps_man = Utils.defaultdict(list)
104 """Manual dependencies set by :py:meth:`waflib.Build.BuildContext.add_manual_dependency`"""
105
106 # just the structure here
107 self.current_group = 0
108 """
109 Current build group
110 """
111
112 self.groups = []
113 """
114 List containing lists of task generators
115 """
116 self.group_names = {}
117 """
118 Map group names to the group lists. See :py:meth:`waflib.Build.BuildContext.add_group`
119 """
120
121 def get_variant_dir(self):
122 """Getter for the variant_dir attribute"""
123 if not self.variant:
124 return self.out_dir
125 return os.path.join(self.out_dir, self.variant)
126 variant_dir = property(get_variant_dir, None)
127
128 def __call__(self, *k, **kw):
129 """
130 Create a task generator and add it to the current build group. The following forms are equivalent::
131
132 def build(bld):
133 tg = bld(a=1, b=2)
134
135 def build(bld):
136 tg = bld()
137 tg.a = 1
138 tg.b = 2
139
140 def build(bld):
141 tg = TaskGen.task_gen(a=1, b=2)
142 bld.add_to_group(tg, None)
143
144 :param group: group name to add the task generator to
145 :type group: string
146 """
147 kw['bld'] = self
148 ret = TaskGen.task_gen(*k, **kw)
149 self.task_gen_cache_names = {} # reset the cache, each time
150 self.add_to_group(ret, group=kw.get('group', None))
151 return ret
152
153 def __copy__(self):
154 """Implemented to prevents copies of build contexts (raises an exception)"""
155 raise Errors.WafError('build contexts are not supposed to be copied')
156
157 def install_files(self, *k, **kw):
158 """Actual implementation provided by :py:meth:`waflib.Build.InstallContext.install_files`"""
159 pass
160
161 def install_as(self, *k, **kw):
162 """Actual implementation provided by :py:meth:`waflib.Build.InstallContext.install_as`"""
163 pass
164
165 def symlink_as(self, *k, **kw):
166 """Actual implementation provided by :py:meth:`waflib.Build.InstallContext.symlink_as`"""
167 pass
168
169 def load_envs(self):
170 """
171 The configuration command creates files of the form ``build/c4che/NAMEcache.py``. This method
172 creates a :py:class:`waflib.ConfigSet.ConfigSet` instance for each ``NAME`` by reading those
173 files. The config sets are then stored in the dict :py:attr:`waflib.Build.BuildContext.allenvs`.
174 """
175 node = self.root.find_node(self.cache_dir)
176 if not node:
177 raise Errors.WafError('The project was not configured: run "waf configure" first!')
178 lst = node.ant_glob('**/*%s' % CACHE_SUFFIX, quiet=True)
179
180 if not lst:
181 raise Errors.WafError('The cache directory is empty: reconfigure the project')
182
183 for x in lst:
184 name = x.path_from(node).replace(CACHE_SUFFIX, '').replace('\\', '/')
185 env = ConfigSet.ConfigSet(x.abspath())
186 self.all_envs[name] = env
187 for f in env[CFG_FILES]:
188 newnode = self.root.find_resource(f)
189 try:
190 h = Utils.h_file(newnode.abspath())
191 except (IOError, AttributeError):
192 Logs.error('cannot find %r' % f)
193 h = Utils.SIG_NIL
194 newnode.sig = h
195
196 def init_dirs(self):
197 """
198 Initialize the project directory and the build directory by creating the nodes
199 :py:attr:`waflib.Build.BuildContext.srcnode` and :py:attr:`waflib.Build.BuildContext.bldnode`
200 corresponding to ``top_dir`` and ``variant_dir`` respectively. The ``bldnode`` directory will be
201 created if it does not exist.
202 """
203
204 if not (os.path.isabs(self.top_dir) and os.path.isabs(self.out_dir)):
205 raise Errors.WafError('The project was not configured: run "waf configure" first!')
206
207 self.path = self.srcnode = self.root.find_dir(self.top_dir)
208 self.bldnode = self.root.make_node(self.variant_dir)
209 self.bldnode.mkdir()
210
211 def execute(self):
212 """
213 Restore the data from previous builds and call :py:meth:`waflib.Build.BuildContext.execute_build`. Overrides from :py:func:`waflib.Context.Context.execute`
214 """
215 self.restore()
216 if not self.all_envs:
217 self.load_envs()
218
219 self.execute_build()
220
221 def execute_build(self):
222 """
223 Execute the build by:
224
225 * reading the scripts (see :py:meth:`waflib.Context.Context.recurse`)
226 * calling :py:meth:`waflib.Build.BuildContext.pre_build` to call user build functions
227 * calling :py:meth:`waflib.Build.BuildContext.compile` to process the tasks
228 * calling :py:meth:`waflib.Build.BuildContext.post_build` to call user build functions
229 """
230
231 Logs.info("Waf: Entering directory `%s'" % self.variant_dir)
232 self.recurse([self.run_dir])
233 self.pre_build()
234
235 # display the time elapsed in the progress bar
236 self.timer = Utils.Timer()
237
238 if self.progress_bar:
239 sys.stderr.write(Logs.colors.cursor_off)
240 try:
241 self.compile()
242 finally:
243 if self.progress_bar == 1:
244 c = len(self.returned_tasks) or 1
245 self.to_log(self.progress_line(c, c, Logs.colors.BLUE, Logs.colors.NORMAL))
246 print('')
247 sys.stdout.flush()
248 sys.stderr.write(Logs.colors.cursor_on)
249 Logs.info("Waf: Leaving directory `%s'" % self.variant_dir)
250 self.post_build()
251
252 def restore(self):
253 """
254 Load the data from a previous run, sets the attributes listed in :py:const:`waflib.Build.SAVED_ATTRS`
255 """
256 try:
257 env = ConfigSet.ConfigSet(os.path.join(self.cache_dir, 'build.config.py'))
258 except (IOError, OSError):
259 pass
260 else:
261 if env['version'] < Context.HEXVERSION:
262 raise Errors.WafError('Version mismatch! reconfigure the project')
263 for t in env['tools']:
264 self.setup(**t)
265
266 f = None
267 try:
268 dbfn = os.path.join(self.variant_dir, Context.DBFILE)
269 try:
270 f = open(dbfn, 'rb')
271 except (IOError, EOFError):
272 # handle missing file/empty file
273 Logs.debug('build: could not load the build cache %s (missing)' % dbfn)
274 else:
275 try:
276 waflib.Node.pickle_lock.acquire()
277 waflib.Node.Nod3 = self.node_class
278 try:
279 data = cPickle.load(f)
280 except Exception as e:
281 Logs.debug('build: could not pickle the build cache %s: %r' % (dbfn, e))
282 else:
283 for x in SAVED_ATTRS:
284 setattr(self, x, data[x])
285 finally:
286 waflib.Node.pickle_lock.release()
287 finally:
288 if f:
289 f.close()
290
291 self.init_dirs()
292
293 def store(self):
294 """
295 Store the data for next runs, sets the attributes listed in :py:const:`waflib.Build.SAVED_ATTRS`. Uses a temporary
296 file to avoid problems on ctrl+c.
297 """
298
299 data = {}
300 for x in SAVED_ATTRS:
301 data[x] = getattr(self, x)
302 db = os.path.join(self.variant_dir, Context.DBFILE)
303
304 try:
305 waflib.Node.pickle_lock.acquire()
306 waflib.Node.Nod3 = self.node_class
307
308 f = None
309 try:
310 f = open(db + '.tmp', 'wb')
311 cPickle.dump(data, f)
312 finally:
313 if f:
314 f.close()
315 finally:
316 waflib.Node.pickle_lock.release()
317
318 try:
319 st = os.stat(db)
320 os.unlink(db)
321 if not Utils.is_win32: # win32 has no chown but we're paranoid
322 os.chown(db + '.tmp', st.st_uid, st.st_gid)
323 except (AttributeError, OSError):
324 pass
325
326 # do not use shutil.move (copy is not thread-safe)
327 os.rename(db + '.tmp', db)
328
329 def compile(self):
330 """
331 Run the build by creating an instance of :py:class:`waflib.Runner.Parallel`
332 The cache file is not written if the build is up to date (no task executed).
333 """
334 Logs.debug('build: compile()')
335
336 # use another object to perform the producer-consumer logic (reduce the complexity)
337 self.producer = Runner.Parallel(self, self.jobs)
338 self.producer.biter = self.get_build_iterator()
339 self.returned_tasks = [] # not part of the API yet
340 try:
341 self.producer.start()
342 except KeyboardInterrupt:
343 self.store()
344 raise
345 else:
346 if self.producer.dirty:
347 self.store()
348
349 if self.producer.error:
350 raise Errors.BuildError(self.producer.error)
351
352 def setup(self, tool, tooldir=None, funs=None):
353 """
354 Import waf tools, used to import those accessed during the configuration::
355
356 def configure(conf):
357 conf.load('glib2')
358
359 def build(bld):
360 pass # glib2 is imported implicitly
361
362 :param tool: tool list
363 :type tool: list
364 :param tooldir: optional tool directory (sys.path)
365 :type tooldir: list of string
366 :param funs: unused variable
367 """
368 if isinstance(tool, list):
369 for i in tool: self.setup(i, tooldir)
370 return
371
372 module = Context.load_tool(tool, tooldir)
373 if hasattr(module, "setup"): module.setup(self)
374
375 def get_env(self):
376 """Getter for the env property"""
377 try:
378 return self.all_envs[self.variant]
379 except KeyError:
380 return self.all_envs['']
381 def set_env(self, val):
382 """Setter for the env property"""
383 self.all_envs[self.variant] = val
384
385 env = property(get_env, set_env)
386
387 def add_manual_dependency(self, path, value):
388 """
389 Adds a dependency from a node object to a value::
390
391 def build(bld):
392 bld.add_manual_dependency(
393 bld.path.find_resource('wscript'),
394 bld.root.find_resource('/etc/fstab'))
395
396 :param path: file path
397 :type path: string or :py:class:`waflib.Node.Node`
398 :param value: value to depend on
399 :type value: :py:class:`waflib.Node.Node`, string, or function returning a string
400 """
401 if isinstance(path, waflib.Node.Node):
402 node = path
403 elif os.path.isabs(path):
404 node = self.root.find_resource(path)
405 else:
406 node = self.path.find_resource(path)
407 self.deps_man[id(node)].append(value)
408
409 def launch_node(self):
410 """Returns the launch directory as a :py:class:`waflib.Node.Node` object"""
411 try:
412 # private cache
413 return self.p_ln
414 except AttributeError:
415 self.p_ln = self.root.find_dir(self.launch_dir)
416 return self.p_ln
417
418 def hash_env_vars(self, env, vars_lst):
419 """
420 Hash configuration set variables::
421
422 def build(bld):
423 bld.hash_env_vars(bld.env, ['CXX', 'CC'])
424
425 :param env: Configuration Set
426 :type env: :py:class:`waflib.ConfigSet.ConfigSet`
427 :param vars_lst: list of variables
428 :type vars_list: list of string
429 """
430
431 if not env.table:
432 env = env.parent
433 if not env:
434 return Utils.SIG_NIL
435
436 idx = str(id(env)) + str(vars_lst)
437 try:
438 cache = self.cache_env
439 except AttributeError:
440 cache = self.cache_env = {}
441 else:
442 try:
443 return self.cache_env[idx]
444 except KeyError:
445 pass
446
447 lst = [env[a] for a in vars_lst]
448 ret = Utils.h_list(lst)
449 Logs.debug('envhash: %s %r', Utils.to_hex(ret), lst)
450
451 cache[idx] = ret
452
453 return ret
454
455 def get_tgen_by_name(self, name):
456 """
457 Retrieves a task generator from its name or its target name
458 the name must be unique::
459
460 def build(bld):
461 tg = bld(name='foo')
462 tg == bld.get_tgen_by_name('foo')
463 """
464 cache = self.task_gen_cache_names
465 if not cache:
466 # create the index lazily
467 for g in self.groups:
468 for tg in g:
469 try:
470 cache[tg.name] = tg
471 except AttributeError:
472 # raised if not a task generator, which should be uncommon
473 pass
474 try:
475 return cache[name]
476 except KeyError:
477 raise Errors.WafError('Could not find a task generator for the name %r' % name)
478
479 def progress_line(self, state, total, col1, col2):
480 """
481 Compute the progress bar used by ``waf -p``
482 """
483 n = len(str(total))
484
485 Utils.rot_idx += 1
486 ind = Utils.rot_chr[Utils.rot_idx % 4]
487
488 pc = (100.*state)/total
489 eta = str(self.timer)
490 fs = "[%%%dd/%%%dd][%%s%%2d%%%%%%s][%s][" % (n, n, ind)
491 left = fs % (state, total, col1, pc, col2)
492 right = '][%s%s%s]' % (col1, eta, col2)
493
494 cols = Logs.get_term_cols() - len(left) - len(right) + 2*len(col1) + 2*len(col2)
495 if cols < 7: cols = 7
496
497 ratio = ((cols*state)//total) - 1
498
499 bar = ('='*ratio+'>').ljust(cols)
500 msg = Utils.indicator % (left, bar, right)
501
502 return msg
503
504 def declare_chain(self, *k, **kw):
505 """
506 Wrapper for :py:func:`waflib.TaskGen.declare_chain` provided for convenience
507 """
508 return TaskGen.declare_chain(*k, **kw)
509
510 def pre_build(self):
511 """Execute user-defined methods before the build starts, see :py:meth:`waflib.Build.BuildContext.add_pre_fun`"""
512 for m in getattr(self, 'pre_funs', []):
513 m(self)
514
515 def post_build(self):
516 """Executes the user-defined methods after the build is successful, see :py:meth:`waflib.Build.BuildContext.add_post_fun`"""
517 for m in getattr(self, 'post_funs', []):
518 m(self)
519
520 def add_pre_fun(self, meth):
521 """
522 Bind a method to execute after the scripts are read and before the build starts::
523
524 def mycallback(bld):
525 print("Hello, world!")
526
527 def build(bld):
528 bld.add_pre_fun(mycallback)
529 """
530 try:
531 self.pre_funs.append(meth)
532 except AttributeError:
533 self.pre_funs = [meth]
534
535 def add_post_fun(self, meth):
536 """
537 Bind a method to execute immediately after the build is successful::
538
539 def call_ldconfig(bld):
540 bld.exec_command('/sbin/ldconfig')
541
542 def build(bld):
543 if bld.cmd == 'install':
544 bld.add_pre_fun(call_ldconfig)
545 """
546 try:
547 self.post_funs.append(meth)
548 except AttributeError:
549 self.post_funs = [meth]
550
551 def get_group(self, x):
552 """
553 Get the group x, or return the current group if x is None
554
555 :param x: name or number or None
556 :type x: string, int or None
557 """
558 if not self.groups:
559 self.add_group()
560 if x is None:
561 return self.groups[self.current_group]
562 if x in self.group_names:
563 return self.group_names[x]
564 return self.groups[x]
565
566 def add_to_group(self, tgen, group=None):
567 """add a task or a task generator for the build"""
568 # paranoid
569 assert(isinstance(tgen, TaskGen.task_gen) or isinstance(tgen, Task.TaskBase))
570 tgen.bld = self
571 self.get_group(group).append(tgen)
572
573 def get_group_name(self, g):
574 """name for the group g (utility)"""
575 if not isinstance(g, list):
576 g = self.groups[g]
577 for x in self.group_names:
578 if id(self.group_names[x]) == id(g):
579 return x
580 return ''
581
582 def get_group_idx(self, tg):
583 """
584 Index of the group containing the task generator given as argument::
585
586 def build(bld):
587 tg = bld(name='nada')
588 0 == bld.get_group_idx(tg)
589
590 :param tg: Task generator object
591 :type tg: :py:class:`waflib.TaskGen.task_gen`
592 """
593 se = id(tg)
594 for i in range(len(self.groups)):
595 for t in self.groups[i]:
596 if id(t) == se:
597 return i
598 return None
599
600 def add_group(self, name=None, move=True):
601 """
602 Add a new group of tasks/task generators. By default the new group becomes the default group for new task generators.
603
604 :param name: name for this group
605 :type name: string
606 :param move: set the group created as default group (True by default)
607 :type move: bool
608 """
609 #if self.groups and not self.groups[0].tasks:
610 # error('add_group: an empty group is already present')
611 if name and name in self.group_names:
612 Logs.error('add_group: name %s already present' % name)
613 g = []
614 self.group_names[name] = g
615 self.groups.append(g)
616 if move:
617 self.current_group = len(self.groups) - 1
618
619 def set_group(self, idx):
620 """
621 Set the current group to be idx: now new task generators will be added to this group by default::
622
623 def build(bld):
624 bld(rule='touch ${TGT}', target='foo.txt')
625 bld.add_group() # now the current group is 1
626 bld(rule='touch ${TGT}', target='bar.txt')
627 bld.set_group(0) # now the current group is 0
628 bld(rule='touch ${TGT}', target='truc.txt') # build truc.txt before bar.txt
629
630 :param idx: group name or group index
631 :type idx: string or int
632 """
633 if isinstance(idx, str):
634 g = self.group_names[idx]
635 for i in range(len(self.groups)):
636 if id(g) == id(self.groups[i]):
637 self.current_group = i
638 else:
639 self.current_group = idx
640
641 def total(self):
642 """
643 Approximate task count: this value may be inaccurate if task generators are posted lazily (see :py:attr:`waflib.Build.BuildContext.post_mode`).
644 The value :py:attr:`waflib.Runner.Parallel.total` is updated during the task execution.
645 """
646 total = 0
647 for group in self.groups:
648 for tg in group:
649 try:
650 total += len(tg.tasks)
651 except AttributeError:
652 total += 1
653 return total
654
655 def get_targets(self):
656 """
657 Return the task generator corresponding to the 'targets' list, used by :py:meth:`waflib.Build.BuildContext.get_build_iterator`::
658
659 $ waf --targets=myprogram,myshlib
660 """
661 to_post = []
662 min_grp = 0
663 for name in self.targets.split(','):
664 tg = self.get_tgen_by_name(name)
665 if not tg:
666 raise Errors.WafError('target %r does not exist' % name)
667
668 m = self.get_group_idx(tg)
669 if m > min_grp:
670 min_grp = m
671 to_post = [tg]
672 elif m == min_grp:
673 to_post.append(tg)
674 return (min_grp, to_post)
675
676 def post_group(self):
677 """
678 Post the task generators from the group indexed by self.cur, used by :py:meth:`waflib.Build.BuildContext.get_build_iterator`
679 """
680 if self.targets == '*':
681 for tg in self.groups[self.cur]:
682 try:
683 f = tg.post
684 except AttributeError:
685 pass
686 else:
687 f()
688 elif self.targets:
689 if self.cur < self._min_grp:
690 for tg in self.groups[self.cur]:
691 try:
692 f = tg.post
693 except AttributeError:
694 pass
695 else:
696 f()
697 else:
698 for tg in self._exact_tg:
699 tg.post()
700 else:
701 ln = self.launch_node()
702 for tg in self.groups[self.cur]:
703 try:
704 f = tg.post
705 except AttributeError:
706 pass
707 else:
708 if tg.path.is_child_of(ln):
709 f()
710
711 def get_tasks_group(self, idx):
712 """
713 Return all the tasks for the group of num idx, used by :py:meth:`waflib.Build.BuildContext.get_build_iterator`
714 """
715 tasks = []
716 for tg in self.groups[idx]:
717 # TODO a try-except might be more efficient
718 if isinstance(tg, Task.TaskBase):
719 tasks.append(tg)
720 else:
721 tasks.extend(tg.tasks)
722 return tasks
723
724 def get_build_iterator(self):
725 """
726 Creates a generator object that returns lists of tasks executable in parallel (yield)
727
728 :return: tasks which can be executed immediatly
729 :rtype: list of :py:class:`waflib.Task.TaskBase`
730 """
731 self.cur = 0
732
733 if self.targets and self.targets != '*':
734 (self._min_grp, self._exact_tg) = self.get_targets()
735
736 global lazy_post
737 if self.post_mode != POST_LAZY:
738 while self.cur < len(self.groups):
739 self.post_group()
740 self.cur += 1
741 self.cur = 0
742
743 while self.cur < len(self.groups):
744 # first post the task generators for the group
745 if self.post_mode != POST_AT_ONCE:
746 self.post_group()
747
748 # then extract the tasks
749 tasks = self.get_tasks_group(self.cur)
750 # if the constraints are set properly (ext_in/ext_out, before/after)
751 # the call to set_file_constraints may be removed (can be a 15% penalty on no-op rebuilds)
752 # (but leave set_file_constraints for the installation step)
753 #
754 # if the tasks have only files, set_file_constraints is required but set_precedence_constraints is not necessary
755 #
756 Task.set_file_constraints(tasks)
757 Task.set_precedence_constraints(tasks)
758
759 self.cur_tasks = tasks
760 self.cur += 1
761 if not tasks: # return something else the build will stop
762 continue
763 yield tasks
764 while 1:
765 yield []
766
767
768 #def install_dir(self, path, env=None):
769 # """
770 # Create empty folders for the installation (very rarely used) TODO
771 # """
772 # return
773
774 class inst(Task.Task):
775 """
776 Special task used for installing files and symlinks, it behaves both like a task
777 and like a task generator
778 """
779 color = 'CYAN'
780
781 def post(self):
782 """
783 Same interface as in :py:meth:`waflib.TaskGen.task_gen.post`
784 """
785 buf = []
786 for x in self.source:
787 if isinstance(x, waflib.Node.Node):
788 y = x
789 else:
790 y = self.path.find_resource(x)
791 if not y:
792 if Logs.verbose:
793 Logs.warn('Could not find %s immediately (may cause broken builds)' % x)
794 idx = self.generator.bld.get_group_idx(self)
795 for tg in self.generator.bld.groups[idx]:
796 if not isinstance(tg, inst) and id(tg) != id(self):
797 tg.post()
798 y = self.path.find_resource(x)
799 if y:
800 break
801 else:
802 raise Errors.WafError('could not find %r in %r' % (x, self.path))
803 buf.append(y)
804 self.inputs = buf
805
806 def runnable_status(self):
807 """
808 Installation tasks are always executed, so this method returns either :py:const:`waflib.Task.ASK_LATER` or :py:const:`waflib.Task.RUN_ME`.
809 """
810 ret = super(inst, self).runnable_status()
811 if ret == Task.SKIP_ME:
812 return Task.RUN_ME
813 return ret
814
815 def __str__(self):
816 """Return an empty string to disable the display"""
817 return ''
818
819 def run(self):
820 """The attribute 'exec_task' holds the method to execute"""
821 return self.generator.exec_task()
822
823 def get_install_path(self, destdir=True):
824 """
825 Installation path obtained from ``self.dest`` and prefixed by the destdir.
826 The variables such as '${PREFIX}/bin' are substituted.
827 """
828 dest = Utils.subst_vars(self.dest, self.env)
829 dest = dest.replace('/', os.sep)
830 if destdir and Options.options.destdir:
831 dest = os.path.join(Options.options.destdir, os.path.splitdrive(dest)[1].lstrip(os.sep))
832 return dest
833
834 def exec_install_files(self):
835 """
836 Predefined method for installing files
837 """
838 destpath = self.get_install_path()
839 if not destpath:
840 raise Errors.WafError('unknown installation path %r' % self.generator)
841 for x, y in zip(self.source, self.inputs):
842 if self.relative_trick:
843 destfile = os.path.join(destpath, y.path_from(self.path))
844 Utils.check_dir(os.path.dirname(destfile))
845 else:
846 destfile = os.path.join(destpath, y.name)
847 self.generator.bld.do_install(y.abspath(), destfile, self.chmod)
848
849 def exec_install_as(self):
850 """
851 Predefined method for installing one file with a given name
852 """
853 destfile = self.get_install_path()
854 self.generator.bld.do_install(self.inputs[0].abspath(), destfile, self.chmod)
855
856 def exec_symlink_as(self):
857 """
858 Predefined method for installing a symlink
859 """
860 destfile = self.get_install_path()
861 self.generator.bld.do_link(self.link, destfile)
862
863 class InstallContext(BuildContext):
864 '''installs the targets on the system'''
865 cmd = 'install'
866
867 def __init__(self, **kw):
868 super(InstallContext, self).__init__(**kw)
869
870 # list of targets to uninstall for removing the empty folders after uninstalling
871 self.uninstall = []
872 self.is_install = INSTALL
873
874 def do_install(self, src, tgt, chmod=Utils.O644):
875 """
876 Copy a file from src to tgt with given file permissions. The actual copy is not performed
877 if the source and target file have the same size and the same timestamps. When the copy occurs,
878 the file is first removed and then copied (prevent stale inodes).
879
880 This method is overridden in :py:meth:`waflib.Build.UninstallContext.do_install` to remove the file.
881
882 :param src: file name as absolute path
883 :type src: string
884 :param tgt: file destination, as absolute path
885 :type tgt: string
886 :param chmod: installation mode
887 :type chmod: int
888 """
889 d, _ = os.path.split(tgt)
890 if not d:
891 raise Errors.WafError('Invalid installation given %r->%r' % (src, tgt))
892 Utils.check_dir(d)
893
894 srclbl = src.replace(self.srcnode.abspath() + os.sep, '')
895 if not Options.options.force:
896 # check if the file is already there to avoid a copy
897 try:
898 st1 = os.stat(tgt)
899 st2 = os.stat(src)
900 except OSError:
901 pass
902 else:
903 # same size and identical timestamps -> make no copy
904 if st1.st_mtime + 2 >= st2.st_mtime and st1.st_size == st2.st_size:
905 if not self.progress_bar:
906 Logs.info('- install %s (from %s)' % (tgt, srclbl))
907 return False
908
909 if not self.progress_bar:
910 Logs.info('+ install %s (from %s)' % (tgt, srclbl))
911
912 # following is for shared libs and stale inodes (-_-)
913 try:
914 os.remove(tgt)
915 except OSError:
916 pass
917
918 try:
919 shutil.copy2(src, tgt)
920 os.chmod(tgt, chmod)
921 except IOError:
922 try:
923 os.stat(src)
924 except (OSError, IOError):
925 Logs.error('File %r does not exist' % src)
926 raise Errors.WafError('Could not install the file %r' % tgt)
927
928 def do_link(self, src, tgt):
929 """
930 Create a symlink from tgt to src.
931
932 This method is overridden in :py:meth:`waflib.Build.UninstallContext.do_link` to remove the symlink.
933
934 :param src: file name as absolute path
935 :type src: string
936 :param tgt: file destination, as absolute path
937 :type tgt: string
938 """
939 d, _ = os.path.split(tgt)
940 Utils.check_dir(d)
941
942 link = False
943 if not os.path.islink(tgt):
944 link = True
945 elif os.readlink(tgt) != src:
946 link = True
947
948 if link:
949 try: os.remove(tgt)
950 except OSError: pass
951 if not self.progress_bar:
952 Logs.info('+ symlink %s (to %s)' % (tgt, src))
953 os.symlink(src, tgt)
954 else:
955 if not self.progress_bar:
956 Logs.info('- symlink %s (to %s)' % (tgt, src))
957
958 def run_task_now(self, tsk, postpone):
959 """
960 This method is called by :py:meth:`waflib.Build.InstallContext.install_files`,
961 :py:meth:`waflib.Build.InstallContext.install_as` and :py:meth:`waflib.Build.InstallContext.symlink_as` immediately
962 after the installation task is created. Its role is to force the immediate execution if necessary, that is when
963 ``postpone=False`` was given.
964 """
965 tsk.post()
966 if not postpone:
967 if tsk.runnable_status() == Task.ASK_LATER:
968 raise self.WafError('cannot post the task %r' % tsk)
969 tsk.run()
970
971 def install_files(self, dest, files, env=None, chmod=Utils.O644, relative_trick=False, cwd=None, add=True, postpone=True):
972 """
973 Create a task to install files on the system::
974
975 def build(bld):
976 bld.install_files('${DATADIR}', self.path.find_resource('wscript'))
977
978 :param dest: absolute path of the destination directory
979 :type dest: string
980 :param files: input files
981 :type files: list of strings or list of nodes
982 :param env: configuration set for performing substitutions in dest
983 :type env: Configuration set
984 :param relative_trick: preserve the folder hierarchy when installing whole folders
985 :type relative_trick: bool
986 :param cwd: parent node for searching srcfile, when srcfile is not a :py:class:`waflib.Node.Node`
987 :type cwd: :py:class:`waflib.Node.Node`
988 :param add: add the task created to a build group - set ``False`` only if the installation task is created after the build has started
989 :type add: bool
990 :param postpone: execute the task immediately to perform the installation
991 :type postpone: bool
992 """
993 tsk = inst(env=env or self.env)
994 tsk.bld = self
995 tsk.path = cwd or self.path
996 tsk.chmod = chmod
997 if isinstance(files, waflib.Node.Node):
998 tsk.source = [files]
999 else:
1000 tsk.source = Utils.to_list(files)
1001 tsk.dest = dest
1002 tsk.exec_task = tsk.exec_install_files
1003 tsk.relative_trick = relative_trick
1004 if add: self.add_to_group(tsk)
1005 self.run_task_now(tsk, postpone)
1006 return tsk
1007
1008 def install_as(self, dest, srcfile, env=None, chmod=Utils.O644, cwd=None, add=True, postpone=True):
1009 """
1010 Create a task to install a file on the system with a different name::
1011
1012 def build(bld):
1013 bld.install_as('${PREFIX}/bin', 'myapp', chmod=Utils.O755)
1014
1015 :param dest: absolute path of the destination file
1016 :type dest: string
1017 :param srcfile: input file
1018 :type srcfile: string or node
1019 :param cwd: parent node for searching srcfile, when srcfile is not a :py:class:`waflib.Node.Node`
1020 :type cwd: :py:class:`waflib.Node.Node`
1021 :param env: configuration set for performing substitutions in dest
1022 :type env: Configuration set
1023 :param add: add the task created to a build group - set ``False`` only if the installation task is created after the build has started
1024 :type add: bool
1025 :param postpone: execute the task immediately to perform the installation
1026 :type postpone: bool
1027 """
1028 tsk = inst(env=env or self.env)
1029 tsk.bld = self
1030 tsk.path = cwd or self.path
1031 tsk.chmod = chmod
1032 tsk.source = [srcfile]
1033 tsk.dest = dest
1034 tsk.exec_task = tsk.exec_install_as
1035 if add: self.add_to_group(tsk)
1036 self.run_task_now(tsk, postpone)
1037 return tsk
1038
1039 def symlink_as(self, dest, src, env=None, cwd=None, add=True, postpone=True):
1040 """
1041 Create a task to install a symlink::
1042
1043 def build(bld):
1044 bld.symlink_as('${PREFIX}/lib/libfoo.so', 'libfoo.so.1.2.3')
1045
1046 :param dest: absolute path of the symlink
1047 :type dest: string
1048 :param src: absolute or relative path of the link
1049 :type src: string
1050 :param env: configuration set for performing substitutions in dest
1051 :type env: Configuration set
1052 :param add: add the task created to a build group - set ``False`` only if the installation task is created after the build has started
1053 :type add: bool
1054 :param postpone: execute the task immediately to perform the installation
1055 :type postpone: bool
1056 """
1057
1058 if Utils.is_win32:
1059 # symlinks *cannot* work on that platform
1060 return
1061
1062 tsk = inst(env=env or self.env)
1063 tsk.bld = self
1064 tsk.dest = dest
1065 tsk.path = cwd or self.path
1066 tsk.source = []
1067 tsk.link = src
1068 tsk.exec_task = tsk.exec_symlink_as
1069 if add: self.add_to_group(tsk)
1070 self.run_task_now(tsk, postpone)
1071 return tsk
1072
1073 class UninstallContext(InstallContext):
1074 '''removes the targets installed'''
1075 cmd = 'uninstall'
1076
1077 def __init__(self, **kw):
1078 super(UninstallContext, self).__init__(**kw)
1079 self.is_install = UNINSTALL
1080
1081 def do_install(self, src, tgt, chmod=Utils.O644):
1082 """See :py:meth:`waflib.Build.InstallContext.do_install`"""
1083 if not self.progress_bar:
1084 Logs.info('- remove %s' % tgt)
1085
1086 self.uninstall.append(tgt)
1087 try:
1088 os.remove(tgt)
1089 except OSError as e:
1090 if e.errno != errno.ENOENT:
1091 if not getattr(self, 'uninstall_error', None):
1092 self.uninstall_error = True
1093 Logs.warn('build: some files could not be uninstalled (retry with -vv to list them)')
1094 if Logs.verbose > 1:
1095 Logs.warn('could not remove %s (error code %r)' % (e.filename, e.errno))
1096
1097 # TODO ita refactor this into a post build action to uninstall the folders (optimization)
1098 while tgt:
1099 tgt = os.path.dirname(tgt)
1100 try:
1101 os.rmdir(tgt)
1102 except OSError:
1103 break
1104
1105 def do_link(self, src, tgt):
1106 """See :py:meth:`waflib.Build.InstallContext.do_link`"""
1107 try:
1108 if not self.progress_bar:
1109 Logs.info('- unlink %s' % tgt)
1110 os.remove(tgt)
1111 except OSError:
1112 pass
1113
1114 # TODO ita refactor this into a post build action to uninstall the folders (optimization)?
1115 while tgt:
1116 tgt = os.path.dirname(tgt)
1117 try:
1118 os.rmdir(tgt)
1119 except OSError:
1120 break
1121
1122 def execute(self):
1123 """
1124 See :py:func:`waflib.Context.Context.execute`
1125 """
1126 try:
1127 # do not execute any tasks
1128 def runnable_status(self):
1129 return Task.SKIP_ME
1130 setattr(Task.Task, 'runnable_status_back', Task.Task.runnable_status)
1131 setattr(Task.Task, 'runnable_status', runnable_status)
1132
1133 super(UninstallContext, self).execute()
1134 finally:
1135 setattr(Task.Task, 'runnable_status', Task.Task.runnable_status_back)
1136
1137 class CleanContext(BuildContext):
1138 '''cleans the project'''
1139 cmd = 'clean'
1140 def execute(self):
1141 """
1142 See :py:func:`waflib.Context.Context.execute`
1143 """
1144 self.restore()
1145 if not self.all_envs:
1146 self.load_envs()
1147
1148 self.recurse([self.run_dir])
1149 try:
1150 self.clean()
1151 finally:
1152 self.store()
1153
1154 def clean(self):
1155 """clean the data and some files in the build dir .. well, TODO"""
1156 Logs.debug('build: clean called')
1157
1158 if self.bldnode != self.srcnode:
1159 # would lead to a disaster if top == out
1160 lst = [self.root.find_or_declare(f) for f in self.env[CFG_FILES]]
1161 for n in self.bldnode.ant_glob('**/*', excl='lock* *conf_check_*/** config.log c4che/*', quiet=True):
1162 if n in lst:
1163 continue
1164 n.delete()
1165 self.root.children = {}
1166
1167 for v in 'node_deps task_sigs raw_deps'.split():
1168 setattr(self, v, {})
1169
1170 class ListContext(BuildContext):
1171 '''lists the targets to execute'''
1172
1173 cmd = 'list'
1174 def execute(self):
1175 """
1176 See :py:func:`waflib.Context.Context.execute`.
1177 """
1178 self.restore()
1179 if not self.all_envs:
1180 self.load_envs()
1181
1182 self.recurse([self.run_dir])
1183 self.pre_build()
1184
1185 # display the time elapsed in the progress bar
1186 self.timer = Utils.Timer()
1187
1188 for g in self.groups:
1189 for tg in g:
1190 try:
1191 f = tg.post
1192 except AttributeError:
1193 pass
1194 else:
1195 f()
1196
1197 try:
1198 # force the cache initialization
1199 self.get_tgen_by_name('')
1200 except:
1201 pass
1202 lst = list(self.task_gen_cache_names.keys())
1203 lst.sort()
1204 for k in lst:
1205 Logs.pprint('GREEN', k)
1206
1207 class StepContext(BuildContext):
1208 '''executes tasks in a step-by-step fashion, for debugging'''
1209 cmd = 'step'
1210
1211 def __init__(self, **kw):
1212 super(StepContext, self).__init__(**kw)
1213 self.files = Options.options.files
1214
1215 def compile(self):
1216 """
1217 Compile the tasks matching the input/output files given (regular expression matching). Derived from :py:meth:`waflib.Build.BuildContext.compile`::
1218
1219 $ waf step --files=foo.c,bar.c,in:truc.c,out:bar.o
1220 $ waf step --files=in:foo.cpp.1.o # link task only
1221
1222 """
1223 if not self.files:
1224 Logs.warn('Add a pattern for the debug build, for example "waf step --files=main.c,app"')
1225 BuildContext.compile(self)
1226 return
1227
1228 for g in self.groups:
1229 for tg in g:
1230 try:
1231 f = tg.post
1232 except AttributeError:
1233 pass
1234 else:
1235 f()
1236
1237 for pat in self.files.split(','):
1238 matcher = self.get_matcher(pat)
1239 for tg in g:
1240 if isinstance(tg, Task.TaskBase):
1241 lst = [tg]
1242 else:
1243 lst = tg.tasks
1244 for tsk in lst:
1245 do_exec = False
1246 for node in getattr(tsk, 'inputs', []):
1247 if matcher(node, output=False):
1248 do_exec = True
1249 break
1250 for node in getattr(tsk, 'outputs', []):
1251 if matcher(node, output=True):
1252 do_exec = True
1253 break
1254 if do_exec:
1255 ret = tsk.run()
1256 Logs.info('%s -> exit %r' % (str(tsk), ret))
1257
1258 def get_matcher(self, pat):
1259 # this returns a function
1260 inn = True
1261 out = True
1262 if pat.startswith('in:'):
1263 out = False
1264 pat = pat.replace('in:', '')
1265 elif pat.startswith('out:'):
1266 inn = False
1267 pat = pat.replace('out:', '')
1268
1269 anode = self.root.find_node(pat)
1270 pattern = None
1271 if not anode:
1272 if not pat.startswith('^'):
1273 pat = '^.+?%s' % pat
1274 if not pat.endswith('$'):
1275 pat = '%s$' % pat
1276 pattern = re.compile(pat)
1277
1278 def match(node, output):
1279 if output == True and not out:
1280 return False
1281 if output == False and not inn:
1282 return False
1283
1284 if anode:
1285 return anode == node
1286 else:
1287 return pattern.match(node.abspath())
1288 return match
1289
1290 BuildContext.store = Utils.nogc(BuildContext.store)
1291 BuildContext.restore = Utils.nogc(BuildContext.restore)
1292
0 #!/usr/bin/env python
1 # encoding: utf-8
2 # Thomas Nagy, 2005-2010 (ita)
3
4 """
5
6 ConfigSet: a special dict
7
8 The values put in :py:class:`ConfigSet` must be lists
9 """
10
11 import copy, re, os
12 from waflib import Logs, Utils
13 re_imp = re.compile('^(#)*?([^#=]*?)\ =\ (.*?)$', re.M)
14
15 class ConfigSet(object):
16 """
17 A dict that honor serialization and parent relationships. The serialization format
18 is human-readable (python-like) and performed by using eval() and repr().
19 For high performance prefer pickle. Do not store functions as they are not serializable.
20
21 The values can be accessed by attributes or by keys::
22
23 from waflib.ConfigSet import ConfigSet
24 env = ConfigSet()
25 env.FOO = 'test'
26 env['FOO'] = 'test'
27 """
28 __slots__ = ('table', 'parent')
29 def __init__(self, filename=None):
30 self.table = {}
31 """
32 Internal dict holding the object values
33 """
34 #self.parent = None
35
36 if filename:
37 self.load(filename)
38
39 def __contains__(self, key):
40 """
41 Enable the *in* syntax::
42
43 if 'foo' in env:
44 print env['foo']
45 """
46 if key in self.table: return True
47 try: return self.parent.__contains__(key)
48 except AttributeError: return False # parent may not exist
49
50 def keys(self):
51 """Dict interface (unknown purpose)"""
52 keys = set()
53 cur = self
54 while cur:
55 keys.update(cur.table.keys())
56 cur = getattr(cur, 'parent', None)
57 keys = list(keys)
58 keys.sort()
59 return keys
60
61 def __str__(self):
62 """Text representation of the ConfigSet (for debugging purposes)"""
63 return "\n".join(["%r %r" % (x, self.__getitem__(x)) for x in self.keys()])
64
65 def __getitem__(self, key):
66 """
67 Dictionary interface: get value from key::
68
69 def configure(conf):
70 conf.env['foo'] = {}
71 print(env['foo'])
72 """
73 try:
74 while 1:
75 x = self.table.get(key, None)
76 if not x is None:
77 return x
78 self = self.parent
79 except AttributeError:
80 return []
81
82 def __setitem__(self, key, value):
83 """
84 Dictionary interface: get value from key
85 """
86 self.table[key] = value
87
88 def __delitem__(self, key):
89 """
90 Dictionary interface: get value from key
91 """
92 self[key] = []
93
94 def __getattr__(self, name):
95 """
96 Attribute access provided for convenience. The following forms are equivalent::
97
98 def configure(conf):
99 conf.env.value
100 conf.env['value']
101 """
102 if name in self.__slots__:
103 return object.__getattr__(self, name)
104 else:
105 return self[name]
106
107 def __setattr__(self, name, value):
108 """
109 Attribute access provided for convenience. The following forms are equivalent::
110
111 def configure(conf):
112 conf.env.value = x
113 env['value'] = x
114 """
115 if name in self.__slots__:
116 object.__setattr__(self, name, value)
117 else:
118 self[name] = value
119
120 def __delattr__(self, name):
121 """
122 Attribute access provided for convenience. The following forms are equivalent::
123
124 def configure(conf):
125 del env.value
126 del env['value']
127 """
128 if name in self.__slots__:
129 object.__delattr__(self, name)
130 else:
131 del self[name]
132
133 def derive(self):
134 """
135 Returns a new ConfigSet deriving from self. The copy returned
136 will be a shallow copy::
137
138 from waflib.ConfigSet import ConfigSet
139 env = ConfigSet()
140 env.append_value('CFLAGS', ['-O2'])
141 child = env.derive()
142 child.CFLAGS.append('test') # warning! this will modify 'env'
143 child.CFLAGS = ['-O3'] # new list, ok
144 child.append_value('CFLAGS', ['-O3']) # ok
145
146 Use :py:func:`ConfigSet.detach` to detach the child from the parent.
147 """
148 newenv = ConfigSet()
149 newenv.parent = self
150 return newenv
151
152 def detach(self):
153 """
154 Detach self from its parent (if existing)
155
156 Modifying the parent :py:class:`ConfigSet` will not change the current object
157 Modifying this :py:class:`ConfigSet` will not modify the parent one.
158 """
159 tbl = self.get_merged_dict()
160 try:
161 delattr(self, 'parent')
162 except AttributeError:
163 pass
164 else:
165 keys = tbl.keys()
166 for x in keys:
167 tbl[x] = copy.deepcopy(tbl[x])
168 self.table = tbl
169
170 def get_flat(self, key):
171 """
172 Return a value as a string. If the input is a list, the value returned is space-separated.
173
174 :param key: key to use
175 :type key: string
176 """
177 s = self[key]
178 if isinstance(s, str): return s
179 return ' '.join(s)
180
181 def _get_list_value_for_modification(self, key):
182 """
183 Return a list value for further modification.
184
185 The list may be modified inplace and there is no need to do this afterwards::
186
187 self.table[var] = value
188 """
189 try:
190 value = self.table[key]
191 except KeyError:
192 try: value = self.parent[key]
193 except AttributeError: value = []
194 if isinstance(value, list):
195 value = value[:]
196 else:
197 value = [value]
198 else:
199 if not isinstance(value, list):
200 value = [value]
201 self.table[key] = value
202 return value
203
204 def append_value(self, var, val):
205 """
206 Appends a value to the specified config key::
207
208 def build(bld):
209 bld.env.append_value('CFLAGS', ['-O2'])
210
211 The value must be a list or a tuple
212 """
213 current_value = self._get_list_value_for_modification(var)
214 if isinstance(val, str): # if there were string everywhere we could optimize this
215 val = [val]
216 current_value.extend(val)
217
218 def prepend_value(self, var, val):
219 """
220 Prepends a value to the specified item::
221
222 def configure(conf):
223 conf.env.prepend_value('CFLAGS', ['-O2'])
224
225 The value must be a list or a tuple
226 """
227 if isinstance(val, str):
228 val = [val]
229 self.table[var] = val + self._get_list_value_for_modification(var)
230
231 def append_unique(self, var, val):
232 """
233 Append a value to the specified item only if it's not already present::
234
235 def build(bld):
236 bld.env.append_unique('CFLAGS', ['-O2', '-g'])
237
238 The value must be a list or a tuple
239 """
240 if isinstance(val, str):
241 val = [val]
242 current_value = self._get_list_value_for_modification(var)
243
244 for x in val:
245 if x not in current_value:
246 current_value.append(x)
247
248 def get_merged_dict(self):
249 """
250 Compute the merged dictionary from the fusion of self and all its parent
251
252 :rtype: a ConfigSet object
253 """
254 table_list = []
255 env = self
256 while 1:
257 table_list.insert(0, env.table)
258 try: env = env.parent
259 except AttributeError: break
260 merged_table = {}
261 for table in table_list:
262 merged_table.update(table)
263 return merged_table
264
265 def store(self, filename):
266 """
267 Write the :py:class:`ConfigSet` data into a file. See :py:meth:`ConfigSet.load` for reading such files.
268
269 :param filename: file to use
270 :type filename: string
271 """
272 try:
273 os.makedirs(os.path.split(filename)[0])
274 except OSError:
275 pass
276
277 f = None
278 try:
279 f = open(filename, 'w')
280 merged_table = self.get_merged_dict()
281 keys = list(merged_table.keys())
282 keys.sort()
283 for k in keys:
284 if k != 'undo_stack':
285 f.write('%s = %r\n' % (k, merged_table[k]))
286 finally:
287 if f:
288 f.close()
289
290 def load(self, filename):
291 """
292 Retrieve the :py:class:`ConfigSet` data from a file. See :py:meth:`ConfigSet.store` for writing such files
293
294 :param filename: file to use
295 :type filename: string
296 """
297 tbl = self.table
298 code = Utils.readf(filename)
299 for m in re_imp.finditer(code):
300 g = m.group
301 tbl[g(2)] = eval(g(3))
302 Logs.debug('env: %s' % str(self.table))
303
304 def update(self, d):
305 """
306 Dictionary interface: replace values from another dict
307
308 :param d: object to use the value from
309 :type d: dict-like object
310 """
311 for k, v in d.items():
312 self[k] = v
313
314 def stash(self):
315 """
316 Store the object state, to provide a kind of transaction support::
317
318 env = ConfigSet()
319 env.stash()
320 try:
321 env.append_value('CFLAGS', '-O3')
322 call_some_method(env)
323 finally:
324 env.revert()
325
326 The history is kept in a stack, and is lost during the serialization by :py:meth:`ConfigSet.store`
327 """
328 self.undo_stack = self.undo_stack + [self.table]
329 self.table = self.table.copy()
330
331 def revert(self):
332 """
333 Reverts the object to a previous state. See :py:meth:`ConfigSet.stash`
334 """
335 self.table = self.undo_stack.pop(-1)
336
0 #!/usr/bin/env python
1 # encoding: utf-8
2 # Thomas Nagy, 2005-2010 (ita)
3
4 """
5 Configuration system
6
7 A :py:class:`waflib.Configure.ConfigurationContext` instance is created when ``waf configure`` is called, it is used to:
8
9 * create data dictionaries (ConfigSet instances)
10 * store the list of modules to import
11 * hold configuration routines such as ``find_program``, etc
12 """
13
14 import os, shlex, sys, time
15 from waflib import ConfigSet, Utils, Options, Logs, Context, Build, Errors
16
17 try:
18 from urllib import request
19 except:
20 from urllib import urlopen
21 else:
22 urlopen = request.urlopen
23
24 BREAK = 'break'
25 """In case of a configuration error, break"""
26
27 CONTINUE = 'continue'
28 """In case of a configuration error, continue"""
29
30 WAF_CONFIG_LOG = 'config.log'
31 """Name of the configuration log file"""
32
33 autoconfig = False
34 """Execute the configuration automatically"""
35
36 conf_template = '''# project %(app)s configured on %(now)s by
37 # waf %(wafver)s (abi %(abi)s, python %(pyver)x on %(systype)s)
38 # using %(args)s
39 #'''
40
41 def download_check(node):
42 """
43 Hook to check for the tools which are downloaded. Replace with your function if necessary.
44 """
45 pass
46
47 def download_tool(tool, force=False, ctx=None):
48 """
49 Download a Waf tool from the remote repository defined in :py:const:`waflib.Context.remote_repo`::
50
51 $ waf configure --download
52 """
53 for x in Utils.to_list(Context.remote_repo):
54 for sub in Utils.to_list(Context.remote_locs):
55 url = '/'.join((x, sub, tool + '.py'))
56 try:
57 web = urlopen(url)
58 try:
59 if web.getcode() != 200:
60 continue
61 except AttributeError:
62 pass
63 except Exception:
64 # on python3 urlopen throws an exception
65 # python 2.3 does not have getcode and throws an exception to fail
66 continue
67 else:
68 tmp = ctx.root.make_node(os.sep.join((Context.waf_dir, 'waflib', 'extras', tool + '.py')))
69 tmp.write(web.read())
70 Logs.warn('Downloaded %s from %s' % (tool, url))
71 download_check(tmp)
72 try:
73 module = Context.load_tool(tool)
74 except:
75 Logs.warn('The tool %s from %s is unusable' % (tool, url))
76 try:
77 tmp.delete()
78 except:
79 pass
80 continue
81 return module
82 raise Errors.WafError('Could not load the Waf tool')
83
84 class ConfigurationContext(Context.Context):
85 '''configures the project'''
86
87 cmd = 'configure'
88
89 error_handlers = []
90 """
91 Additional functions to handle configuration errors
92 """
93
94 def __init__(self, **kw):
95 super(ConfigurationContext, self).__init__(**kw)
96 self.environ = dict(os.environ)
97 self.all_envs = {}
98
99 self.top_dir = None
100 self.out_dir = None
101
102 self.tools = [] # tools loaded in the configuration, and that will be loaded when building
103
104 self.hash = 0
105 self.files = []
106
107 self.tool_cache = []
108
109 self.setenv('')
110
111 def setenv(self, name, env=None):
112 """
113 Set a new config set for conf.env. If a config set of that name already exists,
114 recall it without modification.
115
116 The name is the filename prefix to save to ``c4che/NAME_cache.py``, and it
117 is also used as *variants* by the build commands.
118 Though related to variants, whatever kind of data may be stored in the config set::
119
120 def configure(cfg):
121 cfg.env.ONE = 1
122 cfg.setenv('foo')
123 cfg.env.ONE = 2
124
125 def build(bld):
126 2 == bld.env_of_name('foo').ONE
127
128 :param name: name of the configuration set
129 :type name: string
130 :param env: ConfigSet to copy, or an empty ConfigSet is created
131 :type env: :py:class:`waflib.ConfigSet.ConfigSet`
132 """
133 if name not in self.all_envs or env:
134 if not env:
135 env = ConfigSet.ConfigSet()
136 self.prepare_env(env)
137 else:
138 env = env.derive()
139 self.all_envs[name] = env
140 self.variant = name
141
142 def get_env(self):
143 """Getter for the env property"""
144 return self.all_envs[self.variant]
145 def set_env(self, val):
146 """Setter for the env property"""
147 self.all_envs[self.variant] = val
148
149 env = property(get_env, set_env)
150
151 def init_dirs(self):
152 """
153 Initialize the project directory and the build directory
154 """
155
156 top = self.top_dir
157 if not top:
158 top = Options.options.top
159 if not top:
160 top = getattr(Context.g_module, Context.TOP, None)
161 if not top:
162 top = self.path.abspath()
163 top = os.path.abspath(top)
164
165 self.srcnode = (os.path.isabs(top) and self.root or self.path).find_dir(top)
166 assert(self.srcnode)
167
168 out = self.out_dir
169 if not out:
170 out = Options.options.out
171 if not out:
172 out = getattr(Context.g_module, Context.OUT, None)
173 if not out:
174 out = Options.lockfile.replace('.lock-waf_%s_' % sys.platform, '').replace('.lock-waf', '')
175
176 self.bldnode = (os.path.isabs(out) and self.root or self.path).make_node(out)
177 self.bldnode.mkdir()
178
179 if not os.path.isdir(self.bldnode.abspath()):
180 conf.fatal('could not create the build directory %s' % self.bldnode.abspath())
181
182 def execute(self):
183 """
184 See :py:func:`waflib.Context.Context.execute`
185 """
186 self.init_dirs()
187
188 self.cachedir = self.bldnode.make_node(Build.CACHE_DIR)
189 self.cachedir.mkdir()
190
191 path = os.path.join(self.bldnode.abspath(), WAF_CONFIG_LOG)
192 self.logger = Logs.make_logger(path, 'cfg')
193
194 app = getattr(Context.g_module, 'APPNAME', '')
195 if app:
196 ver = getattr(Context.g_module, 'VERSION', '')
197 if ver:
198 app = "%s (%s)" % (app, ver)
199
200 now = time.ctime()
201 pyver = sys.hexversion
202 systype = sys.platform
203 args = " ".join(sys.argv)
204 wafver = Context.WAFVERSION
205 abi = Context.ABI
206 self.to_log(conf_template % vars())
207
208 self.msg('Setting top to', self.srcnode.abspath())
209 self.msg('Setting out to', self.bldnode.abspath())
210
211 if id(self.srcnode) == id(self.bldnode):
212 Logs.warn('Setting top == out (remember to use "update_outputs")')
213 elif id(self.path) != id(self.srcnode):
214 if self.srcnode.is_child_of(self.path):
215 Logs.warn('Are you certain that you do not want to set top="." ?')
216
217 super(ConfigurationContext, self).execute()
218
219 self.store()
220
221 Context.top_dir = self.srcnode.abspath()
222 Context.out_dir = self.bldnode.abspath()
223
224 # this will write a configure lock so that subsequent builds will
225 # consider the current path as the root directory (see prepare_impl).
226 # to remove: use 'waf distclean'
227 env = ConfigSet.ConfigSet()
228 env['argv'] = sys.argv
229 env['options'] = Options.options.__dict__
230
231 env.run_dir = Context.run_dir
232 env.top_dir = Context.top_dir
233 env.out_dir = Context.out_dir
234
235 # conf.hash & conf.files hold wscript files paths and hash
236 # (used only by Configure.autoconfig)
237 env['hash'] = self.hash
238 env['files'] = self.files
239 env['environ'] = dict(self.environ)
240
241 if not self.env.NO_LOCK_IN_RUN:
242 env.store(Context.run_dir + os.sep + Options.lockfile)
243 if not self.env.NO_LOCK_IN_TOP:
244 env.store(Context.top_dir + os.sep + Options.lockfile)
245 if not self.env.NO_LOCK_IN_OUT:
246 env.store(Context.out_dir + os.sep + Options.lockfile)
247
248 def prepare_env(self, env):
249 """
250 Insert *PREFIX*, *BINDIR* and *LIBDIR* values into ``env``
251
252 :type env: :py:class:`waflib.ConfigSet.ConfigSet`
253 :param env: a ConfigSet, usually ``conf.env``
254 """
255 if not env.PREFIX:
256 env.PREFIX = os.path.abspath(os.path.expanduser(Options.options.prefix))
257 if not env.BINDIR:
258 env.BINDIR = Utils.subst_vars('${PREFIX}/bin', env)
259 if not env.LIBDIR:
260 env.LIBDIR = Utils.subst_vars('${PREFIX}/lib', env)
261
262 def store(self):
263 """Save the config results into the cache file"""
264 n = self.cachedir.make_node('build.config.py')
265 n.write('version = 0x%x\ntools = %r\n' % (Context.HEXVERSION, self.tools))
266
267 if not self.all_envs:
268 self.fatal('nothing to store in the configuration context!')
269
270 for key in self.all_envs:
271 tmpenv = self.all_envs[key]
272 tmpenv.store(os.path.join(self.cachedir.abspath(), key + Build.CACHE_SUFFIX))
273
274 def load(self, input, tooldir=None, funs=None, download=True):
275 """
276 Load Waf tools, which will be imported whenever a build is started.
277
278 :param input: waf tools to import
279 :type input: list of string
280 :param tooldir: paths for the imports
281 :type tooldir: list of string
282 :param funs: functions to execute from the waf tools
283 :type funs: list of string
284 :param download: whether to download the tool from the waf repository
285 :type download: bool
286 """
287
288 tools = Utils.to_list(input)
289 if tooldir: tooldir = Utils.to_list(tooldir)
290 for tool in tools:
291 # avoid loading the same tool more than once with the same functions
292 # used by composite projects
293
294 mag = (tool, id(self.env), funs)
295 if mag in self.tool_cache:
296 self.to_log('(tool %s is already loaded, skipping)' % tool)
297 continue
298 self.tool_cache.append(mag)
299
300 module = None
301 try:
302 module = Context.load_tool(tool, tooldir)
303 except ImportError as e:
304 if Options.options.download:
305 module = download_tool(tool, ctx=self)
306 if not module:
307 self.fatal('Could not load the Waf tool %r or download a suitable replacement from the repository (sys.path %r)\n%s' % (tool, sys.path, e))
308 else:
309 self.fatal('Could not load the Waf tool %r from %r (try the --download option?):\n%s' % (tool, sys.path, e))
310 except Exception as e:
311 self.to_log('imp %r (%r & %r)' % (tool, tooldir, funs))
312 self.to_log(Utils.ex_stack())
313 raise
314
315 if funs is not None:
316 self.eval_rules(funs)
317 else:
318 func = getattr(module, 'configure', None)
319 if func:
320 if type(func) is type(Utils.readf): func(self)
321 else: self.eval_rules(func)
322
323 self.tools.append({'tool':tool, 'tooldir':tooldir, 'funs':funs})
324
325 def post_recurse(self, node):
326 """
327 Records the path and a hash of the scripts visited, see :py:meth:`waflib.Context.Context.post_recurse`
328
329 :param node: script
330 :type node: :py:class:`waflib.Node.Node`
331 """
332 super(ConfigurationContext, self).post_recurse(node)
333 self.hash = hash((self.hash, node.read('rb')))
334 self.files.append(node.abspath())
335
336 def eval_rules(self, rules):
337 """
338 Execute the configuration tests. The method :py:meth:`waflib.Configure.ConfigurationContext.err_handler`
339 is used to process the eventual exceptions
340
341 :param rules: list of configuration method names
342 :type rules: list of string
343 """
344 self.rules = Utils.to_list(rules)
345 for x in self.rules:
346 f = getattr(self, x)
347 if not f: self.fatal("No such method '%s'." % x)
348 try:
349 f()
350 except Exception as e:
351 ret = self.err_handler(x, e)
352 if ret == BREAK:
353 break
354 elif ret == CONTINUE:
355 continue
356 else:
357 raise
358
359 def err_handler(self, fun, error):
360 """
361 Error handler for the configuration tests, the default is to let the exception raise
362
363 :param fun: configuration test
364 :type fun: method
365 :param error: exception
366 :type error: exception
367 """
368 pass
369
370 def conf(f):
371 """
372 Decorator: attach new configuration functions to :py:class:`waflib.Build.BuildContext` and
373 :py:class:`waflib.Configure.ConfigurationContext`. The methods bound will accept a parameter
374 named 'mandatory' to disable the configuration errors::
375
376 def configure(conf):
377 conf.find_program('abc', mandatory=False)
378
379 :param f: method to bind
380 :type f: function
381 """
382 def fun(*k, **kw):
383 mandatory = True
384 if 'mandatory' in kw:
385 mandatory = kw['mandatory']
386 del kw['mandatory']
387
388 try:
389 return f(*k, **kw)
390 except Errors.ConfigurationError as e:
391 if mandatory:
392 raise e
393
394 setattr(ConfigurationContext, f.__name__, fun)
395 setattr(Build.BuildContext, f.__name__, fun)
396 return f
397
398 @conf
399 def add_os_flags(self, var, dest=None):
400 """
401 Import operating system environment values into ``conf.env`` dict::
402
403 def configure(conf):
404 conf.add_os_flags('CFLAGS')
405
406 :param var: variable to use
407 :type var: string
408 :param dest: destination variable, by default the same as var
409 :type dest: string
410 """
411 # do not use 'get' to make certain the variable is not defined
412 try: self.env.append_value(dest or var, shlex.split(self.environ[var]))
413 except KeyError: pass
414
415 @conf
416 def cmd_to_list(self, cmd):
417 """
418 Detect if a command is written in pseudo shell like ``ccache g++`` and return a list.
419
420 :param cmd: command
421 :type cmd: a string or a list of string
422 """
423 if isinstance(cmd, str) and cmd.find(' '):
424 try:
425 os.stat(cmd)
426 except OSError:
427 return shlex.split(cmd)
428 else:
429 return [cmd]
430 return cmd
431
432 @conf
433 def check_waf_version(self, mini='1.6.0', maxi='1.7.0'):
434 """
435 check for the waf version
436
437 Versions should be supplied as hex. 0x01000000 means 1.0.0,
438 0x010408 means 1.4.8, etc.
439
440 :type mini: number, tuple or string
441 :param mini: Minimum required version
442 :type maxi: number, tuple or string
443 :param maxi: Maximum allowed version
444 """
445 self.start_msg('Checking for waf version in %s-%s' % (str(mini), str(maxi)))
446 ver = Context.HEXVERSION
447 if Utils.num2ver(mini) > ver:
448 self.fatal('waf version should be at least %r (%r found)' % (Utils.num2ver(mini), ver))
449
450 if Utils.num2ver(maxi) < ver:
451 self.fatal('waf version should be at most %r (%r found)' % (Utils.num2ver(maxi), ver))
452 self.end_msg('ok')
453
454 @conf
455 def find_file(self, filename, path_list=[]):
456 """
457 Find a file in a list of paths
458
459 :param filename: name of the file to search for
460 :param path_list: list of directories to search
461 :return: the first occurrence filename or '' if filename could not be found
462 """
463 for n in Utils.to_list(filename):
464 for d in Utils.to_list(path_list):
465 p = os.path.join(d, n)
466 if os.path.exists(p):
467 return p
468 self.fatal('Could not find %r' % filename)
469
470 @conf
471 def find_program(self, filename, **kw):
472 """
473 Search for a program on the operating system
474
475 When var is used, you may set os.environ[var] to help find a specific program version, for example::
476
477 $ VALAC=/usr/bin/valac_test waf configure
478
479 :param path_list: paths to use for searching
480 :type param_list: list of string
481 :param var: store the result to conf.env[var], by default use filename.upper()
482 :type var: string
483 :param ext: list of extensions for the binary (do not add an extension for portability)
484 :type ext: list of string
485 """
486
487 exts = kw.get('exts', Utils.is_win32 and '.exe,.com,.bat,.cmd' or ',.sh,.pl,.py')
488
489 environ = kw.get('environ', os.environ)
490
491 ret = ''
492 filename = Utils.to_list(filename)
493
494 var = kw.get('var', '')
495 if not var:
496 var = filename[0].upper()
497
498 if self.env[var]:
499 ret = self.env[var]
500 elif var in environ:
501 ret = environ[var]
502
503 path_list = kw.get('path_list', '')
504 if not ret:
505 if path_list:
506 path_list = Utils.to_list(path_list)
507 else:
508 path_list = environ.get('PATH', '').split(os.pathsep)
509
510 if not isinstance(filename, list):
511 filename = [filename]
512
513 for a in exts.split(','):
514 if ret:
515 break
516 for b in filename:
517 if ret:
518 break
519 for c in path_list:
520 if ret:
521 break
522 x = os.path.expanduser(os.path.join(c, b + a))
523 if os.path.isfile(x):
524 ret = x
525
526 if not ret and Utils.winreg:
527 ret = Utils.get_registry_app_path(Utils.winreg.HKEY_CURRENT_USER, filename)
528 if not ret and Utils.winreg:
529 ret = Utils.get_registry_app_path(Utils.winreg.HKEY_LOCAL_MACHINE, filename)
530
531 self.msg('Checking for program ' + ','.join(filename), ret or False)
532 self.to_log('find program=%r paths=%r var=%r -> %r' % (filename, path_list, var, ret))
533
534 if not ret:
535 self.fatal(kw.get('errmsg', '') or 'Could not find the program %s' % ','.join(filename))
536
537 if var:
538 self.env[var] = ret
539 return ret
540
541
542 @conf
543 def find_perl_program(self, filename, path_list=[], var=None, environ=None, exts=''):
544 """
545 Search for a perl program on the operating system
546
547 :param filename: file to search for
548 :type filename: string
549 :param path_list: list of paths to look into
550 :type path_list: list of string
551 :param var: store the results into *conf.env.var*
552 :type var: string
553 :param environ: operating system environment to pass to :py:func:`waflib.Configure.find_program`
554 :type environ: dict
555 :param exts: extensions given to :py:func:`waflib.Configure.find_program`
556 :type exts: list
557 """
558
559 try:
560 app = self.find_program(filename, path_list=path_list, var=var, environ=environ, exts=exts)
561 except:
562 self.find_program('perl', var='PERL')
563 app = self.find_file(filename, os.environ['PATH'].split(os.pathsep))
564 if not app:
565 raise
566 if var:
567 self.env[var] = Utils.to_list(self.env['PERL']) + [app]
568 self.msg('Checking for %r' % filename, app)
569
0 #!/usr/bin/env python
1 # encoding: utf-8
2 # Thomas Nagy, 2010 (ita)
3
4 """
5 Classes and functions required for waf commands
6 """
7
8 import os, imp, sys
9 from waflib import Utils, Errors, Logs
10 import waflib.Node
11
12 # the following 3 constants are updated on each new release (do not touch)
13 HEXVERSION=0x1060b00
14 """Constant updated on new releases"""
15
16 WAFVERSION="1.6.11"
17 """Constant updated on new releases"""
18
19 WAFREVISION="a7e69d6b81b04729804754c4d5214da063779a65"
20 """Constant updated on new releases"""
21
22 ABI = 98
23 """Version of the build data cache file format (used in :py:const:`waflib.Context.DBFILE`)"""
24
25 DBFILE = '.wafpickle-%d' % ABI
26 """Name of the pickle file for storing the build data"""
27
28 APPNAME = 'APPNAME'
29 """Default application name (used by ``waf dist``)"""
30
31 VERSION = 'VERSION'
32 """Default application version (used by ``waf dist``)"""
33
34 TOP = 'top'
35 """The variable name for the top-level directory in wscript files"""
36
37 OUT = 'out'
38 """The variable name for the output directory in wscript files"""
39
40 WSCRIPT_FILE = 'wscript'
41 """Name of the waf script files"""
42
43
44 launch_dir = ''
45 """Directory from which waf has been called"""
46 run_dir = ''
47 """Location of the wscript file to use as the entry point"""
48 top_dir = ''
49 """Location of the project directory (top), if the project was configured"""
50 out_dir = ''
51 """Location of the build directory (out), if the project was configured"""
52 waf_dir = ''
53 """Directory containing the waf modules"""
54
55 local_repo = ''
56 """Local repository containing additional Waf tools (plugins)"""
57 remote_repo = 'http://waf.googlecode.com/git/'
58 """
59 Remote directory containing downloadable waf tools. The missing tools can be downloaded by using::
60
61 $ waf configure --download
62 """
63
64 remote_locs = ['waflib/extras', 'waflib/Tools']
65 """
66 Remote directories for use with :py:const:`waflib.Context.remote_repo`
67 """
68
69 g_module = None
70 """
71 Module representing the main wscript file (see :py:const:`waflib.Context.run_dir`)
72 """
73
74 STDOUT = 1
75 STDERR = -1
76 BOTH = 0
77
78 classes = []
79 """
80 List of :py:class:`waflib.Context.Context` subclasses that can be used as waf commands. The classes
81 are added automatically by a metaclass.
82 """
83
84
85 def create_context(cmd_name, *k, **kw):
86 """
87 Create a new :py:class:`waflib.Context.Context` instance corresponding to the given command.
88 Used in particular by :py:func:`waflib.Scripting.run_command`
89
90 :param cmd_name: command
91 :type cmd_name: string
92 :param k: arguments to give to the context class initializer
93 :type k: list
94 :param k: keyword arguments to give to the context class initializer
95 :type k: dict
96 """
97 global classes
98 for x in classes:
99 if x.cmd == cmd_name:
100 return x(*k, **kw)
101 ctx = Context(*k, **kw)
102 ctx.fun = cmd_name
103 return ctx
104
105 class store_context(type):
106 """
107 Metaclass for storing the command classes into the list :py:const:`waflib.Context.classes`
108 Context classes must provide an attribute 'cmd' representing the command to execute
109 """
110 def __init__(cls, name, bases, dict):
111 super(store_context, cls).__init__(name, bases, dict)
112 name = cls.__name__
113
114 if name == 'ctx' or name == 'Context':
115 return
116
117 try:
118 cls.cmd
119 except AttributeError:
120 raise Errors.WafError('Missing command for the context class %r (cmd)' % name)
121
122 if not getattr(cls, 'fun', None):
123 cls.fun = cls.cmd
124
125 global classes
126 classes.insert(0, cls)
127
128 ctx = store_context('ctx', (object,), {})
129 """Base class for the :py:class:`waflib.Context.Context` classes"""
130
131 class Context(ctx):
132 """
133 Default context for waf commands, and base class for new command contexts.
134
135 Context objects are passed to top-level functions::
136
137 def foo(ctx):
138 print(ctx.__class__.__name__) # waflib.Context.Context
139
140 Subclasses must define the attribute 'cmd':
141
142 :param cmd: command to execute as in ``waf cmd``
143 :type cmd: string
144 :param fun: function name to execute when the command is called
145 :type fun: string
146
147 .. inheritance-diagram:: waflib.Context.Context waflib.Build.BuildContext waflib.Build.InstallContext waflib.Build.UninstallContext waflib.Build.StepContext waflib.Build.ListContext waflib.Configure.ConfigurationContext waflib.Scripting.Dist waflib.Scripting.DistCheck waflib.Build.CleanContext
148
149 """
150
151 errors = Errors
152 """
153 Shortcut to :py:mod:`waflib.Errors` provided for convenience
154 """
155
156 tools = {}
157 """
158 A cache for modules (wscript files) read by :py:meth:`Context.Context.load`
159 """
160
161 def __init__(self, **kw):
162 try:
163 rd = kw['run_dir']
164 except KeyError:
165 global run_dir
166 rd = run_dir
167
168 # binds the context to the nodes in use to avoid a context singleton
169 class node_class(waflib.Node.Node):
170 pass
171 self.node_class = node_class
172 self.node_class.__module__ = "waflib.Node"
173 self.node_class.__name__ = "Nod3"
174 self.node_class.ctx = self
175
176 self.root = self.node_class('', None)
177 self.cur_script = None
178 self.path = self.root.find_dir(rd)
179
180 self.stack_path = []
181 self.exec_dict = {'ctx':self, 'conf':self, 'bld':self, 'opt':self}
182 self.logger = None
183
184 def __hash__(self):
185 """
186 Return a hash value for storing context objects in dicts or sets. The value is not persistent.
187
188 :return: hash value
189 :rtype: int
190 """
191 return id(self)
192
193 def load(self, tool_list, *k, **kw):
194 """
195 Load a Waf tool as a module, and try calling the function named :py:const:`waflib.Context.Context.fun` from it.
196 A ``tooldir`` value may be provided as a list of module paths.
197
198 :type tool_list: list of string or space-separated string
199 :param tool_list: list of Waf tools to use
200 """
201 tools = Utils.to_list(tool_list)
202 path = Utils.to_list(kw.get('tooldir', ''))
203
204 for t in tools:
205 module = load_tool(t, path)
206 fun = getattr(module, kw.get('name', self.fun), None)
207 if fun:
208 fun(self)
209
210 def execute(self):
211 """
212 Execute the command. Redefine this method in subclasses.
213 """
214 global g_module
215 self.recurse([os.path.dirname(g_module.root_path)])
216
217 def pre_recurse(self, node):
218 """
219 Method executed immediately before a folder is read by :py:meth:`waflib.Context.Context.recurse`. The node given is set
220 as an attribute ``self.cur_script``, and as the current path ``self.path``
221
222 :param node: script
223 :type node: :py:class:`waflib.Node.Node`
224 """
225 self.stack_path.append(self.cur_script)
226
227 self.cur_script = node
228 self.path = node.parent
229
230 def post_recurse(self, node):
231 """
232 Restore ``self.cur_script`` and ``self.path`` right after :py:meth:`waflib.Context.Context.recurse` terminates.
233
234 :param node: script
235 :type node: :py:class:`waflib.Node.Node`
236 """
237 self.cur_script = self.stack_path.pop()
238 if self.cur_script:
239 self.path = self.cur_script.parent
240
241 def recurse(self, dirs, name=None, mandatory=True, once=True):
242 """
243 Run user code from the supplied list of directories.
244 The directories can be either absolute, or relative to the directory
245 of the wscript file. The methods :py:meth:`waflib.Context.Context.pre_recurse` and :py:meth:`waflib.Context.Context.post_recurse`
246 are called immediately before and after a script has been executed.
247
248 :param dirs: List of directories to visit
249 :type dirs: list of string or space-separated string
250 :param name: Name of function to invoke from the wscript
251 :type name: string
252 :param mandatory: whether sub wscript files are required to exist
253 :type mandatory: bool
254 :param once: read the script file once for a particular context
255 :type once: bool
256 """
257 try:
258 cache = self.recurse_cache
259 except:
260 cache = self.recurse_cache = {}
261
262 for d in Utils.to_list(dirs):
263
264 if not os.path.isabs(d):
265 # absolute paths only
266 d = os.path.join(self.path.abspath(), d)
267
268 WSCRIPT = os.path.join(d, WSCRIPT_FILE)
269 WSCRIPT_FUN = WSCRIPT + '_' + (name or self.fun)
270
271 node = self.root.find_node(WSCRIPT_FUN)
272 if node and (not once or node not in cache):
273 cache[node] = True
274 self.pre_recurse(node)
275 try:
276 function_code = node.read('rU')
277 exec(compile(function_code, node.abspath(), 'exec'), self.exec_dict)
278 finally:
279 self.post_recurse(node)
280 elif not node:
281 node = self.root.find_node(WSCRIPT)
282 tup = (node, name or self.fun)
283 if node and (not once or tup not in cache):
284 cache[tup] = True
285 self.pre_recurse(node)
286 try:
287 wscript_module = load_module(node.abspath())
288 user_function = getattr(wscript_module, (name or self.fun), None)
289 if not user_function:
290 if not mandatory:
291 continue
292 raise Errors.WafError('No function %s defined in %s' % (name or self.fun, node.abspath()))
293 user_function(self)
294 finally:
295 self.post_recurse(node)
296 elif not node:
297 if not mandatory:
298 continue
299 raise Errors.WafError('No wscript file in directory %s' % d)
300
301 def exec_command(self, cmd, **kw):
302 """
303 Execute a command and return the exit status. If the context has the attribute 'log',
304 capture and log the process stderr/stdout for logging purposes::
305
306 def run(tsk):
307 ret = tsk.generator.bld.exec_command('touch foo.txt')
308 return ret
309
310 Do not confuse this method with :py:meth:`waflib.Context.Context.cmd_and_log` which is used to
311 return the standard output/error values.
312
313 :param cmd: command argument for subprocess.Popen
314 :param kw: keyword arguments for subprocess.Popen
315 """
316 subprocess = Utils.subprocess
317 kw['shell'] = isinstance(cmd, str)
318 Logs.debug('runner: %r' % cmd)
319 Logs.debug('runner_env: kw=%s' % kw)
320
321 try:
322 if self.logger:
323 # warning: may deadlock with a lot of output (subprocess limitation)
324
325 self.logger.info(cmd)
326
327 kw['stdout'] = kw['stderr'] = subprocess.PIPE
328 p = subprocess.Popen(cmd, **kw)
329 (out, err) = p.communicate()
330 if out:
331 self.logger.debug('out: %s' % out.decode(sys.stdout.encoding or 'iso8859-1'))
332 if err:
333 self.logger.error('err: %s' % err.decode(sys.stdout.encoding or 'iso8859-1'))
334 return p.returncode
335 else:
336 p = subprocess.Popen(cmd, **kw)
337 return p.wait()
338 except OSError:
339 return -1
340
341 def cmd_and_log(self, cmd, **kw):
342 """
343 Execute a command and return stdout if the execution is successful.
344 An exception is thrown when the exit status is non-0. In that case, both stderr and stdout
345 will be bound to the WafError object::
346
347 def configure(conf):
348 out = conf.cmd_and_log(['echo', 'hello'], output=waflib.Context.STDOUT, quiet=waflib.Context.BOTH)
349 (out, err) = conf.cmd_and_log(['echo', 'hello'], output=waflib.Context.BOTH)
350 try:
351 conf.cmd_and_log(['which', 'someapp'], output=waflib.Context.BOTH)
352 except Exception as e:
353 print(e.stdout, e.stderr)
354
355 :param cmd: args for subprocess.Popen
356 :param kw: keyword arguments for subprocess.Popen
357 """
358 subprocess = Utils.subprocess
359 kw['shell'] = isinstance(cmd, str)
360 Logs.debug('runner: %r' % cmd)
361
362 if 'quiet' in kw:
363 quiet = kw['quiet']
364 del kw['quiet']
365 else:
366 quiet = None
367
368 if 'output' in kw:
369 to_ret = kw['output']
370 del kw['output']
371 else:
372 to_ret = STDOUT
373
374 kw['stdout'] = kw['stderr'] = subprocess.PIPE
375 if quiet is None:
376 self.to_log(cmd)
377 try:
378 p = subprocess.Popen(cmd, **kw)
379 (out, err) = p.communicate()
380 except Exception as e:
381 raise Errors.WafError('Execution failure: %s' % str(e), ex=e)
382
383 if not isinstance(out, str):
384 out = out.decode(sys.stdout.encoding or 'iso8859-1')
385 if not isinstance(err, str):
386 err = err.decode(sys.stdout.encoding or 'iso8859-1')
387
388 if out and quiet != STDOUT and quiet != BOTH:
389 self.to_log('out: %s' % out)
390 if err and quiet != STDERR and quiet != BOTH:
391 self.to_log('err: %s' % err)
392
393 if p.returncode:
394 e = Errors.WafError('Command %r returned %r' % (cmd, p.returncode))
395 e.returncode = p.returncode
396 e.stderr = err
397 e.stdout = out
398 raise e
399
400 if to_ret == BOTH:
401 return (out, err)
402 elif to_ret == STDERR:
403 return err
404 return out
405
406 def fatal(self, msg, ex=None):
407 """
408 Raise a configuration error to interrupt the execution immediately::
409
410 def configure(conf):
411 conf.fatal('a requirement is missing')
412
413 :param msg: message to display
414 :type msg: string
415 :param ex: optional exception object
416 :type ex: exception
417 """
418 if self.logger:
419 self.logger.info('from %s: %s' % (self.path.abspath(), msg))
420 try:
421 msg = '%s\n(complete log in %s)' % (msg, self.logger.handlers[0].baseFilename)
422 except:
423 pass
424 raise self.errors.ConfigurationError(msg, ex=ex)
425
426 def to_log(self, msg):
427 """
428 Log some information to the logger (if present), or to stderr. If the message is empty,
429 it is not printed::
430
431 def build(bld):
432 bld.to_log('starting the build')
433
434 When in doubt, override this method, or provide a logger on the context class.
435
436 :param msg: message
437 :type msg: string
438 """
439 if not msg:
440 return
441 if self.logger:
442 self.logger.info(msg)
443 else:
444 sys.stderr.write(str(msg))
445 sys.stderr.flush()
446
447
448 def msg(self, msg, result, color=None):
449 """
450 Print a configuration message of the form ``msg: result``.
451 The second part of the message will be in colors. The output
452 can be disabled easly by setting ``in_msg`` to a positive value::
453
454 def configure(conf):
455 self.in_msg = 1
456 conf.msg('Checking for library foo', 'ok')
457 # no output
458
459 :param msg: message to display to the user
460 :type msg: string
461 :param result: result to display
462 :type result: string or boolean
463 :param color: color to use, see :py:const:`waflib.Logs.colors_lst`
464 :type color: string
465 """
466 self.start_msg(msg)
467
468 if not isinstance(color, str):
469 color = result and 'GREEN' or 'YELLOW'
470
471 self.end_msg(result, color)
472
473 def start_msg(self, msg):
474 """
475 Print the beginning of a 'Checking for xxx' message. See :py:meth:`waflib.Context.Context.msg`
476 """
477 try:
478 if self.in_msg:
479 self.in_msg += 1
480 return
481 except:
482 self.in_msg = 0
483 self.in_msg += 1
484
485 try:
486 self.line_just = max(self.line_just, len(msg))
487 except AttributeError:
488 self.line_just = max(40, len(msg))
489 for x in (self.line_just * '-', msg):
490 self.to_log(x)
491 Logs.pprint('NORMAL', "%s :" % msg.ljust(self.line_just), sep='')
492
493 def end_msg(self, result, color=None):
494 """Print the end of a 'Checking for' message. See :py:meth:`waflib.Context.Context.msg`"""
495 self.in_msg -= 1
496 if self.in_msg:
497 return
498
499 defcolor = 'GREEN'
500 if result == True:
501 msg = 'ok'
502 elif result == False:
503 msg = 'not found'
504 defcolor = 'YELLOW'
505 else:
506 msg = str(result)
507
508 self.to_log(msg)
509 Logs.pprint(color or defcolor, msg)
510
511
512 def load_special_tools(self, var, ban=[]):
513 global waf_dir
514 lst = self.root.find_node(waf_dir).find_node('waflib/extras').ant_glob(var)
515 for x in lst:
516 if not x.name in ban:
517 load_tool(x.name.replace('.py', ''))
518
519 cache_modules = {}
520 """
521 Dictionary holding already loaded modules, keyed by their absolute path.
522 The modules are added automatically by :py:func:`waflib.Context.load_module`
523 """
524
525 def load_module(path):
526 """
527 Load a source file as a python module.
528
529 :param path: file path
530 :type path: string
531 :return: Loaded Python module
532 :rtype: module
533 """
534 try:
535 return cache_modules[path]
536 except KeyError:
537 pass
538
539 module = imp.new_module(WSCRIPT_FILE)
540 try:
541 code = Utils.readf(path, m='rU')
542 except (IOError, OSError):
543 raise Errors.WafError('Could not read the file %r' % path)
544
545 module_dir = os.path.dirname(path)
546 sys.path.insert(0, module_dir)
547
548 exec(compile(code, path, 'exec'), module.__dict__)
549 sys.path.remove(module_dir)
550
551 cache_modules[path] = module
552
553 return module
554
555 def load_tool(tool, tooldir=None):
556 """
557 Import a Waf tool (python module), and store it in the dict :py:const:`waflib.Context.Context.tools`
558
559 :type tool: string
560 :param tool: Name of the tool
561 :type tooldir: list
562 :param tooldir: List of directories to search for the tool module
563 """
564 tool = tool.replace('++', 'xx')
565 tool = tool.replace('java', 'javaw')
566 tool = tool.replace('compiler_cc', 'compiler_c')
567
568 if tooldir:
569 assert isinstance(tooldir, list)
570 sys.path = tooldir + sys.path
571 try:
572 __import__(tool)
573 ret = sys.modules[tool]
574 Context.tools[tool] = ret
575 return ret
576 finally:
577 for d in tooldir:
578 sys.path.remove(d)
579 else:
580 global waf_dir
581 try:
582 os.stat(os.path.join(waf_dir, 'waflib', 'extras', tool + '.py'))
583 d = 'waflib.extras.%s' % tool
584 except:
585 try:
586 os.stat(os.path.join(waf_dir, 'waflib', 'Tools', tool + '.py'))
587 d = 'waflib.Tools.%s' % tool
588 except:
589 d = tool # user has messed with sys.path
590
591 __import__(d)
592 ret = sys.modules[d]
593 Context.tools[tool] = ret
594 return ret
595
0 #!/usr/bin/env python
1 # encoding: utf-8
2 # Thomas Nagy, 2010 (ita)
3
4 """
5 Exceptions used in the Waf code
6 """
7
8 import traceback, sys
9
10 class WafError(Exception):
11 """Base class for all Waf errors"""
12 def __init__(self, msg='', ex=None):
13 """
14 :param msg: error message
15 :type msg: string
16 :param ex: exception causing this error (optional)
17 :type ex: exception
18 """
19 self.msg = msg
20 assert not isinstance(msg, Exception)
21
22 self.stack = []
23 if ex:
24 if not msg:
25 self.msg = str(ex)
26 if isinstance(ex, WafError):
27 self.stack = ex.stack
28 else:
29 self.stack = traceback.extract_tb(sys.exc_info()[2])
30 self.stack += traceback.extract_stack()[:-1]
31 self.verbose_msg = ''.join(traceback.format_list(self.stack))
32
33 def __str__(self):
34 return str(self.msg)
35
36 class BuildError(WafError):
37 """
38 Errors raised during the build and install phases
39 """
40 def __init__(self, error_tasks=[]):
41 """
42 :param error_tasks: tasks that could not complete normally
43 :type error_tasks: list of task objects
44 """
45 self.tasks = error_tasks
46 WafError.__init__(self, self.format_error())
47
48 def format_error(self):
49 """format the error messages from the tasks that failed"""
50 lst = ['Build failed']
51 for tsk in self.tasks:
52 txt = tsk.format_error()
53 if txt: lst.append(txt)
54 return '\n'.join(lst)
55
56 class ConfigurationError(WafError):
57 """
58 Configuration exception raised in particular by :py:meth:`waflib.Context.Context.fatal`
59 """
60 pass
61
62 class TaskRescan(WafError):
63 """task-specific exception type, trigger a signature recomputation"""
64 pass
65
66 class TaskNotReady(WafError):
67 """task-specific exception type, raised when the task signature cannot be computed"""
68 pass
69
0 #!/usr/bin/env python
1 # encoding: utf-8
2 # Thomas Nagy, 2005-2010 (ita)
3
4 """
5 logging, colors, terminal width and pretty-print
6 """
7
8 import os, re, traceback, sys
9
10 _nocolor = os.environ.get('NOCOLOR', 'no') not in ('no', '0', 'false')
11 try:
12 if not _nocolor:
13 import waflib.ansiterm
14 except:
15 # optional module for colors on win32, just ignore if it cannot be imported
16 pass
17
18 import logging # do it after
19
20 LOG_FORMAT = "%(asctime)s %(c1)s%(zone)s%(c2)s %(message)s"
21 HOUR_FORMAT = "%H:%M:%S"
22
23 zones = ''
24 verbose = 0
25
26 colors_lst = {
27 'USE' : True,
28 'BOLD' :'\x1b[01;1m',
29 'RED' :'\x1b[01;31m',
30 'GREEN' :'\x1b[32m',
31 'YELLOW':'\x1b[33m',
32 'PINK' :'\x1b[35m',
33 'BLUE' :'\x1b[01;34m',
34 'CYAN' :'\x1b[36m',
35 'NORMAL':'\x1b[0m',
36 'cursor_on' :'\x1b[?25h',
37 'cursor_off' :'\x1b[?25l',
38 }
39
40 got_tty = not os.environ.get('TERM', 'dumb') in ['dumb', 'emacs']
41 if got_tty:
42 try:
43 got_tty = sys.stderr.isatty()
44 except AttributeError:
45 got_tty = False
46
47 if (not got_tty and os.environ.get('TERM', 'dumb') != 'msys') or _nocolor:
48 colors_lst['USE'] = False
49
50 def get_term_cols():
51 return 80
52
53 # If console packages are available, replace the dummy function with a real
54 # implementation
55 try:
56 import struct, fcntl, termios
57 except ImportError:
58 pass
59 else:
60 if got_tty:
61 def get_term_cols_real():
62 """
63 Private use only.
64 """
65
66 dummy_lines, cols = struct.unpack("HHHH", \
67 fcntl.ioctl(sys.stderr.fileno(),termios.TIOCGWINSZ , \
68 struct.pack("HHHH", 0, 0, 0, 0)))[:2]
69 return cols
70 # try the function once to see if it really works
71 try:
72 get_term_cols_real()
73 except:
74 pass
75 else:
76 get_term_cols = get_term_cols_real
77
78 get_term_cols.__doc__ = """
79 Get the console width in characters.
80
81 :return: the number of characters per line
82 :rtype: int
83 """
84
85 def get_color(cl):
86 if not colors_lst['USE']: return ''
87 return colors_lst.get(cl, '')
88
89 class color_dict(object):
90 """attribute-based color access, eg: colors.PINK"""
91 def __getattr__(self, a):
92 return get_color(a)
93 def __call__(self, a):
94 return get_color(a)
95
96 colors = color_dict()
97
98 re_log = re.compile(r'(\w+): (.*)', re.M)
99 class log_filter(logging.Filter):
100 """
101 The waf logs are of the form 'name: message', and can be filtered by 'waf --zones=name'.
102 For example, the following::
103
104 from waflib import Logs
105 Logs.debug('test: here is a message')
106
107 Will be displayed only when executing::
108
109 $ waf --zones=test
110 """
111 def __init__(self, name=None):
112 pass
113
114 def filter(self, rec):
115 """
116 filter a record, adding the colors automatically
117
118 * error: red
119 * warning: yellow
120
121 :param rec: message to record
122 """
123
124 rec.c1 = colors.PINK
125 rec.c2 = colors.NORMAL
126 rec.zone = rec.module
127 if rec.levelno >= logging.INFO:
128 if rec.levelno >= logging.ERROR:
129 rec.c1 = colors.RED
130 elif rec.levelno >= logging.WARNING:
131 rec.c1 = colors.YELLOW
132 else:
133 rec.c1 = colors.GREEN
134 return True
135
136 m = re_log.match(rec.msg)
137 if m:
138 rec.zone = m.group(1)
139 rec.msg = m.group(2)
140
141 if zones:
142 return getattr(rec, 'zone', '') in zones or '*' in zones
143 elif not verbose > 2:
144 return False
145 return True
146
147 class formatter(logging.Formatter):
148 """Simple log formatter which handles colors"""
149 def __init__(self):
150 logging.Formatter.__init__(self, LOG_FORMAT, HOUR_FORMAT)
151
152 def format(self, rec):
153 """Messages in warning, error or info mode are displayed in color by default"""
154 if rec.levelno >= logging.WARNING or rec.levelno == logging.INFO:
155 try:
156 msg = rec.msg.decode('utf-8')
157 except:
158 msg = rec.msg
159 return '%s%s%s' % (rec.c1, msg, rec.c2)
160 return logging.Formatter.format(self, rec)
161
162 log = None
163 """global logger for Logs.debug, Logs.error, etc"""
164
165 def debug(*k, **kw):
166 """
167 Wrap logging.debug, the output is filtered for performance reasons
168 """
169 if verbose:
170 k = list(k)
171 k[0] = k[0].replace('\n', ' ')
172 global log
173 log.debug(*k, **kw)
174
175 def error(*k, **kw):
176 """
177 Wrap logging.errors, display the origin of the message when '-vv' is set
178 """
179 global log
180 log.error(*k, **kw)
181 if verbose > 2:
182 st = traceback.extract_stack()
183 if st:
184 st = st[:-1]
185 buf = []
186 for filename, lineno, name, line in st:
187 buf.append(' File "%s", line %d, in %s' % (filename, lineno, name))
188 if line:
189 buf.append(' %s' % line.strip())
190 if buf: log.error("\n".join(buf))
191
192 def warn(*k, **kw):
193 """
194 Wrap logging.warn
195 """
196 global log
197 log.warn(*k, **kw)
198
199 def info(*k, **kw):
200 """
201 Wrap logging.info
202 """
203 global log
204 log.info(*k, **kw)
205
206 def init_log():
207 """
208 Initialize the loggers globally
209 """
210 global log
211 log = logging.getLogger('waflib')
212 log.handlers = []
213 log.filters = []
214 hdlr = logging.StreamHandler()
215 hdlr.setFormatter(formatter())
216 log.addHandler(hdlr)
217 log.addFilter(log_filter())
218 log.setLevel(logging.DEBUG)
219
220 def make_logger(path, name):
221 """
222 Create a simple logger, which is often used to redirect the context command output::
223
224 from waflib import Logs
225 bld.logger = Logs.make_logger('test.log', 'build')
226 bld.check(header_name='sadlib.h', features='cxx cprogram', mandatory=False)
227 bld.logger = None
228
229 :param path: file name to write the log output to
230 :type path: string
231 :param name: logger name (loggers are reused)
232 :type name: string
233 """
234 logger = logging.getLogger(name)
235 hdlr = logging.FileHandler(path, 'w')
236 formatter = logging.Formatter('%(message)s')
237 hdlr.setFormatter(formatter)
238 logger.addHandler(hdlr)
239 logger.setLevel(logging.DEBUG)
240 return logger
241
242 def make_mem_logger(name, to_log, size=10000):
243 """
244 Create a memory logger to avoid writing concurrently to the main logger
245 """
246 from logging.handlers import MemoryHandler
247 logger = logging.getLogger(name)
248 hdlr = MemoryHandler(size, target=to_log)
249 formatter = logging.Formatter('%(message)s')
250 hdlr.setFormatter(formatter)
251 logger.addHandler(hdlr)
252 logger.memhandler = hdlr
253 logger.setLevel(logging.DEBUG)
254 return logger
255
256 def pprint(col, str, label='', sep='\n'):
257 """
258 Print messages in color immediately on stderr::
259
260 from waflib import Logs
261 Logs.pprint('RED', 'Something bad just happened')
262
263 :param col: color name to use in :py:const:`Logs.colors_lst`
264 :type col: string
265 :param str: message to display
266 :type str: string or a value that can be printed by %s
267 :param label: a message to add after the colored output
268 :type label: string
269 :param sep: a string to append at the end (line separator)
270 :type sep: string
271 """
272 sys.stderr.write("%s%s%s %s%s" % (colors(col), str, colors.NORMAL, label, sep))
273
0 #!/usr/bin/env python
1 # encoding: utf-8
2 # Thomas Nagy, 2005-2010 (ita)
3
4 """
5 Node: filesystem structure, contains lists of nodes
6
7 #. Each file/folder is represented by exactly one node.
8
9 #. Some potential class properties are stored on :py:class:`waflib.Build.BuildContext` : nodes to depend on, etc.
10 Unused class members can increase the `.wafpickle` file size sensibly.
11
12 #. Node objects should never be created directly, use
13 the methods :py:func:`Node.make_node` or :py:func:`Node.find_node`
14
15 #. The methods :py:func:`Node.find_resource`, :py:func:`Node.find_dir` :py:func:`Node.find_or_declare` should be
16 used when a build context is present
17
18 #. Each instance of :py:class:`waflib.Context.Context` has a unique :py:class:`Node` subclass.
19 (:py:class:`waflib.Node.Nod3`, see the :py:class:`waflib.Context.Context` initializer). A reference to the context owning a node is held as self.ctx
20 """
21
22 import os, re, sys, shutil
23 from waflib import Utils, Errors
24
25 exclude_regs = '''
26 **/*~
27 **/#*#
28 **/.#*
29 **/%*%
30 **/._*
31 **/CVS
32 **/CVS/**
33 **/.cvsignore
34 **/SCCS
35 **/SCCS/**
36 **/vssver.scc
37 **/.svn
38 **/.svn/**
39 **/BitKeeper
40 **/.git
41 **/.git/**
42 **/.gitignore
43 **/.bzr
44 **/.bzrignore
45 **/.bzr/**
46 **/.hg
47 **/.hg/**
48 **/_MTN
49 **/_MTN/**
50 **/.arch-ids
51 **/{arch}
52 **/_darcs
53 **/_darcs/**
54 **/.intlcache
55 **/.DS_Store'''
56 """
57 Ant patterns for files and folders to exclude while doing the
58 recursive traversal in :py:meth:`waflib.Node.Node.ant_glob`
59 """
60
61 # TODO optimize split_path by performing a replacement when unpacking?
62
63 def split_path(path):
64 """
65 Split a path by os.sep (This is not os.path.split)
66
67 :param path: path to split
68 :type path: string
69 :rtype: list of string
70 :return: the path, split
71 """
72 return path.split('/')
73
74 def split_path_cygwin(path):
75 if path.startswith('//'):
76 ret = path.split('/')[2:]
77 ret[0] = '/' + ret[0]
78 return ret
79 return path.split('/')
80
81 re_sp = re.compile('[/\\\\]')
82 def split_path_win32(path):
83 if path.startswith('\\\\'):
84 ret = re.split(re_sp, path)[2:]
85 ret[0] = '\\' + ret[0]
86 return ret
87 return re.split(re_sp, path)
88
89 if sys.platform == 'cygwin':
90 split_path = split_path_cygwin
91 elif Utils.is_win32:
92 split_path = split_path_win32
93
94 class Node(object):
95 """
96 This class is organized in two parts
97
98 * The basic methods meant for filesystem access (compute paths, create folders, etc)
99 * The methods bound to a :py:class:`waflib.Build.BuildContext` (require ``bld.srcnode`` and ``bld.bldnode``)
100
101 The Node objects are not thread safe in any way.
102 """
103
104 __slots__ = ('name', 'sig', 'children', 'parent', 'cache_abspath', 'cache_isdir')
105 def __init__(self, name, parent):
106 self.name = name
107 self.parent = parent
108
109 if parent:
110 if name in parent.children:
111 raise Errors.WafError('node %s exists in the parent files %r already' % (name, parent))
112 parent.children[name] = self
113
114 def __setstate__(self, data):
115 "Deserializes from data"
116 self.name = data[0]
117 self.parent = data[1]
118 if data[2] is not None:
119 self.children = data[2]
120 if data[3] is not None:
121 self.sig = data[3]
122
123 def __getstate__(self):
124 "Serialize the node info"
125 return (self.name, self.parent, getattr(self, 'children', None), getattr(self, 'sig', None))
126
127 def __str__(self):
128 "String representation (name), for debugging purposes"
129 return self.name
130
131 def __repr__(self):
132 "String representation (abspath), for debugging purposes"
133 return self.abspath()
134
135 def __hash__(self):
136 "Node hash, used for storage in dicts. This hash is not persistent."
137 return id(self)
138
139 def __eq__(self, node):
140 "Node comparison, based on the IDs"
141 return id(self) == id(node)
142
143 def __copy__(self):
144 "Implemented to prevent nodes from being copied (raises an exception)"
145 raise Errors.WafError('nodes are not supposed to be copied')
146
147 def read(self, flags='r'):
148 """
149 Return the contents of the file represented by this node::
150
151 def build(bld):
152 bld.path.find_node('wscript').read()
153
154 :type fname: string
155 :param fname: Path to file
156 :type m: string
157 :param m: Open mode
158 :rtype: string
159 :return: File contents
160 """
161 return Utils.readf(self.abspath(), flags)
162
163 def write(self, data, flags='w'):
164 """
165 Write some text to the physical file represented by this node::
166
167 def build(bld):
168 bld.path.make_node('foo.txt').write('Hello, world!')
169
170 :type data: string
171 :param data: data to write
172 :type flags: string
173 :param flags: Write mode
174 """
175 f = None
176 try:
177 f = open(self.abspath(), flags)
178 f.write(data)
179 finally:
180 if f:
181 f.close()
182
183 def chmod(self, val):
184 """
185 Change file/dir permissions::
186
187 def build(bld):
188 bld.path.chmod(493) # 0755
189 """
190 os.chmod(self.abspath(), val)
191
192 def delete(self):
193 """Delete the file/folder physically (but not the node)"""
194 try:
195 if getattr(self, 'children', None):
196 shutil.rmtree(self.abspath())
197 else:
198 os.unlink(self.abspath())
199 except:
200 pass
201
202 try:
203 delattr(self, 'children')
204 except:
205 pass
206
207 def suffix(self):
208 """Return the file extension"""
209 k = max(0, self.name.rfind('.'))
210 return self.name[k:]
211
212 def height(self):
213 """Depth in the folder hierarchy from the filesystem root or from all the file drives"""
214 d = self
215 val = -1
216 while d:
217 d = d.parent
218 val += 1
219 return val
220
221 def listdir(self):
222 """List the folder contents"""
223 lst = Utils.listdir(self.abspath())
224 lst.sort()
225 return lst
226
227 def mkdir(self):
228 """
229 Create a folder represented by this node, creating intermediate nodes as needed
230 An exception will be raised only when the folder cannot possibly exist there
231 """
232 if getattr(self, 'cache_isdir', None):
233 return
234
235 try:
236 self.parent.mkdir()
237 except:
238 pass
239
240 if self.name:
241 try:
242 os.makedirs(self.abspath())
243 except OSError:
244 pass
245
246 if not os.path.isdir(self.abspath()):
247 raise Errors.WafError('Could not create the directory %s' % self.abspath())
248
249 try:
250 self.children
251 except:
252 self.children = {}
253
254 self.cache_isdir = True
255
256 def find_node(self, lst):
257 """
258 Find a node on the file system (files or folders), create intermediate nodes as needed
259
260 :param lst: path
261 :type lst: string or list of string
262 """
263
264 if isinstance(lst, str):
265 lst = [x for x in split_path(lst) if x and x != '.']
266
267 cur = self
268 for x in lst:
269 if x == '..':
270 cur = cur.parent or cur
271 continue
272
273 try:
274 if x in cur.children:
275 cur = cur.children[x]
276 continue
277 except:
278 cur.children = {}
279
280 # optimistic: create the node first then look if it was correct to do so
281 cur = self.__class__(x, cur)
282 try:
283 os.stat(cur.abspath())
284 except:
285 del cur.parent.children[x]
286 return None
287
288 ret = cur
289
290 try:
291 os.stat(ret.abspath())
292 except:
293 del ret.parent.children[ret.name]
294 return None
295
296 try:
297 while not getattr(cur.parent, 'cache_isdir', None):
298 cur = cur.parent
299 cur.cache_isdir = True
300 except AttributeError:
301 pass
302
303 return ret
304
305 def make_node(self, lst):
306 """
307 Find or create a node without looking on the filesystem
308
309 :param lst: path
310 :type lst: string or list of string
311 """
312 if isinstance(lst, str):
313 lst = [x for x in split_path(lst) if x and x != '.']
314
315 cur = self
316 for x in lst:
317 if x == '..':
318 cur = cur.parent or cur
319 continue
320
321 if getattr(cur, 'children', {}):
322 if x in cur.children:
323 cur = cur.children[x]
324 continue
325 else:
326 cur.children = {}
327 cur = self.__class__(x, cur)
328 return cur
329
330 def search(self, lst):
331 """
332 Search for a node without looking on the filesystem
333
334 :param lst: path
335 :type lst: string or list of string
336 """
337 if isinstance(lst, str):
338 lst = [x for x in split_path(lst) if x and x != '.']
339
340 cur = self
341 try:
342 for x in lst:
343 if x == '..':
344 cur = cur.parent or cur
345 else:
346 cur = cur.children[x]
347 return cur
348 except:
349 pass
350
351 def path_from(self, node):
352 """
353 Path of this node seen from the other::
354
355 def build(bld):
356 n1 = bld.path.find_node('foo/bar/xyz.txt')
357 n2 = bld.path.find_node('foo/stuff/')
358 n1.path_from(n2) # './bar/xyz.txt'
359
360 :param node: path to use as a reference
361 :type node: :py:class:`waflib.Node.Node`
362 """
363
364 c1 = self
365 c2 = node
366
367 c1h = c1.height()
368 c2h = c2.height()
369
370 lst = []
371 up = 0
372
373 while c1h > c2h:
374 lst.append(c1.name)
375 c1 = c1.parent
376 c1h -= 1
377
378 while c2h > c1h:
379 up += 1
380 c2 = c2.parent
381 c2h -= 1
382
383 while id(c1) != id(c2):
384 lst.append(c1.name)
385 up += 1
386
387 c1 = c1.parent
388 c2 = c2.parent
389
390 for i in range(up):
391 lst.append('..')
392 lst.reverse()
393 return os.sep.join(lst) or '.'
394
395 def abspath(self):
396 """
397 Absolute path. A cache is kept in the context as ``cache_node_abspath``
398 """
399 try:
400 return self.cache_abspath
401 except:
402 pass
403 # think twice before touching this (performance + complexity + correctness)
404
405 if os.sep == '/':
406 if not self.parent:
407 val = os.sep
408 elif not self.parent.name:
409 val = os.sep + self.name
410 else:
411 val = self.parent.abspath() + os.sep + self.name
412 else:
413 if not self.parent:
414 val = ''
415 elif not self.parent.name:
416 val = self.name + os.sep
417 else:
418 val = self.parent.abspath().rstrip(os.sep) + os.sep + self.name
419
420 self.cache_abspath = val
421 return val
422
423 def is_child_of(self, node):
424 """
425 Does this node belong to the subtree node?::
426
427 def build(bld):
428 node = bld.path.find_node('wscript')
429 node.is_child_of(bld.path) # True
430
431 :param node: path to use as a reference
432 :type node: :py:class:`waflib.Node.Node`
433 """
434 p = self
435 diff = self.height() - node.height()
436 while diff > 0:
437 diff -= 1
438 p = p.parent
439 return id(p) == id(node)
440
441 def ant_iter(self, accept=None, maxdepth=25, pats=[], dir=False, src=True, remove=True):
442 """
443 Semi-private and recursive method used by ant_glob.
444
445 :param accept: function used for accepting/rejecting a node, returns the patterns that can be still accepted in recursion
446 :type accept: function
447 :param maxdepth: maximum depth in the filesystem (25)
448 :type maxdepth: int
449 :param pats: list of patterns to accept and list of patterns to exclude
450 :type pats: tuple
451 :param dir: return folders too (False by default)
452 :type dir: bool
453 :param src: return files (True by default)
454 :type src: bool
455 :param remove: remove files/folders that do not exist (True by default)
456 :type remove: bool
457 """
458 dircont = self.listdir()
459 dircont.sort()
460
461 try:
462 lst = set(self.children.keys())
463 if remove:
464 for x in lst - set(dircont):
465 del self.children[x]
466 except:
467 self.children = {}
468
469 for name in dircont:
470 npats = accept(name, pats)
471 if npats and npats[0]:
472 accepted = [] in npats[0]
473
474 node = self.make_node([name])
475
476 isdir = os.path.isdir(node.abspath())
477 if accepted:
478 if isdir:
479 if dir:
480 yield node
481 else:
482 if src:
483 yield node
484
485 if getattr(node, 'cache_isdir', None) or isdir:
486 node.cache_isdir = True
487 if maxdepth:
488 for k in node.ant_iter(accept=accept, maxdepth=maxdepth - 1, pats=npats, dir=dir, src=src, remove=remove):
489 yield k
490 raise StopIteration
491
492 def ant_glob(self, *k, **kw):
493 """
494 This method is used for finding files across folders. It behaves like ant patterns:
495
496 * ``**/*`` find all files recursively
497 * ``**/*.class`` find all files ending by .class
498 * ``..`` find files having two dot characters
499
500 For example::
501
502 def configure(cfg):
503 cfg.path.ant_glob('**/*.cpp') # find all .cpp files
504 cfg.root.ant_glob('etc/*.txt') # using the filesystem root can be slow
505 cfg.path.ant_glob('*.cpp', excl=['*.c'], src=True, dir=False)
506
507 For more information see http://ant.apache.org/manual/dirtasks.html
508
509 The nodes that correspond to files and folders that do not exist will be removed. To prevent this
510 behaviour, pass 'remove=False'
511
512 :param incl: ant patterns or list of patterns to include
513 :type incl: string or list of strings
514 :param excl: ant patterns or list of patterns to exclude
515 :type excl: string or list of strings
516 :param dir: return folders too (False by default)
517 :type dir: bool
518 :param src: return files (True by default)
519 :type src: bool
520 :param remove: remove files/folders that do not exist (True by default)
521 :type remove: bool
522 :param maxdepth: maximum depth of recursion
523 :type maxdepth: int
524 """
525
526 src = kw.get('src', True)
527 dir = kw.get('dir', False)
528
529 excl = kw.get('excl', exclude_regs)
530 incl = k and k[0] or kw.get('incl', '**')
531
532 def to_pat(s):
533 lst = Utils.to_list(s)
534 ret = []
535 for x in lst:
536 x = x.replace('\\', '/').replace('//', '/')
537 if x.endswith('/'):
538 x += '**'
539 lst2 = x.split('/')
540 accu = []
541 for k in lst2:
542 if k == '**':
543 accu.append(k)
544 else:
545 k = k.replace('.', '[.]').replace('*','.*').replace('?', '.').replace('+', '\\+')
546 k = '^%s$' % k
547 try:
548 #print "pattern", k
549 accu.append(re.compile(k))
550 except Exception as e:
551 raise Errors.WafError("Invalid pattern: %s" % k, e)
552 ret.append(accu)
553 return ret
554
555 def filtre(name, nn):
556 ret = []
557 for lst in nn:
558 if not lst:
559 pass
560 elif lst[0] == '**':
561 ret.append(lst)
562 if len(lst) > 1:
563 if lst[1].match(name):
564 ret.append(lst[2:])
565 else:
566 ret.append([])
567 elif lst[0].match(name):
568 ret.append(lst[1:])
569 return ret
570
571 def accept(name, pats):
572 nacc = filtre(name, pats[0])
573 nrej = filtre(name, pats[1])
574 if [] in nrej:
575 nacc = []
576 return [nacc, nrej]
577
578 ret = [x for x in self.ant_iter(accept=accept, pats=[to_pat(incl), to_pat(excl)], maxdepth=25, dir=dir, src=src, remove=kw.get('remove', True))]
579 if kw.get('flat', False):
580 return ' '.join([x.path_from(self) for x in ret])
581
582 return ret
583
584 def find_nodes(self, find_dirs=True, find_files=True, match_fun=lambda x: True):
585 # FIXME not part of the stable API: find_node vs find_nodes? consistency with argument names on other functions?
586 x = """
587 Recursively finds nodes::
588
589 def configure(cnf):
590 cnf.find_nodes()
591
592 :param find_dirs: whether to return directories
593 :param find_files: whether to return files
594 :param match_fun: matching function, taking a node as parameter
595 :rtype generator
596 :return: a generator that iterates over all the requested files
597 """
598 files = self.listdir()
599 for f in files:
600 node = self.make_node([f])
601 if os.path.isdir(node.abspath()):
602 if find_dirs and match_fun(node):
603 yield node
604 gen = node.find_nodes(find_dirs, find_files, match_fun)
605 for g in gen:
606 yield g
607 else:
608 if find_files and match_fun(node):
609 yield node
610
611
612 # --------------------------------------------------------------------------------
613 # the following methods require the source/build folders (bld.srcnode/bld.bldnode)
614 # using a subclass is a possibility, but is that really necessary?
615 # --------------------------------------------------------------------------------
616
617 def is_src(self):
618 """
619 True if the node is below the source directory
620 note: !is_src does not imply is_bld()
621
622 :rtype: bool
623 """
624 cur = self
625 x = id(self.ctx.srcnode)
626 y = id(self.ctx.bldnode)
627 while cur.parent:
628 if id(cur) == y:
629 return False
630 if id(cur) == x:
631 return True
632 cur = cur.parent
633 return False
634
635 def is_bld(self):
636 """
637 True if the node is below the build directory
638 note: !is_bld does not imply is_src
639
640 :rtype: bool
641 """
642 cur = self
643 y = id(self.ctx.bldnode)
644 while cur.parent:
645 if id(cur) == y:
646 return True
647 cur = cur.parent
648 return False
649
650 def get_src(self):
651 """
652 Return the equivalent src node (or self if not possible)
653
654 :rtype: :py:class:`waflib.Node.Node`
655 """
656 cur = self
657 x = id(self.ctx.srcnode)
658 y = id(self.ctx.bldnode)
659 lst = []
660 while cur.parent:
661 if id(cur) == y:
662 lst.reverse()
663 return self.ctx.srcnode.make_node(lst)
664 if id(cur) == x:
665 return self
666 lst.append(cur.name)
667 cur = cur.parent
668 return self
669
670 def get_bld(self):
671 """
672 Return the equivalent bld node (or self if not possible)
673
674 :rtype: :py:class:`waflib.Node.Node`
675 """
676 cur = self
677 x = id(self.ctx.srcnode)
678 y = id(self.ctx.bldnode)
679 lst = []
680 while cur.parent:
681 if id(cur) == y:
682 return self
683 if id(cur) == x:
684 lst.reverse()
685 return self.ctx.bldnode.make_node(lst)
686 lst.append(cur.name)
687 cur = cur.parent
688 # the file is external to the current project, make a fake root in the current build directory
689 lst.reverse()
690 if lst and Utils.is_win32 and len(lst[0]) == 2 and lst[0].endswith(':'):
691 lst[0] = lst[0][0]
692 return self.ctx.bldnode.make_node(['__root__'] + lst)
693
694 def find_resource(self, lst):
695 """
696 Try to find a declared build node or a source file
697
698 :param lst: path
699 :type lst: string or list of string
700 """
701 if isinstance(lst, str):
702 lst = [x for x in split_path(lst) if x and x != '.']
703
704 node = self.get_bld().search(lst)
705 if not node:
706 self = self.get_src()
707 node = self.find_node(lst)
708 try:
709 pat = node.abspath()
710 if os.path.isdir(pat):
711 return None
712 except:
713 pass
714 return node
715
716 def find_or_declare(self, lst):
717 """
718 if 'self' is in build directory, try to return an existing node
719 if no node is found, go to the source directory
720 try to find an existing node in the source directory
721 if no node is found, create it in the build directory
722
723 :param lst: path
724 :type lst: string or list of string
725 """
726 if isinstance(lst, str):
727 lst = [x for x in split_path(lst) if x and x != '.']
728
729 node = self.get_bld().search(lst)
730 if node:
731 if not os.path.isfile(node.abspath()):
732 node.sig = None
733 try:
734 node.parent.mkdir()
735 except:
736 pass
737 return node
738 self = self.get_src()
739 node = self.find_node(lst)
740 if node:
741 if not os.path.isfile(node.abspath()):
742 node.sig = None
743 try:
744 node.parent.mkdir()
745 except:
746 pass
747 return node
748 node = self.get_bld().make_node(lst)
749 node.parent.mkdir()
750 return node
751
752 def find_dir(self, lst):
753 """
754 Search for a folder in the filesystem
755
756 :param lst: path
757 :type lst: string or list of string
758 """
759 if isinstance(lst, str):
760 lst = [x for x in split_path(lst) if x and x != '.']
761
762 node = self.find_node(lst)
763 try:
764 if not os.path.isdir(node.abspath()):
765 return None
766 except (OSError, AttributeError):
767 # the node might be None, and raise an AttributeError
768 return None
769 return node
770
771 # helpers for building things
772 def change_ext(self, ext, ext_in=None):
773 """
774 :return: A build node of the same path, but with a different extension
775 :rtype: :py:class:`waflib.Node.Node`
776 """
777 name = self.name
778 if ext_in is None:
779 k = name.rfind('.')
780 if k >= 0:
781 name = name[:k] + ext
782 else:
783 name = name + ext
784 else:
785 name = name[:- len(ext_in)] + ext
786
787 return self.parent.find_or_declare([name])
788
789 def nice_path(self, env=None):
790 """
791 Return the path seen from the launch directory. It is often used for printing nodes in the console to open
792 files easily.
793
794 :param env: unused, left for compatibility with waf 1.5
795 """
796 return self.path_from(self.ctx.launch_node())
797
798 def bldpath(self):
799 "Path seen from the build directory default/src/foo.cpp"
800 return self.path_from(self.ctx.bldnode)
801
802 def srcpath(self):
803 "Path seen from the source directory ../src/foo.cpp"
804 return self.path_from(self.ctx.srcnode)
805
806 def relpath(self):
807 "If a file in the build directory, bldpath, else srcpath"
808 cur = self
809 x = id(self.ctx.bldnode)
810 while cur.parent:
811 if id(cur) == x:
812 return self.bldpath()
813 cur = cur.parent
814 return self.srcpath()
815
816 def bld_dir(self):
817 "Build path without the file name"
818 return self.parent.bldpath()
819
820 def bld_base(self):
821 "Build path without the extension: src/dir/foo(.cpp)"
822 s = os.path.splitext(self.name)[0]
823 return self.bld_dir() + os.sep + s
824
825 def get_bld_sig(self):
826 """
827 Node signature, assuming the file is in the build directory
828 """
829 try:
830 ret = self.ctx.hash_cache[id(self)]
831 except KeyError:
832 pass
833 except AttributeError:
834 self.ctx.hash_cache = {}
835 else:
836 return ret
837
838 if not self.is_bld() or self.ctx.bldnode is self.ctx.srcnode:
839 self.sig = Utils.h_file(self.abspath())
840 self.ctx.hash_cache[id(self)] = ret = self.sig
841 return ret
842
843 pickle_lock = Utils.threading.Lock()
844 """Lock mandatory for thread-safe node serialization"""
845
846 class Nod3(Node):
847 """Mandatory subclass for thread-safe node serialization"""
848 pass # do not remove
849
850
0 #!/usr/bin/env python
1 # encoding: utf-8
2 # Scott Newton, 2005 (scottn)
3 # Thomas Nagy, 2006-2010 (ita)
4
5 """
6 Support for waf command-line options
7
8 Provides default command-line options,
9 as well as custom ones, used by the ``options`` wscript function.
10
11 """
12
13 import os, tempfile, optparse, sys, re
14 from waflib import Logs, Utils, Context
15
16 cmds = 'distclean configure build install clean uninstall check dist distcheck'.split()
17 """
18 Constant representing the default waf commands displayed in::
19
20 $ waf --help
21
22 """
23
24 options = {}
25 """
26 A dictionary representing the command-line options::
27
28 $ waf --foo=bar
29
30 """
31
32 commands = []
33 """
34 List of commands to execute extracted from the command-line. This list is consumed during the execution, see :py:func:`waflib.Scripting.run_commands`.
35 """
36
37 lockfile = os.environ.get('WAFLOCK', '.lock-waf_%s_build' % sys.platform)
38 try: cache_global = os.path.abspath(os.environ['WAFCACHE'])
39 except KeyError: cache_global = ''
40 platform = Utils.unversioned_sys_platform()
41
42
43 class opt_parser(optparse.OptionParser):
44 """
45 Command-line options parser.
46 """
47 def __init__(self, ctx):
48 optparse.OptionParser.__init__(self, conflict_handler="resolve", version='waf %s (%s)' % (Context.WAFVERSION, Context.WAFREVISION))
49
50 self.formatter.width = Logs.get_term_cols()
51 p = self.add_option
52 self.ctx = ctx
53
54 jobs = ctx.jobs()
55 p('-j', '--jobs', dest='jobs', default=jobs, type='int', help='amount of parallel jobs (%r)' % jobs)
56 p('-k', '--keep', dest='keep', default=0, action='count', help='keep running happily even if errors are found')
57 p('-v', '--verbose', dest='verbose', default=0, action='count', help='verbosity level -v -vv or -vvv [default: 0]')
58 p('--nocache', dest='nocache', default=False, action='store_true', help='ignore the WAFCACHE (if set)')
59 p('--zones', dest='zones', default='', action='store', help='debugging zones (task_gen, deps, tasks, etc)')
60
61 gr = optparse.OptionGroup(self, 'configure options')
62 self.add_option_group(gr)
63
64 gr.add_option('-o', '--out', action='store', default='', help='build dir for the project', dest='out')
65 gr.add_option('-t', '--top', action='store', default='', help='src dir for the project', dest='top')
66
67 default_prefix = os.environ.get('PREFIX')
68 if not default_prefix:
69 if platform == 'win32':
70 d = tempfile.gettempdir()
71 default_prefix = d[0].upper() + d[1:]
72 # win32 preserves the case, but gettempdir does not
73 else:
74 default_prefix = '/usr/local/'
75 gr.add_option('--prefix', dest='prefix', default=default_prefix, help='installation prefix [default: %r]' % default_prefix)
76 gr.add_option('--download', dest='download', default=False, action='store_true', help='try to download the tools if missing')
77
78
79 gr = optparse.OptionGroup(self, 'build and install options')
80 self.add_option_group(gr)
81
82 gr.add_option('-p', '--progress', dest='progress_bar', default=0, action='count', help= '-p: progress bar; -pp: ide output')
83 gr.add_option('--targets', dest='targets', default='', action='store', help='task generators, e.g. "target1,target2"')
84
85 gr = optparse.OptionGroup(self, 'step options')
86 self.add_option_group(gr)
87 gr.add_option('--files', dest='files', default='', action='store', help='files to process, by regexp, e.g. "*/main.c,*/test/main.o"')
88
89 default_destdir = os.environ.get('DESTDIR', '')
90 gr = optparse.OptionGroup(self, 'install/uninstall options')
91 self.add_option_group(gr)
92 gr.add_option('--destdir', help='installation root [default: %r]' % default_destdir, default=default_destdir, dest='destdir')
93 gr.add_option('-f', '--force', dest='force', default=False, action='store_true', help='force file installation')
94
95 def get_usage(self):
96 """
97 Return the message to print on ``waf --help``
98 """
99 cmds_str = {}
100 for cls in Context.classes:
101 if not cls.cmd or cls.cmd == 'options':
102 continue
103
104 s = cls.__doc__ or ''
105 cmds_str[cls.cmd] = s
106
107 if Context.g_module:
108 for (k, v) in Context.g_module.__dict__.items():
109 if k in ['options', 'init', 'shutdown']:
110 continue
111
112 if type(v) is type(Context.create_context):
113 if v.__doc__ and not k.startswith('_'):
114 cmds_str[k] = v.__doc__
115
116 just = 0
117 for k in cmds_str:
118 just = max(just, len(k))
119
120 lst = [' %s: %s' % (k.ljust(just), v) for (k, v) in cmds_str.items()]
121 lst.sort()
122 ret = '\n'.join(lst)
123
124 return '''waf [commands] [options]
125
126 Main commands (example: ./waf build -j4)
127 %s
128 ''' % ret
129
130
131 class OptionsContext(Context.Context):
132 """
133 Collect custom options from wscript files and parses the command line.
134 Set the global :py:const:`waflib.Options.commands` and :py:const:`waflib.Options.options` values.
135 """
136
137 cmd = 'options'
138 fun = 'options'
139
140 def __init__(self, **kw):
141 super(OptionsContext, self).__init__(**kw)
142
143 self.parser = opt_parser(self)
144 """Instance of :py:class:`waflib.Options.opt_parser`"""
145
146 self.option_groups = {}
147
148 def jobs(self):
149 """
150 Find the amount of cpu cores to set the default amount of tasks executed in parallel. At
151 runtime the options can be obtained from :py:const:`waflib.Options.options` ::
152
153 from waflib.Options import options
154 njobs = options.jobs
155
156 :return: the amount of cpu cores
157 :rtype: int
158 """
159 count = int(os.environ.get('JOBS', 0))
160 if count < 1:
161 if 'NUMBER_OF_PROCESSORS' in os.environ:
162 # on Windows, use the NUMBER_OF_PROCESSORS environment variable
163 count = int(os.environ.get('NUMBER_OF_PROCESSORS', 1))
164 else:
165 # on everything else, first try the POSIX sysconf values
166 if hasattr(os, 'sysconf_names'):
167 if 'SC_NPROCESSORS_ONLN' in os.sysconf_names:
168 count = int(os.sysconf('SC_NPROCESSORS_ONLN'))
169 elif 'SC_NPROCESSORS_CONF' in os.sysconf_names:
170 count = int(os.sysconf('SC_NPROCESSORS_CONF'))
171 if not count and os.name not in ('nt', 'java'):
172 try:
173 tmp = self.cmd_and_log(['sysctl', '-n', 'hw.ncpu'], quiet=0)
174 except Exception:
175 pass
176 else:
177 if re.match('^[0-9]+$', tmp):
178 count = int(tmp)
179 if count < 1:
180 count = 1
181 elif count > 1024:
182 count = 1024
183 return count
184
185 def add_option(self, *k, **kw):
186 """
187 Wrapper for optparse.add_option::
188
189 def options(ctx):
190 ctx.add_option('-u', '--use', dest='use', default=False, action='store_true',
191 help='a boolean option')
192 """
193 self.parser.add_option(*k, **kw)
194
195 def add_option_group(self, *k, **kw):
196 """
197 Wrapper for optparse.add_option_group::
198
199 def options(ctx):
200 ctx.add_option_group('some options')
201 gr.add_option('-u', '--use', dest='use', default=False, action='store_true')
202 """
203 try:
204 gr = self.option_groups[k[0]]
205 except:
206 gr = self.parser.add_option_group(*k, **kw)
207 self.option_groups[k[0]] = gr
208 return gr
209
210 def get_option_group(self, opt_str):
211 """
212 Wrapper for optparse.get_option_group::
213
214 def options(ctx):
215 gr = ctx.get_option_group('configure options')
216 gr.add_option('-o', '--out', action='store', default='',
217 help='build dir for the project', dest='out')
218
219 """
220 try:
221 return self.option_groups[opt_str]
222 except KeyError:
223 for group in self.parser.option_groups:
224 if group.title == opt_str:
225 return group
226 return None
227
228 def parse_args(self, _args=None):
229 """
230 Parse arguments from a list (not bound to the command-line).
231
232 :param _args: arguments
233 :type _args: list of strings
234 """
235 global options, commands
236 (options, leftover_args) = self.parser.parse_args(args=_args)
237 commands = leftover_args
238
239 if options.destdir:
240 options.destdir = os.path.abspath(os.path.expanduser(options.destdir))
241
242 if options.verbose >= 1:
243 self.load('errcheck')
244
245 def execute(self):
246 """
247 See :py:func:`waflib.Context.Context.execute`
248 """
249 super(OptionsContext, self).execute()
250 self.parse_args()
251
0 #!/usr/bin/env python
1 # encoding: utf-8
2 # Thomas Nagy, 2005-2010 (ita)
3
4 """
5 Runner.py: Task scheduling and execution
6
7 """
8
9 import random, atexit
10 try:
11 from queue import Queue
12 except:
13 from Queue import Queue
14 from waflib import Utils, Task, Errors, Logs
15
16 GAP = 10
17 """
18 Wait for free tasks if there are at least ``GAP * njobs`` in queue
19 """
20
21 class TaskConsumer(Utils.threading.Thread):
22 """
23 Task consumers belong to a pool of workers
24
25 They wait for tasks in the queue and then use ``task.process(...)``
26 """
27 def __init__(self):
28 Utils.threading.Thread.__init__(self)
29 self.ready = Queue()
30 """
31 Obtain :py:class:`waflib.Task.TaskBase` instances from this queue.
32 """
33 self.setDaemon(1)
34 self.start()
35
36 def run(self):
37 """
38 Loop over the tasks to execute
39 """
40 try:
41 self.loop()
42 except:
43 pass
44
45 def loop(self):
46 """
47 Obtain tasks from :py:attr:`waflib.Runner.TaskConsumer.ready` and call
48 :py:meth:`waflib.Task.TaskBase.process`. If the object is a function, execute it.
49 """
50 while 1:
51 tsk = self.ready.get()
52 if not isinstance(tsk, Task.TaskBase):
53 tsk(self)
54 else:
55 tsk.process()
56
57 pool = Queue()
58 """
59 Pool of task consumer objects
60 """
61
62 def get_pool():
63 """
64 Obtain a task consumer from :py:attr:`waflib.Runner.pool`.
65 Do not forget to put it back by using :py:func:`waflib.Runner.put_pool`
66 and reset properly (original waiting queue).
67
68 :rtype: :py:class:`waflib.Runner.TaskConsumer`
69 """
70 try:
71 return pool.get(False)
72 except:
73 return TaskConsumer()
74
75 def put_pool(x):
76 """
77 Return a task consumer to the thread pool :py:attr:`waflib.Runner.pool`
78
79 :param x: task consumer object
80 :type x: :py:class:`waflib.Runner.TaskConsumer`
81 """
82 pool.put(x)
83
84 def _free_resources():
85 global pool
86 lst = []
87 while pool.qsize():
88 lst.append(pool.get())
89 for x in lst:
90 x.ready.put(None)
91 for x in lst:
92 x.join()
93 pool = None
94 atexit.register(_free_resources)
95
96 class Parallel(object):
97 """
98 Schedule the tasks obtained from the build context for execution.
99 """
100 def __init__(self, bld, j=2):
101 """
102 The initialization requires a build context reference
103 for computing the total number of jobs.
104 """
105
106 self.numjobs = j
107 """
108 Number of consumers in the pool
109 """
110
111 self.bld = bld
112 """
113 Instance of :py:class:`waflib.Build.BuildContext`
114 """
115
116 self.outstanding = []
117 """List of :py:class:`waflib.Task.TaskBase` that may be ready to be executed"""
118
119 self.frozen = []
120 """List of :py:class:`waflib.Task.TaskBase` that cannot be executed immediately"""
121
122 self.out = Queue(0)
123 """List of :py:class:`waflib.Task.TaskBase` returned by the task consumers"""
124
125 self.count = 0
126 """Amount of tasks that may be processed by :py:class:`waflib.Runner.TaskConsumer`"""
127
128 self.processed = 1
129 """Amount of tasks processed"""
130
131 self.stop = False
132 """Error flag to stop the build"""
133
134 self.error = []
135 """Tasks that could not be executed"""
136
137 self.biter = None
138 """Task iterator which must give groups of parallelizable tasks when calling ``next()``"""
139
140 self.dirty = False
141 """Flag to indicate that tasks have been executed, and that the build cache must be saved (call :py:meth:`waflib.Build.BuildContext.store`)"""
142
143 def get_next_task(self):
144 """
145 Obtain the next task to execute.
146
147 :rtype: :py:class:`waflib.Task.TaskBase`
148 """
149 if not self.outstanding:
150 return None
151 return self.outstanding.pop(0)
152
153 def postpone(self, tsk):
154 """
155 A task cannot be executed at this point, put it in the list :py:attr:`waflib.Runner.Parallel.frozen`.
156
157 :param tsk: task
158 :type tsk: :py:class:`waflib.Task.TaskBase`
159 """
160 if random.randint(0, 1):
161 self.frozen.insert(0, tsk)
162 else:
163 self.frozen.append(tsk)
164
165 def refill_task_list(self):
166 """
167 Put the next group of tasks to execute in :py:attr:`waflib.Runner.Parallel.outstanding`.
168 """
169 while self.count > self.numjobs * GAP:
170 self.get_out()
171
172 while not self.outstanding:
173 if self.count:
174 self.get_out()
175 elif self.frozen:
176 try:
177 cond = self.deadlock == self.processed
178 except:
179 pass
180 else:
181 if cond:
182 msg = 'check the build order for the tasks'
183 for tsk in self.frozen:
184 if not tsk.run_after:
185 msg = 'check the methods runnable_status'
186 break
187 lst = []
188 for tsk in self.frozen:
189 lst.append('%s\t-> %r' % (repr(tsk), [id(x) for x in tsk.run_after]))
190 raise Errors.WafError('Deadlock detected: %s%s' % (msg, ''.join(lst)))
191 self.deadlock = self.processed
192
193 if self.frozen:
194 self.outstanding += self.frozen
195 self.frozen = []
196 elif not self.count:
197 self.outstanding.extend(next(self.biter))
198 self.total = self.bld.total()
199 break
200
201 def add_more_tasks(self, tsk):
202 """
203 Tasks may be added dynamically during the build by binding them to the task :py:attr:`waflib.Task.TaskBase.more_tasks`
204
205 :param tsk: task
206 :type tsk: :py:attr:`waflib.Task.TaskBase`
207 """
208 if getattr(tsk, 'more_tasks', None):
209 self.outstanding += tsk.more_tasks
210 self.total += len(tsk.more_tasks)
211
212 def get_out(self):
213 """
214 Obtain one task returned from the task consumers, and update the task count. Add more tasks if necessary through
215 :py:attr:`waflib.Runner.Parallel.add_more_tasks`.
216
217 :rtype: :py:attr:`waflib.Task.TaskBase`
218 """
219 tsk = self.out.get()
220 if not self.stop:
221 self.add_more_tasks(tsk)
222 self.count -= 1
223 self.dirty = True
224 return tsk
225
226 def error_handler(self, tsk):
227 """
228 Called when a task cannot be executed. The flag :py:attr:`waflib.Runner.Parallel.stop` is set, unless
229 the build is executed with::
230
231 $ waf build -k
232
233 :param tsk: task
234 :type tsk: :py:attr:`waflib.Task.TaskBase`
235 """
236 if not self.bld.keep:
237 self.stop = True
238 self.error.append(tsk)
239
240 def add_task(self, tsk):
241 """
242 Pass a task to a consumer.
243
244 :param tsk: task
245 :type tsk: :py:attr:`waflib.Task.TaskBase`
246 """
247 try:
248 self.pool
249 except AttributeError:
250 self.init_task_pool()
251 self.ready.put(tsk)
252
253 def init_task_pool(self):
254 # lazy creation, and set a common pool for all task consumers
255 pool = self.pool = [get_pool() for i in range(self.numjobs)]
256 self.ready = Queue(0)
257 def setq(consumer):
258 consumer.ready = self.ready
259 for x in pool:
260 x.ready.put(setq)
261 return pool
262
263 def free_task_pool(self):
264 # return the consumers, setting a different queue for each of them
265 def setq(consumer):
266 consumer.ready = Queue(0)
267 self.out.put(self)
268 try:
269 pool = self.pool
270 except:
271 pass
272 else:
273 for x in pool:
274 self.ready.put(setq)
275 for x in pool:
276 self.get_out()
277 for x in pool:
278 put_pool(x)
279 self.pool = []
280
281 def start(self):
282 """
283 Give tasks to :py:class:`waflib.Runner.TaskConsumer` instances until the build finishes or the ``stop`` flag is set.
284 If only one job is used, then execute the tasks one by one, without consumers.
285 """
286
287 self.total = self.bld.total()
288
289 while not self.stop:
290
291 self.refill_task_list()
292
293 # consider the next task
294 tsk = self.get_next_task()
295 if not tsk:
296 if self.count:
297 # tasks may add new ones after they are run
298 continue
299 else:
300 # no tasks to run, no tasks running, time to exit
301 break
302
303 if tsk.hasrun:
304 # if the task is marked as "run", just skip it
305 self.processed += 1
306 continue
307
308 if self.stop: # stop immediately after a failure was detected
309 break
310
311 try:
312 st = tsk.runnable_status()
313 except Exception:
314 self.processed += 1
315 # TODO waf 1.7 this piece of code should go in the error_handler
316 tsk.err_msg = Utils.ex_stack()
317 if not self.stop and self.bld.keep:
318 tsk.hasrun = Task.SKIPPED
319 if self.bld.keep == 1:
320 # if -k stop at the first exception, if -kk try to go as far as possible
321 if Logs.verbose > 1 or not self.error:
322 self.error.append(tsk)
323 self.stop = True
324 else:
325 if Logs.verbose > 1:
326 self.error.append(tsk)
327 continue
328 tsk.hasrun = Task.EXCEPTION
329 self.error_handler(tsk)
330 continue
331
332 if st == Task.ASK_LATER:
333 self.postpone(tsk)
334 elif st == Task.SKIP_ME:
335 self.processed += 1
336 tsk.hasrun = Task.SKIPPED
337 self.add_more_tasks(tsk)
338 else:
339 # run me: put the task in ready queue
340 tsk.position = (self.processed, self.total)
341 self.count += 1
342 tsk.master = self
343 self.processed += 1
344
345 if self.numjobs == 1:
346 tsk.process()
347 else:
348 self.add_task(tsk)
349
350 # self.count represents the tasks that have been made available to the consumer threads
351 # collect all the tasks after an error else the message may be incomplete
352 while self.error and self.count:
353 self.get_out()
354
355 #print loop
356 assert (self.count == 0 or self.stop)
357
358 # free the task pool, if any
359 self.free_task_pool()
360
0 #!/usr/bin/env python
1 # encoding: utf-8
2 # Thomas Nagy, 2005-2010 (ita)
3
4 "Module called for configuring, compiling and installing targets"
5
6 import os, shutil, traceback, errno, sys, stat
7 from waflib import Utils, Configure, Logs, Options, ConfigSet, Context, Errors, Build, Node
8
9 build_dir_override = None
10
11 no_climb_commands = ['configure']
12
13 default_cmd = "build"
14
15 def waf_entry_point(current_directory, version, wafdir):
16 """
17 This is the main entry point, all Waf execution starts here.
18
19 :param current_directory: absolute path representing the current directory
20 :type current_directory: string
21 :param version: version number
22 :type version: string
23 :param wafdir: absolute path representing the directory of the waf library
24 :type wafdir: string
25 """
26
27 Logs.init_log()
28
29 if Context.WAFVERSION != version:
30 Logs.error('Waf script %r and library %r do not match (directory %r)' % (version, Context.WAFVERSION, wafdir))
31 sys.exit(1)
32
33 if '--version' in sys.argv:
34 Context.run_dir = current_directory
35 ctx = Context.create_context('options')
36 ctx.curdir = current_directory
37 ctx.parse_args()
38 sys.exit(0)
39
40 Context.waf_dir = wafdir
41 Context.launch_dir = current_directory
42
43 # if 'configure' is in the commands, do not search any further
44 no_climb = os.environ.get('NOCLIMB', None)
45 if not no_climb:
46 for k in no_climb_commands:
47 if k in sys.argv:
48 no_climb = True
49 break
50
51 # try to find a lock file (if the project was configured)
52 # at the same time, store the first wscript file seen
53 cur = current_directory
54 while cur:
55 lst = os.listdir(cur)
56 if Options.lockfile in lst:
57 env = ConfigSet.ConfigSet()
58 try:
59 env.load(os.path.join(cur, Options.lockfile))
60 ino = os.stat(cur)[stat.ST_INO]
61 except Exception:
62 pass
63 else:
64 # check if the folder was not moved
65 for x in [env.run_dir, env.top_dir, env.out_dir]:
66 if Utils.is_win32:
67 if cur == x:
68 load = True
69 break
70 else:
71 # if the filesystem features symlinks, compare the inode numbers
72 try:
73 ino2 = os.stat(x)[stat.ST_INO]
74 except:
75 pass
76 else:
77 if ino == ino2:
78 load = True
79 break
80 else:
81 Logs.warn('invalid lock file in %s' % cur)
82 load = False
83
84 if load:
85 Context.run_dir = env.run_dir
86 Context.top_dir = env.top_dir
87 Context.out_dir = env.out_dir
88 break
89
90 if not Context.run_dir:
91 if Context.WSCRIPT_FILE in lst:
92 Context.run_dir = cur
93
94 next = os.path.dirname(cur)
95 if next == cur:
96 break
97 cur = next
98
99 if no_climb:
100 break
101
102 if not Context.run_dir:
103 if '-h' in sys.argv or '--help' in sys.argv:
104 Logs.warn('No wscript file found: the help message may be incomplete')
105 Context.run_dir = current_directory
106 ctx = Context.create_context('options')
107 ctx.curdir = current_directory
108 ctx.parse_args()
109 sys.exit(0)
110 Logs.error('Waf: Run from a directory containing a file named %r' % Context.WSCRIPT_FILE)
111 sys.exit(1)
112
113 try:
114 os.chdir(Context.run_dir)
115 except OSError:
116 Logs.error('Waf: The folder %r is unreadable' % Context.run_dir)
117 sys.exit(1)
118
119 try:
120 set_main_module(Context.run_dir + os.sep + Context.WSCRIPT_FILE)
121 except Errors.WafError as e:
122 Logs.pprint('RED', e.verbose_msg)
123 Logs.error(str(e))
124 sys.exit(1)
125 except Exception as e:
126 Logs.error('Waf: The wscript in %r is unreadable' % Context.run_dir, e)
127 traceback.print_exc(file=sys.stdout)
128 sys.exit(2)
129
130 """
131 import cProfile, pstats
132 cProfile.runctx("import Scripting; Scripting.run_commands()", {}, {}, 'profi.txt')
133 p = pstats.Stats('profi.txt')
134 p.sort_stats('time').print_stats(25)
135 """
136 try:
137 run_commands()
138 except Errors.WafError as e:
139 if Logs.verbose > 1:
140 Logs.pprint('RED', e.verbose_msg)
141 Logs.error(e.msg)
142 sys.exit(1)
143 except Exception as e:
144 traceback.print_exc(file=sys.stdout)
145 sys.exit(2)
146 except KeyboardInterrupt:
147 Logs.pprint('RED', 'Interrupted')
148 sys.exit(68)
149 #"""
150
151 def set_main_module(file_path):
152 """
153 Read the main wscript file into :py:const:`waflib.Context.Context.g_module` and
154 bind default functions such as ``init``, ``dist``, ``distclean`` if not defined.
155 Called by :py:func:`waflib.Scripting.waf_entry_point` during the initialization.
156
157 :param file_path: absolute path representing the top-level wscript file
158 :type file_path: string
159 """
160 Context.g_module = Context.load_module(file_path)
161 Context.g_module.root_path = file_path
162
163 # note: to register the module globally, use the following:
164 # sys.modules['wscript_main'] = g_module
165
166 def set_def(obj):
167 name = obj.__name__
168 if not name in Context.g_module.__dict__:
169 setattr(Context.g_module, name, obj)
170 for k in [update, dist, distclean, distcheck, update]:
171 set_def(k)
172 # add dummy init and shutdown functions if they're not defined
173 if not 'init' in Context.g_module.__dict__:
174 Context.g_module.init = Utils.nada
175 if not 'shutdown' in Context.g_module.__dict__:
176 Context.g_module.shutdown = Utils.nada
177 if not 'options' in Context.g_module.__dict__:
178 Context.g_module.options = Utils.nada
179
180 def parse_options():
181 """
182 Parse the command-line options and initialize the logging system.
183 Called by :py:func:`waflib.Scripting.waf_entry_point` during the initialization.
184 """
185 Context.create_context('options').execute()
186
187 if not Options.commands:
188 Options.commands = [default_cmd]
189 Options.commands = [x for x in Options.commands if x != 'options'] # issue 1076
190
191 # process some internal Waf options
192 Logs.verbose = Options.options.verbose
193 Logs.init_log()
194
195 if Options.options.zones:
196 Logs.zones = Options.options.zones.split(',')
197 if not Logs.verbose:
198 Logs.verbose = 1
199 elif Logs.verbose > 0:
200 Logs.zones = ['runner']
201
202 if Logs.verbose > 2:
203 Logs.zones = ['*']
204
205 def run_command(cmd_name):
206 """
207 Execute a single command. Called by :py:func:`waflib.Scripting.run_commands`.
208
209 :param cmd_name: command to execute, like ``build``
210 :type cmd_name: string
211 """
212 ctx = Context.create_context(cmd_name)
213 ctx.options = Options.options # provided for convenience
214 ctx.cmd = cmd_name
215 ctx.execute()
216 return ctx
217
218 def run_commands():
219 """
220 Execute the commands that were given on the command-line, and the other options
221 Called by :py:func:`waflib.Scripting.waf_entry_point` during the initialization, and executed
222 after :py:func:`waflib.Scripting.parse_options`.
223 """
224 parse_options()
225 run_command('init')
226 while Options.commands:
227 cmd_name = Options.commands.pop(0)
228
229 timer = Utils.Timer()
230 run_command(cmd_name)
231 if not Options.options.progress_bar:
232 elapsed = ' (%s)' % str(timer)
233 Logs.info('%r finished successfully%s' % (cmd_name, elapsed))
234 run_command('shutdown')
235
236 ###########################################################################################
237
238 def _can_distclean(name):
239 # WARNING: this method may disappear anytime
240 for k in '.o .moc .exe'.split():
241 if name.endswith(k):
242 return True
243 return False
244
245 def distclean_dir(dirname):
246 """
247 Distclean function called in the particular case when::
248
249 top == out
250
251 :param dirname: absolute path of the folder to clean
252 :type dirname: string
253 """
254 for (root, dirs, files) in os.walk(dirname):
255 for f in files:
256 if _can_distclean(f):
257 fname = root + os.sep + f
258 try:
259 os.unlink(fname)
260 except:
261 Logs.warn('could not remove %r' % fname)
262
263 for x in [Context.DBFILE, 'config.log']:
264 try:
265 os.unlink(x)
266 except:
267 pass
268
269 try:
270 shutil.rmtree('c4che')
271 except:
272 pass
273
274 def distclean(ctx):
275 '''removes the build directory'''
276 lst = os.listdir('.')
277 for f in lst:
278 if f == Options.lockfile:
279 try:
280 proj = ConfigSet.ConfigSet(f)
281 except:
282 Logs.warn('could not read %r' % f)
283 continue
284
285 if proj['out_dir'] != proj['top_dir']:
286 try:
287 shutil.rmtree(proj['out_dir'])
288 except IOError:
289 pass
290 except OSError as e:
291 if e.errno != errno.ENOENT:
292 Logs.warn('project %r cannot be removed' % proj[Context.OUT])
293 else:
294 distclean_dir(proj['out_dir'])
295
296 for k in (proj['out_dir'], proj['top_dir'], proj['run_dir']):
297 try:
298 os.remove(os.path.join(k, Options.lockfile))
299 except OSError as e:
300 if e.errno != errno.ENOENT:
301 Logs.warn('file %r cannot be removed' % f)
302
303 # remove the local waf cache
304 if f.startswith('.waf') and not Options.commands:
305 shutil.rmtree(f, ignore_errors=True)
306
307 class Dist(Context.Context):
308 """
309 Create an archive containing the project source code::
310
311 $ waf dist
312 """
313 cmd = 'dist'
314 fun = 'dist'
315 algo = 'tar.bz2'
316 ext_algo = {}
317
318 def execute(self):
319 """
320 See :py:func:`waflib.Context.Context.execute`
321 """
322 self.recurse([os.path.dirname(Context.g_module.root_path)])
323 self.archive()
324
325 def archive(self):
326 """
327 Create the archive.
328 """
329 import tarfile
330
331 arch_name = self.get_arch_name()
332
333 try:
334 self.base_path
335 except:
336 self.base_path = self.path
337
338 node = self.base_path.make_node(arch_name)
339 try:
340 node.delete()
341 except:
342 pass
343
344 files = self.get_files()
345
346 if self.algo.startswith('tar.'):
347 tar = tarfile.open(arch_name, 'w:' + self.algo.replace('tar.', ''))
348
349 for x in files:
350 self.add_tar_file(x, tar)
351 tar.close()
352 elif self.algo == 'zip':
353 import zipfile
354 zip = zipfile.ZipFile(arch_name, 'w', compression=zipfile.ZIP_DEFLATED)
355
356 for x in files:
357 archive_name = self.get_base_name() + '/' + x.path_from(self.base_path)
358 zip.write(x.abspath(), archive_name, zipfile.ZIP_DEFLATED)
359 zip.close()
360 else:
361 self.fatal('Valid algo types are tar.bz2, tar.gz or zip')
362
363 try:
364 from hashlib import sha1 as sha
365 except ImportError:
366 from sha import sha
367 try:
368 digest = " (sha=%r)" % sha(node.read()).hexdigest()
369 except:
370 digest = ''
371
372 Logs.info('New archive created: %s%s' % (self.arch_name, digest))
373
374 def get_tar_path(self, node):
375 """
376 return the path to use for a node in the tar archive, the purpose of this
377 is to let subclases resolve symbolic links or to change file names
378 """
379 return node.abspath()
380
381 def add_tar_file(self, x, tar):
382 """
383 Add a file to the tar archive. Transform symlinks into files if the files lie out of the project tree.
384 """
385 p = self.get_tar_path(x)
386 tinfo = tar.gettarinfo(name=p, arcname=self.get_tar_prefix() + '/' + x.path_from(self.base_path))
387 tinfo.uid = 0
388 tinfo.gid = 0
389 tinfo.uname = 'root'
390 tinfo.gname = 'root'
391
392 fu = None
393 try:
394 fu = open(p, 'rb')
395 tar.addfile(tinfo, fileobj=fu)
396 finally:
397 if fu:
398 fu.close()
399
400 def get_tar_prefix(self):
401 try:
402 return self.tar_prefix
403 except:
404 return self.get_base_name()
405
406 def get_arch_name(self):
407 """
408 Return the name of the archive to create. Change the default value by setting *arch_name*::
409
410 def dist(ctx):
411 ctx.arch_name = 'ctx.tar.bz2'
412
413 :rtype: string
414 """
415 try:
416 self.arch_name
417 except:
418 self.arch_name = self.get_base_name() + '.' + self.ext_algo.get(self.algo, self.algo)
419 return self.arch_name
420
421 def get_base_name(self):
422 """
423 Return the default name of the main directory in the archive, which is set to *appname-version*.
424 Set the attribute *base_name* to change the default value::
425
426 def dist(ctx):
427 ctx.base_name = 'files'
428
429 :rtype: string
430 """
431 try:
432 self.base_name
433 except:
434 appname = getattr(Context.g_module, Context.APPNAME, 'noname')
435 version = getattr(Context.g_module, Context.VERSION, '1.0')
436 self.base_name = appname + '-' + version
437 return self.base_name
438
439 def get_excl(self):
440 """
441 Return the patterns to exclude for finding the files in the top-level directory. Set the attribute *excl*
442 to change the default value::
443
444 def dist(ctx):
445 ctx.excl = 'build **/*.o **/*.class'
446
447 :rtype: string
448 """
449 try:
450 return self.excl
451 except:
452 self.excl = Node.exclude_regs + ' **/waf-1.6.* **/.waf-1.6* **/waf3-1.6.* **/.waf3-1.6* **/*~ **/*.rej **/*.orig **/*.pyc **/*.pyo **/*.bak **/*.swp **/.lock-w*'
453 nd = self.root.find_node(Context.out_dir)
454 if nd:
455 self.excl += ' ' + nd.path_from(self.base_path)
456 return self.excl
457
458 def get_files(self):
459 """
460 The files to package are searched automatically by :py:func:`waflib.Node.Node.ant_glob`. Set
461 *files* to prevent this behaviour::
462
463 def dist(ctx):
464 ctx.files = ctx.path.find_node('wscript')
465
466 The files are searched from the directory 'base_path', to change it, set::
467
468 def dist(ctx):
469 ctx.base_path = path
470
471 :rtype: list of :py:class:`waflib.Node.Node`
472 """
473 try:
474 files = self.files
475 except:
476 files = self.base_path.ant_glob('**/*', excl=self.get_excl())
477 return files
478
479
480 def dist(ctx):
481 '''makes a tarball for redistributing the sources'''
482 pass
483
484 class DistCheck(Dist):
485 """
486 Create an archive of the project, and try to build the project in a temporary directory::
487
488 $ waf distcheck
489 """
490
491 fun = 'distcheck'
492 cmd = 'distcheck'
493
494 def execute(self):
495 """
496 See :py:func:`waflib.Context.Context.execute`
497 """
498 self.recurse([os.path.dirname(Context.g_module.root_path)])
499 self.archive()
500 self.check()
501
502 def check(self):
503 """
504 Create the archive, uncompress it and try to build the project
505 """
506 import tempfile, tarfile
507
508 t = None
509 try:
510 t = tarfile.open(self.get_arch_name())
511 for x in t:
512 t.extract(x)
513 finally:
514 if t:
515 t.close()
516
517 instdir = tempfile.mkdtemp('.inst', self.get_base_name())
518 ret = Utils.subprocess.Popen([sys.argv[0], 'configure', 'install', 'uninstall', '--destdir=' + instdir], cwd=self.get_base_name()).wait()
519 if ret:
520 raise Errors.WafError('distcheck failed with code %i' % ret)
521
522 if os.path.exists(instdir):
523 raise Errors.WafError('distcheck succeeded, but files were left in %s' % instdir)
524
525 shutil.rmtree(self.get_base_name())
526
527
528 def distcheck(ctx):
529 '''checks if the project compiles (tarball from 'dist')'''
530 pass
531
532 def update(ctx):
533 '''updates the plugins from the *waflib/extras* directory'''
534 lst = Options.options.files.split(',')
535 if not lst:
536 lst = [x for x in Utils.listdir(Context.waf_dir + '/waflib/extras') if x.endswith('.py')]
537 for x in lst:
538 tool = x.replace('.py', '')
539 try:
540 Configure.download_tool(tool, force=True, ctx=ctx)
541 except Errors.WafError:
542 Logs.error('Could not find the tool %s in the remote repository' % x)
543
544 def autoconfigure(execute_method):
545 """
546 Decorator used to set the commands that can be configured automatically
547 """
548 def execute(self):
549 if not Configure.autoconfig:
550 return execute_method(self)
551
552 env = ConfigSet.ConfigSet()
553 do_config = False
554 try:
555 env.load(os.path.join(Context.top_dir, Options.lockfile))
556 except Exception:
557 Logs.warn('Configuring the project')
558 do_config = True
559 else:
560 if env.run_dir != Context.run_dir:
561 do_config = True
562 else:
563 h = 0
564 for f in env['files']:
565 h = hash((h, Utils.readf(f, 'rb')))
566 do_config = h != env.hash
567
568 if do_config:
569 Options.commands.insert(0, self.cmd)
570 Options.commands.insert(0, 'configure')
571 return
572
573 return execute_method(self)
574 return execute
575 Build.BuildContext.execute = autoconfigure(Build.BuildContext.execute)
576
0 #!/usr/bin/env python
1 # encoding: utf-8
2 # Thomas Nagy, 2005-2010 (ita)
3
4 """
5 Tasks represent atomic operations such as processes.
6 """
7
8 import os, shutil, re, tempfile
9 from waflib import Utils, Logs, Errors
10
11 # task states
12 NOT_RUN = 0
13 """The task was not executed yet"""
14
15 MISSING = 1
16 """The task has been executed but the files have not been created"""
17
18 CRASHED = 2
19 """The task execution returned a non-zero exit status"""
20
21 EXCEPTION = 3
22 """An exception occured in the task execution"""
23
24 SKIPPED = 8
25 """The task did not have to be executed"""
26
27 SUCCESS = 9
28 """The task was successfully executed"""
29
30 ASK_LATER = -1
31 """The task is not ready to be executed"""
32
33 SKIP_ME = -2
34 """The task does not need to be executed"""
35
36 RUN_ME = -3
37 """The task must be executed"""
38
39 COMPILE_TEMPLATE_SHELL = '''
40 def f(tsk):
41 env = tsk.env
42 gen = tsk.generator
43 bld = gen.bld
44 wd = getattr(tsk, 'cwd', None)
45 p = env.get_flat
46 tsk.last_cmd = cmd = \'\'\' %s \'\'\' % s
47 return tsk.exec_command(cmd, cwd=wd, env=env.env or None)
48 '''
49
50 COMPILE_TEMPLATE_NOSHELL = '''
51 def f(tsk):
52 env = tsk.env
53 gen = tsk.generator
54 bld = gen.bld
55 wd = getattr(tsk, 'cwd', None)
56 def to_list(xx):
57 if isinstance(xx, str): return [xx]
58 return xx
59 tsk.last_cmd = lst = []
60 %s
61 lst = [x for x in lst if x]
62 return tsk.exec_command(lst, cwd=wd, env=env.env or None)
63 '''
64
65 def cache_outputs(cls):
66 """
67 Task class decorator applied to all task classes by default unless they define the attribute 'nocache'::
68
69 from waflib import Task
70 class foo(Task.Task):
71 nocache = True
72
73 If bld.cache_global is defined and if the task instances produces output nodes,
74 the files will be copied into a folder in the cache directory
75
76 The files may also be retrieved from that folder, if it exists
77 """
78 m1 = cls.run
79 def run(self):
80 bld = self.generator.bld
81 if bld.cache_global and not bld.nocache:
82 if self.can_retrieve_cache():
83 return 0
84 return m1(self)
85 cls.run = run
86
87 m2 = cls.post_run
88 def post_run(self):
89 bld = self.generator.bld
90 ret = m2(self)
91 if bld.cache_global and not bld.nocache:
92 self.put_files_cache()
93 return ret
94 cls.post_run = post_run
95
96 return cls
97
98
99 classes = {}
100 "class tasks created by user scripts or Waf tools are kept in this dict name -> class object"
101
102 class store_task_type(type):
103 """
104 Metaclass: store the task types into :py:const:`waflib.Task.classes`.
105 The attribute 'run_str' will be processed to compute a method 'run' on the task class
106 The decorator :py:func:`waflib.Task.cache_outputs` is also applied to the class
107 """
108 def __init__(cls, name, bases, dict):
109 super(store_task_type, cls).__init__(name, bases, dict)
110 name = cls.__name__
111
112 if name.endswith('_task'):
113 name = name.replace('_task', '')
114 if name != 'evil' and name != 'TaskBase':
115 global classes
116
117 if getattr(cls, 'run_str', None):
118 # if a string is provided, convert it to a method
119 (f, dvars) = compile_fun(cls.run_str, cls.shell)
120 cls.hcode = cls.run_str
121 cls.run_str = None
122 cls.run = f
123 cls.vars = list(set(cls.vars + dvars))
124 cls.vars.sort()
125 elif getattr(cls, 'run', None) and not 'hcode' in cls.__dict__:
126 # getattr(cls, 'hcode') would look in the upper classes
127 cls.hcode = Utils.h_fun(cls.run)
128
129 if not getattr(cls, 'nocache', None):
130 cls = cache_outputs(cls)
131
132 classes[name] = cls
133
134 evil = store_task_type('evil', (object,), {})
135 "Base class provided to avoid writing a metaclass, so the code can run in python 2.6 and 3.x unmodified"
136
137 class TaskBase(evil):
138 """
139 Base class for all Waf tasks, which should be seen as an interface.
140 For illustration purposes, instances of this class will execute the attribute
141 'fun' in :py:meth:`waflib.Task.TaskBase.run`. When in doubt, create
142 subclasses of :py:class:`waflib.Task.Task` instead.
143
144 Subclasses should override these methods:
145
146 #. __str__: string to display to the user
147 #. runnable_status: ask the task if it should be run, skipped, or if we have to ask later
148 #. run: let threads execute the task
149 #. post_run: let threads update the data regarding the task (cache)
150 """
151
152 color = 'GREEN'
153 """Color for the console display, see :py:const:`waflib.Logs.colors_lst`"""
154
155 ext_in = []
156 """File extensions that objects of this task class might use"""
157
158 ext_out = []
159 """File extensions that objects of this task class might create"""
160
161 before = []
162 """List of task class names to execute before instances of this class"""
163
164 after = []
165 """List of task class names to execute after instances of this class"""
166
167 hcode = ''
168 """String representing an additional hash for the class representation"""
169
170 def __init__(self, *k, **kw):
171 """
172 The base task class requires a task generator, which will be itself if missing
173 """
174 self.hasrun = NOT_RUN
175 try:
176 self.generator = kw['generator']
177 except KeyError:
178 self.generator = self
179
180 def __repr__(self):
181 "for debugging purposes"
182 return '\n\t{task %r: %s %s}' % (self.__class__.__name__, id(self), str(getattr(self, 'fun', '')))
183
184 def __str__(self):
185 "string to display to the user"
186 if hasattr(self, 'fun'):
187 return 'executing: %s\n' % self.fun.__name__
188 return self.__class__.__name__ + '\n'
189
190 def __hash__(self):
191 "Very fast hashing scheme but not persistent (replace/implement in subclasses and see :py:meth:`waflib.Task.Task.uid`)"
192 return id(self)
193
194 def exec_command(self, cmd, **kw):
195 """
196 Wrapper for :py:meth:`waflib.Context.Context.exec_command` which sets a current working directory to ``build.variant_dir``
197
198 :return: the return code
199 :rtype: int
200 """
201 bld = self.generator.bld
202 try:
203 if not kw.get('cwd', None):
204 kw['cwd'] = bld.cwd
205 except AttributeError:
206 bld.cwd = kw['cwd'] = bld.variant_dir
207 return bld.exec_command(cmd, **kw)
208
209 def runnable_status(self):
210 """
211 State of the task
212
213 :return: a task state in :py:const:`waflib.Task.RUN_ME`, :py:const:`waflib.Task.SKIP_ME` or :py:const:`waflib.Task.ASK_LATER`.
214 :rtype: int
215 """
216 return RUN_ME
217
218 def process(self):
219 """
220 Assume that the task has had a new attribute ``master`` which is an instance of :py:class:`waflib.Runner.Parallel`.
221 Execute the task and then put it back in the queue :py:attr:`waflib.Runner.Parallel.out` (may be replaced by subclassing).
222 """
223 m = self.master
224 if m.stop:
225 m.out.put(self)
226 return
227
228 # remove the task signature immediately before it is executed
229 # in case of failure the task will be executed again
230 try:
231 del self.generator.bld.task_sigs[self.uid()]
232 except:
233 pass
234
235 try:
236 self.generator.bld.returned_tasks.append(self)
237 self.log_display(self.generator.bld)
238 ret = self.run()
239 except Exception:
240 self.err_msg = Utils.ex_stack()
241 self.hasrun = EXCEPTION
242
243 # TODO cleanup
244 m.error_handler(self)
245 m.out.put(self)
246 return
247
248 if ret:
249 self.err_code = ret
250 self.hasrun = CRASHED
251 else:
252 try:
253 self.post_run()
254 except Errors.WafError:
255 pass
256 except Exception:
257 self.err_msg = Utils.ex_stack()
258 self.hasrun = EXCEPTION
259 else:
260 self.hasrun = SUCCESS
261 if self.hasrun != SUCCESS:
262 m.error_handler(self)
263
264 m.out.put(self)
265
266 def run(self):
267 """
268 Called by threads to execute the tasks. The default is empty and meant to be overridden in subclasses.
269 It is a bad idea to create nodes in this method (so, no node.ant_glob)
270
271 :rtype: int
272 """
273 if hasattr(self, 'fun'):
274 return self.fun(self)
275 return 0
276
277 def post_run(self):
278 "Update the cache files (executed by threads). Override in subclasses."
279 pass
280
281 def log_display(self, bld):
282 "Write the execution status on the context logger"
283 bld.to_log(self.display())
284
285 def display(self):
286 """
287 Return an execution status for the console, the progress bar, or the IDE output.
288
289 :rtype: string
290 """
291 col1 = Logs.colors(self.color)
292 col2 = Logs.colors.NORMAL
293 master = self.master
294
295 def cur():
296 # the current task position, computed as late as possible
297 tmp = -1
298 if hasattr(master, 'ready'):
299 tmp -= master.ready.qsize()
300 return master.processed + tmp
301
302 if self.generator.bld.progress_bar == 1:
303 return self.generator.bld.progress_line(cur(), master.total, col1, col2)
304
305 if self.generator.bld.progress_bar == 2:
306 ela = str(self.generator.bld.timer)
307 try:
308 ins = ','.join([n.name for n in self.inputs])
309 except AttributeError:
310 ins = ''
311 try:
312 outs = ','.join([n.name for n in self.outputs])
313 except AttributeError:
314 outs = ''
315 return '|Total %s|Current %s|Inputs %s|Outputs %s|Time %s|\n' % (master.total, cur(), ins, outs, ela)
316
317 s = str(self)
318 if not s:
319 return None
320
321 total = master.total
322 n = len(str(total))
323 fs = '[%%%dd/%%%dd] %%s%%s%%s' % (n, n)
324 return fs % (cur(), total, col1, s, col2)
325
326 def attr(self, att, default=None):
327 """
328 Retrieve an attribute from the instance or from the class.
329
330 :param att: variable name
331 :type att: string
332 :param default: default value
333 """
334 ret = getattr(self, att, self)
335 if ret is self: return getattr(self.__class__, att, default)
336 return ret
337
338 def hash_constraints(self):
339 """
340 Identify a task type for all the constraints relevant for the scheduler: precedence, file production
341
342 :return: a hash value
343 :rtype: string
344 """
345 cls = self.__class__
346 tup = (str(cls.before), str(cls.after), str(cls.ext_in), str(cls.ext_out), cls.__name__, cls.hcode)
347 h = hash(tup)
348 return h
349
350 def format_error(self):
351 """
352 Error message to display to the user when a build fails
353
354 :rtype: string
355 """
356 msg = getattr(self, 'last_cmd', '')
357 name = getattr(self.generator, 'name', '')
358 if getattr(self, "err_msg", None):
359 return self.err_msg
360 elif not self.hasrun:
361 return 'task in %r was not executed for some reason: %r' % (name, self)
362 elif self.hasrun == CRASHED:
363 try:
364 return ' -> task in %r failed (exit status %r): %r\n%r' % (name, self.err_code, self, msg)
365 except AttributeError:
366 return ' -> task in %r failed: %r\n%r' % (name, self, msg)
367 elif self.hasrun == MISSING:
368 return ' -> missing files in %r: %r\n%r' % (name, self, msg)
369 else:
370 return 'invalid status for task in %r: %r' % (name, self.hasrun)
371
372 def colon(self, var1, var2):
373 """
374 private function for the moment
375
376 used for scriptlet expressions such as ${FOO_ST:FOO}, for example, if
377 env.FOO_ST = ['-a', '-b']
378 env.FOO = ['1', '2']
379 then the result will be ['-a', '-b', '1', '-a', '-b', '2']
380 """
381 tmp = self.env[var1]
382 if isinstance(var2, str):
383 it = self.env[var2]
384 else:
385 it = var2
386 if isinstance(tmp, str):
387 return [tmp % x for x in it]
388 else:
389 if Logs.verbose and not tmp and it:
390 Logs.warn('Missing env variable %r for task %r (generator %r)' % (var1, self, self.generator))
391 lst = []
392 for y in it:
393 lst.extend(tmp)
394 lst.append(y)
395 return lst
396
397 class Task(TaskBase):
398 """
399 This class deals with the filesystem (:py:class:`waflib.Node.Node`). The method :py:class:`waflib.Task.Task.runnable_status`
400 uses a hash value (from :py:class:`waflib.Task.Task.signature`) which is persistent from build to build. When the value changes,
401 the task has to be executed. The method :py:class:`waflib.Task.Task.post_run` will assign the task signature to the output
402 nodes (if present).
403 """
404 vars = []
405 """Variables to depend on (class attribute used for :py:meth:`waflib.Task.Task.sig_vars`)"""
406
407 shell = False
408 """Execute the command with the shell (class attribute)"""
409
410 def __init__(self, *k, **kw):
411 TaskBase.__init__(self, *k, **kw)
412
413 self.env = kw['env']
414 """ConfigSet object (make sure to provide one)"""
415
416 self.inputs = []
417 """List of input nodes, which represent the files used by the task instance"""
418
419 self.outputs = []
420 """List of output nodes, which represent the files created by the task instance"""
421
422 self.dep_nodes = []
423 """List of additional nodes to depend on"""
424
425 self.run_after = set([])
426 """Set of tasks that must be executed before this one"""
427
428 # Additionally, you may define the following
429 #self.dep_vars = 'PREFIX DATADIR'
430
431 def __str__(self):
432 "string to display to the user"
433 env = self.env
434 src_str = ' '.join([a.nice_path(env) for a in self.inputs])
435 tgt_str = ' '.join([a.nice_path(env) for a in self.outputs])
436 if self.outputs: sep = ' -> '
437 else: sep = ''
438 return '%s: %s%s%s\n' % (self.__class__.__name__.replace('_task', ''), src_str, sep, tgt_str)
439
440 def __repr__(self):
441 "for debugging purposes"
442 return "".join(['\n\t{task %r: ' % id(self), self.__class__.__name__, " ", ",".join([x.name for x in self.inputs]), " -> ", ",".join([x.name for x in self.outputs]), '}'])
443
444 def uid(self):
445 """
446 Return an identifier used to determine if tasks are up-to-date. Since the
447 identifier will be stored between executions, it must be:
448
449 - unique: no two tasks return the same value (for a given build context)
450 - the same for a given task instance
451
452 By default, the node paths, the class name, and the function are used
453 as inputs to compute a hash.
454
455 The pointer to the object (python built-in 'id') will change between build executions,
456 and must be avoided in such hashes.
457
458 :return: hash value
459 :rtype: string
460 """
461 try:
462 return self.uid_
463 except AttributeError:
464 # this is not a real hot zone, but we want to avoid surprizes here
465 m = Utils.md5()
466 up = m.update
467 up(self.__class__.__name__.encode())
468 for x in self.inputs + self.outputs:
469 up(x.abspath().encode())
470 self.uid_ = m.digest()
471 return self.uid_
472
473 def set_inputs(self, inp):
474 """
475 Append the nodes to the *inputs*
476
477 :param inp: input nodes
478 :type inp: node or list of nodes
479 """
480 if isinstance(inp, list): self.inputs += inp
481 else: self.inputs.append(inp)
482
483 def set_outputs(self, out):
484 """
485 Append the nodes to the *outputs*
486
487 :param out: output nodes
488 :type out: node or list of nodes
489 """
490 if isinstance(out, list): self.outputs += out
491 else: self.outputs.append(out)
492
493 def set_run_after(self, task):
494 """
495 Run this task only after *task*. Affect :py:meth:`waflib.Task.runnable_status`
496
497 :param task: task
498 :type task: :py:class:`waflib.Task.Task`
499 """
500 # TODO: handle lists too?
501 assert isinstance(task, TaskBase)
502 self.run_after.add(task)
503
504 def signature(self):
505 """
506 Task signatures are stored between build executions, they are use to track the changes
507 made to the input nodes (not to the outputs!). The signature hashes data from various sources:
508
509 * explicit dependencies: files listed in the inputs (list of node objects) :py:meth:`waflib.Task.Task.sig_explicit_deps`
510 * implicit dependencies: list of nodes returned by scanner methods (when present) :py:meth:`waflib.Task.Task.sig_implicit_deps`
511 * hashed data: variables/values read from task.__class__.vars/task.env :py:meth:`waflib.Task.Task.sig_vars`
512
513 If the signature is expected to give a different result, clear the cache kept in ``self.cache_sig``::
514
515 from waflib import Task
516 class cls(Task.Task):
517 def signature(self):
518 sig = super(Task.Task, self).signature()
519 delattr(self, 'cache_sig')
520 return super(Task.Task, self).signature()
521 """
522 try: return self.cache_sig
523 except AttributeError: pass
524
525 self.m = Utils.md5()
526 self.m.update(self.hcode.encode())
527
528 # explicit deps
529 self.sig_explicit_deps()
530
531 # env vars
532 self.sig_vars()
533
534 # implicit deps / scanner results
535 if self.scan:
536 try:
537 self.sig_implicit_deps()
538 except Errors.TaskRescan:
539 return self.signature()
540
541 ret = self.cache_sig = self.m.digest()
542 return ret
543
544 def runnable_status(self):
545 """
546 Override :py:meth:`waflib.Task.TaskBase.runnable_status` to determine if the task is ready
547 to be run (:py:attr:`waflib.Task.Task.run_after`)
548 """
549 #return 0 # benchmarking
550
551 for t in self.run_after:
552 if not t.hasrun:
553 return ASK_LATER
554
555 bld = self.generator.bld
556
557 # first compute the signature
558 try:
559 new_sig = self.signature()
560 except Errors.TaskNotReady:
561 return ASK_LATER
562
563 # compare the signature to a signature computed previously
564 key = self.uid()
565 try:
566 prev_sig = bld.task_sigs[key]
567 except KeyError:
568 Logs.debug("task: task %r must run as it was never run before or the task code changed" % self)
569 return RUN_ME
570
571 # compare the signatures of the outputs
572 for node in self.outputs:
573 try:
574 if node.sig != new_sig:
575 return RUN_ME
576 except AttributeError:
577 Logs.debug("task: task %r must run as the output nodes do not exist" % self)
578 return RUN_ME
579
580 if new_sig != prev_sig:
581 return RUN_ME
582 return SKIP_ME
583
584 def post_run(self):
585 """
586 Called after successful execution to update the cache data :py:class:`waflib.Node.Node` sigs
587 and :py:attr:`waflib.Build.BuildContext.task_sigs`.
588
589 The node signature is obtained from the task signature, but the output nodes may also get the signature
590 of their contents. See the class decorator :py:func:`waflib.Task.update_outputs` if you need this behaviour.
591 """
592 bld = self.generator.bld
593 sig = self.signature()
594
595 for node in self.outputs:
596 # check if the node exists ..
597 try:
598 os.stat(node.abspath())
599 except OSError:
600 self.hasrun = MISSING
601 self.err_msg = '-> missing file: %r' % node.abspath()
602 raise Errors.WafError(self.err_msg)
603
604 # important, store the signature for the next run
605 node.sig = sig
606
607 bld.task_sigs[self.uid()] = self.cache_sig
608
609 def sig_explicit_deps(self):
610 """
611 Used by :py:meth:`waflib.Task.Task.signature`, hash :py:attr:`waflib.Task.Task.inputs`
612 and :py:attr:`waflib.Task.Task.dep_nodes` signatures.
613
614 :rtype: hash value
615 """
616 bld = self.generator.bld
617 upd = self.m.update
618
619 # the inputs
620 for x in self.inputs + self.dep_nodes:
621 try:
622 upd(x.get_bld_sig())
623 except (AttributeError, TypeError):
624 raise Errors.WafError('Missing node signature for %r (required by %r)' % (x, self))
625
626 # manual dependencies, they can slow down the builds
627 if bld.deps_man:
628 additional_deps = bld.deps_man
629 for x in self.inputs + self.outputs:
630 try:
631 d = additional_deps[id(x)]
632 except KeyError:
633 continue
634
635 for v in d:
636 if isinstance(v, bld.root.__class__):
637 try:
638 v = v.get_bld_sig()
639 except AttributeError:
640 raise Errors.WafError('Missing node signature for %r (required by %r)' % (v, self))
641 elif hasattr(v, '__call__'):
642 v = v() # dependency is a function, call it
643 upd(v)
644
645 return self.m.digest()
646
647 def sig_vars(self):
648 """
649 Used by :py:meth:`waflib.Task.Task.signature`, hash :py:attr:`waflib.Task.Task.env` variables/values
650
651 :rtype: hash value
652 """
653 bld = self.generator.bld
654 env = self.env
655 upd = self.m.update
656
657 # dependencies on the environment vars
658 act_sig = bld.hash_env_vars(env, self.__class__.vars)
659 upd(act_sig)
660
661 # additional variable dependencies, if provided
662 dep_vars = getattr(self, 'dep_vars', None)
663 if dep_vars:
664 upd(bld.hash_env_vars(env, dep_vars))
665
666 return self.m.digest()
667
668 scan = None
669 """
670 This method, when provided, returns a tuple containing:
671
672 * a list of nodes corresponding to real files
673 * a list of names for files not found in path_lst
674
675 For example::
676
677 from waflib.Task import Task
678 class mytask(Task):
679 def scan(self, node):
680 return ((), ())
681
682 The first and second lists are stored in :py:attr:`waflib.Build.BuildContext.node_deps` and
683 :py:attr:`waflib.Build.BuildContext.raw_deps` respectively.
684 """
685
686 def sig_implicit_deps(self):
687 """
688 Used by :py:meth:`waflib.Task.Task.signature` hashes node signatures obtained by scanning for dependencies (:py:meth:`waflib.Task.Task.scan`).
689
690 The exception :py:class:`waflib.Errors.TaskRescan` is thrown
691 when a file has changed. When this occurs, :py:meth:`waflib.Task.Task.signature` is called
692 once again, and this method will be executed once again, this time calling :py:meth:`waflib.Task.Task.scan`
693 for searching the dependencies.
694
695 :rtype: hash value
696 """
697
698 bld = self.generator.bld
699
700 # get the task signatures from previous runs
701 key = self.uid()
702 prev = bld.task_sigs.get((key, 'imp'), [])
703
704 # for issue #379
705 if prev:
706 try:
707 if prev == self.compute_sig_implicit_deps():
708 return prev
709 except:
710 # when a file was renamed (IOError usually), remove the stale nodes (headers in folders without source files)
711 # this will break the order calculation for headers created during the build in the source directory (should be uncommon)
712 # the behaviour will differ when top != out
713 for x in bld.node_deps.get(self.uid(), []):
714 if x.is_child_of(bld.srcnode):
715 try:
716 os.stat(x.abspath())
717 except:
718 try:
719 del x.parent.children[x.name]
720 except:
721 pass
722 del bld.task_sigs[(key, 'imp')]
723 raise Errors.TaskRescan('rescan')
724
725 # no previous run or the signature of the dependencies has changed, rescan the dependencies
726 (nodes, names) = self.scan()
727 if Logs.verbose:
728 Logs.debug('deps: scanner for %s returned %s %s' % (str(self), str(nodes), str(names)))
729
730 # store the dependencies in the cache
731 bld.node_deps[key] = nodes
732 bld.raw_deps[key] = names
733
734 # might happen
735 self.are_implicit_nodes_ready()
736
737 # recompute the signature and return it
738 try:
739 bld.task_sigs[(key, 'imp')] = sig = self.compute_sig_implicit_deps()
740 except:
741 if Logs.verbose:
742 for k in bld.node_deps.get(self.uid(), []):
743 try:
744 k.get_bld_sig()
745 except:
746 Logs.warn('Missing signature for node %r (may cause rebuilds)' % k)
747 else:
748 return sig
749
750 def compute_sig_implicit_deps(self):
751 """
752 Used by :py:meth:`waflib.Task.Task.sig_implicit_deps` for computing the actual hash of the
753 :py:class:`waflib.Node.Node` returned by the scanner.
754
755 :return: hash value
756 :rtype: string
757 """
758
759 upd = self.m.update
760
761 bld = self.generator.bld
762
763 self.are_implicit_nodes_ready()
764
765 # scanner returns a node that does not have a signature
766 # just *ignore* the error and let them figure out from the compiler output
767 # waf -k behaviour
768 for k in bld.node_deps.get(self.uid(), []):
769 upd(k.get_bld_sig())
770 return self.m.digest()
771
772 def are_implicit_nodes_ready(self):
773 """
774 For each node returned by the scanner, see if there is a task behind it, and force the build order
775
776 The performance impact on null builds is nearly invisible (1.66s->1.86s), but this is due to
777 agressive caching (1.86s->28s)
778 """
779 bld = self.generator.bld
780 try:
781 cache = bld.dct_implicit_nodes
782 except:
783 bld.dct_implicit_nodes = cache = {}
784
785 try:
786 dct = cache[bld.cur]
787 except KeyError:
788 dct = cache[bld.cur] = {}
789 for tsk in bld.cur_tasks:
790 for x in tsk.outputs:
791 dct[x] = tsk
792
793 modified = False
794 for x in bld.node_deps.get(self.uid(), []):
795 if x in dct:
796 self.run_after.add(dct[x])
797 modified = True
798
799 if modified:
800 for tsk in self.run_after:
801 if not tsk.hasrun:
802 #print "task is not ready..."
803 raise Errors.TaskNotReady('not ready')
804
805 def can_retrieve_cache(self):
806 """
807 Used by :py:meth:`waflib.Task.cache_outputs`
808
809 Retrieve build nodes from the cache
810 update the file timestamps to help cleaning the least used entries from the cache
811 additionally, set an attribute 'cached' to avoid re-creating the same cache files
812
813 Suppose there are files in `cache/dir1/file1` and `cache/dir2/file2`:
814
815 #. read the timestamp of dir1
816 #. try to copy the files
817 #. look at the timestamp again, if it has changed, the data may have been corrupt (cache update by another process)
818 #. should an exception occur, ignore the data
819 """
820
821 if not getattr(self, 'outputs', None):
822 return None
823
824 sig = self.signature()
825 ssig = Utils.to_hex(self.uid()) + Utils.to_hex(sig)
826
827 # first try to access the cache folder for the task
828 dname = os.path.join(self.generator.bld.cache_global, ssig)
829 try:
830 t1 = os.stat(dname).st_mtime
831 except OSError:
832 return None
833
834 for node in self.outputs:
835 orig = os.path.join(dname, node.name)
836 try:
837 shutil.copy2(orig, node.abspath())
838 # mark the cache file as used recently (modified)
839 os.utime(orig, None)
840 except (OSError, IOError):
841 Logs.debug('task: failed retrieving file')
842 return None
843
844 # is it the same folder?
845 try:
846 t2 = os.stat(dname).st_mtime
847 except OSError:
848 return None
849
850 if t1 != t2:
851 return None
852
853 for node in self.outputs:
854 node.sig = sig
855 if self.generator.bld.progress_bar < 1:
856 self.generator.bld.to_log('restoring from cache %r\n' % node.abspath())
857
858 self.cached = True
859 return True
860
861 def put_files_cache(self):
862 """
863 Used by :py:func:`waflib.Task.cache_outputs` to store the build files in the cache
864 """
865
866 # file caching, if possible
867 # try to avoid data corruption as much as possible
868 if getattr(self, 'cached', None):
869 return None
870 if not getattr(self, 'outputs', None):
871 return None
872
873 sig = self.signature()
874 ssig = Utils.to_hex(self.uid()) + Utils.to_hex(sig)
875 dname = os.path.join(self.generator.bld.cache_global, ssig)
876 tmpdir = tempfile.mkdtemp(prefix=self.generator.bld.cache_global + os.sep + 'waf')
877
878 try:
879 shutil.rmtree(dname)
880 except:
881 pass
882
883 try:
884 for node in self.outputs:
885 dest = os.path.join(tmpdir, node.name)
886 shutil.copy2(node.abspath(), dest)
887 except (OSError, IOError):
888 try:
889 shutil.rmtree(tmpdir)
890 except:
891 pass
892 else:
893 try:
894 os.rename(tmpdir, dname)
895 except OSError:
896 try:
897 shutil.rmtree(tmpdir)
898 except:
899 pass
900 else:
901 try:
902 os.chmod(dname, Utils.O755)
903 except:
904 pass
905
906 def is_before(t1, t2):
907 """
908 Return a non-zero value if task t1 is to be executed before task t2::
909
910 t1.ext_out = '.h'
911 t2.ext_in = '.h'
912 t2.after = ['t1']
913 t1.before = ['t2']
914 waflib.Task.is_before(t1, t2) # True
915
916 :param t1: task
917 :type t1: :py:class:`waflib.Task.TaskBase`
918 :param t2: task
919 :type t2: :py:class:`waflib.Task.TaskBase`
920 """
921 to_list = Utils.to_list
922 for k in to_list(t2.ext_in):
923 if k in to_list(t1.ext_out):
924 return 1
925
926 if t1.__class__.__name__ in to_list(t2.after):
927 return 1
928
929 if t2.__class__.__name__ in to_list(t1.before):
930 return 1
931
932 return 0
933
934 def set_file_constraints(tasks):
935 """
936 Adds tasks to the task 'run_after' attribute based on the task inputs and outputs
937
938 :param tasks: tasks
939 :type tasks: list of :py:class:`waflib.Task.TaskBase`
940 """
941 ins = Utils.defaultdict(set)
942 outs = Utils.defaultdict(set)
943 for x in tasks:
944 for a in getattr(x, 'inputs', []) + getattr(x, 'dep_nodes', []):
945 ins[id(a)].add(x)
946 for a in getattr(x, 'outputs', []):
947 outs[id(a)].add(x)
948
949 links = set(ins.keys()).intersection(outs.keys())
950 for k in links:
951 for a in ins[k]:
952 a.run_after.update(outs[k])
953
954 def set_precedence_constraints(tasks):
955 """
956 Add tasks to the task 'run_after' attribute based on the after/before/ext_out/ext_in attributes
957
958 :param tasks: tasks
959 :type tasks: list of :py:class:`waflib.Task.TaskBase`
960 """
961 cstr_groups = Utils.defaultdict(list)
962 for x in tasks:
963 h = x.hash_constraints()
964 cstr_groups[h].append(x)
965
966 keys = list(cstr_groups.keys())
967 maxi = len(keys)
968
969 # this list should be short
970 for i in range(maxi):
971 t1 = cstr_groups[keys[i]][0]
972 for j in range(i + 1, maxi):
973 t2 = cstr_groups[keys[j]][0]
974
975 # add the constraints based on the comparisons
976 if is_before(t1, t2):
977 a = i
978 b = j
979 elif is_before(t2, t1):
980 a = j
981 b = i
982 else:
983 continue
984 for x in cstr_groups[keys[b]]:
985 x.run_after.update(cstr_groups[keys[a]])
986
987 def funex(c):
988 """
989 Compile a function by 'exec'
990
991 :param c: function to compile
992 :type c: string
993 :return: the function 'f' declared in the input string
994 :rtype: function
995 """
996 dc = {}
997 exec(c, dc)
998 return dc['f']
999
1000 reg_act = re.compile(r"(?P<backslash>\\)|(?P<dollar>\$\$)|(?P<subst>\$\{(?P<var>\w+)(?P<code>.*?)\})", re.M)
1001 def compile_fun_shell(line):
1002 """
1003 Create a compiled function to execute a process with the shell
1004 WARNING: this method may disappear anytime, so use compile_fun instead
1005 """
1006
1007 extr = []
1008 def repl(match):
1009 g = match.group
1010 if g('dollar'): return "$"
1011 elif g('backslash'): return '\\\\'
1012 elif g('subst'): extr.append((g('var'), g('code'))); return "%s"
1013 return None
1014
1015 line = reg_act.sub(repl, line) or line
1016
1017 parm = []
1018 dvars = []
1019 app = parm.append
1020 for (var, meth) in extr:
1021 if var == 'SRC':
1022 if meth: app('tsk.inputs%s' % meth)
1023 else: app('" ".join([a.path_from(bld.bldnode) for a in tsk.inputs])')
1024 elif var == 'TGT':
1025 if meth: app('tsk.outputs%s' % meth)
1026 else: app('" ".join([a.path_from(bld.bldnode) for a in tsk.outputs])')
1027 elif meth:
1028 if meth.startswith(':'):
1029 m = meth[1:]
1030 if m == 'SRC':
1031 m = '[a.path_from(bld.bldnode) for a in tsk.inputs]'
1032 elif m == 'TGT':
1033 m = '[a.path_from(bld.bldnode) for a in tsk.outputs]'
1034 elif m[:3] not in ('tsk', 'gen', 'bld'):
1035 dvars.extend([var, meth[1:]])
1036 m = '%r' % m
1037 app('" ".join(tsk.colon(%r, %s))' % (var, m))
1038 else:
1039 app('%s%s' % (var, meth))
1040 else:
1041 if not var in dvars: dvars.append(var)
1042 app("p('%s')" % var)
1043 if parm: parm = "%% (%s) " % (',\n\t\t'.join(parm))
1044 else: parm = ''
1045
1046 c = COMPILE_TEMPLATE_SHELL % (line, parm)
1047
1048 Logs.debug('action: %s' % c)
1049 return (funex(c), dvars)
1050
1051 def compile_fun_noshell(line):
1052 """
1053 Create a compiled function to execute a process without the shell
1054 WARNING: this method may disappear anytime, so use compile_fun instead
1055 """
1056 extr = []
1057 def repl(match):
1058 g = match.group
1059 if g('dollar'): return "$"
1060 elif g('subst'): extr.append((g('var'), g('code'))); return "<<|@|>>"
1061 return None
1062
1063 line2 = reg_act.sub(repl, line)
1064 params = line2.split('<<|@|>>')
1065 assert(extr)
1066
1067 buf = []
1068 dvars = []
1069 app = buf.append
1070 for x in range(len(extr)):
1071 params[x] = params[x].strip()
1072 if params[x]:
1073 app("lst.extend(%r)" % params[x].split())
1074 (var, meth) = extr[x]
1075 if var == 'SRC':
1076 if meth: app('lst.append(tsk.inputs%s)' % meth)
1077 else: app("lst.extend([a.path_from(bld.bldnode) for a in tsk.inputs])")
1078 elif var == 'TGT':
1079 if meth: app('lst.append(tsk.outputs%s)' % meth)
1080 else: app("lst.extend([a.path_from(bld.bldnode) for a in tsk.outputs])")
1081 elif meth:
1082 if meth.startswith(':'):
1083 m = meth[1:]
1084 if m == 'SRC':
1085 m = '[a.path_from(bld.bldnode) for a in tsk.inputs]'
1086 elif m == 'TGT':
1087 m = '[a.path_from(bld.bldnode) for a in tsk.outputs]'
1088 elif m[:3] not in ('tsk', 'gen', 'bld'):
1089 dvars.extend([var, m])
1090 m = '%r' % m
1091 app('lst.extend(tsk.colon(%r, %s))' % (var, m))
1092 else:
1093 app('lst.extend(gen.to_list(%s%s))' % (var, meth))
1094 else:
1095 app('lst.extend(to_list(env[%r]))' % var)
1096 if not var in dvars: dvars.append(var)
1097
1098 if extr:
1099 if params[-1]:
1100 app("lst.extend(%r)" % params[-1].split())
1101 fun = COMPILE_TEMPLATE_NOSHELL % "\n\t".join(buf)
1102 Logs.debug('action: %s' % fun)
1103 return (funex(fun), dvars)
1104
1105 def compile_fun(line, shell=False):
1106 """
1107 Parse a string expression such as "${CC} ${SRC} -o ${TGT}" and return a pair containing:
1108
1109 * the function created (compiled) for use as :py:meth:`waflib.Task.TaskBase.run`
1110 * the list of variables that imply a dependency from self.env
1111
1112 for example::
1113
1114 from waflib.Task import compile_fun
1115 compile_fun('cxx', '${CXX} -o ${TGT[0]} ${SRC} -I ${SRC[0].parent.bldpath()}')
1116
1117 def build(bld):
1118 bld(source='wscript', rule='echo "foo\\${SRC[0].name}\\bar"')
1119
1120 The env variables (CXX, ..) on the task must not hold dicts (order)
1121 The reserved keywords *TGT* and *SRC* represent the task input and output nodes
1122
1123 """
1124 if line.find('<') > 0 or line.find('>') > 0 or line.find('&&') > 0:
1125 shell = True
1126
1127 if shell:
1128 return compile_fun_shell(line)
1129 else:
1130 return compile_fun_noshell(line)
1131
1132 def task_factory(name, func=None, vars=None, color='GREEN', ext_in=[], ext_out=[], before=[], after=[], shell=False, scan=None):
1133 """
1134 Return a new task subclass with the function ``run`` compiled from the line given.
1135 Provided for compatibility with waf 1.4-1.5, when we did not use metaclasses to register new objects.
1136
1137 :param func: method run
1138 :type func: string or function
1139 :param vars: list of variables to hash
1140 :type vars: list of string
1141 :param color: color to use
1142 :type color: string
1143 :param shell: when *func* is a string, enable/disable the use of the shell
1144 :type shell: bool
1145 :param scan: method scan
1146 :type scan: function
1147 :rtype: :py:class:`waflib.Task.Task`
1148 """
1149
1150 params = {
1151 'vars': vars or [], # function arguments are static, and this one may be modified by the class
1152 'color': color,
1153 'name': name,
1154 'ext_in': Utils.to_list(ext_in),
1155 'ext_out': Utils.to_list(ext_out),
1156 'before': Utils.to_list(before),
1157 'after': Utils.to_list(after),
1158 'shell': shell,
1159 'scan': scan,
1160 }
1161
1162 if isinstance(func, str):
1163 params['run_str'] = func
1164 else:
1165 params['run'] = func
1166
1167 cls = type(Task)(name, (Task,), params)
1168 global classes
1169 classes[name] = cls
1170 return cls
1171
1172
1173 def always_run(cls):
1174 """
1175 Task class decorator
1176
1177 Set all task instances of this class to be executed whenever a build is started
1178 The task signature is calculated, but the result of the comparation between
1179 task signatures is bypassed
1180 """
1181 old = cls.runnable_status
1182 def always(self):
1183 ret = old(self)
1184 if ret == SKIP_ME:
1185 ret = RUN_ME
1186 return ret
1187 cls.runnable_status = always
1188 return cls
1189
1190 def update_outputs(cls):
1191 """
1192 Task class decorator
1193
1194 If you want to create files in the source directory. For example, to keep *foo.txt* in the source
1195 directory, create it first and declare::
1196
1197 def build(bld):
1198 bld(rule='cp ${SRC} ${TGT}', source='wscript', target='foo.txt', update_outputs=True)
1199 """
1200 old_post_run = cls.post_run
1201 def post_run(self):
1202 old_post_run(self)
1203 for node in self.outputs:
1204 node.sig = Utils.h_file(node.abspath())
1205 self.generator.bld.task_sigs[node.abspath()] = self.uid() # issue #1017
1206 cls.post_run = post_run
1207
1208
1209 old_runnable_status = cls.runnable_status
1210 def runnable_status(self):
1211 status = old_runnable_status(self)
1212 if status != RUN_ME:
1213 return status
1214
1215 try:
1216 # by default, we check that the output nodes have the signature of the task
1217 # perform a second check, returning 'SKIP_ME' as we are expecting that
1218 # the signatures do not match
1219 bld = self.generator.bld
1220 prev_sig = bld.task_sigs[self.uid()]
1221 if prev_sig == self.signature():
1222 for x in self.outputs:
1223 if not x.sig or bld.task_sigs[x.abspath()] != self.uid():
1224 return RUN_ME
1225 return SKIP_ME
1226 except KeyError:
1227 pass
1228 except IndexError:
1229 pass
1230 except AttributeError:
1231 pass
1232 return RUN_ME
1233 cls.runnable_status = runnable_status
1234
1235 return cls
1236
1237
0 #!/usr/bin/env python
1 # encoding: utf-8
2 # Thomas Nagy, 2005-2010 (ita)
3
4 """
5 Task generators
6
7 The class :py:class:`waflib.TaskGen.task_gen` encapsulates the creation of task objects (low-level code)
8 The instances can have various parameters, but the creation of task nodes (Task.py)
9 is always postponed. To achieve this, various methods are called from the method "apply"
10
11
12 """
13
14 import copy, re, os
15 from waflib import Task, Utils, Logs, Errors, ConfigSet
16
17 feats = Utils.defaultdict(set)
18 """remember the methods declaring features"""
19
20 class task_gen(object):
21 """
22 Instances of this class create :py:class:`waflib.Task.TaskBase` when
23 calling the method :py:meth:`waflib.TaskGen.task_gen.post` from the main thread.
24 A few notes:
25
26 * The methods to call (*self.meths*) can be specified dynamically (removing, adding, ..)
27 * The 'features' are used to add methods to self.meths and then execute them
28 * The attribute 'path' is a node representing the location of the task generator
29 * The tasks created are added to the attribute *tasks*
30 * The attribute 'idx' is a counter of task generators in the same path
31 """
32
33 mappings = {}
34 prec = Utils.defaultdict(list)
35
36 def __init__(self, *k, **kw):
37 """
38 The task generator objects predefine various attributes (source, target) for possible
39 processing by process_rule (make-like rules) or process_source (extensions, misc methods)
40
41 The tasks are stored on the attribute 'tasks'. They are created by calling methods
42 listed in self.meths *or* referenced in the attribute features
43 A topological sort is performed to ease the method re-use.
44
45 The extra key/value elements passed in kw are set as attributes
46 """
47
48 # so we will have to play with directed acyclic graphs
49 # detect cycles, etc
50 self.source = ''
51 self.target = ''
52
53 self.meths = []
54 """
55 List of method names to execute (it is usually a good idea to avoid touching this)
56 """
57
58 self.prec = Utils.defaultdict(list)
59 """
60 Precedence table for sorting the methods in self.meths
61 """
62
63 self.mappings = {}
64 """
65 List of mappings {extension -> function} for processing files by extension
66 """
67
68 self.features = []
69 """
70 List of feature names for bringing new methods in
71 """
72
73 self.tasks = []
74 """
75 List of tasks created.
76 """
77
78 if not 'bld' in kw:
79 # task generators without a build context :-/
80 self.env = ConfigSet.ConfigSet()
81 self.idx = 0
82 self.path = None
83 else:
84 self.bld = kw['bld']
85 self.env = self.bld.env.derive()
86 self.path = self.bld.path # emulate chdir when reading scripts
87
88 # provide a unique id
89 try:
90 self.idx = self.bld.idx[id(self.path)] = self.bld.idx.get(id(self.path), 0) + 1
91 except AttributeError:
92 self.bld.idx = {}
93 self.idx = self.bld.idx[id(self.path)] = 1
94
95 for key, val in kw.items():
96 setattr(self, key, val)
97
98 def __str__(self):
99 """for debugging purposes"""
100 return "<task_gen %r declared in %s>" % (self.name, self.path.abspath())
101
102 def __repr__(self):
103 """for debugging purposes"""
104 lst = []
105 for x in self.__dict__.keys():
106 if x not in ['env', 'bld', 'compiled_tasks', 'tasks']:
107 lst.append("%s=%s" % (x, repr(getattr(self, x))))
108 return "bld(%s) in %s" % (", ".join(lst), self.path.abspath())
109
110 def get_name(self):
111 """
112 If not set, the name is computed from the target name::
113
114 def build(bld):
115 x = bld(name='foo')
116 x.get_name() # foo
117 y = bld(target='bar')
118 y.get_name() # bar
119
120 :rtype: string
121 :return: name of this task generator
122 """
123 try:
124 return self._name
125 except AttributeError:
126 if isinstance(self.target, list):
127 lst = [str(x) for x in self.target]
128 name = self._name = ','.join(lst)
129 else:
130 name = self._name = str(self.target)
131 return name
132 def set_name(self, name):
133 self._name = name
134
135 name = property(get_name, set_name)
136
137 def to_list(self, val):
138 """
139 Ensure that a parameter is a list
140
141 :type val: string or list of string
142 :param val: input to return as a list
143 :rtype: list
144 """
145 if isinstance(val, str): return val.split()
146 else: return val
147
148 def post(self):
149 """
150 Create task objects. The following operations are performed:
151
152 #. The body of this method is called only once and sets the attribute ``posted``
153 #. The attribute ``features`` is used to add more methods in ``self.meths``
154 #. The methods are sorted by the precedence table ``self.prec`` or `:waflib:attr:waflib.TaskGen.task_gen.prec`
155 #. The methods are then executed in order
156 #. The tasks created are added to :py:attr:`waflib.TaskGen.task_gen.tasks`
157 """
158
159 # we could add a decorator to let the task run once, but then python 2.3 will be difficult to support
160 if getattr(self, 'posted', None):
161 #error("OBJECT ALREADY POSTED" + str( self))
162 return False
163 self.posted = True
164
165 keys = set(self.meths)
166
167 # add the methods listed in the features
168 self.features = Utils.to_list(self.features)
169 for x in self.features + ['*']:
170 st = feats[x]
171 if not st:
172 if not x in Task.classes:
173 Logs.warn('feature %r does not exist - bind at least one method to it' % x)
174 keys.update(list(st)) # ironpython 2.7 wants the cast to list
175
176 # copy the precedence table
177 prec = {}
178 prec_tbl = self.prec or task_gen.prec
179 for x in prec_tbl:
180 if x in keys:
181 prec[x] = prec_tbl[x]
182
183 # elements disconnected
184 tmp = []
185 for a in keys:
186 for x in prec.values():
187 if a in x: break
188 else:
189 tmp.append(a)
190
191 # TODO waf 1.7
192 #tmp.sort()
193
194 # topological sort
195 out = []
196 while tmp:
197 e = tmp.pop()
198 if e in keys: out.append(e)
199 try:
200 nlst = prec[e]
201 except KeyError:
202 pass
203 else:
204 del prec[e]
205 for x in nlst:
206 for y in prec:
207 if x in prec[y]:
208 break
209 else:
210 tmp.append(x)
211
212 if prec:
213 raise Errors.WafError('Cycle detected in the method execution %r' % prec)
214 out.reverse()
215 self.meths = out
216
217 # then we run the methods in order
218 Logs.debug('task_gen: posting %s %d' % (self, id(self)))
219 for x in out:
220 try:
221 v = getattr(self, x)
222 except AttributeError:
223 raise Errors.WafError('%r is not a valid task generator method' % x)
224 Logs.debug('task_gen: -> %s (%d)' % (x, id(self)))
225 v()
226
227 Logs.debug('task_gen: posted %s' % self.name)
228 return True
229
230 def get_hook(self, node):
231 """
232 :param node: Input file to process
233 :type node: :py:class:`waflib.Tools.Node.Node`
234 :return: A method able to process the input node by looking at the extension
235 :rtype: function
236 """
237 name = node.name
238 for k in self.mappings:
239 if name.endswith(k):
240 return self.mappings[k]
241 for k in task_gen.mappings:
242 if name.endswith(k):
243 return task_gen.mappings[k]
244 raise Errors.WafError("File %r has no mapping in %r (did you forget to load a waf tool?)" % (node, task_gen.mappings.keys()))
245
246 def create_task(self, name, src=None, tgt=None):
247 """
248 Wrapper for creating task objects easily
249
250 :param name: task class name
251 :type name: string
252 :param src: input nodes
253 :type src: list of :py:class:`waflib.Tools.Node.Node`
254 :param tgt: output nodes
255 :type tgt: list of :py:class:`waflib.Tools.Node.Node`
256 :return: A task object
257 :rtype: :py:class:`waflib.Task.TaskBase`
258 """
259 task = Task.classes[name](env=self.env.derive(), generator=self)
260 if src:
261 task.set_inputs(src)
262 if tgt:
263 task.set_outputs(tgt)
264 self.tasks.append(task)
265 return task
266
267 def clone(self, env):
268 """
269 Make a copy of a task generator. Once the copy is made, it is necessary to ensure that the
270 task generator does not create the same output files as the original, or the same files may
271 be compiled twice.
272
273 :param env: A configuration set
274 :type env: :py:class:`waflib.ConfigSet.ConfigSet`
275 :return: A copy
276 :rtype: :py:class:`waflib.TaskGen.task_gen`
277 """
278 newobj = self.bld()
279 for x in self.__dict__:
280 if x in ['env', 'bld']:
281 continue
282 elif x in ['path', 'features']:
283 setattr(newobj, x, getattr(self, x))
284 else:
285 setattr(newobj, x, copy.copy(getattr(self, x)))
286
287 newobj.posted = False
288 if isinstance(env, str):
289 newobj.env = self.bld.all_envs[env].derive()
290 else:
291 newobj.env = env.derive()
292
293 return newobj
294
295 def declare_chain(name='', rule=None, reentrant=None, color='BLUE',
296 ext_in=[], ext_out=[], before=[], after=[], decider=None, scan=None, install_path=None, shell=False):
297 """
298 Create a new mapping and a task class for processing files by extension.
299 See Tools/flex.py for an example.
300
301 :param name: name for the task class
302 :type name: string
303 :param rule: function to execute or string to be compiled in a function
304 :type rule: string or function
305 :param reentrant: re-inject the output file in the process (done automatically, set to 0 to disable)
306 :type reentrant: int
307 :param color: color for the task output
308 :type color: string
309 :param ext_in: execute the task only after the files of such extensions are created
310 :type ext_in: list of string
311 :param ext_out: execute the task only before files of such extensions are processed
312 :type ext_out: list of string
313 :param before: execute instances of this task before classes of the given names
314 :type before: list of string
315 :param after: execute instances of this task after classes of the given names
316 :type after: list of string
317 :param decider: if present, use it to create the output nodes for the task
318 :type decider: function
319 :param scan: scanner function for the task
320 :type scan: function
321 :param install_path: installation path for the output nodes
322 :type install_path: string
323 """
324 ext_in = Utils.to_list(ext_in)
325 ext_out = Utils.to_list(ext_out)
326 if not name:
327 name = rule
328 cls = Task.task_factory(name, rule, color=color, ext_in=ext_in, ext_out=ext_out, before=before, after=after, scan=scan, shell=shell)
329
330 def x_file(self, node):
331 ext = decider and decider(self, node) or cls.ext_out
332 if ext_in:
333 _ext_in = ext_in[0]
334
335 tsk = self.create_task(name, node)
336 cnt = 0
337
338 keys = self.mappings.keys() + self.__class__.mappings.keys()
339 for x in ext:
340 k = node.change_ext(x, ext_in=_ext_in)
341 tsk.outputs.append(k)
342
343 if reentrant != None:
344 if cnt < int(reentrant):
345 self.source.append(k)
346 else:
347 for y in keys: # ~ nfile * nextensions :-/
348 if k.name.endswith(y):
349 self.source.append(k)
350 break
351 cnt += 1
352
353 if install_path:
354 self.bld.install_files(install_path, tsk.outputs)
355 return tsk
356
357 for x in cls.ext_in:
358 task_gen.mappings[x] = x_file
359 return x_file
360
361 def taskgen_method(func):
362 """
363 Decorator: register a method as a task generator method.
364 The function must accept a task generator as first parameter::
365
366 from waflib.TaskGen import taskgen_method
367 @taskgen_method
368 def mymethod(self):
369 pass
370
371 :param func: task generator method to add
372 :type func: function
373 :rtype: function
374 """
375 setattr(task_gen, func.__name__, func)
376 return func
377
378 def feature(*k):
379 """
380 Decorator: register a task generator method that will be executed when the
381 object attribute 'feature' contains the corresponding key(s)::
382
383 from waflib.Task import feature
384 @feature('myfeature')
385 def myfunction(self):
386 print('that is my feature!')
387 def build(bld):
388 bld(features='myfeature')
389
390 :param k: feature names
391 :type k: list of string
392 """
393 def deco(func):
394 setattr(task_gen, func.__name__, func)
395 for name in k:
396 feats[name].update([func.__name__])
397 return func
398 return deco
399
400 def before_method(*k):
401 """
402 Decorator: register a task generator method which will be executed
403 before the functions of given name(s)::
404
405 from waflib.TaskGen import feature, before
406 @feature('myfeature')
407 @before_method('fun2')
408 def fun1(self):
409 print('feature 1!')
410 @feature('myfeature')
411 def fun2(self):
412 print('feature 2!')
413 def build(bld):
414 bld(features='myfeature')
415
416 :param k: method names
417 :type k: list of string
418 """
419 def deco(func):
420 setattr(task_gen, func.__name__, func)
421 for fun_name in k:
422 if not func.__name__ in task_gen.prec[fun_name]:
423 task_gen.prec[fun_name].append(func.__name__)
424 #task_gen.prec[fun_name].sort()
425 return func
426 return deco
427 before = before_method
428
429 def after_method(*k):
430 """
431 Decorator: register a task generator method which will be executed
432 after the functions of given name(s)::
433
434 from waflib.TaskGen import feature, after
435 @feature('myfeature')
436 @after_method('fun2')
437 def fun1(self):
438 print('feature 1!')
439 @feature('myfeature')
440 def fun2(self):
441 print('feature 2!')
442 def build(bld):
443 bld(features='myfeature')
444
445 :param k: method names
446 :type k: list of string
447 """
448 def deco(func):
449 setattr(task_gen, func.__name__, func)
450 for fun_name in k:
451 if not fun_name in task_gen.prec[func.__name__]:
452 task_gen.prec[func.__name__].append(fun_name)
453 #task_gen.prec[func.__name__].sort()
454 return func
455 return deco
456 after = after_method
457
458 def extension(*k):
459 """
460 Decorator: register a task generator method which will be invoked during
461 the processing of source files for the extension given::
462
463 from waflib import Task
464 class mytask(Task):
465 run_str = 'cp ${SRC} ${TGT}'
466 @extension('.moo')
467 def create_maa_file(self, node):
468 self.create_task('mytask', node, node.change_ext('.maa'))
469 def build(bld):
470 bld(source='foo.moo')
471 """
472 def deco(func):
473 setattr(task_gen, func.__name__, func)
474 for x in k:
475 task_gen.mappings[x] = func
476 return func
477 return deco
478
479 # ---------------------------------------------------------------
480 # The following methods are task generator methods commonly used
481 # they are almost examples, the rest of waf core does not depend on them
482
483 @taskgen_method
484 def to_nodes(self, lst, path=None):
485 """
486 Convert the input list into a list of nodes.
487 It is used by :py:func:`waflib.TaskGen.process_source` and :py:func:`waflib.TaskGen.process_rule`.
488 It is designed for source files, for folders, see :py:func:`waflib.Tools.ccroot.to_incnodes`:
489
490 :param lst: input list
491 :type lst: list of string and nodes
492 :param path: path from which to search the nodes (by default, :py:attr:`waflib.TaskGen.task_gen.path`)
493 :type path: :py:class:`waflib.Tools.Node.Node`
494 :rtype: list of :py:class:`waflib.Tools.Node.Node`
495 """
496 tmp = []
497 path = path or self.path
498 find = path.find_resource
499
500 if isinstance(lst, self.path.__class__):
501 lst = [lst]
502
503 # either a list or a string, convert to a list of nodes
504 for x in Utils.to_list(lst):
505 if isinstance(x, str):
506 node = find(x)
507 else:
508 node = x
509 if not node:
510 raise Errors.WafError("source not found: %r in %r" % (x, self))
511 tmp.append(node)
512 return tmp
513
514 @feature('*')
515 def process_source(self):
516 """
517 Process each element in the attribute ``source`` by extension.
518
519 #. The *source* list is converted through :py:meth:`waflib.TaskGen.to_nodes` to a list of :py:class:`waflib.Node.Node` first.
520 #. File extensions are mapped to methods having the signature: ``def meth(self, node)`` by :py:meth:`waflib.TaskGen.extension`
521 #. The method is retrieved through :py:meth:`waflib.TaskGen.task_gen.get_hook`
522 #. When called, the methods may modify self.source to append more source to process
523 #. The mappings can map an extension or a filename (see the code below)
524 """
525 self.source = self.to_nodes(getattr(self, 'source', []))
526 for node in self.source:
527 self.get_hook(node)(self, node)
528
529 @feature('*')
530 @before_method('process_source')
531 def process_rule(self):
532 """
533 Process the attribute ``rule``. When present, :py:meth:`waflib.TaskGen.process_source` is disabled::
534
535 def build(bld):
536 bld(rule='cp ${SRC} ${TGT}', source='wscript', target='bar.txt')
537 """
538 if not getattr(self, 'rule', None):
539 return
540
541 # create the task class
542 name = str(getattr(self, 'name', None) or self.target or self.rule)
543 cls = Task.task_factory(name, self.rule,
544 getattr(self, 'vars', []),
545 shell=getattr(self, 'shell', True), color=getattr(self, 'color', 'BLUE'))
546
547 # now create one instance
548 tsk = self.create_task(name)
549
550 if getattr(self, 'target', None):
551 if isinstance(self.target, str):
552 self.target = self.target.split()
553 if not isinstance(self.target, list):
554 self.target = [self.target]
555 for x in self.target:
556 if isinstance(x, str):
557 tsk.outputs.append(self.path.find_or_declare(x))
558 else:
559 x.parent.mkdir() # if a node was given, create the required folders
560 tsk.outputs.append(x)
561 if getattr(self, 'install_path', None):
562 # from waf 1.5
563 # although convenient, it does not 1. allow to name the target file and 2. symlinks
564 # TODO remove in waf 1.7
565 self.bld.install_files(self.install_path, tsk.outputs)
566
567 if getattr(self, 'source', None):
568 tsk.inputs = self.to_nodes(self.source)
569 # bypass the execution of process_source by setting the source to an empty list
570 self.source = []
571
572 if getattr(self, 'scan', None):
573 cls.scan = self.scan
574 elif getattr(self, 'deps', None):
575 def scan(self):
576 nodes = []
577 for x in self.generator.to_list(self.generator.deps):
578 node = self.generator.path.find_resource(x)
579 if not node:
580 self.generator.bld.fatal('Could not find %r (was it declared?)' % x)
581 nodes.append(node)
582 return [nodes, []]
583 cls.scan = scan
584
585 if getattr(self, 'cwd', None):
586 tsk.cwd = self.cwd
587
588 # TODO remove on_results in waf 1.7
589 if getattr(self, 'update_outputs', None) or getattr(self, 'on_results', None):
590 Task.update_outputs(cls)
591
592 if getattr(self, 'always', None):
593 Task.always_run(cls)
594
595 for x in ['after', 'before', 'ext_in', 'ext_out']:
596 setattr(cls, x, getattr(self, x, []))
597
598 @feature('seq')
599 def sequence_order(self):
600 """
601 Add a strict sequential constraint between the tasks generated by task generators.
602 It works because task generators are posted in order.
603 It will not post objects which belong to other folders.
604
605 Example::
606
607 bld(features='javac seq')
608 bld(features='jar seq')
609
610 To start a new sequence, set the attribute seq_start, for example::
611
612 obj = bld(features='seq')
613 obj.seq_start = True
614
615 Note that the method is executed in last position. This is more an
616 example than a widely-used solution.
617 """
618 if self.meths and self.meths[-1] != 'sequence_order':
619 self.meths.append('sequence_order')
620 return
621
622 if getattr(self, 'seq_start', None):
623 return
624
625 # all the tasks previously declared must be run before these
626 if getattr(self.bld, 'prev', None):
627 self.bld.prev.post()
628 for x in self.bld.prev.tasks:
629 for y in self.tasks:
630 y.set_run_after(x)
631
632 self.bld.prev = self
633
634
635 re_m4 = re.compile('@(\w+)@', re.M)
636
637 class subst_pc(Task.Task):
638 """
639 Create *.pc* files from *.pc.in*. The task is executed whenever an input variable used
640 in the substitution changes.
641 """
642
643 def run(self):
644 "Substitutes variables in a .in file"
645
646 code = self.inputs[0].read()
647
648 # replace all % by %% to prevent errors by % signs
649 code = code.replace('%', '%%')
650
651 # extract the vars foo into lst and replace @foo@ by %(foo)s
652 lst = []
653 def repl(match):
654 g = match.group
655 if g(1):
656 lst.append(g(1))
657 return "%%(%s)s" % g(1)
658 return ''
659 code = re_m4.sub(repl, code)
660
661 try:
662 d = self.generator.dct
663 except AttributeError:
664 d = {}
665 for x in lst:
666 tmp = getattr(self.generator, x, '') or self.env.get_flat(x) or self.env.get_flat(x.upper())
667 d[x] = str(tmp)
668
669 self.outputs[0].write(code % d)
670 self.generator.bld.raw_deps[self.uid()] = self.dep_vars = lst
671
672 # make sure the signature is updated
673 try: delattr(self, 'cache_sig')
674 except AttributeError: pass
675
676 if getattr(self.generator, 'chmod', None):
677 os.chmod(self.outputs[0].abspath(), self.generator.chmod)
678
679 def sig_vars(self):
680 """
681 Compute a hash (signature) of the variables used in the substitution
682 """
683 bld = self.generator.bld
684 env = self.env
685 upd = self.m.update
686
687 # raw_deps: persistent custom values returned by the scanner
688 vars = self.generator.bld.raw_deps.get(self.uid(), [])
689
690 # hash both env vars and task generator attributes
691 act_sig = bld.hash_env_vars(env, vars)
692 upd(act_sig)
693
694 lst = [getattr(self.generator, x, '') for x in vars]
695 upd(Utils.h_list(lst))
696
697 return self.m.digest()
698
699 @extension('.pc.in')
700 def add_pcfile(self, node):
701 """
702 Process *.pc.in* files to *.pc*. Install the results to ``${PREFIX}/lib/pkgconfig/``
703
704 def build(bld):
705 bld(source='foo.pc.in', install_path='${LIBDIR}/pkgconfig/')
706 """
707 tsk = self.create_task('subst_pc', node, node.change_ext('.pc', '.pc.in'))
708 self.bld.install_files(getattr(self, 'install_path', '${LIBDIR}/pkgconfig/'), tsk.outputs)
709
710 class subst(subst_pc):
711 pass
712
713 @feature('subst')
714 @before_method('process_source', 'process_rule')
715 def process_subst(self):
716 """
717 Define a transformation that substitutes the contents of *source* files to *target* files::
718
719 def build(bld):
720 bld(
721 features='subst',
722 source='foo.c.in',
723 target='foo.c',
724 install_path='${LIBDIR}/pkgconfig',
725 VAR = 'val'
726 )
727
728 The input files are supposed to contain macros of the form *@VAR@*, where *VAR* is an argument
729 of the task generator object.
730
731 This method overrides the processing by :py:meth:`waflib.TaskGen.process_source`.
732 """
733 src = self.to_nodes(getattr(self, 'source', []))
734 tgt = getattr(self, 'target', [])
735 if isinstance(tgt, self.path.__class__):
736 tgt = [tgt]
737 tgt = [isinstance(x, self.path.__class__) and x or self.path.find_or_declare(x) for x in Utils.to_list(tgt)]
738
739 if len(src) != len(tgt):
740 raise Errors.WafError('invalid source or target for %r' % self)
741
742 for x, y in zip(src, tgt):
743 if not (x and y):
744 raise Errors.WafError('invalid source or target for %r' % self)
745 tsk = self.create_task('subst', x, y)
746 for a in ('after', 'before', 'ext_in', 'ext_out'):
747 val = getattr(self, a, None)
748 if val:
749 setattr(tsk, a, val)
750
751 inst_to = getattr(self, 'install_path', None)
752 if inst_to:
753 self.bld.install_files(inst_to, tgt, chmod=getattr(self, 'chmod', Utils.O644))
754
755 self.source = []
756
0 #!/usr/bin/env python
1 # encoding: utf-8
2 # Thomas Nagy, 2005-2010 (ita)
0 #!/usr/bin/env python
1 # encoding: utf-8
2 # Thomas Nagy, 2006-2010 (ita)
3 # Ralf Habacker, 2006 (rh)
4
5 """
6 The **ar** program creates static libraries. This tool is almost always loaded
7 from others (C, C++, D, etc) for static library support.
8 """
9
10 from waflib.Configure import conf
11
12 @conf
13 def find_ar(conf):
14 """Configuration helper used by C/C++ tools to enable the support for static libraries"""
15 conf.load('ar')
16
17 def configure(conf):
18 """Find the ar program and set the default flags in ``conf.env.ARFLAGS``"""
19 conf.find_program('ar', var='AR')
20 conf.env.ARFLAGS = 'rcs'
21
0 #!/usr/bin/env python
1 # encoding: utf-8
2 # Thomas Nagy, 2008-2010 (ita)
3
4 """
5 Assembly support, used by tools such as gas and nasm
6
7 To declare targets using assembly::
8
9 def configure(conf):
10 conf.load('gcc gas')
11
12 def build(bld):
13 bld(
14 features='c cstlib asm',
15 source = 'test.S',
16 target = 'asmtest')
17
18 bld(
19 features='asm asmprogram',
20 source = 'test.S',
21 target = 'asmtest')
22
23 Support for pure asm programs and libraries should also work::
24
25 def configure(conf):
26 conf.load('nasm')
27 conf.find_program('ld', 'ASLINK')
28
29 def build(bld):
30 bld(
31 features='asm asmprogram',
32 source = 'test.S',
33 target = 'asmtest')
34 """
35
36 import os, sys
37 from waflib import Task, Utils
38 import waflib.Task
39 from waflib.Tools.ccroot import link_task, stlink_task
40 from waflib.TaskGen import extension, feature
41
42 class asm(Task.Task):
43 """
44 Compile asm files by gas/nasm/yasm/...
45 """
46 color = 'BLUE'
47 run_str = '${AS} ${ASFLAGS} ${CPPPATH_ST:INCPATHS} ${AS_SRC_F}${SRC} ${AS_TGT_F}${TGT}'
48
49 @extension('.s', '.S', '.asm', '.ASM', '.spp', '.SPP')
50 def asm_hook(self, node):
51 """
52 Bind the asm extension to the asm task
53
54 :param node: input file
55 :type node: :py:class:`waflib.Node.Node`
56 """
57 return self.create_compiled_task('asm', node)
58
59 class asmprogram(link_task):
60 "Link object files into a c program"
61 run_str = '${ASLINK} ${ASLINKFLAGS} ${ASLNK_TGT_F}${TGT} ${ASLNK_SRC_F}${SRC}'
62 ext_out = ['.bin']
63 inst_to = '${BINDIR}'
64 chmod = Utils.O755
65
66 class asmshlib(asmprogram):
67 "Link object files into a c shared library"
68 inst_to = '${LIBDIR}'
69
70 class asmstlib(stlink_task):
71 "Link object files into a c static library"
72 pass # do not remove
73
0 #!/usr/bin/env python
1 # encoding: utf-8
2 # John O'Meara, 2006
3 # Thomas Nagy 2009-2010 (ita)
4
5 """
6 The **bison** program is a code generator which creates C or C++ files.
7 The generated files are compiled into object files.
8 """
9
10 from waflib import Task
11 from waflib.TaskGen import extension
12
13 class bison(Task.Task):
14 """Compile bison files"""
15 color = 'BLUE'
16 run_str = '${BISON} ${BISONFLAGS} ${SRC[0].abspath()} -o ${TGT[0].name}'
17 ext_out = ['.h'] # just to make sure
18
19 @extension('.y', '.yc', '.yy')
20 def big_bison(self, node):
21 """
22 Create a bison task, which must be executed from the directory of the output file.
23 """
24 has_h = '-d' in self.env['BISONFLAGS']
25
26 outs = []
27 if node.name.endswith('.yc'):
28 outs.append(node.change_ext('.tab.cc'))
29 if has_h:
30 outs.append(node.change_ext('.tab.hh'))
31 else:
32 outs.append(node.change_ext('.tab.c'))
33 if has_h:
34 outs.append(node.change_ext('.tab.h'))
35
36 tsk = self.create_task('bison', node, outs)
37 tsk.cwd = node.parent.get_bld().abspath()
38
39 # and the c/cxx file must be compiled too
40 self.source.append(outs[0])
41
42 def configure(conf):
43 """
44 Detect the *bison* program
45 """
46 conf.find_program('bison', var='BISON')
47 conf.env.BISONFLAGS = ['-d']
48
0 #!/usr/bin/env python
1 # encoding: utf-8
2 # Thomas Nagy, 2006-2010 (ita)
3
4 "Base for c programs/libraries"
5
6 from waflib import TaskGen, Task, Utils
7 from waflib.Tools import c_preproc
8 from waflib.Tools.ccroot import link_task, stlink_task
9
10 @TaskGen.extension('.c')
11 def c_hook(self, node):
12 "Bind the c file extension to the creation of a :py:class:`waflib.Tools.c.c` instance"
13 return self.create_compiled_task('c', node)
14
15 class c(Task.Task):
16 "Compile C files into object files"
17 run_str = '${CC} ${ARCH_ST:ARCH} ${CFLAGS} ${CPPFLAGS} ${FRAMEWORKPATH_ST:FRAMEWORKPATH} ${CPPPATH_ST:INCPATHS} ${DEFINES_ST:DEFINES} ${CC_SRC_F}${SRC} ${CC_TGT_F}${TGT}'
18 vars = ['CCDEPS'] # unused variable to depend on, just in case
19 ext_in = ['.h'] # set the build order easily by using ext_out=['.h']
20 scan = c_preproc.scan
21
22 Task.classes['cc'] = cc = c # compat, remove in waf 1.7
23
24 class cprogram(link_task):
25 "Link object files into a c program"
26 run_str = '${LINK_CC} ${LINKFLAGS} ${CCLNK_SRC_F}${SRC} ${CCLNK_TGT_F}${TGT[0].abspath()} ${RPATH_ST:RPATH} ${FRAMEWORKPATH_ST:FRAMEWORKPATH} ${FRAMEWORK_ST:FRAMEWORK} ${ARCH_ST:ARCH} ${STLIB_MARKER} ${STLIBPATH_ST:STLIBPATH} ${STLIB_ST:STLIB} ${SHLIB_MARKER} ${LIBPATH_ST:LIBPATH} ${LIB_ST:LIB}'
27 ext_out = ['.bin']
28 vars = ['LINKDEPS']
29 inst_to = '${BINDIR}'
30 chmod = Utils.O755
31
32 class cshlib(cprogram):
33 "Link object files into a c shared library"
34 inst_to = '${LIBDIR}'
35
36 class cstlib(stlink_task):
37 "Link object files into a c static library"
38 pass # do not remove
39
0 #!/usr/bin/env python
1 # encoding: utf-8
2 # Thomas Nagy, 2005-2010 (ita)
3
4 "base for all c/c++ programs and libraries"
5
6 import os, sys, re
7 from waflib import Utils, Build
8 from waflib.Configure import conf
9
10 def get_extensions(lst):
11 """
12 :param lst: files to process
13 :list lst: list of string or :py:class:`waflib.Node.Node`
14 :return: list of file extensions
15 :rtype: list of string
16 """
17 ret = []
18 for x in Utils.to_list(lst):
19 try:
20 if not isinstance(x, str):
21 x = x.name
22 ret.append(x[x.rfind('.') + 1:])
23 except:
24 pass
25 return ret
26
27 def sniff_features(**kw):
28 """
29 Look at the source files and return the features for a task generator (mainly cc and cxx)::
30
31 snif_features(source=['foo.c', 'foo.cxx'], type='shlib')
32 # returns ['cxx', 'c', 'cxxshlib', 'cshlib']
33
34 :param source: source files to process
35 :type source: list of string or :py:class:`waflib.Node.Node`
36 :param type: object type in *program*, *shlib* or *stlib*
37 :type type: string
38 :return: the list of features for a task generator processing the source files
39 :rtype: list of string
40 """
41 exts = get_extensions(kw['source'])
42 type = kw['_type']
43 feats = []
44
45 # watch the order, cxx will have the precedence
46 if 'cxx' in exts or 'cpp' in exts or 'c++' in exts or 'cc' in exts or 'C' in exts:
47 feats.append('cxx')
48
49 if 'c' in exts or 'vala' in exts:
50 feats.append('c')
51
52 if 'd' in exts:
53 feats.append('d')
54
55 if 'java' in exts:
56 feats.append('java')
57
58 if 'java' in exts:
59 return 'java'
60
61 if type in ['program', 'shlib', 'stlib']:
62 for x in feats:
63 if x in ['cxx', 'd', 'c']:
64 feats.append(x + type)
65
66 return feats
67
68 def set_features(kw, _type):
69 kw['_type'] = _type
70 kw['features'] = Utils.to_list(kw.get('features', [])) + Utils.to_list(sniff_features(**kw))
71
72 @conf
73 def program(bld, *k, **kw):
74 """
75 Alias for creating programs by looking at the file extensions::
76
77 def build(bld):
78 bld.program(source='foo.c', target='app')
79 # equivalent to:
80 # bld(features='c cprogram', source='foo.c', target='app')
81
82 """
83 set_features(kw, 'program')
84 return bld(*k, **kw)
85
86 @conf
87 def shlib(bld, *k, **kw):
88 """
89 Alias for creating shared libraries by looking at the file extensions::
90
91 def build(bld):
92 bld.shlib(source='foo.c', target='app')
93 # equivalent to:
94 # bld(features='c cshlib', source='foo.c', target='app')
95
96 """
97 set_features(kw, 'shlib')
98 return bld(*k, **kw)
99
100 @conf
101 def stlib(bld, *k, **kw):
102 """
103 Alias for creating static libraries by looking at the file extensions::
104
105 def build(bld):
106 bld.stlib(source='foo.cpp', target='app')
107 # equivalent to:
108 # bld(features='cxx cxxstlib', source='foo.cpp', target='app')
109
110 """
111 set_features(kw, 'stlib')
112 return bld(*k, **kw)
113
114 @conf
115 def objects(bld, *k, **kw):
116 """
117 Alias for creating object files by looking at the file extensions::
118
119 def build(bld):
120 bld.objects(source='foo.c', target='app')
121 # equivalent to:
122 # bld(features='c', source='foo.c', target='app')
123
124 """
125 set_features(kw, 'objects')
126 return bld(*k, **kw)
127
0 #!/usr/bin/env python
1 # encoding: utf-8
2 # Thomas Nagy, 2005-2010 (ita)
3
4 """
5 C/C++/D configuration helpers
6 """
7
8 import os, imp, sys, re, shlex, shutil
9 from waflib import Build, Utils, Configure, Task, Options, Logs, TaskGen, Errors, ConfigSet, Runner
10 from waflib.TaskGen import before_method, after_method, feature
11 from waflib.Configure import conf
12
13 WAF_CONFIG_H = 'config.h'
14 """default name for the config.h file"""
15
16 DEFKEYS = 'define_key'
17 INCKEYS = 'include_key'
18
19 cfg_ver = {
20 'atleast-version': '>=',
21 'exact-version': '==',
22 'max-version': '<=',
23 }
24
25 SNIP_FUNCTION = '''
26 int main() {
27 void *p;
28 p=(void*)(%s);
29 return 0;
30 }
31 '''
32 """Code template for checking for functions"""
33
34 SNIP_TYPE = '''
35 int main() {
36 if ((%(type_name)s *) 0) return 0;
37 if (sizeof (%(type_name)s)) return 0;
38 }
39 '''
40 """Code template for checking for types"""
41
42 SNIP_CLASS = '''
43 int main() {
44 if (
45 }
46 '''
47
48 SNIP_EMPTY_PROGRAM = '''
49 int main() {
50 return 0;
51 }
52 '''
53
54 SNIP_FIELD = '''
55 int main() {
56 char *off;
57 off = (char*) &((%(type_name)s*)0)->%(field_name)s;
58 return (size_t) off < sizeof(%(type_name)s);
59 }
60 '''
61
62 MACRO_TO_DESTOS = {
63 '__linux__' : 'linux',
64 '__GNU__' : 'gnu', # hurd
65 '__FreeBSD__' : 'freebsd',
66 '__NetBSD__' : 'netbsd',
67 '__OpenBSD__' : 'openbsd',
68 '__sun' : 'sunos',
69 '__hpux' : 'hpux',
70 '__sgi' : 'irix',
71 '_AIX' : 'aix',
72 '__CYGWIN__' : 'cygwin',
73 '__MSYS__' : 'msys',
74 '_UWIN' : 'uwin',
75 '_WIN64' : 'win32',
76 '_WIN32' : 'win32',
77 # Note about darwin: this is also tested with 'defined __APPLE__ && defined __MACH__' somewhere below in this file.
78 '__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__' : 'darwin',
79 '__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__' : 'darwin', # iphone
80 '__QNX__' : 'qnx',
81 '__native_client__' : 'nacl' # google native client platform
82 }
83
84 MACRO_TO_DEST_CPU = {
85 '__x86_64__' : 'x86_64',
86 '__i386__' : 'x86',
87 '__ia64__' : 'ia',
88 '__mips__' : 'mips',
89 '__sparc__' : 'sparc',
90 '__alpha__' : 'alpha',
91 '__arm__' : 'arm',
92 '__hppa__' : 'hppa',
93 '__powerpc__' : 'powerpc',
94 }
95
96 @conf
97 def parse_flags(self, line, uselib, env=None, force_static=False):
98 """
99 Parse the flags from the input lines, and add them to the relevant use variables::
100
101 def configure(conf):
102 conf.parse_flags('-O3', uselib_store='FOO')
103 # conf.env.CXXFLAGS_FOO = ['-O3']
104 # conf.env.CFLAGS_FOO = ['-O3']
105
106 :param line: flags
107 :type line: string
108 :param uselib: where to add the flags
109 :type uselib: string
110 :param env: config set or conf.env by default
111 :type env: :py:class:`waflib.ConfigSet.ConfigSet`
112 """
113
114 assert(isinstance(line, str))
115
116 env = env or self.env
117
118 # append_unique is not always possible
119 # for example, apple flags may require both -arch i386 and -arch ppc
120
121 app = env.append_value
122 appu = env.append_unique
123 #lst = shlex.split(line)
124 # issue #811
125 lex = shlex.shlex(line, posix=False)
126 lex.whitespace_split = True
127 lex.commenters = ''
128 lst = list(lex)
129
130 while lst:
131 x = lst.pop(0)
132 st = x[:2]
133 ot = x[2:]
134
135 if st == '-I' or st == '/I':
136 if not ot: ot = lst.pop(0)
137 appu('INCLUDES_' + uselib, [ot])
138 elif st == '-include':
139 tmp = [x, lst.pop(0)]
140 app('CFLAGS', tmp)
141 app('CXXFLAGS', tmp)
142 elif st == '-D' or (self.env.CXX_NAME == 'msvc' and st == '/D'): # not perfect but..
143 if not ot: ot = lst.pop(0)
144 app('DEFINES_' + uselib, [ot])
145 elif st == '-l':
146 if not ot: ot = lst.pop(0)
147 prefix = force_static and 'STLIB_' or 'LIB_'
148 appu(prefix + uselib, [ot])
149 elif st == '-L':
150 if not ot: ot = lst.pop(0)
151 appu('LIBPATH_' + uselib, [ot])
152 elif x == '-pthread' or x.startswith('+') or x.startswith('-std'):
153 app('CFLAGS_' + uselib, [x])
154 app('CXXFLAGS_' + uselib, [x])
155 app('LINKFLAGS_' + uselib, [x])
156 elif x == '-framework':
157 appu('FRAMEWORK_' + uselib, [lst.pop(0)])
158 elif x.startswith('-F'):
159 appu('FRAMEWORKPATH_' + uselib, [x[2:]])
160 elif x.startswith('-Wl'):
161 app('LINKFLAGS_' + uselib, [x])
162 elif x.startswith('-m') or x.startswith('-f') or x.startswith('-dynamic'):
163 app('CFLAGS_' + uselib, [x])
164 app('CXXFLAGS_' + uselib, [x])
165 elif x.startswith('-bundle'):
166 app('LINKFLAGS_' + uselib, [x])
167 elif x.startswith('-undefined'):
168 arg = lst.pop(0)
169 app('LINKFLAGS_' + uselib, [x, arg])
170 elif x.startswith('-arch') or x.startswith('-isysroot'):
171 tmp = [x, lst.pop(0)]
172 app('CFLAGS_' + uselib, tmp)
173 app('CXXFLAGS_' + uselib, tmp)
174 app('LINKFLAGS_' + uselib, tmp)
175 elif x.endswith('.a') or x.endswith('.so') or x.endswith('.dylib'):
176 appu('LINKFLAGS_' + uselib, [x]) # not cool, #762
177
178 @conf
179 def ret_msg(self, f, kw):
180 if isinstance(f, str):
181 return f
182 return f(kw)
183
184 @conf
185 def validate_cfg(self, kw):
186 """
187 Search for the program *pkg-config* if missing, and validate the parameters to pass to
188 :py:func:`waflib.Tools.c_config.exec_cfg`.
189
190 :param path: the **-config program to use** (default is *pkg-config*)
191 :type path: list of string
192 :param msg: message to display to describe the test executed
193 :type msg: string
194 :param okmsg: message to display when the test is successful
195 :type okmsg: string
196 :param errmsg: message to display in case of error
197 :type errmsg: string
198 """
199 if not 'path' in kw:
200 if not self.env.PKGCONFIG:
201 self.find_program('pkg-config', var='PKGCONFIG')
202 kw['path'] = self.env.PKGCONFIG
203
204 # pkg-config version
205 if 'atleast_pkgconfig_version' in kw:
206 if not 'msg' in kw:
207 kw['msg'] = 'Checking for pkg-config version >= %r' % kw['atleast_pkgconfig_version']
208 return
209
210 if not 'okmsg' in kw:
211 kw['okmsg'] = 'yes'
212 if not 'errmsg' in kw:
213 kw['errmsg'] = 'not found'
214
215 if 'modversion' in kw:
216 if not 'msg' in kw:
217 kw['msg'] = 'Checking for %r version' % kw['modversion']
218 return
219
220 # checking for the version of a module, for the moment, one thing at a time
221 for x in cfg_ver.keys():
222 y = x.replace('-', '_')
223 if y in kw:
224 if not 'package' in kw:
225 raise ValueError('%s requires a package' % x)
226
227 if not 'msg' in kw:
228 kw['msg'] = 'Checking for %r %s %s' % (kw['package'], cfg_ver[x], kw[y])
229 return
230
231 if not 'msg' in kw:
232 kw['msg'] = 'Checking for %r' % (kw['package'] or kw['path'])
233
234 @conf
235 def exec_cfg(self, kw):
236 """
237 Execute the program *pkg-config*:
238
239 * if atleast_pkgconfig_version is given, check that pkg-config has the version n and return
240 * if modversion is given, then return the module version
241 * else, execute the *-config* program with the *args* and *variables* given, and set the flags on the *conf.env.FLAGS_name* variable
242
243 :param atleast_pkgconfig_version: minimum pkg-config version to use (disable other tests)
244 :type atleast_pkgconfig_version: string
245 :param package: package name, for example *gtk+-2.0*
246 :type package: string
247 :param uselib_store: if the test is successful, define HAVE\_*name*. It is also used to define *conf.env.FLAGS_name* variables.
248 :type uselib_store: string
249 :param modversion: if provided, return the version of the given module and define *name*\_VERSION
250 :type modversion: string
251 :param args: arguments to give to *package* when retrieving flags
252 :type args: list of string
253 :param variables: return the values of particular variables
254 :type variables: list of string
255 :param define_variable: additional variables to define (also in conf.env.PKG_CONFIG_DEFINES)
256 :type define_variable: dict(string: string)
257 """
258
259 # pkg-config version
260 if 'atleast_pkgconfig_version' in kw:
261 cmd = [kw['path'], '--atleast-pkgconfig-version=%s' % kw['atleast_pkgconfig_version']]
262 self.cmd_and_log(cmd)
263 if not 'okmsg' in kw:
264 kw['okmsg'] = 'yes'
265 return
266
267 # checking for the version of a module
268 for x in cfg_ver:
269 y = x.replace('-', '_')
270 if y in kw:
271 self.cmd_and_log([kw['path'], '--%s=%s' % (x, kw[y]), kw['package']])
272 if not 'okmsg' in kw:
273 kw['okmsg'] = 'yes'
274 self.define(self.have_define(kw.get('uselib_store', kw['package'])), 1, 0)
275 break
276
277 # retrieving the version of a module
278 if 'modversion' in kw:
279 version = self.cmd_and_log([kw['path'], '--modversion', kw['modversion']]).strip()
280 self.define('%s_VERSION' % Utils.quote_define_name(kw.get('uselib_store', kw['modversion'])), version)
281 return version
282
283 lst = [kw['path']]
284
285 defi = kw.get('define_variable', None)
286 if not defi:
287 defi = self.env.PKG_CONFIG_DEFINES or {}
288 for key, val in defi.items():
289 lst.append('--define-variable=%s=%s' % (key, val))
290
291 if kw['package']:
292 lst.extend(Utils.to_list(kw['package']))
293
294 # retrieving variables of a module
295 if 'variables' in kw:
296 env = kw.get('env', self.env)
297 uselib = kw.get('uselib_store', kw['package'].upper())
298 vars = Utils.to_list(kw['variables'])
299 for v in vars:
300 val = self.cmd_and_log(lst + ['--variable=' + v]).strip()
301 var = '%s_%s' % (uselib, v)
302 env[var] = val
303 if not 'okmsg' in kw:
304 kw['okmsg'] = 'yes'
305 return
306
307 static = False
308 if 'args' in kw:
309 args = Utils.to_list(kw['args'])
310 if '--static' in args or '--static-libs' in args:
311 static = True
312 lst += args
313 # so we assume the command-line will output flags to be parsed afterwards
314 ret = self.cmd_and_log(lst)
315 if not 'okmsg' in kw:
316 kw['okmsg'] = 'yes'
317
318 self.define(self.have_define(kw.get('uselib_store', kw['package'])), 1, 0)
319 self.parse_flags(ret, kw.get('uselib_store', kw['package'].upper()), kw.get('env', self.env), force_static=static)
320 return ret
321
322 @conf
323 def check_cfg(self, *k, **kw):
324 """
325 Check for configuration flags using a **-config**-like program (pkg-config, sdl-config, etc).
326 Encapsulate the calls to :py:func:`waflib.Tools.c_config.validate_cfg` and :py:func:`waflib.Tools.c_config.exec_cfg`
327
328 A few examples::
329
330 def configure(conf):
331 conf.load('compiler_c')
332 conf.check_cfg(package='glib-2.0', args='--libs --cflags')
333 conf.check_cfg(package='glib-2.0', uselib_store='GLIB', atleast_version='2.10.0',
334 args='--cflags --libs')
335 conf.check_cfg(package='pango')
336 conf.check_cfg(package='pango', uselib_store='MYPANGO', args=['--cflags', '--libs'])
337 conf.check_cfg(package='pango',
338 args=['pango >= 0.1.0', 'pango < 9.9.9', '--cflags', '--libs'],
339 msg="Checking for 'pango 0.1.0'")
340 conf.check_cfg(path='sdl-config', args='--cflags --libs', package='', uselib_store='SDL')
341 conf.check_cfg(path='mpicc', args='--showme:compile --showme:link',
342 package='', uselib_store='OPEN_MPI', mandatory=False)
343
344 """
345 if k:
346 lst = k[0].split()
347 kw['package'] = lst[0]
348 kw['args'] = ' '.join(lst[1:])
349
350 self.validate_cfg(kw)
351 if 'msg' in kw:
352 self.start_msg(kw['msg'])
353 ret = None
354 try:
355 ret = self.exec_cfg(kw)
356 except self.errors.WafError as e:
357 if 'errmsg' in kw:
358 self.end_msg(kw['errmsg'], 'YELLOW')
359 if Logs.verbose > 1:
360 raise
361 else:
362 self.fatal('The configuration failed')
363 else:
364 kw['success'] = ret
365 if 'okmsg' in kw:
366 self.end_msg(self.ret_msg(kw['okmsg'], kw))
367
368 return ret
369
370 @conf
371 def validate_c(self, kw):
372 """
373 pre-check the parameters that will be given to run_c_code
374
375 :param env: an optional environment (modified -> provide a copy)
376 :type env: :py:class:`waflib.ConfigSet.ConfigSet`
377 :param compiler: c or cxx (tries to guess what is best)
378 :type compiler: string
379 :param type: cprogram, cshlib, cstlib - not required if *features are given directly*
380 :type type: binary to create
381 :param feature: desired features for the task generator that will execute the test, for example ``cxx cxxstlib``
382 :type feature: list of string
383 :param fragment: provide a piece of code for the test (default is to let the system create one)
384 :type fragment: string
385 :param uselib_store: define variables after the test is executed (IMPORTANT!)
386 :type uselib_store: string
387 :param use: parameters to use for building (just like the normal *use* keyword)
388 :type use: list of string
389 :param define_name: define to set when the check is over
390 :type define_name: string
391 :param execute: execute the resulting binary
392 :type execute: bool
393 :param define_ret: if execute is set to True, use the execution output in both the define and the return value
394 :type define_ret: bool
395 :param header_name: check for a particular header
396 :type header_name: string
397 :param auto_add_header_name: if header_name was set, add the headers in env.INCKEYS so the next tests will include these headers
398 :type auto_add_header_name: bool
399 """
400
401 if not 'env' in kw:
402 kw['env'] = self.env.derive()
403 env = kw['env']
404
405 if not 'compiler' in kw and not 'features' in kw:
406 kw['compiler'] = 'c'
407 if env['CXX_NAME'] and Task.classes.get('cxx', None):
408 kw['compiler'] = 'cxx'
409 if not self.env['CXX']:
410 self.fatal('a c++ compiler is required')
411 else:
412 if not self.env['CC']:
413 self.fatal('a c compiler is required')
414
415 if not 'compile_mode' in kw:
416 kw['compile_mode'] = 'c'
417 if 'cxx' in Utils.to_list(kw.get('features',[])) or kw.get('compiler', '') == 'cxx':
418 kw['compile_mode'] = 'cxx'
419
420 if not 'type' in kw:
421 kw['type'] = 'cprogram'
422
423 if not 'features' in kw:
424 kw['features'] = [kw['compile_mode'], kw['type']] # "cprogram c"
425 else:
426 kw['features'] = Utils.to_list(kw['features'])
427
428 if not 'compile_filename' in kw:
429 kw['compile_filename'] = 'test.c' + ((kw['compile_mode'] == 'cxx') and 'pp' or '')
430
431
432 def to_header(dct):
433 if 'header_name' in dct:
434 dct = Utils.to_list(dct['header_name'])
435 return ''.join(['#include <%s>\n' % x for x in dct])
436 return ''
437
438 #OSX
439 if 'framework_name' in kw:
440 fwkname = kw['framework_name']
441 if not 'uselib_store' in kw:
442 kw['uselib_store'] = fwkname.upper()
443
444 if not kw.get('no_header', False):
445 if not 'header_name' in kw:
446 kw['header_name'] = []
447 fwk = '%s/%s.h' % (fwkname, fwkname)
448 if kw.get('remove_dot_h', None):
449 fwk = fwk[:-2]
450 kw['header_name'] = Utils.to_list(kw['header_name']) + [fwk]
451
452 kw['msg'] = 'Checking for framework %s' % fwkname
453 kw['framework'] = fwkname
454 #kw['frameworkpath'] = set it yourself
455
456 if 'function_name' in kw:
457 fu = kw['function_name']
458 if not 'msg' in kw:
459 kw['msg'] = 'Checking for function %s' % fu
460 kw['code'] = to_header(kw) + SNIP_FUNCTION % fu
461 if not 'uselib_store' in kw:
462 kw['uselib_store'] = fu.upper()
463 if not 'define_name' in kw:
464 kw['define_name'] = self.have_define(fu)
465
466 elif 'type_name' in kw:
467 tu = kw['type_name']
468 if not 'header_name' in kw:
469 kw['header_name'] = 'stdint.h'
470 if 'field_name' in kw:
471 field = kw['field_name']
472 kw['code'] = to_header(kw) + SNIP_FIELD % {'type_name' : tu, 'field_name' : field}
473 if not 'msg' in kw:
474 kw['msg'] = 'Checking for field %s in %s' % (field, tu)
475 if not 'define_name' in kw:
476 kw['define_name'] = self.have_define((tu + '_' + field).upper())
477 else:
478 kw['code'] = to_header(kw) + SNIP_TYPE % {'type_name' : tu}
479 if not 'msg' in kw:
480 kw['msg'] = 'Checking for type %s' % tu
481 if not 'define_name' in kw:
482 kw['define_name'] = self.have_define(tu.upper())
483
484 elif 'header_name' in kw:
485 if not 'msg' in kw:
486 kw['msg'] = 'Checking for header %s' % kw['header_name']
487
488 l = Utils.to_list(kw['header_name'])
489 assert len(l)>0, 'list of headers in header_name is empty'
490
491 kw['code'] = to_header(kw) + SNIP_EMPTY_PROGRAM
492
493 if not 'uselib_store' in kw:
494 kw['uselib_store'] = l[0].upper()
495
496 if not 'define_name' in kw:
497 kw['define_name'] = self.have_define(l[0])
498
499 if 'lib' in kw:
500 if not 'msg' in kw:
501 kw['msg'] = 'Checking for library %s' % kw['lib']
502 if not 'uselib_store' in kw:
503 kw['uselib_store'] = kw['lib'].upper()
504
505 if 'stlib' in kw:
506 if not 'msg' in kw:
507 kw['msg'] = 'Checking for static library %s' % kw['stlib']
508 if not 'uselib_store' in kw:
509 kw['uselib_store'] = kw['stlib'].upper()
510
511 if 'fragment' in kw:
512 # an additional code fragment may be provided to replace the predefined code
513 # in custom headers
514 kw['code'] = kw['fragment']
515 if not 'msg' in kw:
516 kw['msg'] = 'Checking for code snippet'
517 if not 'errmsg' in kw:
518 kw['errmsg'] = 'no'
519
520 for (flagsname,flagstype) in [('cxxflags','compiler'), ('cflags','compiler'), ('linkflags','linker')]:
521 if flagsname in kw:
522 if not 'msg' in kw:
523 kw['msg'] = 'Checking for %s flags %s' % (flagstype, kw[flagsname])
524 if not 'errmsg' in kw:
525 kw['errmsg'] = 'no'
526
527 if not 'execute' in kw:
528 kw['execute'] = False
529 if kw['execute']:
530 kw['features'].append('test_exec')
531
532 if not 'errmsg' in kw:
533 kw['errmsg'] = 'not found'
534
535 if not 'okmsg' in kw:
536 kw['okmsg'] = 'yes'
537
538 if not 'code' in kw:
539 kw['code'] = SNIP_EMPTY_PROGRAM
540
541 # if there are headers to append automatically to the next tests
542 if self.env[INCKEYS]:
543 kw['code'] = '\n'.join(['#include <%s>' % x for x in self.env[INCKEYS]]) + '\n' + kw['code']
544
545 if not kw.get('success'): kw['success'] = None
546
547 if 'define_name' in kw:
548 self.undefine(kw['define_name'])
549
550 assert 'msg' in kw, 'invalid parameters, read http://freehackers.org/~tnagy/wafbook/single.html#config_helpers_c'
551
552 @conf
553 def post_check(self, *k, **kw):
554 "Set the variables after a test executed in :py:func:`waflib.Tools.c_config.check` was run successfully"
555
556 is_success = 0
557 if kw['execute']:
558 if kw['success'] is not None:
559 if kw.get('define_ret', False):
560 is_success = kw['success']
561 else:
562 is_success = (kw['success'] == 0)
563 else:
564 is_success = (kw['success'] == 0)
565
566 if 'define_name' in kw:
567 # TODO simplify?
568 if 'header_name' in kw or 'function_name' in kw or 'type_name' in kw or 'fragment' in kw:
569 nm = kw['define_name']
570 if kw['execute'] and kw.get('define_ret', None) and isinstance(is_success, str):
571 self.define(kw['define_name'], is_success, quote=kw.get('quote', 1))
572 else:
573 self.define_cond(kw['define_name'], is_success)
574 else:
575 self.define_cond(kw['define_name'], is_success)
576
577 if 'header_name' in kw:
578 if kw.get('auto_add_header_name', False):
579 self.env.append_value(INCKEYS, Utils.to_list(kw['header_name']))
580
581 if is_success and 'uselib_store' in kw:
582 from waflib.Tools import ccroot
583
584 # TODO see get_uselib_vars from ccroot.py
585 _vars = set([])
586 for x in kw['features']:
587 if x in ccroot.USELIB_VARS:
588 _vars |= ccroot.USELIB_VARS[x]
589
590 for k in _vars:
591 lk = k.lower()
592 if k == 'INCLUDES': lk = 'includes'
593 if k == 'DEFINES': lk = 'defines'
594 if lk in kw:
595 val = kw[lk]
596 # remove trailing slash
597 if isinstance(val, str):
598 val = val.rstrip(os.path.sep)
599 self.env.append_unique(k + '_' + kw['uselib_store'], val)
600 return is_success
601
602 @conf
603 def check(self, *k, **kw):
604 """
605 Perform a configuration test by calling :py:func:`waflib.Tools.c_config.run_c_code`.
606 For the complete list of parameters, see :py:func:`waflib.Tools.c_config.validate_c`.
607 To force a specific compiler, prefer the methods :py:func:`waflib.Tools.c_config.check_cxx` or :py:func:`waflib.Tools.c_config.check_cc`
608 """
609 self.validate_c(kw)
610 self.start_msg(kw['msg'])
611 ret = None
612 try:
613 ret = self.run_c_code(*k, **kw)
614 except self.errors.ConfigurationError as e:
615 self.end_msg(kw['errmsg'], 'YELLOW')
616 if Logs.verbose > 1:
617 raise
618 else:
619 self.fatal('The configuration failed')
620 else:
621 kw['success'] = ret
622 self.end_msg(self.ret_msg(kw['okmsg'], kw))
623
624 ret = self.post_check(*k, **kw)
625 if not ret:
626 self.fatal('The configuration failed %r' % ret)
627 return ret
628
629 class test_exec(Task.Task):
630 """
631 A task for executing a programs after they are built. See :py:func:`waflib.Tools.c_config.test_exec_fun`.
632 """
633 color = 'PINK'
634 def run(self):
635 if getattr(self.generator, 'rpath', None):
636 if getattr(self.generator, 'define_ret', False):
637 self.generator.bld.retval = self.generator.bld.cmd_and_log([self.inputs[0].abspath()])
638 else:
639 self.generator.bld.retval = self.generator.bld.exec_command([self.inputs[0].abspath()])
640 else:
641 env = self.env.env or {}
642 env.update(dict(os.environ))
643 for var in ('LD_LIBRARY_PATH', 'DYLD_LIBRARY_PATH', 'PATH'):
644 env[var] = self.inputs[0].parent.abspath() + os.path.pathsep + env.get(var, '')
645 if getattr(self.generator, 'define_ret', False):
646 self.generator.bld.retval = self.generator.bld.cmd_and_log([self.inputs[0].abspath()], env=env)
647 else:
648 self.generator.bld.retval = self.generator.bld.exec_command([self.inputs[0].abspath()], env=env)
649
650 @feature('test_exec')
651 @after_method('apply_link')
652 def test_exec_fun(self):
653 """
654 The feature **test_exec** is used to create a task that will to execute the binary
655 created (link task output) during the build. The exit status will be set
656 on the build context, so only one program may have the feature *test_exec*.
657 This is used by configuration tests::
658
659 def configure(conf):
660 conf.check(execute=True)
661 """
662 self.create_task('test_exec', self.link_task.outputs[0])
663
664 CACHE_RESULTS = 1
665 COMPILE_ERRORS = 2
666
667 @conf
668 def run_c_code(self, *k, **kw):
669 """
670 Create a temporary build context to execute a build. A reference to that build
671 context is kept on self.test_bld for debugging purposes, and you should not rely
672 on it too much (read the note on the cache below).
673 The parameters given in the arguments to this function are passed as arguments for
674 a single task generator created in the build. Only three parameters are obligatory:
675
676 :param features: features to pass to a task generator created in the build
677 :type features: list of string
678 :param compile_filename: file to create for the compilation (default: *test.c*)
679 :type compile_filename: string
680 :param code: code to write in the filename to compile
681 :type code: string
682
683 Though this function returns *0* by default, the build may set an attribute named *retval* on the
684 build context object to return a particular value. See :py:func:`waflib.Tools.c_config.test_exec_fun` for example.
685
686 This function also provides a limited cache. To use it, provide the following option::
687
688 def options(opt):
689 opt.add_option('--confcache', dest='confcache', default=0,
690 action='count', help='Use a configuration cache')
691
692 And execute the configuration with the following command-line::
693
694 $ waf configure --confcache
695
696 """
697
698 lst = [str(v) for (p, v) in kw.items() if p != 'env']
699 h = Utils.h_list(lst)
700 dir = self.bldnode.abspath() + os.sep + (not Utils.is_win32 and '.' or '') + 'conf_check_' + Utils.to_hex(h)
701
702 try:
703 os.makedirs(dir)
704 except:
705 pass
706
707 try:
708 os.stat(dir)
709 except:
710 self.fatal('cannot use the configuration test folder %r' % dir)
711
712 cachemode = getattr(Options.options, 'confcache', None)
713 if cachemode == CACHE_RESULTS:
714 try:
715 proj = ConfigSet.ConfigSet(os.path.join(dir, 'cache_run_c_code'))
716 ret = proj['cache_run_c_code']
717 except:
718 pass
719 else:
720 if isinstance(ret, str) and ret.startswith('Test does not build'):
721 self.fatal(ret)
722 return ret
723
724 bdir = os.path.join(dir, 'testbuild')
725
726 if not os.path.exists(bdir):
727 os.makedirs(bdir)
728
729 self.test_bld = bld = Build.BuildContext(top_dir=dir, out_dir=bdir)
730 bld.init_dirs()
731 bld.progress_bar = 0
732 bld.targets = '*'
733
734 if kw['compile_filename']:
735 node = bld.srcnode.make_node(kw['compile_filename'])
736 node.write(kw['code'])
737
738 bld.logger = self.logger
739 bld.all_envs.update(self.all_envs) # not really necessary
740 bld.env = kw['env']
741
742 o = bld(features=kw['features'], source=kw['compile_filename'], target='testprog')
743
744 for k, v in kw.items():
745 setattr(o, k, v)
746
747 self.to_log("==>\n%s\n<==" % kw['code'])
748
749 # compile the program
750 bld.targets = '*'
751
752 ret = -1
753 try:
754 try:
755 bld.compile()
756 except Errors.WafError:
757 ret = 'Test does not build: %s' % Utils.ex_stack()
758 self.fatal(ret)
759 else:
760 ret = getattr(bld, 'retval', 0)
761 finally:
762 # cache the results each time
763 proj = ConfigSet.ConfigSet()
764 proj['cache_run_c_code'] = ret
765 proj.store(os.path.join(dir, 'cache_run_c_code'))
766
767 return ret
768
769 @conf
770 def check_cxx(self, *k, **kw):
771 """
772 Same as :py:func:`waflib.Tools.c_config.check` but default to the *c++* programming language
773 """
774 kw['compiler'] = 'cxx'
775 return self.check(*k, **kw)
776
777 @conf
778 def check_cc(self, *k, **kw):
779 """
780 Same as :py:func:`waflib.Tools.c_config.check` but default to the *c* programming language
781 """
782 kw['compiler'] = 'c'
783 return self.check(*k, **kw)
784
785 @conf
786 def define(self, key, val, quote=True):
787 """
788 Store a single define and its state into conf.env.DEFINES
789
790 :param key: define name
791 :type key: string
792 :param val: value
793 :type val: int or string
794 :param quote: enclose strings in quotes (yes by default)
795 :type quote: bool
796 """
797 assert key and isinstance(key, str)
798
799 if isinstance(val, int) or isinstance(val, float):
800 s = '%s=%s'
801 else:
802 s = quote and '%s="%s"' or '%s=%s'
803 app = s % (key, str(val))
804
805 ban = key + '='
806 lst = self.env['DEFINES']
807 for x in lst:
808 if x.startswith(ban):
809 lst[lst.index(x)] = app
810 break
811 else:
812 self.env.append_value('DEFINES', app)
813
814 self.env.append_unique(DEFKEYS, key)
815
816 @conf
817 def undefine(self, key):
818 """
819 Remove a define from conf.env.DEFINES
820
821 :param key: define name
822 :type key: string
823 """
824 assert key and isinstance(key, str)
825
826 ban = key + '='
827 lst = [x for x in self.env['DEFINES'] if not x.startswith(ban)]
828 self.env['DEFINES'] = lst
829 self.env.append_unique(DEFKEYS, key)
830
831 @conf
832 def define_cond(self, key, val):
833 """
834 Conditionally define a name::
835
836 def configure(conf):
837 conf.define_cond('A', True)
838 # equivalent to:
839 # if val: conf.define('A', 1)
840 # else: conf.undefine('A')
841
842 :param key: define name
843 :type key: string
844 :param val: value
845 :type val: int or string
846 """
847 assert key and isinstance(key, str)
848
849 if val:
850 self.define(key, 1)
851 else:
852 self.undefine(key)
853
854 @conf
855 def is_defined(self, key):
856 """
857 :param key: define name
858 :type key: string
859 :return: True if the define is set
860 :rtype: bool
861 """
862 assert key and isinstance(key, str)
863
864 ban = key + '='
865 for x in self.env['DEFINES']:
866 if x.startswith(ban):
867 return True
868 return False
869
870 @conf
871 def get_define(self, key):
872 """
873 :param key: define name
874 :type key: string
875 :return: the value of a previously stored define or None if it is not set
876 """
877 assert key and isinstance(key, str)
878
879 ban = key + '='
880 for x in self.env['DEFINES']:
881 if x.startswith(ban):
882 return x[len(ban):]
883 return None
884
885 @conf
886 def have_define(self, key):
887 """
888 :param key: define name
889 :type key: string
890 :return: the input key prefixed by *HAVE_* and substitute any invalid characters.
891 :rtype: string
892 """
893 return self.__dict__.get('HAVE_PAT', 'HAVE_%s') % Utils.quote_define_name(key)
894
895 @conf
896 def write_config_header(self, configfile='', guard='', top=False, env=None, defines=True, headers=False, remove=True):
897 """
898 Write a configuration header containing defines and includes::
899
900 def configure(cnf):
901 cnf.define('A', 1)
902 cnf.write_config_header('config.h')
903
904 :param configfile: relative path to the file to create
905 :type configfile: string
906 :param env: config set to read the definitions from (default is conf.env)
907 :type env: :py:class:`waflib.ConfigSet.ConfigSet`
908 :param top: write the configuration header from the build directory (default is from the current path)
909 :type top: bool
910 :param defines: add the defines (yes by default)
911 :type defines: bool
912 :param headers: add #include in the file
913 :type headers: bool
914 :param remove: remove the defines after they are added (yes by default)
915 :type remove: bool
916 """
917 if not configfile: configfile = WAF_CONFIG_H
918 waf_guard = guard or '_%s_WAF' % Utils.quote_define_name(configfile)
919
920 node = top and self.bldnode or self.path.get_bld()
921 node = node.make_node(configfile)
922 node.parent.mkdir()
923
924 lst = ['/* WARNING! All changes made to this file will be lost! */\n']
925 lst.append('#ifndef %s\n#define %s\n' % (waf_guard, waf_guard))
926 lst.append(self.get_config_header(defines, headers))
927 lst.append('\n#endif /* %s */\n' % waf_guard)
928
929 node.write('\n'.join(lst))
930
931 env = env or self.env
932
933 # config files are not removed on "waf clean"
934 env.append_unique(Build.CFG_FILES, [node.abspath()])
935
936 if remove:
937 for key in self.env[DEFKEYS]:
938 self.undefine(key)
939 self.env[DEFKEYS] = []
940
941 @conf
942 def get_config_header(self, defines=True, headers=False):
943 """
944 Create the contents of a ``config.h`` file from the defines and includes
945 set in conf.env.define_key / conf.env.include_key. No include guards are added.
946
947 :param defines: write the defines values
948 :type defines: bool
949 :param headers: write the headers
950 :type headers: bool
951 :return: the contents of a ``config.h`` file
952 :rtype: string
953 """
954 lst = []
955 if headers:
956 for x in self.env[INCKEYS]:
957 lst.append('#include <%s>' % x)
958
959 if defines:
960 for x in self.env[DEFKEYS]:
961 if self.is_defined(x):
962 val = self.get_define(x)
963 lst.append('#define %s %s' % (x, val))
964 else:
965 lst.append('/* #undef %s */' % x)
966 return "\n".join(lst)
967
968 @conf
969 def cc_add_flags(conf):
970 """
971 Read the CFLAGS/CPPFLAGS from os.environ and add to conf.env.CFLAGS
972 """
973 conf.add_os_flags('CPPFLAGS', 'CFLAGS')
974 conf.add_os_flags('CFLAGS')
975
976 @conf
977 def cxx_add_flags(conf):
978 """
979 Read the CXXFLAGS/CPPFLAGS and add to conf.env.CXXFLAGS
980 """
981 conf.add_os_flags('CPPFLAGS', 'CXXFLAGS')
982 conf.add_os_flags('CXXFLAGS')
983
984 @conf
985 def link_add_flags(conf):
986 """
987 Read the LINKFLAGS/LDFLAGS and add to conf.env.LDFLAGS
988 """
989 conf.add_os_flags('LINKFLAGS')
990 conf.add_os_flags('LDFLAGS', 'LINKFLAGS')
991
992 @conf
993 def cc_load_tools(conf):
994 """
995 Load the c tool
996 """
997 if not conf.env.DEST_OS:
998 conf.env.DEST_OS = Utils.unversioned_sys_platform()
999 conf.load('c')
1000
1001 @conf
1002 def cxx_load_tools(conf):
1003 """
1004 Load the cxx tool
1005 """
1006 if not conf.env.DEST_OS:
1007 conf.env.DEST_OS = Utils.unversioned_sys_platform()
1008 conf.load('cxx')
1009
1010 @conf
1011 def get_cc_version(conf, cc, gcc=False, icc=False):
1012 """
1013 Run the preprocessor to determine the compiler version
1014
1015 The variables CC_VERSION, DEST_OS, DEST_BINFMT and DEST_CPU will be set in *conf.env*
1016 """
1017 cmd = cc + ['-dM', '-E', '-']
1018 env = conf.env.env or None
1019 try:
1020 p = Utils.subprocess.Popen(cmd, stdin=Utils.subprocess.PIPE, stdout=Utils.subprocess.PIPE, stderr=Utils.subprocess.PIPE, env=env)
1021 p.stdin.write('\n'.encode())
1022 out = p.communicate()[0]
1023 except:
1024 conf.fatal('Could not determine the compiler version %r' % cmd)
1025
1026 if not isinstance(out, str):
1027 out = out.decode(sys.stdout.encoding)
1028
1029 if gcc:
1030 if out.find('__INTEL_COMPILER') >= 0:
1031 conf.fatal('The intel compiler pretends to be gcc')
1032 if out.find('__GNUC__') < 0:
1033 conf.fatal('Could not determine the compiler type')
1034
1035 if icc and out.find('__INTEL_COMPILER') < 0:
1036 conf.fatal('Not icc/icpc')
1037
1038 k = {}
1039 if icc or gcc:
1040 out = out.split('\n')
1041 for line in out:
1042 lst = shlex.split(line)
1043 if len(lst)>2:
1044 key = lst[1]
1045 val = lst[2]
1046 k[key] = val
1047
1048 def isD(var):
1049 return var in k
1050
1051 def isT(var):
1052 return var in k and k[var] != '0'
1053
1054 # Some documentation is available at http://predef.sourceforge.net
1055 # The names given to DEST_OS must match what Utils.unversioned_sys_platform() returns.
1056 if not conf.env.DEST_OS:
1057 conf.env.DEST_OS = ''
1058 for i in MACRO_TO_DESTOS:
1059 if isD(i):
1060 conf.env.DEST_OS = MACRO_TO_DESTOS[i]
1061 break
1062 else:
1063 if isD('__APPLE__') and isD('__MACH__'):
1064 conf.env.DEST_OS = 'darwin'
1065 elif isD('__unix__'): # unix must be tested last as it's a generic fallback
1066 conf.env.DEST_OS = 'generic'
1067
1068 if isD('__ELF__'):
1069 conf.env.DEST_BINFMT = 'elf'
1070 elif isD('__WINNT__') or isD('__CYGWIN__'):
1071 conf.env.DEST_BINFMT = 'pe'
1072 conf.env.LIBDIR = conf.env['PREFIX'] + '/bin'
1073 elif isD('__APPLE__'):
1074 conf.env.DEST_BINFMT = 'mac-o'
1075
1076 if not conf.env.DEST_BINFMT:
1077 # Infer the binary format from the os name.
1078 conf.env.DEST_BINFMT = Utils.destos_to_binfmt(conf.env.DEST_OS)
1079
1080 for i in MACRO_TO_DEST_CPU:
1081 if isD(i):
1082 conf.env.DEST_CPU = MACRO_TO_DEST_CPU[i]
1083 break
1084
1085 Logs.debug('ccroot: dest platform: ' + ' '.join([conf.env[x] or '?' for x in ('DEST_OS', 'DEST_BINFMT', 'DEST_CPU')]))
1086 if icc:
1087 ver = k['__INTEL_COMPILER']
1088 conf.env['CC_VERSION'] = (ver[:-2], ver[-2], ver[-1])
1089 else:
1090 conf.env['CC_VERSION'] = (k['__GNUC__'], k['__GNUC_MINOR__'], k['__GNUC_PATCHLEVEL__'])
1091 return k
1092
1093 @conf
1094 def get_xlc_version(conf, cc):
1095 """Get the compiler version"""
1096
1097 version_re = re.compile(r"IBM XL C/C\+\+.*, V(?P<major>\d*)\.(?P<minor>\d*)", re.I).search
1098 cmd = cc + ['-qversion']
1099
1100 try:
1101 out, err = conf.cmd_and_log(cmd, output=0)
1102 except Errors.WafError:
1103 conf.fatal('Could not find xlc %r' % cmd)
1104 if out: match = version_re(out)
1105 else: match = version_re(err)
1106 if not match:
1107 conf.fatal('Could not determine the XLC version.')
1108 k = match.groupdict()
1109 conf.env['CC_VERSION'] = (k['major'], k['minor'])
1110
1111 # ============ the --as-needed flag should added during the configuration, not at runtime =========
1112
1113 @conf
1114 def add_as_needed(self):
1115 """
1116 Add ``--as-needed`` to the *LINKFLAGS*
1117 """
1118 if self.env.DEST_BINFMT == 'elf' and 'gcc' in (self.env.CXX_NAME, self.env.CC_NAME):
1119 self.env.append_unique('LINKFLAGS', '--as-needed')
1120
1121 # ============ parallel configuration
1122
1123 class cfgtask(Task.TaskBase):
1124 """
1125 A task that executes configuration tests
1126 make sure that the checks write to conf.env in a thread-safe manner
1127
1128 for the moment it only executes conf.check
1129 """
1130 def display(self):
1131 return ''
1132
1133 def runnable_status(self):
1134 return Task.RUN_ME
1135
1136 def run(self):
1137 conf = self.conf
1138 bld = Build.BuildContext(top_dir=conf.srcnode.abspath(), out_dir=conf.bldnode.abspath())
1139 bld.env = conf.env
1140 bld.init_dirs()
1141 bld.in_msg = 1 # suppress top-level start_msg
1142 bld.logger = self.logger
1143 try:
1144 bld.check(**self.args)
1145 except:
1146 return 1
1147
1148 @conf
1149 def multicheck(self, *k, **kw):
1150 """
1151 Use tuples to perform parallel configuration tests
1152 """
1153 self.start_msg(kw.get('msg', 'Executing %d configuration tests' % len(k)))
1154
1155 class par(object):
1156 def __init__(self):
1157 self.keep = False
1158 self.cache_global = Options.cache_global
1159 self.nocache = Options.options.nocache
1160 self.returned_tasks = []
1161 def total(self):
1162 return len(tasks)
1163 def to_log(self, *k, **kw):
1164 return
1165
1166 bld = par()
1167 tasks = []
1168 for dct in k:
1169 x = cfgtask(bld=bld)
1170 tasks.append(x)
1171 x.args = dct
1172 x.bld = bld
1173 x.conf = self
1174 x.args = dct
1175
1176 # bind a logger that will keep the info in memory
1177 x.logger = Logs.make_mem_logger(str(id(x)), self.logger)
1178
1179 def it():
1180 yield tasks
1181 while 1:
1182 yield []
1183 p = Runner.Parallel(bld, Options.options.jobs)
1184 p.biter = it()
1185 p.start()
1186
1187 # flush the logs in order into the config.log
1188 for x in tasks:
1189 x.logger.memhandler.flush()
1190
1191 for x in tasks:
1192 if x.hasrun != Task.SUCCESS:
1193 self.end_msg(kw.get('errmsg', 'no'), color='YELLOW')
1194 self.fatal(kw.get('fatalmsg', None) or 'One of the tests has failed, see the config.log for more information')
1195
1196 self.end_msg('ok')
1197
0 #!/usr/bin/env python
1 # encoding: utf-8
2 # Thomas Nagy 2008-2010
3
4 """
5 MacOSX related tools
6 """
7
8 import os, shutil, sys, platform
9 from waflib import TaskGen, Task, Build, Options, Utils, Errors
10 from waflib.TaskGen import taskgen_method, feature, after_method, before_method
11
12 app_info = '''
13 <?xml version="1.0" encoding="UTF-8"?>
14 <!DOCTYPE plist SYSTEM "file://localhost/System/Library/DTDs/PropertyList.dtd">
15 <plist version="0.9">
16 <dict>
17 <key>CFBundlePackageType</key>
18 <string>APPL</string>
19 <key>CFBundleGetInfoString</key>
20 <string>Created by Waf</string>
21 <key>CFBundleSignature</key>
22 <string>????</string>
23 <key>NOTE</key>
24 <string>THIS IS A GENERATED FILE, DO NOT MODIFY</string>
25 <key>CFBundleExecutable</key>
26 <string>%s</string>
27 </dict>
28 </plist>
29 '''
30 """
31 plist template
32 """
33
34 @feature('c', 'cxx')
35 def set_macosx_deployment_target(self):
36 """
37 see WAF issue 285 and also and also http://trac.macports.org/ticket/17059
38 """
39 if self.env['MACOSX_DEPLOYMENT_TARGET']:
40 os.environ['MACOSX_DEPLOYMENT_TARGET'] = self.env['MACOSX_DEPLOYMENT_TARGET']
41 elif 'MACOSX_DEPLOYMENT_TARGET' not in os.environ:
42 if Utils.unversioned_sys_platform() == 'darwin':
43 os.environ['MACOSX_DEPLOYMENT_TARGET'] = '.'.join(platform.mac_ver()[0].split('.')[:2])
44
45 @taskgen_method
46 def create_bundle_dirs(self, name, out):
47 """
48 Create bundle folders, used by :py:func:`create_task_macplist` and :py:func:`create_task_macapp`
49 """
50 bld = self.bld
51 dir = out.parent.find_or_declare(name)
52 dir.mkdir()
53 macos = dir.find_or_declare(['Contents', 'MacOS'])
54 macos.mkdir()
55 return dir
56
57 def bundle_name_for_output(out):
58 name = out.name
59 k = name.rfind('.')
60 if k >= 0:
61 name = name[:k] + '.app'
62 else:
63 name = name + '.app'
64 return name
65
66 @feature('cprogram', 'cxxprogram')
67 @after_method('apply_link')
68 def create_task_macapp(self):
69 """
70 To compile an executable into a Mac application (a .app), set its *mac_app* attribute::
71
72 def build(bld):
73 bld.shlib(source='a.c', target='foo', mac_app = True)
74
75 To force *all* executables to be transformed into Mac applications::
76
77 def build(bld):
78 bld.env.MACAPP = True
79 bld.shlib(source='a.c', target='foo')
80 """
81 if self.env['MACAPP'] or getattr(self, 'mac_app', False):
82 out = self.link_task.outputs[0]
83
84 name = bundle_name_for_output(out)
85 dir = self.create_bundle_dirs(name, out)
86
87 n1 = dir.find_or_declare(['Contents', 'MacOS', out.name])
88
89 self.apptask = self.create_task('macapp', self.link_task.outputs, n1)
90 inst_to = getattr(self, 'install_path', '/Applications') + '/%s/Contents/MacOS/' % name
91 self.bld.install_files(inst_to, n1, chmod=Utils.O755)
92
93 if getattr(self, 'mac_resources', None):
94 res_dir = n1.parent.parent.make_node('Resources')
95 inst_to = getattr(self, 'install_path', '/Applications') + '/%s/Resources' % name
96 for x in self.to_list(self.mac_resources):
97 node = self.path.find_node(x)
98 if not node:
99 raise Errors.WafError('Missing mac_resource %r in %r' % (x, self))
100
101 parent = node.parent
102 if os.path.isdir(node.abspath()):
103 nodes = node.ant_glob('**')
104 else:
105 nodes = [node]
106 for node in nodes:
107 rel = node.path_from(parent)
108 tsk = self.create_task('macapp', node, res_dir.make_node(rel))
109 self.bld.install_as(inst_to + '/%s' % rel, node)
110
111 if getattr(self.bld, 'is_install', None):
112 # disable the normal binary installation
113 self.install_task.hasrun = Task.SKIP_ME
114
115 @feature('cprogram', 'cxxprogram')
116 @after_method('apply_link')
117 def create_task_macplist(self):
118 """
119 Create a :py:class:`waflib.Tools.c_osx.macplist` instance.
120 """
121 if self.env['MACAPP'] or getattr(self, 'mac_app', False):
122 out = self.link_task.outputs[0]
123
124 name = bundle_name_for_output(out)
125
126 dir = self.create_bundle_dirs(name, out)
127 n1 = dir.find_or_declare(['Contents', 'Info.plist'])
128 self.plisttask = plisttask = self.create_task('macplist', [], n1)
129
130 if getattr(self, 'mac_plist', False):
131 node = self.path.find_resource(self.mac_plist)
132 if node:
133 plisttask.inputs.append(node)
134 else:
135 plisttask.code = self.mac_plist
136 else:
137 plisttask.code = app_info % self.link_task.outputs[0].name
138
139 inst_to = getattr(self, 'install_path', '/Applications') + '/%s/Contents/' % name
140 self.bld.install_files(inst_to, n1)
141
142 @feature('cshlib', 'cxxshlib')
143 @before_method('apply_link', 'propagate_uselib_vars')
144 def apply_bundle(self):
145 """
146 To make a bundled shared library (a ``.bundle``), set the *mac_bundle* attribute::
147
148 def build(bld):
149 bld.shlib(source='a.c', target='foo', mac_bundle = True)
150
151 To force *all* executables to be transformed into bundles::
152
153 def build(bld):
154 bld.env.MACBUNDLE = True
155 bld.shlib(source='a.c', target='foo')
156 """
157 if self.env['MACBUNDLE'] or getattr(self, 'mac_bundle', False):
158 self.env['LINKFLAGS_cshlib'] = self.env['LINKFLAGS_cxxshlib'] = [] # disable the '-dynamiclib' flag
159 self.env['cshlib_PATTERN'] = self.env['cxxshlib_PATTERN'] = self.env['macbundle_PATTERN']
160 use = self.use = self.to_list(getattr(self, 'use', []))
161 if not 'MACBUNDLE' in use:
162 use.append('MACBUNDLE')
163
164 app_dirs = ['Contents', 'Contents/MacOS', 'Contents/Resources']
165
166 class macapp(Task.Task):
167 """
168 Create mac applications
169 """
170 color = 'PINK'
171 def run(self):
172 self.outputs[0].parent.mkdir()
173 shutil.copy2(self.inputs[0].srcpath(), self.outputs[0].abspath())
174
175 class macplist(Task.Task):
176 """
177 Create plist files
178 """
179 color = 'PINK'
180 ext_in = ['.bin']
181 def run(self):
182 if getattr(self, 'code', None):
183 txt = self.code
184 else:
185 txt = self.inputs[0].read()
186 self.outputs[0].write(txt)
187
0 #!/usr/bin/env python
1 # encoding: utf-8
2 # Thomas Nagy, 2006-2010 (ita)
3
4 """
5 C/C++ preprocessor for finding dependencies
6
7 Reasons for using the Waf preprocessor by default
8
9 #. Some c/c++ extensions (Qt) require a custom preprocessor for obtaining the dependencies (.moc files)
10 #. Not all compilers provide .d files for obtaining the dependencies (portability)
11 #. A naive file scanner will not catch the constructs such as "#include foo()"
12 #. A naive file scanner will catch unnecessary dependencies (change an unused header -> recompile everything)
13
14 Regarding the speed concerns:
15
16 * the preprocessing is performed only when files must be compiled
17 * the macros are evaluated only for #if/#elif/#include
18 * system headers are not scanned by default
19
20 Now if you do not want the Waf preprocessor, the tool +gccdeps* uses the .d files produced
21 during the compilation to track the dependencies (useful when used with the boost libraries).
22 It only works with gcc >= 4.4 though.
23
24 A dumb preprocessor is also available in the tool *c_dumbpreproc*
25 """
26 # TODO: more varargs, pragma once
27
28 import re, sys, os, string, traceback
29 from waflib import Logs, Build, Utils, Errors
30 from waflib.Logs import debug, error
31
32 class PreprocError(Errors.WafError):
33 pass
34
35 POPFILE = '-'
36 "Constant representing a special token used in :py:meth:`waflib.Tools.c_preproc.c_parser.start` iteration to switch to a header read previously"
37
38 recursion_limit = 150
39 "Limit on the amount of files to read in the dependency scanner"
40
41 go_absolute = False
42 "Set to True to track headers on files in /usr/include, else absolute paths are ignored (but it becomes very slow)"
43
44 standard_includes = ['/usr/include']
45 if Utils.is_win32:
46 standard_includes = []
47
48 use_trigraphs = 0
49 """Apply trigraph rules (False by default)"""
50
51 strict_quotes = 0
52 """Reserve the "#include <>" quotes for system includes (do not search for those includes). False by default."""
53
54 g_optrans = {
55 'not':'!',
56 'and':'&&',
57 'bitand':'&',
58 'and_eq':'&=',
59 'or':'||',
60 'bitor':'|',
61 'or_eq':'|=',
62 'xor':'^',
63 'xor_eq':'^=',
64 'compl':'~',
65 }
66 """Operators such as and/or/xor for c++. Set an empty dict to disable."""
67
68 # ignore #warning and #error
69 re_lines = re.compile(
70 '^[ \t]*(#|%:)[ \t]*(ifdef|ifndef|if|else|elif|endif|include|import|define|undef|pragma)[ \t]*(.*)\r*$',
71 re.IGNORECASE | re.MULTILINE)
72 """Match #include lines"""
73
74 re_mac = re.compile("^[a-zA-Z_]\w*")
75 """Match macro definitions"""
76
77 re_fun = re.compile('^[a-zA-Z_][a-zA-Z0-9_]*[(]')
78 """Match macro functions"""
79
80 re_pragma_once = re.compile('^\s*once\s*', re.IGNORECASE)
81 """Match #pragma once statements"""
82
83 re_nl = re.compile('\\\\\r*\n', re.MULTILINE)
84 """Match newlines"""
85
86 re_cpp = re.compile(
87 r"""(/\*[^*]*\*+([^/*][^*]*\*+)*/)|//[^\n]*|("(\\.|[^"\\])*"|'(\\.|[^'\\])*'|.[^/"'\\]*)""",
88 re.MULTILINE)
89 """Filter C/C++ comments"""
90
91 trig_def = [('??'+a, b) for a, b in zip("=-/!'()<>", r'#~\|^[]{}')]
92 """Trigraph definitions"""
93
94 chr_esc = {'0':0, 'a':7, 'b':8, 't':9, 'n':10, 'f':11, 'v':12, 'r':13, '\\':92, "'":39}
95 """Escape characters"""
96
97 NUM = 'i'
98 """Number token"""
99
100 OP = 'O'
101 """Operator token"""
102
103 IDENT = 'T'
104 """Identifier token"""
105
106 STR = 's'
107 """String token"""
108
109 CHAR = 'c'
110 """Character token"""
111
112 tok_types = [NUM, STR, IDENT, OP]
113 """Token types"""
114
115 exp_types = [
116 r"""0[xX](?P<hex>[a-fA-F0-9]+)(?P<qual1>[uUlL]*)|L*?'(?P<char>(\\.|[^\\'])+)'|(?P<n1>\d+)[Ee](?P<exp0>[+-]*?\d+)(?P<float0>[fFlL]*)|(?P<n2>\d*\.\d+)([Ee](?P<exp1>[+-]*?\d+))?(?P<float1>[fFlL]*)|(?P<n4>\d+\.\d*)([Ee](?P<exp2>[+-]*?\d+))?(?P<float2>[fFlL]*)|(?P<oct>0*)(?P<n0>\d+)(?P<qual2>[uUlL]*)""",
117 r'L?"([^"\\]|\\.)*"',
118 r'[a-zA-Z_]\w*',
119 r'%:%:|<<=|>>=|\.\.\.|<<|<%|<:|<=|>>|>=|\+\+|\+=|--|->|-=|\*=|/=|%:|%=|%>|==|&&|&=|\|\||\|=|\^=|:>|!=|##|[\(\)\{\}\[\]<>\?\|\^\*\+&=:!#;,%/\-\?\~\.]',
120 ]
121 """Expression types"""
122
123 re_clexer = re.compile('|'.join(["(?P<%s>%s)" % (name, part) for name, part in zip(tok_types, exp_types)]), re.M)
124 """Match expressions into tokens"""
125
126 accepted = 'a'
127 """Parser state is *accepted*"""
128
129 ignored = 'i'
130 """Parser state is *ignored*, for example preprocessor lines in an #if 0 block"""
131
132 undefined = 'u'
133 """Parser state is *undefined* at the moment"""
134
135 skipped = 's'
136 """Parser state is *skipped*, for example preprocessor lines in a #elif 0 block"""
137
138 def repl(m):
139 """Replace function used with :py:attr:`waflib.Tools.c_preproc.re_cpp`"""
140 s = m.group(1)
141 if s:
142 return ' '
143 return m.group(3) or ''
144
145 def filter_comments(filename):
146 """
147 Filter the comments from a c/h file, and return the preprocessor lines.
148 The regexps :py:attr:`waflib.Tools.c_preproc.re_cpp`, :py:attr:`waflib.Tools.c_preproc.re_nl` and :py:attr:`waflib.Tools.c_preproc.re_lines` are used internally.
149
150 :return: the preprocessor directives as a list of (keyword, line)
151 :rtype: a list of string pairs
152 """
153 # return a list of tuples : keyword, line
154 code = Utils.readf(filename)
155 if use_trigraphs:
156 for (a, b) in trig_def: code = code.split(a).join(b)
157 code = re_nl.sub('', code)
158 code = re_cpp.sub(repl, code)
159 return [(m.group(2), m.group(3)) for m in re.finditer(re_lines, code)]
160
161 prec = {}
162 """
163 Operator precendence rules required for parsing expressions of the form::
164
165 #if 1 && 2 != 0
166 """
167 ops = ['* / %', '+ -', '<< >>', '< <= >= >', '== !=', '& | ^', '&& ||', ',']
168 for x in range(len(ops)):
169 syms = ops[x]
170 for u in syms.split():
171 prec[u] = x
172
173 def trimquotes(s):
174 """
175 Remove the single quotes around an expression::
176
177 trimquotes("'test'") == "test"
178
179 :param s: expression to transform
180 :type s: string
181 :rtype: string
182 """
183 if not s: return ''
184 s = s.rstrip()
185 if s[0] == "'" and s[-1] == "'": return s[1:-1]
186 return s
187
188 def reduce_nums(val_1, val_2, val_op):
189 """
190 Apply arithmetic rules to compute a result
191
192 :param val1: input parameter
193 :type val1: int or string
194 :param val2: input parameter
195 :type val2: int or string
196 :param val_op: C operator in *+*, */*, *-*, etc
197 :type val_op: string
198 :rtype: int
199 """
200 #print val_1, val_2, val_op
201
202 # now perform the operation, make certain a and b are numeric
203 try: a = 0 + val_1
204 except TypeError: a = int(val_1)
205 try: b = 0 + val_2
206 except TypeError: b = int(val_2)
207
208 d = val_op
209 if d == '%': c = a%b
210 elif d=='+': c = a+b
211 elif d=='-': c = a-b
212 elif d=='*': c = a*b
213 elif d=='/': c = a/b
214 elif d=='^': c = a^b
215 elif d=='|': c = a|b
216 elif d=='||': c = int(a or b)
217 elif d=='&': c = a&b
218 elif d=='&&': c = int(a and b)
219 elif d=='==': c = int(a == b)
220 elif d=='!=': c = int(a != b)
221 elif d=='<=': c = int(a <= b)
222 elif d=='<': c = int(a < b)
223 elif d=='>': c = int(a > b)
224 elif d=='>=': c = int(a >= b)
225 elif d=='^': c = int(a^b)
226 elif d=='<<': c = a<<b
227 elif d=='>>': c = a>>b
228 else: c = 0
229 return c
230
231 def get_num(lst):
232 """
233 Try to obtain a number from a list of tokens. The token types are defined in :py:attr:`waflib.Tools.ccroot.tok_types`.
234
235 :param lst: list of preprocessor tokens
236 :type lst: list of tuple (tokentype, value)
237 :return: a pair containing the number and the rest of the list
238 :rtype: tuple(value, list)
239 """
240 if not lst: raise PreprocError("empty list for get_num")
241 (p, v) = lst[0]
242 if p == OP:
243 if v == '(':
244 count_par = 1
245 i = 1
246 while i < len(lst):
247 (p, v) = lst[i]
248
249 if p == OP:
250 if v == ')':
251 count_par -= 1
252 if count_par == 0:
253 break
254 elif v == '(':
255 count_par += 1
256 i += 1
257 else:
258 raise PreprocError("rparen expected %r" % lst)
259
260 (num, _) = get_term(lst[1:i])
261 return (num, lst[i+1:])
262
263 elif v == '+':
264 return get_num(lst[1:])
265 elif v == '-':
266 num, lst = get_num(lst[1:])
267 return (reduce_nums('-1', num, '*'), lst)
268 elif v == '!':
269 num, lst = get_num(lst[1:])
270 return (int(not int(num)), lst)
271 elif v == '~':
272 return (~ int(num), lst)
273 else:
274 raise PreprocError("Invalid op token %r for get_num" % lst)
275 elif p == NUM:
276 return v, lst[1:]
277 elif p == IDENT:
278 # all macros should have been replaced, remaining identifiers eval to 0
279 return 0, lst[1:]
280 else:
281 raise PreprocError("Invalid token %r for get_num" % lst)
282
283 def get_term(lst):
284 """
285 Evaluate an expression recursively, for example::
286
287 1+1+1 -> 2+1 -> 3
288
289 :param lst: list of tokens
290 :type lst: list of tuple(token, value)
291 :return: the value and the remaining tokens
292 :rtype: value, list
293 """
294
295 if not lst: raise PreprocError("empty list for get_term")
296 num, lst = get_num(lst)
297 if not lst:
298 return (num, [])
299 (p, v) = lst[0]
300 if p == OP:
301 if v == '&&' and not num:
302 return (num, [])
303 elif v == '||' and num:
304 return (num, [])
305 elif v == ',':
306 # skip
307 return get_term(lst[1:])
308 elif v == '?':
309 count_par = 0
310 i = 1
311 while i < len(lst):
312 (p, v) = lst[i]
313
314 if p == OP:
315 if v == ')':
316 count_par -= 1
317 elif v == '(':
318 count_par += 1
319 elif v == ':':
320 if count_par == 0:
321 break
322 i += 1
323 else:
324 raise PreprocError("rparen expected %r" % lst)
325
326 if int(num):
327 return get_term(lst[1:i])
328 else:
329 return get_term(lst[i+1:])
330
331 else:
332 num2, lst = get_num(lst[1:])
333
334 if not lst:
335 # no more tokens to process
336 num2 = reduce_nums(num, num2, v)
337 return get_term([(NUM, num2)] + lst)
338
339 # operator precedence
340 p2, v2 = lst[0]
341 if p2 != OP:
342 raise PreprocError("op expected %r" % lst)
343
344 if prec[v2] >= prec[v]:
345 num2 = reduce_nums(num, num2, v)
346 return get_term([(NUM, num2)] + lst)
347 else:
348 num3, lst = get_num(lst[1:])
349 num3 = reduce_nums(num2, num3, v2)
350 return get_term([(NUM, num), (p, v), (NUM, num3)] + lst)
351
352
353 raise PreprocError("cannot reduce %r" % lst)
354
355 def reduce_eval(lst):
356 """
357 Take a list of tokens and output true or false for #if/#elif conditions.
358
359 :param lst: a list of tokens
360 :type lst: list of tuple(token, value)
361 :return: a token
362 :rtype: tuple(NUM, int)
363 """
364 num, lst = get_term(lst)
365 return (NUM, num)
366
367 def stringize(lst):
368 """
369 Merge a list of tokens into a string
370
371 :param lst: a list of tokens
372 :type lst: list of tuple(token, value)
373 :rtype: string
374 """
375 lst = [str(v2) for (p2, v2) in lst]
376 return "".join(lst)
377
378 def paste_tokens(t1, t2):
379 """
380 Token pasting works between identifiers, particular operators, and identifiers and numbers::
381
382 a ## b -> ab
383 > ## = -> >=
384 a ## 2 -> a2
385
386 :param t1: token
387 :type t1: tuple(type, value)
388 :param t2: token
389 :type t2: tuple(type, value)
390 """
391 p1 = None
392 if t1[0] == OP and t2[0] == OP:
393 p1 = OP
394 elif t1[0] == IDENT and (t2[0] == IDENT or t2[0] == NUM):
395 p1 = IDENT
396 elif t1[0] == NUM and t2[0] == NUM:
397 p1 = NUM
398 if not p1:
399 raise PreprocError('tokens do not make a valid paste %r and %r' % (t1, t2))
400 return (p1, t1[1] + t2[1])
401
402 def reduce_tokens(lst, defs, ban=[]):
403 """
404 Replace the tokens in lst, using the macros provided in defs, and a list of macros that cannot be re-applied
405
406 :param lst: list of tokens
407 :type lst: list of tuple(token, value)
408 :param defs: macro definitions
409 :type defs: dict
410 :param ban: macros that cannot be substituted (recursion is not allowed)
411 :type ban: list of string
412 :return: the new list of tokens
413 :rtype: value, list
414 """
415 i = 0
416
417 while i < len(lst):
418 (p, v) = lst[i]
419
420 if p == IDENT and v == "defined":
421 del lst[i]
422 if i < len(lst):
423 (p2, v2) = lst[i]
424 if p2 == IDENT:
425 if v2 in defs:
426 lst[i] = (NUM, 1)
427 else:
428 lst[i] = (NUM, 0)
429 elif p2 == OP and v2 == '(':
430 del lst[i]
431 (p2, v2) = lst[i]
432 del lst[i] # remove the ident, and change the ) for the value
433 if v2 in defs:
434 lst[i] = (NUM, 1)
435 else:
436 lst[i] = (NUM, 0)
437 else:
438 raise PreprocError("Invalid define expression %r" % lst)
439
440 elif p == IDENT and v in defs:
441
442 if isinstance(defs[v], str):
443 a, b = extract_macro(defs[v])
444 defs[v] = b
445 macro_def = defs[v]
446 to_add = macro_def[1]
447
448 if isinstance(macro_def[0], list):
449 # macro without arguments
450 del lst[i]
451 for x in range(len(to_add)):
452 lst.insert(i, to_add[x])
453 i += 1
454 else:
455 # collect the arguments for the funcall
456
457 args = []
458 del lst[i]
459
460 if i >= len(lst):
461 raise PreprocError("expected '(' after %r (got nothing)" % v)
462
463 (p2, v2) = lst[i]
464 if p2 != OP or v2 != '(':
465 raise PreprocError("expected '(' after %r" % v)
466
467 del lst[i]
468
469 one_param = []
470 count_paren = 0
471 while i < len(lst):
472 p2, v2 = lst[i]
473
474 del lst[i]
475 if p2 == OP and count_paren == 0:
476 if v2 == '(':
477 one_param.append((p2, v2))
478 count_paren += 1
479 elif v2 == ')':
480 if one_param: args.append(one_param)
481 break
482 elif v2 == ',':
483 if not one_param: raise PreprocError("empty param in funcall %s" % p)
484 args.append(one_param)
485 one_param = []
486 else:
487 one_param.append((p2, v2))
488 else:
489 one_param.append((p2, v2))
490 if v2 == '(': count_paren += 1
491 elif v2 == ')': count_paren -= 1
492 else:
493 raise PreprocError('malformed macro')
494
495 # substitute the arguments within the define expression
496 accu = []
497 arg_table = macro_def[0]
498 j = 0
499 while j < len(to_add):
500 (p2, v2) = to_add[j]
501
502 if p2 == OP and v2 == '#':
503 # stringize is for arguments only
504 if j+1 < len(to_add) and to_add[j+1][0] == IDENT and to_add[j+1][1] in arg_table:
505 toks = args[arg_table[to_add[j+1][1]]]
506 accu.append((STR, stringize(toks)))
507 j += 1
508 else:
509 accu.append((p2, v2))
510 elif p2 == OP and v2 == '##':
511 # token pasting, how can man invent such a complicated system?
512 if accu and j+1 < len(to_add):
513 # we have at least two tokens
514
515 t1 = accu[-1]
516
517 if to_add[j+1][0] == IDENT and to_add[j+1][1] in arg_table:
518 toks = args[arg_table[to_add[j+1][1]]]
519
520 if toks:
521 accu[-1] = paste_tokens(t1, toks[0]) #(IDENT, accu[-1][1] + toks[0][1])
522 accu.extend(toks[1:])
523 else:
524 # error, case "a##"
525 accu.append((p2, v2))
526 accu.extend(toks)
527 elif to_add[j+1][0] == IDENT and to_add[j+1][1] == '__VA_ARGS__':
528 # TODO not sure
529 # first collect the tokens
530 va_toks = []
531 st = len(macro_def[0])
532 pt = len(args)
533 for x in args[pt-st+1:]:
534 va_toks.extend(x)
535 va_toks.append((OP, ','))
536 if va_toks: va_toks.pop() # extra comma
537 if len(accu)>1:
538 (p3, v3) = accu[-1]
539 (p4, v4) = accu[-2]
540 if v3 == '##':
541 # remove the token paste
542 accu.pop()
543 if v4 == ',' and pt < st:
544 # remove the comma
545 accu.pop()
546 accu += va_toks
547 else:
548 accu[-1] = paste_tokens(t1, to_add[j+1])
549
550 j += 1
551 else:
552 # Invalid paste, case "##a" or "b##"
553 accu.append((p2, v2))
554
555 elif p2 == IDENT and v2 in arg_table:
556 toks = args[arg_table[v2]]
557 reduce_tokens(toks, defs, ban+[v])
558 accu.extend(toks)
559 else:
560 accu.append((p2, v2))
561
562 j += 1
563
564
565 reduce_tokens(accu, defs, ban+[v])
566
567 for x in range(len(accu)-1, -1, -1):
568 lst.insert(i, accu[x])
569
570 i += 1
571
572
573 def eval_macro(lst, defs):
574 """
575 Reduce the tokens by :py:func:`waflib.Tools.c_preproc.reduce_tokens` and try to return a 0/1 result by :py:func:`waflib.Tools.c_preproc.reduce_eval`.
576
577 :param lst: list of tokens
578 :type lst: list of tuple(token, value)
579 :param defs: macro definitions
580 :type defs: dict
581 :rtype: int
582 """
583 reduce_tokens(lst, defs, [])
584 if not lst: raise PreprocError("missing tokens to evaluate")
585 (p, v) = reduce_eval(lst)
586 return int(v) != 0
587
588 def extract_macro(txt):
589 """
590 Process a macro definition of the form::
591 #define f(x, y) x * y
592
593 into a function or a simple macro without arguments
594
595 :param txt: expression to exact a macro definition from
596 :type txt: string
597 :return: a tuple containing the name, the list of arguments and the replacement
598 :rtype: tuple(string, [list, list])
599 """
600 t = tokenize(txt)
601 if re_fun.search(txt):
602 p, name = t[0]
603
604 p, v = t[1]
605 if p != OP: raise PreprocError("expected open parenthesis")
606
607 i = 1
608 pindex = 0
609 params = {}
610 prev = '('
611
612 while 1:
613 i += 1
614 p, v = t[i]
615
616 if prev == '(':
617 if p == IDENT:
618 params[v] = pindex
619 pindex += 1
620 prev = p
621 elif p == OP and v == ')':
622 break
623 else:
624 raise PreprocError("unexpected token (3)")
625 elif prev == IDENT:
626 if p == OP and v == ',':
627 prev = v
628 elif p == OP and v == ')':
629 break
630 else:
631 raise PreprocError("comma or ... expected")
632 elif prev == ',':
633 if p == IDENT:
634 params[v] = pindex
635 pindex += 1
636 prev = p
637 elif p == OP and v == '...':
638 raise PreprocError("not implemented (1)")
639 else:
640 raise PreprocError("comma or ... expected (2)")
641 elif prev == '...':
642 raise PreprocError("not implemented (2)")
643 else:
644 raise PreprocError("unexpected else")
645
646 #~ print (name, [params, t[i+1:]])
647 return (name, [params, t[i+1:]])
648 else:
649 (p, v) = t[0]
650 return (v, [[], t[1:]])
651
652 re_include = re.compile('^\s*(<(?P<a>.*)>|"(?P<b>.*)")')
653 def extract_include(txt, defs):
654 """
655 Process a line in the form::
656
657 #include foo
658
659 :param txt: include line to process
660 :type txt: string
661 :param defs: macro definitions
662 :type defs: dict
663 :return: the file name
664 :rtype: string
665 """
666 m = re_include.search(txt)
667 if m:
668 if m.group('a'): return '<', m.group('a')
669 if m.group('b'): return '"', m.group('b')
670
671 # perform preprocessing and look at the result, it must match an include
672 toks = tokenize(txt)
673 reduce_tokens(toks, defs, ['waf_include'])
674
675 if not toks:
676 raise PreprocError("could not parse include %s" % txt)
677
678 if len(toks) == 1:
679 if toks[0][0] == STR:
680 return '"', toks[0][1]
681 else:
682 if toks[0][1] == '<' and toks[-1][1] == '>':
683 return stringize(toks).lstrip('<').rstrip('>')
684
685 raise PreprocError("could not parse include %s." % txt)
686
687 def parse_char(txt):
688 """
689 Parse a c character
690
691 :param txt: character to parse
692 :type txt: string
693 :return: a character literal
694 :rtype: string
695 """
696
697 if not txt: raise PreprocError("attempted to parse a null char")
698 if txt[0] != '\\':
699 return ord(txt)
700 c = txt[1]
701 if c == 'x':
702 if len(txt) == 4 and txt[3] in string.hexdigits: return int(txt[2:], 16)
703 return int(txt[2:], 16)
704 elif c.isdigit():
705 if c == '0' and len(txt)==2: return 0
706 for i in 3, 2, 1:
707 if len(txt) > i and txt[1:1+i].isdigit():
708 return (1+i, int(txt[1:1+i], 8))
709 else:
710 try: return chr_esc[c]
711 except KeyError: raise PreprocError("could not parse char literal '%s'" % txt)
712
713 @Utils.run_once
714 def tokenize(s):
715 """
716 Convert a string into a list of tokens (shlex.split does not apply to c/c++/d)
717
718 :param s: input to tokenize
719 :type s: string
720 :return: a list of tokens
721 :rtype: list of tuple(token, value)
722 """
723 # the same headers are read again and again - 10% improvement on preprocessing the samba headers
724 ret = []
725 for match in re_clexer.finditer(s):
726 m = match.group
727 for name in tok_types:
728 v = m(name)
729 if v:
730 if name == IDENT:
731 try: v = g_optrans[v]; name = OP
732 except KeyError:
733 # c++ specific
734 if v.lower() == "true":
735 v = 1
736 name = NUM
737 elif v.lower() == "false":
738 v = 0
739 name = NUM
740 elif name == NUM:
741 if m('oct'): v = int(v, 8)
742 elif m('hex'): v = int(m('hex'), 16)
743 elif m('n0'): v = m('n0')
744 else:
745 v = m('char')
746 if v: v = parse_char(v)
747 else: v = m('n2') or m('n4')
748 elif name == OP:
749 if v == '%:': v = '#'
750 elif v == '%:%:': v = '##'
751 elif name == STR:
752 # remove the quotes around the string
753 v = v[1:-1]
754 ret.append((name, v))
755 break
756 return ret
757
758 @Utils.run_once
759 def define_name(line):
760 """
761 :param line: define line
762 :type line: string
763 :rtype: string
764 :return: the define name
765 """
766 return re_mac.match(line).group(0)
767
768 class c_parser(object):
769 """
770 Used by :py:func:`waflib.Tools.c_preproc.scan` to parse c/h files. Note that by default,
771 only project headers are parsed.
772 """
773 def __init__(self, nodepaths=None, defines=None):
774 self.lines = []
775 """list of lines read"""
776
777 if defines is None:
778 self.defs = {}
779 else:
780 self.defs = dict(defines) # make a copy
781 self.state = []
782
783 self.count_files = 0
784 self.currentnode_stack = []
785
786 self.nodepaths = nodepaths or []
787 """Include paths"""
788
789 self.nodes = []
790 """List of :py:class:`waflib.Node.Node` found so far"""
791
792 self.names = []
793 """List of file names that could not be matched by any file"""
794
795 self.curfile = ''
796 """Current file"""
797
798 self.ban_includes = set([])
799 """Includes that must not be read (#pragma once)"""
800
801 def cached_find_resource(self, node, filename):
802 """
803 Find a file from the input directory
804
805 :param node: directory
806 :type node: :py:class:`waflib.Node.Node`
807 :param filename: header to find
808 :type filename: string
809 :return: the node if found, or None
810 :rtype: :py:class:`waflib.Node.Node`
811 """
812 try:
813 nd = node.ctx.cache_nd
814 except:
815 nd = node.ctx.cache_nd = {}
816
817 tup = (node, filename)
818 try:
819 return nd[tup]
820 except KeyError:
821 ret = node.find_resource(filename)
822 if ret:
823 if getattr(ret, 'children', None):
824 ret = None
825 elif ret.is_child_of(node.ctx.bldnode):
826 tmp = node.ctx.srcnode.search(ret.path_from(node.ctx.bldnode))
827 if tmp and getattr(tmp, 'children', None):
828 ret = None
829 nd[tup] = ret
830 return ret
831
832 def tryfind(self, filename):
833 """
834 Try to obtain a node from the filename based from the include paths. Will add
835 the node found to :py:attr:`waflib.Tools.c_preproc.c_parser.nodes` or the file name to
836 :py:attr:`waflib.Tools.c_preproc.c_parser.names` if no corresponding file is found. Called by
837 :py:attr:`waflib.Tools.c_preproc.c_parser.start`.
838
839 :param filename: header to find
840 :type filename: string
841 :return: the node if found
842 :rtype: :py:class:`waflib.Node.Node`
843 """
844 self.curfile = filename
845
846 # for msvc it should be a for loop on the whole stack
847 found = self.cached_find_resource(self.currentnode_stack[-1], filename)
848
849 for n in self.nodepaths:
850 if found:
851 break
852 found = self.cached_find_resource(n, filename)
853
854 if found:
855 # TODO the duplicates do not increase the no-op build times too much, but they may be worth removing
856 self.nodes.append(found)
857 if filename[-4:] != '.moc':
858 self.addlines(found)
859 else:
860 if not filename in self.names:
861 self.names.append(filename)
862 return found
863
864 def addlines(self, node):
865 """
866 Add the lines from a header in the list of preprocessor lines to parse
867
868 :param node: header
869 :type node: :py:class:`waflib.Node.Node`
870 """
871
872 self.currentnode_stack.append(node.parent)
873 filepath = node.abspath()
874
875 self.count_files += 1
876 if self.count_files > recursion_limit:
877 # issue #812
878 raise PreprocError("recursion limit exceeded")
879 pc = self.parse_cache
880 debug('preproc: reading file %r', filepath)
881 try:
882 lns = pc[filepath]
883 except KeyError:
884 pass
885 else:
886 self.lines.extend(lns)
887 return
888
889 try:
890 lines = filter_comments(filepath)
891 lines.append((POPFILE, ''))
892 lines.reverse()
893 pc[filepath] = lines # cache the lines filtered
894 self.lines.extend(lines)
895 except IOError:
896 raise PreprocError("could not read the file %s" % filepath)
897 except Exception:
898 if Logs.verbose > 0:
899 error("parsing %s failed" % filepath)
900 traceback.print_exc()
901
902 def start(self, node, env):
903 """
904 Preprocess a source file to obtain the dependencies, which are accumulated to :py:attr:`waflib.Tools.c_preproc.c_parser.nodes`
905 and :py:attr:`waflib.Tools.c_preproc.c_parser.names`.
906
907 :param node: source file
908 :type node: :py:class:`waflib.Node.Node`
909 :param env: config set containing additional defines to take into account
910 :type env: :py:class:`waflib.ConfigSet.ConfigSet`
911 """
912
913 debug('preproc: scanning %s (in %s)', node.name, node.parent.name)
914
915 bld = node.ctx
916 try:
917 self.parse_cache = bld.parse_cache
918 except AttributeError:
919 bld.parse_cache = {}
920 self.parse_cache = bld.parse_cache
921
922 self.addlines(node)
923
924 # macros may be defined on the command-line, so they must be parsed as if they were part of the file
925 if env['DEFINES']:
926 try:
927 lst = ['%s %s' % (x[0], trimquotes('='.join(x[1:]))) for x in [y.split('=') for y in env['DEFINES']]]
928 lst.reverse()
929 self.lines.extend([('define', x) for x in lst])
930 except AttributeError:
931 # if the defines are invalid the compiler will tell the user
932 pass
933
934 while self.lines:
935 (token, line) = self.lines.pop()
936 if token == POPFILE:
937 self.count_files -= 1
938 self.currentnode_stack.pop()
939 continue
940
941 try:
942 ve = Logs.verbose
943 if ve: debug('preproc: line is %s - %s state is %s', token, line, self.state)
944 state = self.state
945
946 # make certain we define the state if we are about to enter in an if block
947 if token[:2] == 'if':
948 state.append(undefined)
949 elif token == 'endif':
950 state.pop()
951
952 # skip lines when in a dead 'if' branch, wait for the endif
953 if token[0] != 'e':
954 if skipped in self.state or ignored in self.state:
955 continue
956
957 if token == 'if':
958 ret = eval_macro(tokenize(line), self.defs)
959 if ret: state[-1] = accepted
960 else: state[-1] = ignored
961 elif token == 'ifdef':
962 m = re_mac.match(line)
963 if m and m.group(0) in self.defs: state[-1] = accepted
964 else: state[-1] = ignored
965 elif token == 'ifndef':
966 m = re_mac.match(line)
967 if m and m.group(0) in self.defs: state[-1] = ignored
968 else: state[-1] = accepted
969 elif token == 'include' or token == 'import':
970 (kind, inc) = extract_include(line, self.defs)
971 if inc in self.ban_includes:
972 continue
973 if token == 'import': self.ban_includes.add(inc)
974 if ve: debug('preproc: include found %s (%s) ', inc, kind)
975 if kind == '"' or not strict_quotes:
976 self.tryfind(inc)
977 elif token == 'elif':
978 if state[-1] == accepted:
979 state[-1] = skipped
980 elif state[-1] == ignored:
981 if eval_macro(tokenize(line), self.defs):
982 state[-1] = accepted
983 elif token == 'else':
984 if state[-1] == accepted: state[-1] = skipped
985 elif state[-1] == ignored: state[-1] = accepted
986 elif token == 'define':
987 try:
988 self.defs[define_name(line)] = line
989 except:
990 raise PreprocError("Invalid define line %s" % line)
991 elif token == 'undef':
992 m = re_mac.match(line)
993 if m and m.group(0) in self.defs:
994 self.defs.__delitem__(m.group(0))
995 #print "undef %s" % name
996 elif token == 'pragma':
997 if re_pragma_once.match(line.lower()):
998 self.ban_includes.add(self.curfile)
999 except Exception as e:
1000 if Logs.verbose:
1001 debug('preproc: line parsing failed (%s): %s %s', e, line, Utils.ex_stack())
1002
1003 def scan(task):
1004 """
1005 Get the dependencies using a c/c++ preprocessor, this is required for finding dependencies of the kind::
1006
1007 #include some_macro()
1008
1009 This function is bound as a task method on :py:class:`waflib.Tools.c.c` and :py:class:`waflib.Tools.cxx.cxx` for example
1010 """
1011
1012 global go_absolute
1013
1014 try:
1015 incn = task.generator.includes_nodes
1016 except AttributeError:
1017 raise Errors.WafError('%r is missing a feature such as "c", "cxx" or "includes": ' % task.generator)
1018
1019 if go_absolute:
1020 nodepaths = incn + standard_includes
1021 else:
1022 nodepaths = [x for x in incn if x.is_child_of(x.ctx.srcnode) or x.is_child_of(x.ctx.bldnode)]
1023
1024 tmp = c_parser(nodepaths)
1025 tmp.start(task.inputs[0], task.env)
1026 if Logs.verbose:
1027 debug('deps: deps for %r: %r; unresolved %r' % (task.inputs, tmp.nodes, tmp.names))
1028 return (tmp.nodes, tmp.names)
1029
0 #!/usr/bin/env python
1 # encoding: utf-8
2 # Thomas Nagy, 2010 (ita)
3
4 """
5 Various configuration tests.
6 """
7
8 from waflib import Task
9 from waflib.Configure import conf
10 from waflib.TaskGen import feature, before_method, after_method
11 import sys
12
13 LIB_CODE = '''
14 #ifdef _MSC_VER
15 #define testEXPORT __declspec(dllexport)
16 #else
17 #define testEXPORT
18 #endif
19 testEXPORT int lib_func(void) { return 9; }
20 '''
21
22 MAIN_CODE = '''
23 #ifdef _MSC_VER
24 #define testEXPORT __declspec(dllimport)
25 #else
26 #define testEXPORT
27 #endif
28 testEXPORT int lib_func(void);
29 int main(void) {return !(lib_func() == 9);}
30 '''
31
32 @feature('link_lib_test')
33 @before_method('process_source')
34 def link_lib_test_fun(self):
35 """
36 The configuration test :py:func:`waflib.Tools.ccroot.run_c_code` declares a unique task generator,
37 so we need to create other task generators from here to check if the linker is able to link libraries.
38 """
39 def write_test_file(task):
40 task.outputs[0].write(task.generator.code)
41
42 rpath = []
43 if getattr(self, 'add_rpath', False):
44 rpath = [self.bld.path.get_bld().abspath()]
45
46 mode = self.mode
47 m = '%s %s' % (mode, mode)
48 ex = self.test_exec and 'test_exec' or ''
49 bld = self.bld
50 bld(rule=write_test_file, target='test.' + mode, code=LIB_CODE)
51 bld(rule=write_test_file, target='main.' + mode, code=MAIN_CODE)
52 bld(features='%sshlib' % m, source='test.' + mode, target='test')
53 bld(features='%sprogram %s' % (m, ex), source='main.' + mode, target='app', use='test', rpath=rpath)
54
55 @conf
56 def check_library(self, mode=None, test_exec=True):
57 """
58 Check if libraries can be linked with the current linker. Uses :py:func:`waflib.Tools.c_tests.link_lib_test_fun`.
59
60 :param mode: c or cxx or d
61 :type mode: string
62 """
63 if not mode:
64 mode = 'c'
65 if self.env.CXX:
66 mode = 'cxx'
67 self.check(
68 compile_filename = [],
69 features = 'link_lib_test',
70 msg = 'Checking for libraries',
71 mode = mode,
72 test_exec = test_exec,
73 )
74
75 ########################################################################################
76
77 INLINE_CODE = '''
78 typedef int foo_t;
79 static %s foo_t static_foo () {return 0; }
80 %s foo_t foo () {
81 return 0;
82 }
83 '''
84 INLINE_VALUES = ['inline', '__inline__', '__inline']
85
86 @conf
87 def check_inline(self, **kw):
88 """
89 Check for the right value for inline macro.
90 Define INLINE_MACRO to 1 if the define is found.
91 If the inline macro is not 'inline', add a define to the ``config.h`` (#define inline __inline__)
92
93 :param define_name: define INLINE_MACRO by default to 1 if the macro is defined
94 :type define_name: string
95 :param features: by default *c* or *cxx* depending on the compiler present
96 :type features: list of string
97 """
98
99 self.start_msg('Checking for inline')
100
101 if not 'define_name' in kw:
102 kw['define_name'] = 'INLINE_MACRO'
103 if not 'features' in kw:
104 if self.env.CXX:
105 kw['features'] = ['cxx']
106 else:
107 kw['features'] = ['c']
108
109 for x in INLINE_VALUES:
110 kw['fragment'] = INLINE_CODE % (x, x)
111
112 try:
113 self.check(**kw)
114 except self.errors.ConfigurationError:
115 continue
116 else:
117 self.end_msg(x)
118 if x != 'inline':
119 self.define('inline', x, quote=False)
120 return x
121 self.fatal('could not use inline functions')
122
123 ########################################################################################
124
125 LARGE_FRAGMENT = '#include <unistd.h>\nint main() { return !(sizeof(off_t) >= 8); }\n'
126
127 @conf
128 def check_large_file(self, **kw):
129 """
130 Check for large file support and define the macro HAVE_LARGEFILE
131 The test is skipped on win32 systems (DEST_BINFMT == pe).
132
133 :param define_name: define to set, by default *HAVE_LARGEFILE*
134 :type define_name: string
135 :param execute: execute the test (yes by default)
136 :type execute: bool
137 """
138
139 if not 'define_name' in kw:
140 kw['define_name'] = 'HAVE_LARGEFILE'
141 if not 'execute' in kw:
142 kw['execute'] = True
143
144 if not 'features' in kw:
145 if self.env.CXX:
146 kw['features'] = ['cxx', 'cxxprogram']
147 else:
148 kw['features'] = ['c', 'cprogram']
149
150 kw['fragment'] = LARGE_FRAGMENT
151
152 kw['msg'] = 'Checking for large file support'
153 ret = True
154 try:
155 if self.env.DEST_BINFMT != 'pe':
156 ret = self.check(**kw)
157 except self.errors.ConfigurationError:
158 pass
159 else:
160 if ret:
161 return True
162
163 kw['msg'] = 'Checking for -D_FILE_OFFSET_BITS=64'
164 kw['defines'] = ['_FILE_OFFSET_BITS=64']
165 try:
166 ret = self.check(**kw)
167 except self.errors.ConfigurationError:
168 pass
169 else:
170 self.define('_FILE_OFFSET_BITS', 64)
171 return ret
172
173 self.fatal('There is no support for large files')
174
175 ########################################################################################
176
177 ENDIAN_FRAGMENT = '''
178 short int ascii_mm[] = { 0x4249, 0x4765, 0x6E44, 0x6961, 0x6E53, 0x7953, 0 };
179 short int ascii_ii[] = { 0x694C, 0x5454, 0x656C, 0x6E45, 0x6944, 0x6E61, 0 };
180 int use_ascii (int i) {
181 return ascii_mm[i] + ascii_ii[i];
182 }
183 short int ebcdic_ii[] = { 0x89D3, 0xE3E3, 0x8593, 0x95C5, 0x89C4, 0x9581, 0 };
184 short int ebcdic_mm[] = { 0xC2C9, 0xC785, 0x95C4, 0x8981, 0x95E2, 0xA8E2, 0 };
185 int use_ebcdic (int i) {
186 return ebcdic_mm[i] + ebcdic_ii[i];
187 }
188 extern int foo;
189 '''
190
191 class grep_for_endianness(Task.Task):
192 color = 'PINK'
193 def run(self):
194 txt = self.inputs[0].read(flags='rb').decode('iso8859-1')
195 if txt.find('LiTTleEnDian') > -1:
196 self.generator.tmp.append('little')
197 elif txt.find('BIGenDianSyS') > -1:
198 self.generator.tmp.append('big')
199 else:
200 return -1
201
202 @feature('grep_for_endianness')
203 @after_method('process_source')
204 def grep_for_endianness_fun(self):
205 self.create_task('grep_for_endianness', self.compiled_tasks[0].outputs[0])
206
207 @conf
208 def check_endianness(self):
209 """
210 Execute a configuration test to determine the endianness
211 """
212 tmp = []
213 def check_msg(self):
214 return tmp[0]
215 self.check(fragment=ENDIAN_FRAGMENT, features='c grep_for_endianness', msg="Checking for endianness", define='ENDIANNESS', tmp=tmp, okmsg=check_msg)
216 return tmp[0]
217
0 #!/usr/bin/env python
1 # encoding: utf-8
2 # Thomas Nagy, 2005-2010 (ita)
3
4 """
5 Classes and methods shared by tools providing support for C-like language such
6 as C/C++/D/Assembly/Go (this support module is almost never used alone).
7 """
8
9 import os, sys, re
10 from waflib import TaskGen, Task, Utils, Logs, Build, Options, Node, Errors
11 from waflib.Logs import error, debug, warn
12 from waflib.TaskGen import after_method, before_method, feature, taskgen_method, extension
13 from waflib.Tools import c_aliases, c_preproc, c_config, c_osx, c_tests
14 from waflib.Configure import conf
15
16 USELIB_VARS = Utils.defaultdict(set)
17 """
18 Mapping for features to :py:class:`waflib.ConfigSet.ConfigSet` variables. See :py:func:`waflib.Tools.ccroot.propagate_uselib_vars`.
19 """
20
21 USELIB_VARS['c'] = set(['INCLUDES', 'FRAMEWORKPATH', 'DEFINES', 'CPPFLAGS', 'CCDEPS', 'CFLAGS', 'ARCH'])
22 USELIB_VARS['cxx'] = set(['INCLUDES', 'FRAMEWORKPATH', 'DEFINES', 'CPPFLAGS', 'CXXDEPS', 'CXXFLAGS', 'ARCH'])
23 USELIB_VARS['d'] = set(['INCLUDES', 'DFLAGS'])
24
25 USELIB_VARS['cprogram'] = USELIB_VARS['cxxprogram'] = set(['LIB', 'STLIB', 'LIBPATH', 'STLIBPATH', 'LINKFLAGS', 'RPATH', 'LINKDEPS', 'FRAMEWORK', 'FRAMEWORKPATH', 'ARCH'])
26 USELIB_VARS['cshlib'] = USELIB_VARS['cxxshlib'] = set(['LIB', 'STLIB', 'LIBPATH', 'STLIBPATH', 'LINKFLAGS', 'RPATH', 'LINKDEPS', 'FRAMEWORK', 'FRAMEWORKPATH', 'ARCH'])
27 USELIB_VARS['cstlib'] = USELIB_VARS['cxxstlib'] = set(['ARFLAGS', 'LINKDEPS'])
28
29 USELIB_VARS['dprogram'] = set(['LIB', 'STLIB', 'LIBPATH', 'STLIBPATH', 'LINKFLAGS', 'RPATH', 'LINKDEPS'])
30 USELIB_VARS['dshlib'] = set(['LIB', 'STLIB', 'LIBPATH', 'STLIBPATH', 'LINKFLAGS', 'RPATH', 'LINKDEPS'])
31 USELIB_VARS['dstlib'] = set(['ARFLAGS', 'LINKDEPS'])
32
33 USELIB_VARS['go'] = set(['GOCFLAGS'])
34 USELIB_VARS['goprogram'] = set(['GOLFLAGS'])
35
36 USELIB_VARS['asm'] = set(['ASFLAGS'])
37
38 # =================================================================================================
39
40 @taskgen_method
41 def create_compiled_task(self, name, node):
42 """
43 Create the compilation task: c, cxx, asm, etc. The output node is created automatically (object file with a typical **.o** extension).
44 The task is appended to the list *compiled_tasks* which is then used by :py:func:`waflib.Tools.ccroot.apply_link`
45
46 :param name: name of the task class
47 :type name: string
48 :param node: the file to compile
49 :type node: :py:class:`waflib.Node.Node`
50 :return: The task created
51 :rtype: :py:class:`waflib.Task.Task`
52 """
53 out = '%s.%d.o' % (node.name, self.idx)
54 task = self.create_task(name, node, node.parent.find_or_declare(out))
55 try:
56 self.compiled_tasks.append(task)
57 except AttributeError:
58 self.compiled_tasks = [task]
59 return task
60
61 @taskgen_method
62 def to_incnodes(self, inlst):
63 """
64 Task generator method provided to convert a list of string/nodes into a list of includes folders.
65
66 The paths are assumed to be relative to the task generator path, except if they begin by **#**
67 in which case they are searched from the top-level directory (``bld.srcnode``).
68 The folders are simply assumed to be existing.
69
70 The node objects in the list are returned in the output list. The strings are converted
71 into node objects if possible. The node is searched from the source directory, and if a match is found,
72 the equivalent build directory is created and added to the returned list too. When a folder cannot be found, it is ignored.
73
74 :param inlst: list of folders
75 :type inlst: space-delimited string or a list of string/nodes
76 :rtype: list of :py:class:`waflib.Node.Node`
77 :return: list of include folders as nodes
78 """
79 lst = []
80 seen = set([])
81 for x in self.to_list(inlst):
82 if x in seen or not x:
83 continue
84 seen.add(x)
85
86 if isinstance(x, Node.Node):
87 lst.append(x)
88 else:
89 if os.path.isabs(x):
90 lst.append(self.bld.root.make_node(x) or x)
91 else:
92 if x[0] == '#':
93 p = self.bld.bldnode.make_node(x[1:])
94 v = self.bld.srcnode.make_node(x[1:])
95 else:
96 p = self.path.get_bld().make_node(x)
97 v = self.path.make_node(x)
98 if p.is_child_of(self.bld.bldnode):
99 p.mkdir()
100 lst.append(p)
101 lst.append(v)
102 return lst
103
104 @feature('c', 'cxx', 'd', 'go', 'asm', 'fc', 'includes')
105 @after_method('propagate_uselib_vars', 'process_source')
106 def apply_incpaths(self):
107 """
108 Task generator method that processes the attribute *includes*::
109
110 tg = bld(features='includes', includes='.')
111
112 The folders only need to be relative to the current directory, the equivalent build directory is
113 added automatically (for headers created in the build directory). This enable using a build directory
114 or not (``top == out``).
115
116 This method will add a list of nodes read by :py:func:`waflib.Tools.ccroot.to_incnodes` in ``tg.env.INCPATHS``,
117 and the list of include paths in ``tg.env.INCLUDES``.
118 """
119
120 lst = self.to_incnodes(self.to_list(getattr(self, 'includes', [])) + self.env['INCLUDES'])
121 self.includes_nodes = lst
122 self.env['INCPATHS'] = [x.abspath() for x in lst]
123
124 class link_task(Task.Task):
125 """
126 Base class for all link tasks. A task generator is supposed to have at most one link task bound in the attribute *link_task*. See :py:func:`waflib.Tools.ccroot.apply_link`.
127
128 .. inheritance-diagram:: waflib.Tools.ccroot.stlink_task waflib.Tools.c.cprogram waflib.Tools.c.cshlib waflib.Tools.cxx.cxxstlib waflib.Tools.cxx.cxxprogram waflib.Tools.cxx.cxxshlib waflib.Tools.d.dprogram waflib.Tools.d.dshlib waflib.Tools.d.dstlib waflib.Tools.ccroot.fake_shlib waflib.Tools.ccroot.fake_stlib waflib.Tools.asm.asmprogram waflib.Tools.asm.asmshlib waflib.Tools.asm.asmstlib
129 """
130 color = 'YELLOW'
131
132 inst_to = None
133 """Default installation path for the link task outputs, or None to disable"""
134
135 chmod = Utils.O644
136 """Default installation mode for the link task outputs"""
137
138 def add_target(self, target):
139 """
140 Process the *target* attribute to add the platform-specific prefix/suffix such as *.so* or *.exe*.
141 The settings are retrieved from ``env.clsname_PATTERN``
142 """
143 if isinstance(target, str):
144 pattern = self.env[self.__class__.__name__ + '_PATTERN']
145 if not pattern:
146 pattern = '%s'
147 folder, name = os.path.split(target)
148
149 if self.__class__.__name__.find('shlib') > 0:
150 if self.env.DEST_BINFMT == 'pe' and getattr(self.generator, 'vnum', None):
151 # include the version in the dll file name,
152 # the import lib file name stays unversionned.
153 name = name + '-' + self.generator.vnum.split('.')[0]
154
155 tmp = folder + os.sep + pattern % name
156 target = self.generator.path.find_or_declare(tmp)
157 self.set_outputs(target)
158
159 class stlink_task(link_task):
160 """
161 Base for static link tasks, which use *ar* most of the time.
162 The target is always removed before being written.
163 """
164 run_str = '${AR} ${ARFLAGS} ${AR_TGT_F}${TGT} ${AR_SRC_F}${SRC}'
165
166 def rm_tgt(cls):
167 old = cls.run
168 def wrap(self):
169 try: os.remove(self.outputs[0].abspath())
170 except OSError: pass
171 return old(self)
172 setattr(cls, 'run', wrap)
173 rm_tgt(stlink_task)
174
175 @feature('c', 'cxx', 'd', 'go', 'fc', 'asm')
176 @after_method('process_source')
177 def apply_link(self):
178 """
179 Collect the tasks stored in ``compiled_tasks`` (created by :py:func:`waflib.Tools.ccroot.create_compiled_task`), and
180 use the outputs for a new instance of :py:class:`waflib.Tools.ccroot.link_task`. The class to use is the first link task
181 matching a name from the attribute *features*, for example::
182
183 def build(bld):
184 tg = bld(features='cxx cxxprogram cprogram', source='main.c', target='app')
185
186 will create the task ``tg.link_task`` as a new instance of :py:class:`waflib.Tools.cxx.cxxprogram`
187 """
188
189 for x in self.features:
190 if x == 'cprogram' and 'cxx' in self.features: # limited compat
191 x = 'cxxprogram'
192 elif x == 'cshlib' and 'cxx' in self.features:
193 x = 'cxxshlib'
194
195 if x in Task.classes:
196 if issubclass(Task.classes[x], link_task):
197 link = x
198 break
199 else:
200 return
201
202 objs = [t.outputs[0] for t in getattr(self, 'compiled_tasks', [])]
203 self.link_task = self.create_task(link, objs)
204 self.link_task.add_target(self.target)
205
206 # remember that the install paths are given by the task generators
207 # we need to define install_task even during the build phase because others might need the installation path
208 try:
209 inst_to = self.install_path
210 except AttributeError:
211 inst_to = self.link_task.__class__.inst_to
212 if inst_to:
213 # install a copy of the node list we have at this moment (implib not added)
214 self.install_task = self.bld.install_files(inst_to, self.link_task.outputs[:], env=self.env, chmod=self.link_task.chmod)
215
216 @taskgen_method
217 def use_rec(self, name, **kw):
218 """
219 Processes the ``use`` keyword recursively. This method is kind of private and only meant to be used from ``process_use``
220 """
221
222 if name in self.tmp_use_not or name in self.tmp_use_seen:
223 return
224
225 try:
226 y = self.bld.get_tgen_by_name(name)
227 except Errors.WafError:
228 self.uselib.append(name)
229 self.tmp_use_not.add(name)
230 return
231
232 self.tmp_use_seen.append(name)
233 y.post()
234
235 # bind temporary attributes on the task generator
236 y.tmp_use_objects = objects = kw.get('objects', True)
237 y.tmp_use_stlib = stlib = kw.get('stlib', True)
238 try:
239 link_task = y.link_task
240 except AttributeError:
241 y.tmp_use_var = ''
242 else:
243 objects = False
244 if not isinstance(y.link_task, stlink_task):
245 stlib = False
246 y.tmp_use_var = 'LIB'
247 else:
248 y.tmp_use_var = 'STLIB'
249
250 p = self.tmp_use_prec
251 for x in self.to_list(getattr(y, 'use', [])):
252 try:
253 p[x].append(name)
254 except:
255 p[x] = [name]
256 self.use_rec(x, objects=objects, stlib=stlib)
257
258 @feature('c', 'cxx', 'd', 'use', 'fc')
259 @before_method('apply_incpaths', 'propagate_uselib_vars')
260 @after_method('apply_link', 'process_source')
261 def process_use(self):
262 """
263 Process the ``use`` attribute which contains a list of task generator names::
264
265 def build(bld):
266 bld.shlib(source='a.c', target='lib1')
267 bld.program(source='main.c', target='app', use='lib1')
268
269 See :py:func:`waflib.Tools.ccroot.use_rec`.
270 """
271
272 use_not = self.tmp_use_not = set([])
273 use_seen = self.tmp_use_seen = [] # we would like an ordered set
274 use_prec = self.tmp_use_prec = {}
275 self.uselib = self.to_list(getattr(self, 'uselib', []))
276 self.includes = self.to_list(getattr(self, 'includes', []))
277 names = self.to_list(getattr(self, 'use', []))
278
279 for x in names:
280 self.use_rec(x)
281
282 for x in use_not:
283 if x in use_prec:
284 del use_prec[x]
285
286 # topological sort
287 out = []
288 tmp = []
289 for x in self.tmp_use_seen:
290 for k in use_prec.values():
291 if x in k:
292 break
293 else:
294 tmp.append(x)
295
296 while tmp:
297 e = tmp.pop()
298 out.append(e)
299 try:
300 nlst = use_prec[e]
301 except KeyError:
302 pass
303 else:
304 del use_prec[e]
305 for x in nlst:
306 for y in use_prec:
307 if x in use_prec[y]:
308 break
309 else:
310 tmp.append(x)
311 if use_prec:
312 raise Errors.WafError('Cycle detected in the use processing %r' % use_prec)
313 out.reverse()
314
315 link_task = getattr(self, 'link_task', None)
316 for x in out:
317 y = self.bld.get_tgen_by_name(x)
318 var = y.tmp_use_var
319 if var and link_task:
320 if var == 'LIB' or y.tmp_use_stlib:
321 self.env.append_value(var, [y.target[y.target.rfind(os.sep) + 1:]])
322 self.link_task.dep_nodes.extend(y.link_task.outputs)
323 tmp_path = y.link_task.outputs[0].parent.path_from(self.bld.bldnode)
324 self.env.append_value(var + 'PATH', [tmp_path])
325 else:
326 if y.tmp_use_objects:
327 self.add_objects_from_tgen(y)
328
329 if getattr(y, 'export_includes', None):
330 self.includes.extend(y.to_incnodes(y.export_includes))
331
332 # and finally, add the uselib variables (no recursion needed)
333 for x in names:
334 try:
335 y = self.bld.get_tgen_by_name(x)
336 except:
337 if not self.env['STLIB_' + x] and not x in self.uselib:
338 self.uselib.append(x)
339 else:
340 for k in self.to_list(getattr(y, 'uselib', [])):
341 if not self.env['STLIB_' + k] and not k in self.uselib:
342 self.uselib.append(k)
343
344 @taskgen_method
345 def add_objects_from_tgen(self, tg):
346 # Not public yet, wait for waf 1.6.7 at least - the purpose of this is to add pdb files to the compiled
347 # tasks but not to the link tasks (to avoid errors)
348 try:
349 link_task = self.link_task
350 except AttributeError:
351 pass
352 else:
353 for tsk in getattr(tg, 'compiled_tasks', []):
354 for x in tsk.outputs:
355 if x.name.endswith('.o') or x.name.endswith('.obj'):
356 link_task.inputs.append(x)
357
358 @taskgen_method
359 def get_uselib_vars(self):
360 """
361 :return: the *uselib* variables associated to the *features* attribute (see :py:attr:`waflib.Tools.ccroot.USELIB_VARS`)
362 :rtype: list of string
363 """
364 _vars = set([])
365 for x in self.features:
366 if x in USELIB_VARS:
367 _vars |= USELIB_VARS[x]
368 return _vars
369
370 @feature('c', 'cxx', 'd', 'fc', 'javac', 'cs', 'uselib')
371 @after_method('process_use')
372 def propagate_uselib_vars(self):
373 """
374 Process uselib variables for adding flags. For example, the following target::
375
376 def build(bld):
377 bld.env.AFLAGS_aaa = ['bar']
378 from waflib.Tools.ccroot import USELIB_VARS
379 USELIB_VARS['aaa'] = set('AFLAGS')
380
381 tg = bld(features='aaa', aflags='test')
382
383 The *aflags* attribute will be processed and this method will set::
384
385 tg.env.AFLAGS = ['bar', 'test']
386 """
387 _vars = self.get_uselib_vars()
388 env = self.env
389
390 for x in _vars:
391 y = x.lower()
392 env.append_unique(x, self.to_list(getattr(self, y, [])))
393
394 for x in self.features:
395 for var in _vars:
396 compvar = '%s_%s' % (var, x)
397 env.append_value(var, env[compvar])
398
399 for x in self.to_list(getattr(self, 'uselib', [])):
400 for v in _vars:
401 env.append_value(v, env[v + '_' + x])
402
403 # ============ the code above must not know anything about import libs ==========
404
405 @feature('cshlib', 'cxxshlib', 'fcshlib')
406 @after_method('apply_link')
407 def apply_implib(self):
408 """
409 Handle dlls and their import libs on Windows-like systems.
410
411 A ``.dll.a`` file called *import library* is generated.
412 It must be installed as it is required for linking the library.
413 """
414 if not self.env.DEST_BINFMT == 'pe':
415 return
416
417 dll = self.link_task.outputs[0]
418 if isinstance(self.target, Node.Node):
419 name = self.target.name
420 else:
421 name = os.path.split(self.target)[1]
422 implib = self.env['implib_PATTERN'] % name
423 implib = dll.parent.find_or_declare(implib)
424 self.env.append_value('LINKFLAGS', self.env['IMPLIB_ST'] % implib.bldpath())
425 self.link_task.outputs.append(implib)
426
427 if getattr(self, 'defs', None) and self.env.DEST_BINFMT == 'pe':
428 node = self.path.find_resource(self.defs)
429 if not node:
430 raise Errors.WafError('invalid def file %r' % self.defs)
431 if 'msvc' in (self.env.CC_NAME, self.env.CXX_NAME):
432 self.env.append_value('LINKFLAGS', '/def:%s' % node.path_from(self.bld.bldnode))
433 self.link_task.dep_nodes.append(node)
434 else:
435 #gcc for windows takes *.def file a an input without any special flag
436 self.link_task.inputs.append(node)
437
438 try:
439 inst_to = self.install_path
440 except AttributeError:
441 inst_to = self.link_task.__class__.inst_to
442 if not inst_to:
443 return
444
445 self.implib_install_task = self.bld.install_as('${PREFIX}/lib/%s' % implib.name, implib, self.env)
446
447 # ============ the code above must not know anything about vnum processing on unix platforms =========
448
449 @feature('cshlib', 'cxxshlib', 'dshlib', 'fcshlib', 'vnum')
450 @after_method('apply_link')
451 def apply_vnum(self):
452 """
453 Enforce version numbering on shared libraries. The valid version numbers must have at most two dots::
454
455 def build(bld):
456 bld.shlib(source='a.c', target='foo', vnum='14.15.16')
457
458 In this example, ``libfoo.so`` is installed as ``libfoo.so.1.2.3``, and the following symbolic links are created:
459
460 * ``libfoo.so → libfoo.so.1.2.3``
461 * ``libfoo.so.1 → libfoo.so.1.2.3``
462 """
463 if not getattr(self, 'vnum', '') or os.name != 'posix' or self.env.DEST_BINFMT not in ('elf', 'mac-o'):
464 return
465
466 link = self.link_task
467 nums = self.vnum.split('.')
468 node = link.outputs[0]
469
470 libname = node.name
471 if libname.endswith('.dylib'):
472 name3 = libname.replace('.dylib', '.%s.dylib' % self.vnum)
473 name2 = libname.replace('.dylib', '.%s.dylib' % nums[0])
474 else:
475 name3 = libname + '.' + self.vnum
476 name2 = libname + '.' + nums[0]
477
478 # add the so name for the ld linker - to disable, just unset env.SONAME_ST
479 if self.env.SONAME_ST:
480 v = self.env.SONAME_ST % name2
481 self.env.append_value('LINKFLAGS', v.split())
482
483 # the following task is just to enable execution from the build dir :-/
484 tsk = self.create_task('vnum', node, [node.parent.find_or_declare(name2), node.parent.find_or_declare(name3)])
485
486 if getattr(self.bld, 'is_install', None):
487 self.install_task.hasrun = Task.SKIP_ME
488 bld = self.bld
489 path = self.install_task.dest
490 t1 = bld.install_as(path + os.sep + name3, node, env=self.env, chmod=self.link_task.chmod)
491 t2 = bld.symlink_as(path + os.sep + name2, name3)
492 t3 = bld.symlink_as(path + os.sep + libname, name3)
493 self.vnum_install_task = (t1, t2, t3)
494
495 if '-dynamiclib' in self.env['LINKFLAGS'] and getattr(self, 'install_task', None):
496 path = os.path.join(self.install_task.get_install_path(), self.link_task.outputs[0].name)
497 self.env.append_value('LINKFLAGS', ['-install_name', path])
498
499 class vnum(Task.Task):
500 """
501 Create the symbolic links for a versioned shared library. Instances are created by :py:func:`waflib.Tools.ccroot.apply_vnum`
502 """
503 color = 'CYAN'
504 quient = True
505 ext_in = ['.bin']
506 def run(self):
507 for x in self.outputs:
508 path = x.abspath()
509 try:
510 os.remove(path)
511 except OSError:
512 pass
513
514 try:
515 os.symlink(self.inputs[0].name, path)
516 except OSError:
517 return 1
518
519 class fake_shlib(link_task):
520 """
521 Task used for reading a system library and adding the dependency on it
522 """
523 def runnable_status(self):
524 for t in self.run_after:
525 if not t.hasrun:
526 return Task.ASK_LATER
527
528 for x in self.outputs:
529 x.sig = Utils.h_file(x.abspath())
530 return Task.SKIP_ME
531
532 class fake_stlib(stlink_task):
533 """
534 Task used for reading a system library and adding the dependency on it
535 """
536 def runnable_status(self):
537 for t in self.run_after:
538 if not t.hasrun:
539 return Task.ASK_LATER
540
541 for x in self.outputs:
542 x.sig = Utils.h_file(x.abspath())
543 return Task.SKIP_ME
544
545 @conf
546 def read_shlib(self, name, paths=[]):
547 """
548 Read a system shared library, enabling its use as a local library. Will trigger a rebuild if the file changes::
549
550 def build(bld):
551 bld.read_shlib('m')
552 bld.program(source='main.c', use='m')
553 """
554 return self(name=name, features='fake_lib', lib_paths=paths, lib_type='shlib')
555
556 @conf
557 def read_stlib(self, name, paths=[]):
558 """
559 Read a system static library, enabling a use as a local library. Will trigger a rebuild if the file changes.
560 """
561 return self(name=name, features='fake_lib', lib_paths=paths, lib_type='stlib')
562
563 lib_patterns = {
564 'shlib' : ['lib%s.so', '%s.so', 'lib%s.dll', '%s.dll'],
565 'stlib' : ['lib%s.a', '%s.a', 'lib%s.dll', '%s.dll', 'lib%s.lib', '%s.lib'],
566 }
567
568 @feature('fake_lib')
569 def process_lib(self):
570 """
571 Find the location of a foreign library. Used by :py:class:`waflib.Tools.ccroot.read_shlib` and :py:class:`waflib.Tools.ccroot.read_stlib`.
572 """
573 node = None
574
575 names = [x % self.name for x in lib_patterns[self.lib_type]]
576 for x in self.lib_paths + [self.path, '/usr/lib64', '/usr/lib', '/usr/local/lib64', '/usr/local/lib']:
577 if not isinstance(x, Node.Node):
578 x = self.bld.root.find_node(x) or self.path.find_node(x)
579 if not x:
580 continue
581
582 for y in names:
583 node = x.find_node(y)
584 if node:
585 node.sig = Utils.h_file(node.abspath())
586 break
587 else:
588 continue
589 break
590 else:
591 raise Errors.WafError('could not find library %r' % self.name)
592 self.link_task = self.create_task('fake_%s' % self.lib_type, [], [node])
593 self.target = self.name
594
595
596 class fake_o(Task.Task):
597 def runnable_status(self):
598 return Task.SKIP_ME
599
600 @extension('.o', '.obj')
601 def add_those_o_files(self, node):
602 tsk = self.create_task('fake_o', [], node)
603 try:
604 self.compiled_tasks.append(tsk)
605 except AttributeError:
606 self.compiled_tasks = [tsk]
607
0 #!/usr/bin/env python
1 # encoding: utf-8
2 # Matthias Jahn jahn dôt matthias ât freenet dôt de, 2007 (pmarat)
3
4 """
5 Try to detect a C compiler from the list of supported compilers (gcc, msvc, etc)::
6
7 def options(opt):
8 opt.load('compiler_c')
9 def configure(cnf):
10 cnf.load('compiler_c')
11 def build(bld):
12 bld.program(source='main.c', target='app')
13
14 The compilers are associated to platforms in :py:attr:`waflib.Tools.compiler_c.c_compiler`. To register
15 a new C compiler named *cfoo* (assuming the tool ``waflib/extras/cfoo.py`` exists), use::
16
17 def options(opt):
18 opt.load('compiler_c')
19 def configure(cnf):
20 from waflib.Tools.compiler_c import c_compiler
21 c_compiler['win32'] = ['cfoo', 'msvc', 'gcc']
22 cnf.load('compiler_c')
23 def build(bld):
24 bld.program(source='main.c', target='app')
25
26 Not all compilers need to have a specific tool. For example, the clang compilers can be detected by the gcc tools when using::
27
28 $ CC=clang waf configure
29 """
30
31 import os, sys, imp, types
32 from waflib.Tools import ccroot
33 from waflib import Utils, Configure
34 from waflib.Logs import debug
35
36 c_compiler = {
37 'win32': ['msvc', 'gcc'],
38 'cygwin': ['gcc'],
39 'darwin': ['gcc'],
40 'aix': ['xlc', 'gcc'],
41 'linux': ['gcc', 'icc'],
42 'sunos': ['suncc', 'gcc'],
43 'irix': ['gcc', 'irixcc'],
44 'hpux': ['gcc'],
45 'gnu': ['gcc'],
46 'java': ['gcc', 'msvc', 'icc'],
47 'default':['gcc'],
48 }
49 """
50 Dict mapping the platform names to waf tools finding specific compilers::
51
52 from waflib.Tools.compiler_c import c_compiler
53 c_compiler['linux'] = ['gcc', 'icc', 'suncc']
54 """
55
56 def configure(conf):
57 """
58 Try to find a suitable C compiler or raise a :py:class:`waflib.Errors.ConfigurationError`.
59 """
60 try: test_for_compiler = conf.options.check_c_compiler
61 except AttributeError: conf.fatal("Add options(opt): opt.load('compiler_c')")
62 for compiler in test_for_compiler.split():
63 conf.env.stash()
64 conf.start_msg('Checking for %r (c compiler)' % compiler)
65 try:
66 conf.load(compiler)
67 except conf.errors.ConfigurationError as e:
68 conf.env.revert()
69 conf.end_msg(False)
70 debug('compiler_c: %r' % e)
71 else:
72 if conf.env['CC']:
73 conf.end_msg(conf.env.get_flat('CC'))
74 conf.env['COMPILER_CC'] = compiler
75 break
76 conf.end_msg(False)
77 else:
78 conf.fatal('could not configure a c compiler!')
79
80 def options(opt):
81 """
82 Restrict the compiler detection from the command-line::
83
84 $ waf configure --check-c-compiler=gcc
85 """
86 opt.load_special_tools('c_*.py', ban=['c_dumbpreproc.py'])
87 global c_compiler
88 build_platform = Utils.unversioned_sys_platform()
89 possible_compiler_list = c_compiler[build_platform in c_compiler and build_platform or 'default']
90 test_for_compiler = ' '.join(possible_compiler_list)
91 cc_compiler_opts = opt.add_option_group("C Compiler Options")
92 cc_compiler_opts.add_option('--check-c-compiler', default="%s" % test_for_compiler,
93 help='On this platform (%s) the following C-Compiler will be checked by default: "%s"' % (build_platform, test_for_compiler),
94 dest="check_c_compiler")
95 for x in test_for_compiler.split():
96 opt.load('%s' % x)
97
0 #!/usr/bin/env python
1 # encoding: utf-8
2 # Matthias Jahn jahn dôt matthias ât freenet dôt de 2007 (pmarat)
3
4 """
5 Try to detect a C++ compiler from the list of supported compilers (g++, msvc, etc)::
6
7 def options(opt):
8 opt.load('compiler_cxx')
9 def configure(cnf):
10 cnf.load('compiler_cxx')
11 def build(bld):
12 bld.program(source='main.cpp', target='app')
13
14 The compilers are associated to platforms in :py:attr:`waflib.Tools.compiler_cxx.cxx_compiler`. To register
15 a new C++ compiler named *cfoo* (assuming the tool ``waflib/extras/cfoo.py`` exists), use::
16
17 def options(opt):
18 opt.load('compiler_cxx')
19 def configure(cnf):
20 from waflib.Tools.compiler_cxx import cxx_compiler
21 cxx_compiler['win32'] = ['cfoo', 'msvc', 'gcc']
22 cnf.load('compiler_cxx')
23 def build(bld):
24 bld.program(source='main.c', target='app')
25
26 Not all compilers need to have a specific tool. For example, the clang compilers can be detected by the gcc tools when using::
27
28 $ CXX=clang waf configure
29 """
30
31
32 import os, sys, imp, types
33 from waflib.Tools import ccroot
34 from waflib import Utils, Configure
35 from waflib.Logs import debug
36
37 cxx_compiler = {
38 'win32': ['msvc', 'g++'],
39 'cygwin': ['g++'],
40 'darwin': ['g++'],
41 'aix': ['xlc++', 'g++'],
42 'linux': ['g++', 'icpc'],
43 'sunos': ['sunc++', 'g++'],
44 'irix': ['g++'],
45 'hpux': ['g++'],
46 'gnu': ['g++'],
47 'java': ['g++', 'msvc', 'icpc'],
48 'default': ['g++']
49 }
50 """
51 Dict mapping the platform names to waf tools finding specific compilers::
52
53 from waflib.Tools.compiler_cxx import cxx_compiler
54 cxx_compiler['linux'] = ['gxx', 'icpc', 'suncxx']
55 """
56
57
58 def configure(conf):
59 """
60 Try to find a suitable C++ compiler or raise a :py:class:`waflib.Errors.ConfigurationError`.
61 """
62 try: test_for_compiler = conf.options.check_cxx_compiler
63 except AttributeError: conf.fatal("Add options(opt): opt.load('compiler_cxx')")
64
65 for compiler in test_for_compiler.split():
66 conf.env.stash()
67 conf.start_msg('Checking for %r (c++ compiler)' % compiler)
68 try:
69 conf.load(compiler)
70 except conf.errors.ConfigurationError as e:
71 conf.env.revert()
72 conf.end_msg(False)
73 debug('compiler_cxx: %r' % e)
74 else:
75 if conf.env['CXX']:
76 conf.end_msg(conf.env.get_flat('CXX'))
77 conf.env['COMPILER_CXX'] = compiler
78 break
79 conf.end_msg(False)
80 else:
81 conf.fatal('could not configure a c++ compiler!')
82
83 def options(opt):
84 """
85 Restrict the compiler detection from the command-line::
86
87 $ waf configure --check-cxx-compiler=gxx
88 """
89 opt.load_special_tools('cxx_*.py')
90 global cxx_compiler
91 build_platform = Utils.unversioned_sys_platform()
92 possible_compiler_list = cxx_compiler[build_platform in cxx_compiler and build_platform or 'default']
93 test_for_compiler = ' '.join(possible_compiler_list)
94 cxx_compiler_opts = opt.add_option_group('C++ Compiler Options')
95 cxx_compiler_opts.add_option('--check-cxx-compiler', default="%s" % test_for_compiler,
96 help='On this platform (%s) the following C++ Compiler will be checked by default: "%s"' % (build_platform, test_for_compiler),
97 dest="check_cxx_compiler")
98
99 for x in test_for_compiler.split():
100 opt.load('%s' % x)
101
0 #!/usr/bin/env python
1 # encoding: utf-8
2 # Carlos Rafael Giani, 2007 (dv)
3 # Thomas Nagy, 2010 (ita)
4
5 """
6 Try to detect a D compiler from the list of supported compilers::
7
8 def options(opt):
9 opt.load('compiler_d')
10 def configure(cnf):
11 cnf.load('compiler_d')
12 def build(bld):
13 bld.program(source='main.d', target='app')
14
15 Only two D compilers are really present at the moment:
16
17 * gdc, the ldc compiler having a very similar command-line interface
18 * dmd
19 """
20
21 import os, sys, imp, types
22 from waflib import Utils, Configure, Options, Logs
23
24 def configure(conf):
25 """
26 Try to find a suitable D compiler or raise a :py:class:`waflib.Errors.ConfigurationError`.
27 """
28 for compiler in conf.options.dcheck.split(','):
29 conf.env.stash()
30 conf.start_msg('Checking for %r (d compiler)' % compiler)
31 try:
32 conf.load(compiler)
33 except conf.errors.ConfigurationError as e:
34 conf.env.revert()
35 conf.end_msg(False)
36 Logs.debug('compiler_cxx: %r' % e)
37 else:
38 if conf.env.D:
39 conf.end_msg(conf.env.get_flat('D'))
40 conf.env['COMPILER_D'] = compiler
41 conf.env.D_COMPILER = conf.env.D # TODO remove this, left for compatibility
42 break
43 conf.end_msg(False)
44 else:
45 conf.fatal('no suitable d compiler was found')
46
47 def options(opt):
48 """
49 Restrict the compiler detection from the command-line::
50
51 $ waf configure --check-d-compiler=dmd
52 """
53 d_compiler_opts = opt.add_option_group('D Compiler Options')
54 d_compiler_opts.add_option('--check-d-compiler', default='gdc,dmd', action='store',
55 help='check for the compiler [Default:gdc,dmd]', dest='dcheck')
56 for d_compiler in ['gdc', 'dmd']:
57 opt.load('%s' % d_compiler)
58
0 #!/usr/bin/env python
1 # encoding: utf-8
2
3 import os, sys, imp, types
4 from waflib import Utils, Configure, Options, Logs, Errors
5 from waflib.Tools import fc
6
7 fc_compiler = {
8 'win32' : ['gfortran','ifort'],
9 'darwin' : ['gfortran', 'g95', 'ifort'],
10 'linux' : ['gfortran', 'g95', 'ifort'],
11 'java' : ['gfortran', 'g95', 'ifort'],
12 'default': ['gfortran'],
13 'aix' : ['gfortran']
14 }
15
16 def __list_possible_compiler(platform):
17 try:
18 return fc_compiler[platform]
19 except KeyError:
20 return fc_compiler["default"]
21
22 def configure(conf):
23 """
24 Try to find a suitable Fortran compiler or raise a :py:class:`waflib.Errors.ConfigurationError`.
25 """
26 try: test_for_compiler = conf.options.check_fc
27 except AttributeError: conf.fatal("Add options(opt): opt.load('compiler_fc')")
28 for compiler in test_for_compiler.split():
29 conf.env.stash()
30 conf.start_msg('Checking for %r (fortran compiler)' % compiler)
31 try:
32 conf.load(compiler)
33 except conf.errors.ConfigurationError as e:
34 conf.env.revert()
35 conf.end_msg(False)
36 Logs.debug('compiler_fortran: %r' % e)
37 else:
38 if conf.env['FC']:
39 conf.end_msg(conf.env.get_flat('FC'))
40 conf.env.COMPILER_FORTRAN = compiler
41 break
42 conf.end_msg(False)
43 else:
44 conf.fatal('could not configure a fortran compiler!')
45
46 def options(opt):
47 """
48 Restrict the compiler detection from the command-line::
49
50 $ waf configure --check-fortran-compiler=ifort
51 """
52 opt.load_special_tools('fc_*.py')
53 build_platform = Utils.unversioned_sys_platform()
54 detected_platform = Options.platform
55 possible_compiler_list = __list_possible_compiler(detected_platform)
56 test_for_compiler = ' '.join(possible_compiler_list)
57 fortran_compiler_opts = opt.add_option_group("Fortran Compiler Options")
58 fortran_compiler_opts.add_option('--check-fortran-compiler',
59 default="%s" % test_for_compiler,
60 help='On this platform (%s) the following Fortran Compiler will be checked by default: "%s"' % (detected_platform, test_for_compiler),
61 dest="check_fc")
62
63 for compiler in test_for_compiler.split():
64 opt.load('%s' % compiler)
65
0 #!/usr/bin/env python
1 # encoding: utf-8
2 # Thomas Nagy, 2006-2010 (ita)
3
4 """
5 C# support. A simple example::
6
7 def configure(conf):
8 conf.load('cs')
9 def build(bld):
10 bld(features='cs', source='main.cs', gen='foo')
11
12 Note that the configuration may compile C# snippets::
13
14 FRAG = '''
15 namespace Moo {
16 public class Test { public static int Main(string[] args) { return 0; } }
17 }'''
18 def configure(conf):
19 conf.check(features='cs', fragment=FRAG, compile_filename='test.cs', gen='test.exe',
20 type='exe', csflags=['-pkg:gtk-sharp-2.0'], msg='Checking for Gtksharp support')
21 """
22
23 from waflib import Utils, Task, Options, Logs, Errors
24 from waflib.TaskGen import before_method, after_method, feature
25 from waflib.Tools import ccroot
26 from waflib.Configure import conf
27
28 ccroot.USELIB_VARS['cs'] = set(['CSFLAGS', 'ASSEMBLIES', 'RESOURCES'])
29 ccroot.lib_patterns['csshlib'] = ['%s']
30
31 @feature('cs')
32 @before_method('process_source')
33 def apply_cs(self):
34 """
35 Create a C# task bound to the attribute *cs_task*. There can be only one C# task by task generator.
36 """
37 cs_nodes = []
38 no_nodes = []
39 for x in self.to_nodes(self.source):
40 if x.name.endswith('.cs'):
41 cs_nodes.append(x)
42 else:
43 no_nodes.append(x)
44 self.source = no_nodes
45
46 bintype = getattr(self, 'type', self.gen.endswith('.dll') and 'library' or 'exe')
47 self.cs_task = tsk = self.create_task('mcs', cs_nodes, self.path.find_or_declare(self.gen))
48 tsk.env.CSTYPE = '/target:%s' % bintype
49 tsk.env.OUT = '/out:%s' % tsk.outputs[0].abspath()
50
51 inst_to = getattr(self, 'install_path', bintype=='exe' and '${BINDIR}' or '${LIBDIR}')
52 if inst_to:
53 # note: we are making a copy, so the files added to cs_task.outputs won't be installed automatically
54 mod = getattr(self, 'chmod', bintype=='exe' and Utils.O755 or Utils.O644)
55 self.install_task = self.bld.install_files(inst_to, self.cs_task.outputs[:], env=self.env, chmod=mod)
56
57 @feature('cs')
58 @after_method('apply_cs')
59 def use_cs(self):
60 """
61 C# applications honor the **use** keyword::
62
63 def build(bld):
64 bld(features='cs', source='My.cs', type='library', gen='my.dll', name='mylib')
65 bld(features='cs', source='Hi.cs', includes='.', type='exe', gen='hi.exe', use='mylib', name='hi')
66 """
67 names = self.to_list(getattr(self, 'use', []))
68 get = self.bld.get_tgen_by_name
69 for x in names:
70 try:
71 y = get(x)
72 except Errors.WafError:
73 self.cs_task.env.append_value('CSFLAGS', '/reference:%s' % x)
74 continue
75 y.post()
76
77 tsk = getattr(y, 'cs_task', None) or getattr(y, 'link_task', None)
78 if not tsk:
79 self.bld.fatal('cs task has no link task for use %r' % self)
80 self.cs_task.dep_nodes.extend(tsk.outputs) # dependency
81 self.cs_task.set_run_after(tsk) # order (redundant, the order is infered from the nodes inputs/outputs)
82 self.cs_task.env.append_value('CSFLAGS', '/reference:%s' % tsk.outputs[0].abspath())
83
84 @feature('cs')
85 @after_method('apply_cs', 'use_cs')
86 def debug_cs(self):
87 """
88 The C# targets may create .mdb or .pdb files::
89
90 def build(bld):
91 bld(features='cs', source='My.cs', type='library', gen='my.dll', csdebug='full')
92 # csdebug is a value in [True, 'full', 'pdbonly']
93 """
94 csdebug = getattr(self, 'csdebug', self.env.CSDEBUG)
95 if not csdebug:
96 return
97
98 node = self.cs_task.outputs[0]
99 if self.env.CS_NAME == 'mono':
100 out = node.parent.find_or_declare(node.name + '.mdb')
101 else:
102 out = node.change_ext('.pdb')
103 self.cs_task.outputs.append(out)
104 try:
105 self.install_task.source.append(out)
106 except AttributeError:
107 pass
108
109 if csdebug == 'pdbonly':
110 val = ['/debug+', '/debug:pdbonly']
111 elif csdebug == 'full':
112 val = ['/debug+', '/debug:full']
113 else:
114 val = ['/debug-']
115 self.cs_task.env.append_value('CSFLAGS', val)
116
117
118 class mcs(Task.Task):
119 """
120 Compile C# files
121 """
122 color = 'YELLOW'
123 run_str = '${MCS} ${CSTYPE} ${CSFLAGS} ${ASS_ST:ASSEMBLIES} ${RES_ST:RESOURCES} ${OUT} ${SRC}'
124
125 def configure(conf):
126 """
127 Find a C# compiler, set the variable MCS for the compiler and CS_NAME (mono or csc)
128 """
129 csc = getattr(Options.options, 'cscbinary', None)
130 if csc:
131 conf.env.MCS = csc
132 conf.find_program(['csc', 'mcs', 'gmcs'], var='MCS')
133 conf.env.ASS_ST = '/r:%s'
134 conf.env.RES_ST = '/resource:%s'
135
136 conf.env.CS_NAME = 'csc'
137 if str(conf.env.MCS).lower().find('mcs') > -1:
138 conf.env.CS_NAME = 'mono'
139
140 def options(opt):
141 """
142 Add a command-line option for the configuration::
143
144 $ waf configure --with-csc-binary=/foo/bar/mcs
145 """
146 opt.add_option('--with-csc-binary', type='string', dest='cscbinary')
147
148 class fake_csshlib(Task.Task):
149 """
150 Task used for reading a foreign .net assembly and adding the dependency on it
151 """
152 color = 'YELLOW'
153 inst_to = None
154
155 def runnable_status(self):
156 for x in self.outputs:
157 x.sig = Utils.h_file(x.abspath())
158 return Task.SKIP_ME
159
160 @conf
161 def read_csshlib(self, name, paths=[]):
162 """
163 Read a foreign .net assembly for the *use* system::
164
165 def build(bld):
166 bld.read_csshlib('ManagedLibrary.dll', paths=[bld.env.mylibrarypath])
167 bld(features='cs', source='Hi.cs', type='exe', gen='hi.exe', use='ManagedLibrary.dll')
168
169 :param name: Name of the library
170 :type name: string
171 :param paths: Folders in which the library may be found
172 :type paths: list of string
173 :return: A task generator having the feature *fake_lib* which will call :py:func:`waflib.Tools.ccroot.process_lib`
174 :rtype: :py:class:`waflib.TaskGen.task_gen`
175 """
176 return self(name=name, features='fake_lib', lib_paths=paths, lib_type='csshlib')
177
0 #!/usr/bin/env python
1 # encoding: utf-8
2 # Thomas Nagy, 2005-2010 (ita)
3
4 "Base for c++ programs and libraries"
5
6 from waflib import TaskGen, Task, Utils
7 from waflib.Tools import c_preproc
8 from waflib.Tools.ccroot import link_task, stlink_task
9
10 def cxx_hook(self, node):
11 "Bind the c++ file extensions to the creation of a :py:class:`waflib.Tools.cxx.cxx` instance"
12 return self.create_compiled_task('cxx', node)
13 TaskGen.extension('.cpp','.cc','.cxx','.C','.c++')(cxx_hook) # leave like this for python 2.3
14
15 if not '.c' in TaskGen.task_gen.mappings:
16 TaskGen.task_gen.mappings['.c'] = TaskGen.task_gen.mappings['.cpp']
17
18 class cxx(Task.Task):
19 "Compile C++ files into object files"
20 run_str = '${CXX} ${ARCH_ST:ARCH} ${CXXFLAGS} ${CPPFLAGS} ${FRAMEWORKPATH_ST:FRAMEWORKPATH} ${CPPPATH_ST:INCPATHS} ${DEFINES_ST:DEFINES} ${CXX_SRC_F}${SRC} ${CXX_TGT_F}${TGT}'
21 vars = ['CXXDEPS'] # unused variable to depend on, just in case
22 ext_in = ['.h'] # set the build order easily by using ext_out=['.h']
23 scan = c_preproc.scan
24
25 class cxxprogram(link_task):
26 "Link object files into a c++ program"
27 run_str = '${LINK_CXX} ${LINKFLAGS} ${CXXLNK_SRC_F}${SRC} ${CXXLNK_TGT_F}${TGT[0].abspath()} ${RPATH_ST:RPATH} ${FRAMEWORKPATH_ST:FRAMEWORKPATH} ${FRAMEWORK_ST:FRAMEWORK} ${ARCH_ST:ARCH} ${STLIB_MARKER} ${STLIBPATH_ST:STLIBPATH} ${STLIB_ST:STLIB} ${SHLIB_MARKER} ${LIBPATH_ST:LIBPATH} ${LIB_ST:LIB}'
28 vars = ['LINKDEPS']
29 ext_out = ['.bin']
30 inst_to = '${BINDIR}'
31 chmod = Utils.O755
32
33 class cxxshlib(cxxprogram):
34 "Link object files into a c++ shared library"
35 inst_to = '${LIBDIR}'
36
37 class cxxstlib(stlink_task):
38 "Link object files into a c++ static library"
39 pass # do not remove
40
0 #!/usr/bin/env python
1 # encoding: utf-8
2 # Carlos Rafael Giani, 2007 (dv)
3 # Thomas Nagy, 2007-2010 (ita)
4
5 from waflib import Utils, Task, Errors
6 from waflib.TaskGen import taskgen_method, feature, extension
7 from waflib.Tools import d_scan, d_config
8 from waflib.Tools.ccroot import link_task, stlink_task
9
10 class d(Task.Task):
11 "Compile a d file into an object file"
12 color = 'GREEN'
13 run_str = '${D} ${DFLAGS} ${DINC_ST:INCPATHS} ${D_SRC_F:SRC} ${D_TGT_F:TGT}'
14 scan = d_scan.scan
15
16 class d_with_header(d):
17 "Compile a d file and generate a header"
18 run_str = '${D} ${DFLAGS} ${DINC_ST:INCPATHS} ${D_HDR_F:tgt.outputs[1].bldpath()} ${D_SRC_F:SRC} ${D_TGT_F:tgt.outputs[0].bldpath()}'
19
20 class d_header(Task.Task):
21 "Compile d headers"
22 color = 'BLUE'
23 run_str = '${D} ${D_HEADER} ${SRC}'
24
25 class dprogram(link_task):
26 "Link object files into a d program"
27 run_str = '${D_LINKER} ${LINKFLAGS} ${DLNK_SRC_F}${SRC} ${DLNK_TGT_F:TGT} ${RPATH_ST:RPATH} ${DSTLIB_MARKER} ${DSTLIBPATH_ST:STLIBPATH} ${DSTLIB_ST:STLIB} ${DSHLIB_MARKER} ${DLIBPATH_ST:LIBPATH} ${DSHLIB_ST:LIB}'
28 inst_to = '${BINDIR}'
29 chmod = Utils.O755
30
31 class dshlib(dprogram):
32 "Link object files into a d shared library"
33 inst_to = '${LIBDIR}'
34
35 class dstlib(stlink_task):
36 "Link object files into a d static library"
37 pass # do not remove
38
39 @extension('.d', '.di', '.D')
40 def d_hook(self, node):
41 """
42 Compile *D* files. To get .di files as well as .o files, set the following::
43
44 def build(bld):
45 bld.program(source='foo.d', target='app', generate_headers=True)
46
47 """
48 ext = Utils.destos_to_binfmt(self.env.DEST_OS) == 'pe' and 'obj' or 'o'
49 out = '%s.%d.%s' % (node.name, self.idx, ext)
50 def create_compiled_task(self, name, node):
51 task = self.create_task(name, node, node.parent.find_or_declare(out))
52 try:
53 self.compiled_tasks.append(task)
54 except AttributeError:
55 self.compiled_tasks = [task]
56 return task
57
58 if getattr(self, 'generate_headers', None):
59 tsk = create_compiled_task(self, 'd_with_header', node)
60 tsk.outputs.append(node.change_ext(self.env['DHEADER_ext']))
61 else:
62 tsk = create_compiled_task(self, 'd', node)
63 return tsk
64
65 @taskgen_method
66 def generate_header(self, filename, install_path=None):
67 """
68 See feature request #104::
69
70 def build(bld):
71 tg = bld.program(source='foo.d', target='app')
72 tg.generate_header('blah.d')
73 # is equivalent to:
74 #tg = bld.program(source='foo.d', target='app', header_lst='blah.d')
75
76 :param filename: header to create
77 :type filename: string
78 :param install_path: unused (TODO)
79 """
80 try:
81 self.header_lst.append([filename, install_path])
82 except AttributeError:
83 self.header_lst = [[filename, install_path]]
84
85 @feature('d')
86 def process_header(self):
87 """
88 Process the attribute 'header_lst' to create the d header compilation tasks::
89
90 def build(bld):
91 bld.program(source='foo.d', target='app', header_lst='blah.d')
92 """
93 for i in getattr(self, 'header_lst', []):
94 node = self.path.find_resource(i[0])
95 if not node:
96 raise Errors.WafError('file %r not found on d obj' % i[0])
97 self.create_task('d_header', node, node.change_ext('.di'))
98
0 #!/usr/bin/env python
1 # encoding: utf-8
2 # Thomas Nagy, 2010 (ita)
3
4 from waflib import Utils
5 from waflib.Configure import conf
6
7 @conf
8 def d_platform_flags(self):
9 """
10 Set the extensions dll/so for d programs and libraries
11 """
12 v = self.env
13 if not v.DEST_OS:
14 v.DEST_OS = Utils.unversioned_sys_platform()
15 if Utils.destos_to_binfmt(self.env.DEST_OS) == 'pe':
16 v['dprogram_PATTERN'] = '%s.exe'
17 v['dshlib_PATTERN'] = 'lib%s.dll'
18 v['dstlib_PATTERN'] = 'lib%s.a'
19 else:
20 v['dprogram_PATTERN'] = '%s'
21 v['dshlib_PATTERN'] = 'lib%s.so'
22 v['dstlib_PATTERN'] = 'lib%s.a'
23
24 DLIB = '''
25 version(D_Version2) {
26 import std.stdio;
27 int main() {
28 writefln("phobos2");
29 return 0;
30 }
31 } else {
32 version(Tango) {
33 import tango.stdc.stdio;
34 int main() {
35 printf("tango");
36 return 0;
37 }
38 } else {
39 import std.stdio;
40 int main() {
41 writefln("phobos1");
42 return 0;
43 }
44 }
45 }
46 '''
47 """Detection string for the D standard library"""
48
49 @conf
50 def check_dlibrary(self):
51 """
52 Detect the kind of standard library that comes with the compiler, will set conf.env.DLIBRARY to tango, phobos1 or phobos2.
53 """
54 ret = self.check_cc(features='d dprogram', fragment=DLIB, compile_filename='test.d', execute=True, define_ret=True)
55 self.env.DLIBRARY = ret.strip()
56
0 #!/usr/bin/env python
1 # encoding: utf-8
2 # Thomas Nagy, 2010 (ita)
3
4 """
5 Provide a scanner for finding dependencies on d files
6 """
7
8 import re
9 from waflib import Utils, Logs
10
11 def filter_comments(filename):
12 """
13 :param filename: d file name
14 :type filename: string
15 :rtype: list
16 :return: a list of characters
17 """
18 txt = Utils.readf(filename)
19 i = 0
20 buf = []
21 max = len(txt)
22 begin = 0
23 while i < max:
24 c = txt[i]
25 if c == '"' or c == "'": # skip a string or character literal
26 buf.append(txt[begin:i])
27 delim = c
28 i += 1
29 while i < max:
30 c = txt[i]
31 if c == delim: break
32 elif c == '\\': # skip the character following backslash
33 i += 1
34 i += 1
35 i += 1
36 begin = i
37 elif c == '/': # try to replace a comment with whitespace
38 buf.append(txt[begin:i])
39 i += 1
40 if i == max: break
41 c = txt[i]
42 if c == '+': # eat nesting /+ +/ comment
43 i += 1
44 nesting = 1
45 c = None
46 while i < max:
47 prev = c
48 c = txt[i]
49 if prev == '/' and c == '+':
50 nesting += 1
51 c = None
52 elif prev == '+' and c == '/':
53 nesting -= 1
54 if nesting == 0: break
55 c = None
56 i += 1
57 elif c == '*': # eat /* */ comment
58 i += 1
59 c = None
60 while i < max:
61 prev = c
62 c = txt[i]
63 if prev == '*' and c == '/': break
64 i += 1
65 elif c == '/': # eat // comment
66 i += 1
67 while i < max and txt[i] != '\n':
68 i += 1
69 else: # no comment
70 begin = i - 1
71 continue
72 i += 1
73 begin = i
74 buf.append(' ')
75 else:
76 i += 1
77 buf.append(txt[begin:])
78 return buf
79
80 class d_parser(object):
81 """
82 Parser for d files
83 """
84 def __init__(self, env, incpaths):
85 #self.code = ''
86 #self.module = ''
87 #self.imports = []
88
89 self.allnames = []
90
91 self.re_module = re.compile("module\s+([^;]+)")
92 self.re_import = re.compile("import\s+([^;]+)")
93 self.re_import_bindings = re.compile("([^:]+):(.*)")
94 self.re_import_alias = re.compile("[^=]+=(.+)")
95
96 self.env = env
97
98 self.nodes = []
99 self.names = []
100
101 self.incpaths = incpaths
102
103 def tryfind(self, filename):
104 """
105 Search file a file matching an module/import directive
106
107 :param filename: file to read
108 :type filename: string
109 """
110 found = 0
111 for n in self.incpaths:
112 found = n.find_resource(filename.replace('.', '/') + '.d')
113 if found:
114 self.nodes.append(found)
115 self.waiting.append(found)
116 break
117 if not found:
118 if not filename in self.names:
119 self.names.append(filename)
120
121 def get_strings(self, code):
122 """
123 :param code: d code to parse
124 :type code: string
125 :return: the modules that the code uses
126 :rtype: a list of match objects
127 """
128 #self.imports = []
129 self.module = ''
130 lst = []
131
132 # get the module name (if present)
133
134 mod_name = self.re_module.search(code)
135 if mod_name:
136 self.module = re.sub('\s+', '', mod_name.group(1)) # strip all whitespaces
137
138 # go through the code, have a look at all import occurrences
139
140 # first, lets look at anything beginning with "import" and ending with ";"
141 import_iterator = self.re_import.finditer(code)
142 if import_iterator:
143 for import_match in import_iterator:
144 import_match_str = re.sub('\s+', '', import_match.group(1)) # strip all whitespaces
145
146 # does this end with an import bindings declaration?
147 # (import bindings always terminate the list of imports)
148 bindings_match = self.re_import_bindings.match(import_match_str)
149 if bindings_match:
150 import_match_str = bindings_match.group(1)
151 # if so, extract the part before the ":" (since the module declaration(s) is/are located there)
152
153 # split the matching string into a bunch of strings, separated by a comma
154 matches = import_match_str.split(',')
155
156 for match in matches:
157 alias_match = self.re_import_alias.match(match)
158 if alias_match:
159 # is this an alias declaration? (alias = module name) if so, extract the module name
160 match = alias_match.group(1)
161
162 lst.append(match)
163 return lst
164
165 def start(self, node):
166 """
167 The parsing starts here
168
169 :param node: input file
170 :type node: :py:class:`waflib.Node.Node`
171 """
172 self.waiting = [node]
173 # while the stack is not empty, add the dependencies
174 while self.waiting:
175 nd = self.waiting.pop(0)
176 self.iter(nd)
177
178 def iter(self, node):
179 """
180 Find all the modules that a file depends on, uses :py:meth:`waflib.Tools.d_scan.d_parser.tryfind` to process dependent files
181
182 :param node: input file
183 :type node: :py:class:`waflib.Node.Node`
184 """
185 path = node.abspath() # obtain the absolute path
186 code = "".join(filter_comments(path)) # read the file and filter the comments
187 names = self.get_strings(code) # obtain the import strings
188 for x in names:
189 # optimization
190 if x in self.allnames: continue
191 self.allnames.append(x)
192
193 # for each name, see if it is like a node or not
194 self.tryfind(x)
195
196 def scan(self):
197 "look for .d/.di used by a d file"
198 env = self.env
199 gruik = d_parser(env, self.generator.includes_nodes)
200 node = self.inputs[0]
201 gruik.start(node)
202 nodes = gruik.nodes
203 names = gruik.names
204
205 if Logs.verbose:
206 Logs.debug('deps: deps for %s: %r; unresolved %r' % (str(node), nodes, names))
207 return (nodes, names)
208
0 #!/usr/bin/env python
1 # encoding: utf-8
2 # Ali Sabil, 2007
3
4 """
5 Compile dbus files with **dbus-binding-tool**
6
7 Typical usage::
8
9 def options(opt):
10 opt.load('compiler_c dbus')
11 def configure(conf):
12 conf.load('compiler_c dbus')
13 def build(bld):
14 tg = bld.program(
15 includes = '.',
16 source = bld.path.ant_glob('*.c'),
17 target = 'gnome-hello')
18 tg.add_dbus_file('test.xml', 'test_prefix', 'glib-server')
19 """
20
21 from waflib import Task, Errors
22 from waflib.TaskGen import taskgen_method, before_method
23
24 @taskgen_method
25 def add_dbus_file(self, filename, prefix, mode):
26 """
27 Add a dbus file to the list of dbus files to process. Store them in the attribute *dbus_lst*.
28
29 :param filename: xml file to compile
30 :type filename: string
31 :param prefix: dbus binding tool prefix (--prefix=prefix)
32 :type prefix: string
33 :param mode: dbus binding tool mode (--mode=mode)
34 :type mode: string
35 """
36 if not hasattr(self, 'dbus_lst'):
37 self.dbus_lst = []
38 if not 'process_dbus' in self.meths:
39 self.meths.append('process_dbus')
40 self.dbus_lst.append([filename, prefix, mode])
41
42 @before_method('apply_core')
43 def process_dbus(self):
44 """
45 Process the dbus files stored in the attribute *dbus_lst* to create :py:class:`waflib.Tools.dbus.dbus_binding_tool` instances.
46 """
47 for filename, prefix, mode in getattr(self, 'dbus_lst', []):
48 node = self.path.find_resource(filename)
49 if not node:
50 raise Errors.WafError('file not found ' + filename)
51 tsk = self.create_task('dbus_binding_tool', node, node.change_ext('.h'))
52 tsk.env.DBUS_BINDING_TOOL_PREFIX = prefix
53 tsk.env.DBUS_BINDING_TOOL_MODE = mode
54
55 class dbus_binding_tool(Task.Task):
56 """
57 Compile a dbus file
58 """
59 color = 'BLUE'
60 ext_out = ['.h']
61 run_str = '${DBUS_BINDING_TOOL} --prefix=${DBUS_BINDING_TOOL_PREFIX} --mode=${DBUS_BINDING_TOOL_MODE} --output=${TGT} ${SRC}'
62 shell = True # temporary workaround for #795
63
64 def configure(conf):
65 """
66 Detect the program dbus-binding-tool and set the *conf.env.DBUS_BINDING_TOOL*
67 """
68 dbus_binding_tool = conf.find_program('dbus-binding-tool', var='DBUS_BINDING_TOOL')
69
0 #!/usr/bin/env python
1 # encoding: utf-8
2 # Carlos Rafael Giani, 2007 (dv)
3 # Thomas Nagy, 2008-2010 (ita)
4
5 import sys
6 from waflib.Tools import ar, d
7 from waflib.Configure import conf
8
9 @conf
10 def find_dmd(conf):
11 """
12 Find the program *dmd* or *ldc* and set the variable *D*
13 """
14 conf.find_program(['dmd', 'ldc'], var='D')
15
16 @conf
17 def common_flags_ldc(conf):
18 """
19 Set the D flags required by *ldc*
20 """
21 v = conf.env
22 v['DFLAGS'] = ['-d-version=Posix']
23 v['LINKFLAGS'] = []
24 v['DFLAGS_dshlib'] = ['-relocation-model=pic']
25
26 @conf
27 def common_flags_dmd(conf):
28 """
29 Set the flags required by *dmd*
30 """
31
32 v = conf.env
33
34 # _DFLAGS _DIMPORTFLAGS
35
36 # Compiler is dmd so 'gdc' part will be ignored, just
37 # ensure key is there, so wscript can append flags to it
38 #v['DFLAGS'] = ['-version=Posix']
39
40 v['D_SRC_F'] = ['-c']
41 v['D_TGT_F'] = '-of%s'
42
43 # linker
44 v['D_LINKER'] = v['D']
45 v['DLNK_SRC_F'] = ''
46 v['DLNK_TGT_F'] = '-of%s'
47 v['DINC_ST'] = '-I%s'
48
49 v['DSHLIB_MARKER'] = v['DSTLIB_MARKER'] = ''
50 v['DSTLIB_ST'] = v['DSHLIB_ST'] = '-L-l%s'
51 v['DSTLIBPATH_ST'] = v['DLIBPATH_ST'] = '-L-L%s'
52
53 v['LINKFLAGS_dprogram']= ['-quiet']
54
55 v['DFLAGS_dshlib'] = ['-fPIC']
56 v['LINKFLAGS_dshlib'] = ['-L-shared']
57
58 v['DHEADER_ext'] = '.di'
59 v.DFLAGS_d_with_header = ['-H', '-Hf']
60 v['D_HDR_F'] = '%s'
61
62 def configure(conf):
63 """
64 Configuration for dmd/ldc
65 """
66 conf.find_dmd()
67
68 if sys.platform == 'win32':
69 out = conf.cmd_and_log([conf.env.D, '--help'])
70 if out.find("D Compiler v2.") > -1:
71 conf.fatal('dmd2 on Windows is not supported, use gdc or ldc instead')
72
73 conf.load('ar')
74 conf.load('d')
75 conf.common_flags_dmd()
76 conf.d_platform_flags()
77
78 if str(conf.env.D).find('ldc') > -1:
79 conf.common_flags_ldc()
80
0 #! /usr/bin/env python
1 # encoding: utf-8
2 # Thomas Nagy, 2011 (ita)
3
4 """
5 errheck: Search for common mistakes
6
7 There is a performance hit, so this tool is only loaded when running "waf -v"
8 """
9
10 typos = {
11 'feature':'features',
12 'sources':'source',
13 'targets':'target',
14 'include':'includes',
15 'export_include':'export_includes',
16 'define':'defines',
17 'importpath':'includes',
18 'installpath':'install_path',
19 }
20
21 meths_typos = ['__call__', 'program', 'shlib', 'stlib', 'objects']
22
23 from waflib import Logs, Build, Node, Task, TaskGen, ConfigSet, Errors, Utils
24 import waflib.Tools.ccroot
25
26 def check_same_targets(self):
27 mp = Utils.defaultdict(list)
28 uids = {}
29
30 def check_task(tsk):
31 if not isinstance(tsk, Task.Task):
32 return
33
34 for node in tsk.outputs:
35 mp[node].append(tsk)
36 try:
37 uids[tsk.uid()].append(tsk)
38 except:
39 uids[tsk.uid()] = [tsk]
40
41 for g in self.groups:
42 for tg in g:
43 try:
44 for tsk in tg.tasks:
45 check_task(tsk)
46 except AttributeError:
47 # raised if not a task generator, which should be uncommon
48 check_task(tg)
49
50 dupe = False
51 for (k, v) in mp.items():
52 if len(v) > 1:
53 dupe = True
54 msg = '* Node %r is created by more than once%s. The task generators are:' % (k, Logs.verbose == 1 and " (full message on 'waf -v -v')" or "")
55 Logs.error(msg)
56 for x in v:
57 if Logs.verbose > 1:
58 Logs.error(' %d. %r' % (1 + v.index(x), x.generator))
59 else:
60 Logs.error(' %d. %r in %r' % (1 + v.index(x), x.generator.name, getattr(x.generator, 'path', None)))
61
62 if not dupe:
63 for (k, v) in uids.items():
64 if len(v) > 1:
65 Logs.error('* Several tasks use the same identifier. Please check the information on\n http://waf.googlecode.com/git/docs/apidocs/Task.html#waflib.Task.Task.uid')
66 for tsk in v:
67 Logs.error(' - object %r (%r) defined in %r' % (tsk.__class__.__name__, tsk, tsk.generator))
68
69 def check_invalid_constraints(self):
70 feat = set([])
71 for x in list(TaskGen.feats.values()):
72 feat.union(set(x))
73 for (x, y) in TaskGen.task_gen.prec.items():
74 feat.add(x)
75 feat.union(set(y))
76 ext = set([])
77 for x in TaskGen.task_gen.mappings.values():
78 ext.add(x.__name__)
79 invalid = ext & feat
80 if invalid:
81 Logs.error('The methods %r have invalid annotations: @extension <-> @feature/@before_method/@after_method' % list(invalid))
82
83 # the build scripts have been read, so we can check for invalid after/before attributes on task classes
84 for cls in list(Task.classes.values()):
85 for x in ('before', 'after'):
86 for y in Utils.to_list(getattr(cls, x, [])):
87 if not Task.classes.get(y, None):
88 Logs.error('Erroneous order constraint %r=%r on task class %r' % (x, y, cls.__name__))
89 if getattr(cls, 'rule', None):
90 Logs.error('Erroneous attribute "rule" on task class %r (rename to "run_str")' % cls.__name__)
91
92 def replace(m):
93 """
94 We could add properties, but they would not work in some cases:
95 bld.program(...) requires 'source' in the attributes
96 """
97 oldcall = getattr(Build.BuildContext, m)
98 def call(self, *k, **kw):
99 ret = oldcall(self, *k, **kw)
100 for x in typos:
101 if x in kw:
102 err = True
103 Logs.error('Fix the typo %r -> %r on %r' % (x, typos[x], ret))
104 return ret
105 setattr(Build.BuildContext, m, call)
106
107 def enhance_lib():
108 """
109 modify existing classes and methods
110 """
111 for m in meths_typos:
112 replace(m)
113
114 # catch '..' in ant_glob patterns
115 def ant_glob(self, *k, **kw):
116 if k:
117 lst=Utils.to_list(k[0])
118 for pat in lst:
119 if '..' in pat.split('/'):
120 Logs.error("In ant_glob pattern %r: '..' means 'two dots', not 'parent directory'" % k[0])
121 if kw.get('remove', True):
122 try:
123 if self.is_child_of(self.ctx.bldnode) and not kw.get('quiet', False):
124 Logs.error('Using ant_glob on the build folder (%r) is dangerous (quiet=True to disable this warning)' % self)
125 except AttributeError:
126 pass
127 return self.old_ant_glob(*k, **kw)
128 Node.Node.old_ant_glob = Node.Node.ant_glob
129 Node.Node.ant_glob = ant_glob
130
131 # catch conflicting ext_in/ext_out/before/after declarations
132 old = Task.is_before
133 def is_before(t1, t2):
134 ret = old(t1, t2)
135 if ret and old(t2, t1):
136 Logs.error('Contradictory order constraints in classes %r %r' % (t1, t2))
137 return ret
138 Task.is_before = is_before
139
140 # check for bld(feature='cshlib') where no 'c' is given - this can be either a mistake or on purpose
141 # so we only issue a warning
142 def check_err_features(self):
143 lst = self.to_list(self.features)
144 if 'shlib' in lst:
145 Logs.error('feature shlib -> cshlib, dshlib or cxxshlib')
146 for x in ('c', 'cxx', 'd', 'fc'):
147 if not x in lst and lst and lst[0] in [x+y for y in ('program', 'shlib', 'stlib')]:
148 Logs.error('%r features is probably missing %r' % (self, x))
149 TaskGen.feature('*')(check_err_features)
150
151 # check for erroneous order constraints
152 def check_err_order(self):
153 if not hasattr(self, 'rule'):
154 for x in ('before', 'after', 'ext_in', 'ext_out'):
155 if hasattr(self, x):
156 Logs.warn('Erroneous order constraint %r on non-rule based task generator %r' % (x, self))
157 else:
158 for x in ('before', 'after'):
159 for y in self.to_list(getattr(self, x, [])):
160 if not Task.classes.get(y, None):
161 Logs.error('Erroneous order constraint %s=%r on %r' % (x, y, self))
162 TaskGen.feature('*')(check_err_order)
163
164 # check for @extension used with @feature/@before_method/@after_method
165 def check_compile(self):
166 check_invalid_constraints(self)
167 try:
168 ret = self.orig_compile()
169 finally:
170 check_same_targets(self)
171 return ret
172 Build.BuildContext.orig_compile = Build.BuildContext.compile
173 Build.BuildContext.compile = check_compile
174
175 # check for invalid build groups #914
176 def use_rec(self, name, **kw):
177 try:
178 y = self.bld.get_tgen_by_name(name)
179 except Errors.WafError:
180 pass
181 else:
182 idx = self.bld.get_group_idx(self)
183 odx = self.bld.get_group_idx(y)
184 if odx > idx:
185 msg = "Invalid 'use' across build groups:"
186 if Logs.verbose > 1:
187 msg += '\n target %r\n uses:\n %r' % (self, y)
188 else:
189 msg += " %r uses %r (try 'waf -v -v' for the full error)" % (self.name, name)
190 raise Errors.WafError(msg)
191 self.orig_use_rec(name, **kw)
192 TaskGen.task_gen.orig_use_rec = TaskGen.task_gen.use_rec
193 TaskGen.task_gen.use_rec = use_rec
194
195 # check for env.append
196 def getattri(self, name, default=None):
197 if name == 'append' or name == 'add':
198 raise Errors.WafError('env.append and env.add do not exist: use env.append_value/env.append_unique')
199 elif name == 'prepend':
200 raise Errors.WafError('env.prepend does not exist: use env.prepend_value')
201 if name in self.__slots__:
202 return object.__getattr__(self, name, default)
203 else:
204 return self[name]
205 ConfigSet.ConfigSet.__getattr__ = getattri
206
207
208 def options(opt):
209 """
210 Add a few methods
211 """
212 enhance_lib()
213
214 def configure(conf):
215 pass
216
0 #! /usr/bin/env python
1 # encoding: utf-8
2 # DC 2008
3 # Thomas Nagy 2010 (ita)
4
5 """
6 fortran support
7 """
8
9 import re
10
11 from waflib import Utils, Task, TaskGen, Logs
12 from waflib.Tools import ccroot, fc_config, fc_scan
13 from waflib.TaskGen import feature, before_method, after_method, extension
14 from waflib.Configure import conf
15
16 ccroot.USELIB_VARS['fc'] = set(['FCFLAGS', 'DEFINES', 'INCLUDES'])
17 ccroot.USELIB_VARS['fcprogram_test'] = ccroot.USELIB_VARS['fcprogram'] = set(['LIB', 'STLIB', 'LIBPATH', 'STLIBPATH', 'LINKFLAGS', 'RPATH', 'LINKDEPS'])
18 ccroot.USELIB_VARS['fcshlib'] = set(['LIB', 'STLIB', 'LIBPATH', 'STLIBPATH', 'LINKFLAGS', 'RPATH', 'LINKDEPS'])
19 ccroot.USELIB_VARS['fcstlib'] = set(['ARFLAGS', 'LINKDEPS'])
20
21 @feature('fcprogram', 'fcshlib', 'fcstlib', 'fcprogram_test')
22 def dummy(self):
23 pass
24
25 @extension('.f', '.f90', '.F', '.F90', '.for', '.FOR')
26 def fc_hook(self, node):
27 "Bind the typical Fortran file extensions to the creation of a :py:class:`waflib.Tools.fc.fc` instance"
28 return self.create_compiled_task('fc', node)
29
30 @conf
31 def modfile(conf, name):
32 """
33 Turn a module name into the right module file name.
34 Defaults to all lower case.
35 """
36 return {'lower' :name.lower() + '.mod',
37 'lower.MOD' :name.upper() + '.MOD',
38 'UPPER.mod' :name.upper() + '.mod',
39 'UPPER' :name.upper() + '.MOD'}[conf.env.FC_MOD_CAPITALIZATION or 'lower']
40
41 def get_fortran_tasks(tsk):
42 """
43 Obtain all other fortran tasks from the same build group. Those tasks must not have
44 the attribute 'nomod' or 'mod_fortran_done'
45 """
46 bld = tsk.generator.bld
47 tasks = bld.get_tasks_group(bld.get_group_idx(tsk.generator))
48 return [x for x in tasks if isinstance(x, fc) and not getattr(x, 'nomod', None) and not getattr(x, 'mod_fortran_done', None)]
49
50 class fc(Task.Task):
51 """
52 The fortran tasks can only run when all fortran tasks in the current group are ready to be executed
53 This may cause a deadlock if another fortran task is waiting for something that cannot happen (circular dependency)
54 in this case, set the 'nomod=True' on those tasks instances to break the loop
55 """
56
57 color = 'GREEN'
58 run_str = '${FC} ${FCFLAGS} ${FCINCPATH_ST:INCPATHS} ${FCDEFINES_ST:DEFINES} ${_FCMODOUTFLAGS} ${FC_TGT_F}${TGT[0].abspath()} ${FC_SRC_F}${SRC[0].abspath()}'
59 vars = ["FORTRANMODPATHFLAG"]
60
61 def scan(self):
62 """scanner for fortran dependencies"""
63 tmp = fc_scan.fortran_parser(self.generator.includes_nodes)
64 tmp.task = self
65 tmp.start(self.inputs[0])
66 if Logs.verbose:
67 Logs.debug('deps: deps for %r: %r; unresolved %r' % (self.inputs, tmp.nodes, tmp.names))
68 return (tmp.nodes, tmp.names)
69
70 def runnable_status(self):
71 """
72 Set the mod file outputs and the dependencies on the mod files over all the fortran tasks
73 executed by the main thread so there are no concurrency issues
74 """
75 if getattr(self, 'mod_fortran_done', None):
76 return super(fc, self).runnable_status()
77
78 # now, if we reach this part it is because this fortran task is the first in the list
79 bld = self.generator.bld
80
81 # obtain the fortran tasks
82 lst = get_fortran_tasks(self)
83
84 # disable this method for other tasks
85 for tsk in lst:
86 tsk.mod_fortran_done = True
87
88 # wait for all the .f tasks to be ready for execution
89 # and ensure that the scanners are called at least once
90 for tsk in lst:
91 ret = tsk.runnable_status()
92 if ret == Task.ASK_LATER:
93 # we have to wait for one of the other fortran tasks to be ready
94 # this may deadlock if there are dependencies between the fortran tasks
95 # but this should not happen (we are setting them here!)
96 for x in lst:
97 x.mod_fortran_done = None
98
99 # TODO sort the list of tasks in bld.producer.outstanding to put all fortran tasks at the end
100 return Task.ASK_LATER
101
102 ins = Utils.defaultdict(set)
103 outs = Utils.defaultdict(set)
104
105 # the .mod files to create
106 for tsk in lst:
107 key = tsk.uid()
108 for x in bld.raw_deps[key]:
109 if x.startswith('MOD@'):
110 name = bld.modfile(x.replace('MOD@', ''))
111 node = bld.srcnode.find_or_declare(name)
112 tsk.set_outputs(node)
113 outs[id(node)].add(tsk)
114
115 # the .mod files to use
116 for tsk in lst:
117 key = tsk.uid()
118 for x in bld.raw_deps[key]:
119 if x.startswith('USE@'):
120 name = bld.modfile(x.replace('USE@', ''))
121 node = bld.srcnode.find_resource(name)
122 if node and node not in tsk.outputs:
123 if not node in bld.node_deps[key]:
124 bld.node_deps[key].append(node)
125 ins[id(node)].add(tsk)
126
127 # if the intersection matches, set the order
128 for k in ins.keys():
129 for a in ins[k]:
130 a.run_after.update(outs[k])
131
132 # the scanner cannot output nodes, so we have to set them
133 # ourselves as task.dep_nodes (additional input nodes)
134 tmp = []
135 for t in outs[k]:
136 tmp.extend(t.outputs)
137 a.dep_nodes.extend(tmp)
138
139 # old python versions
140 try:
141 a.dep_nodes.sort(key=lambda x: x.abspath())
142 except:
143 a.dep_nodes.sort(lambda x, y: cmp(x.abspath(), y.abspath()))
144
145 # the task objects have changed: clear the signature cache
146 for tsk in lst:
147 try:
148 delattr(tsk, 'cache_sig')
149 except AttributeError:
150 pass
151
152 return super(fc, self).runnable_status()
153
154 class fcprogram(ccroot.link_task):
155 """Link fortran programs"""
156 color = 'YELLOW'
157 run_str = '${FC} ${LINKFLAGS} ${FCLNK_SRC_F}${SRC} ${FCLNK_TGT_F}${TGT[0].abspath()} ${RPATH_ST:RPATH} ${FCSTLIB_MARKER} ${FCSTLIBPATH_ST:STLIBPATH} ${FCSTLIB_ST:STLIB} ${FCSHLIB_MARKER} ${FCLIBPATH_ST:LIBPATH} ${FCLIB_ST:LIB}'
158 inst_to = '${BINDIR}'
159 chmod = Utils.O755
160
161 class fcshlib(fcprogram):
162 """Link fortran libraries"""
163 inst_to = '${LIBDIR}'
164
165 class fcprogram_test(fcprogram):
166 """Custom link task to obtain the compiler outputs for fortran configuration tests"""
167
168 def can_retrieve_cache(self):
169 """This task is always executed"""
170 return False
171
172 def runnable_status(self):
173 """This task is always executed"""
174 ret = super(fcprogram_test, self).runnable_status()
175 if ret == Task.SKIP_ME:
176 ret = Task.RUN_ME
177 return ret
178
179 def exec_command(self, cmd, **kw):
180 """Store the compiler std our/err onto the build context, to bld.out + bld.err"""
181 bld = self.generator.bld
182
183 kw['shell'] = isinstance(cmd, str)
184 kw['stdout'] = kw['stderr'] = Utils.subprocess.PIPE
185 kw['cwd'] = bld.variant_dir
186 bld.out = bld.err = ''
187
188 bld.to_log('command: %s\n' % cmd)
189
190 kw['output'] = 0
191 try:
192 (bld.out, bld.err) = bld.cmd_and_log(cmd, **kw)
193 except Exception as e:
194 return -1
195
196 if bld.out:
197 bld.to_log("out: %s\n" % bld.out)
198 if bld.err:
199 bld.to_log("err: %s\n" % bld.err)
200
201 class fcstlib(ccroot.stlink_task):
202 """Link fortran static libraries (uses ar by default)"""
203 pass # do not remove the pass statement
204
0 #! /usr/bin/env python
1 # encoding: utf-8
2 # DC 2008
3 # Thomas Nagy 2010 (ita)
4
5 """
6 Fortran configuration helpers
7 """
8
9 import re, shutil, os, sys, string, shlex
10 from waflib.Configure import conf
11 from waflib.TaskGen import feature, after_method, before_method
12 from waflib import Build, Utils
13
14 FC_FRAGMENT = ' program main\n end program main\n'
15 FC_FRAGMENT2 = ' PROGRAM MAIN\n END\n' # what's the actual difference between these?
16
17 @conf
18 def fc_flags(conf):
19 """
20 Define common fortran configuration flags and file extensions
21 """
22 v = conf.env
23
24 v['FC_SRC_F'] = []
25 v['FC_TGT_F'] = ['-c', '-o']
26 v['FCINCPATH_ST'] = '-I%s'
27 v['FCDEFINES_ST'] = '-D%s'
28
29 if not v['LINK_FC']: v['LINK_FC'] = v['FC']
30 v['FCLNK_SRC_F'] = []
31 v['FCLNK_TGT_F'] = ['-o']
32
33 v['FCFLAGS_fcshlib'] = ['-fpic']
34 v['LINKFLAGS_fcshlib'] = ['-shared']
35 v['fcshlib_PATTERN'] = 'lib%s.so'
36
37 v['fcstlib_PATTERN'] = 'lib%s.a'
38
39 v['FCLIB_ST'] = '-l%s'
40 v['FCLIBPATH_ST'] = '-L%s'
41 v['FCSTLIB_ST'] = '-l%s'
42 v['FCSTLIBPATH_ST'] = '-L%s'
43 v['FCSTLIB_MARKER'] = '-Wl,-Bstatic'
44 v['FCSHLIB_MARKER'] = '-Wl,-Bdynamic'
45
46 v['SONAME_ST'] = '-Wl,-h,%s'
47
48
49 @conf
50 def check_fortran(self, *k, **kw):
51 """See if the fortran compiler works by compiling a simple fortran program"""
52 self.check_cc(
53 fragment = FC_FRAGMENT,
54 compile_filename = 'test.f',
55 features = 'fc fcprogram',
56 msg = 'Compiling a simple fortran app')
57
58 @conf
59 def check_fc(self, *k, **kw):
60 """
61 Same as :py:func:`waflib.Tools.c_config.check` but default to the *Fortran* programming language
62 (Overriding the C defaults in :py:func:`waflib.Tools.c_config.validate_c` here)
63 """
64 kw['compiler'] = 'fc'
65 if not 'compile_mode' in kw:
66 kw['compile_mode'] = 'fc'
67 if not 'type' in kw:
68 kw['type'] = 'fcprogram'
69 if not 'compile_filename' in kw:
70 kw['compile_filename'] = 'test.f90'
71 if not 'code' in kw:
72 kw['code'] = FC_FRAGMENT
73 return self.check(*k, **kw)
74
75 # ------------------------------------------------------------------------
76 # --- These are the default platform modifiers, refactored here for
77 # convenience. gfortran and g95 have much overlap.
78 # ------------------------------------------------------------------------
79
80 @conf
81 def fortran_modifier_darwin(conf):
82 """
83 Define fortran flags and extensions for the OSX systems
84 """
85 v = conf.env
86 v['FCFLAGS_fcshlib'] = ['-fPIC', '-compatibility_version', '1', '-current_version', '1']
87 v['LINKFLAGS_fcshlib'] = ['-dynamiclib']
88 v['fcshlib_PATTERN'] = 'lib%s.dylib'
89 v['FRAMEWORKPATH_ST'] = '-F%s'
90 v['FRAMEWORK_ST'] = '-framework %s'
91
92 v['LINKFLAGS_fcstlib'] = []
93
94 v['FCSHLIB_MARKER'] = ''
95 v['FCSTLIB_MARKER'] = ''
96 v['SONAME_ST'] = ''
97
98
99 @conf
100 def fortran_modifier_win32(conf):
101 """Define fortran flags for the windows platforms"""
102 v = conf.env
103 v['fcprogram_PATTERN'] = v['fcprogram_test_PATTERN'] = '%s.exe'
104
105 v['fcshlib_PATTERN'] = '%s.dll'
106 v['implib_PATTERN'] = 'lib%s.dll.a'
107 v['IMPLIB_ST'] = '-Wl,--out-implib,%s'
108
109 v['FCFLAGS_fcshlib'] = []
110
111 v.append_value('FCFLAGS_fcshlib', ['-DDLL_EXPORT']) # TODO adding nonstandard defines like this DLL_EXPORT is not a good idea
112
113 # Auto-import is enabled by default even without this option,
114 # but enabling it explicitly has the nice effect of suppressing the rather boring, debug-level messages
115 # that the linker emits otherwise.
116 v.append_value('LINKFLAGS', ['-Wl,--enable-auto-import'])
117
118 @conf
119 def fortran_modifier_cygwin(conf):
120 """Define fortran flags for use on cygwin"""
121 fortran_modifier_win32(conf)
122 v = conf.env
123 v['fcshlib_PATTERN'] = 'cyg%s.dll'
124 v.append_value('LINKFLAGS_fcshlib', ['-Wl,--enable-auto-image-base'])
125 v['FCFLAGS_fcshlib'] = []
126 # ------------------------------------------------------------------------
127
128 @conf
129 def check_fortran_dummy_main(self, *k, **kw):
130 """
131 Guess if a main function is needed by compiling a code snippet with
132 the C compiler and link with the Fortran compiler
133
134 TODO: (DC)
135 - handling dialects (F77, F90, etc... -> needs core support first)
136 - fix dummy main check (AC_FC_DUMMY_MAIN vs AC_FC_MAIN)
137
138 TODO: what does the above mean? (ita)
139 """
140
141 if not self.env.CC:
142 self.fatal('A c compiler is required for check_fortran_dummy_main')
143
144 lst = ['MAIN__', '__MAIN', '_MAIN', 'MAIN_', 'MAIN']
145 lst.extend([m.lower() for m in lst])
146 lst.append('')
147
148 self.start_msg('Detecting whether we need a dummy main')
149 for main in lst:
150 kw['fortran_main'] = main
151 try:
152 self.check_cc(
153 fragment = 'int %s() { return 0; }\n' % (main or 'test'),
154 features = 'c fcprogram',
155 mandatory = True
156 )
157 if not main:
158 self.env.FC_MAIN = -1
159 self.end_msg('no')
160 else:
161 self.env.FC_MAIN = main
162 self.end_msg('yes %s' % main)
163 break
164 except self.errors.ConfigurationError:
165 pass
166 else:
167 self.end_msg('not found')
168 self.fatal('could not detect whether fortran requires a dummy main, see the config.log')
169
170 # ------------------------------------------------------------------------
171
172 GCC_DRIVER_LINE = re.compile('^Driving:')
173 POSIX_STATIC_EXT = re.compile('\S+\.a')
174 POSIX_LIB_FLAGS = re.compile('-l\S+')
175
176 @conf
177 def is_link_verbose(self, txt):
178 """Return True if 'useful' link options can be found in txt"""
179 assert isinstance(txt, str)
180 for line in txt.splitlines():
181 if not GCC_DRIVER_LINE.search(line):
182 if POSIX_STATIC_EXT.search(line) or POSIX_LIB_FLAGS.search(line):
183 return True
184 return False
185
186 @conf
187 def check_fortran_verbose_flag(self, *k, **kw):
188 """
189 Check what kind of verbose (-v) flag works, then set it to env.FC_VERBOSE_FLAG
190 """
191 self.start_msg('fortran link verbose flag')
192 for x in ['-v', '--verbose', '-verbose', '-V']:
193 try:
194 self.check_cc(
195 features = 'fc fcprogram_test',
196 fragment = FC_FRAGMENT2,
197 compile_filename = 'test.f',
198 linkflags = [x],
199 mandatory=True
200 )
201 except self.errors.ConfigurationError:
202 pass
203 else:
204 # output is on stderr or stdout (for xlf)
205 if self.is_link_verbose(self.test_bld.err) or self.is_link_verbose(self.test_bld.out):
206 self.end_msg(x)
207 break
208 else:
209 self.end_msg('failure')
210 self.fatal('Could not obtain the fortran link verbose flag (see config.log)')
211
212 self.env.FC_VERBOSE_FLAG = x
213 return x
214
215 # ------------------------------------------------------------------------
216
217 # linkflags which match those are ignored
218 LINKFLAGS_IGNORED = [r'-lang*', r'-lcrt[a-zA-Z0-9\.]*\.o', r'-lc$', r'-lSystem', r'-libmil', r'-LIST:*', r'-LNO:*']
219 if os.name == 'nt':
220 LINKFLAGS_IGNORED.extend([r'-lfrt*', r'-luser32', r'-lkernel32', r'-ladvapi32', r'-lmsvcrt', r'-lshell32', r'-lmingw', r'-lmoldname'])
221 else:
222 LINKFLAGS_IGNORED.append(r'-lgcc*')
223 RLINKFLAGS_IGNORED = [re.compile(f) for f in LINKFLAGS_IGNORED]
224
225 def _match_ignore(line):
226 """Returns True if the line should be ignored (fortran test for verbosity)."""
227 for i in RLINKFLAGS_IGNORED:
228 if i.match(line):
229 return True
230 return False
231
232 def parse_fortran_link(lines):
233 """Given the output of verbose link of Fortran compiler, this returns a
234 list of flags necessary for linking using the standard linker."""
235 # TODO: On windows ?
236 final_flags = []
237 for line in lines:
238 if not GCC_DRIVER_LINE.match(line):
239 _parse_flink_line(line, final_flags)
240 return final_flags
241
242 SPACE_OPTS = re.compile('^-[LRuYz]$')
243 NOSPACE_OPTS = re.compile('^-[RL]')
244
245 def _parse_flink_line(line, final_flags):
246 """private"""
247 lexer = shlex.shlex(line, posix = True)
248 lexer.whitespace_split = True
249
250 t = lexer.get_token()
251 tmp_flags = []
252 while t:
253 def parse(token):
254 # Here we go (convention for wildcard is shell, not regex !)
255 # 1 TODO: we first get some root .a libraries
256 # 2 TODO: take everything starting by -bI:*
257 # 3 Ignore the following flags: -lang* | -lcrt*.o | -lc |
258 # -lgcc* | -lSystem | -libmil | -LANG:=* | -LIST:* | -LNO:*)
259 # 4 take into account -lkernel32
260 # 5 For options of the kind -[[LRuYz]], as they take one argument
261 # after, the actual option is the next token
262 # 6 For -YP,*: take and replace by -Larg where arg is the old
263 # argument
264 # 7 For -[lLR]*: take
265
266 # step 3
267 if _match_ignore(token):
268 pass
269 # step 4
270 elif token.startswith('-lkernel32') and sys.platform == 'cygwin':
271 tmp_flags.append(token)
272 # step 5
273 elif SPACE_OPTS.match(token):
274 t = lexer.get_token()
275 if t.startswith('P,'):
276 t = t[2:]
277 for opt in t.split(os.pathsep):
278 tmp_flags.append('-L%s' % opt)
279 # step 6
280 elif NOSPACE_OPTS.match(token):
281 tmp_flags.append(token)
282 # step 7
283 elif POSIX_LIB_FLAGS.match(token):
284 tmp_flags.append(token)
285 else:
286 # ignore anything not explicitely taken into account
287 pass
288
289 t = lexer.get_token()
290 return t
291 t = parse(t)
292
293 final_flags.extend(tmp_flags)
294 return final_flags
295
296 @conf
297 def check_fortran_clib(self, autoadd=True, *k, **kw):
298 """
299 Obtain the flags for linking with the C library
300 if this check works, add uselib='CLIB' to your task generators
301 """
302 if not self.env.FC_VERBOSE_FLAG:
303 self.fatal('env.FC_VERBOSE_FLAG is not set: execute check_fortran_verbose_flag?')
304
305 self.start_msg('Getting fortran runtime link flags')
306 try:
307 self.check_cc(
308 fragment = FC_FRAGMENT2,
309 compile_filename = 'test.f',
310 features = 'fc fcprogram_test',
311 linkflags = [self.env.FC_VERBOSE_FLAG]
312 )
313 except:
314 self.end_msg(False)
315 if kw.get('mandatory', True):
316 conf.fatal('Could not find the c library flags')
317 else:
318 out = self.test_bld.err
319 flags = parse_fortran_link(out.splitlines())
320 self.end_msg('ok (%s)' % ' '.join(flags))
321 self.env.LINKFLAGS_CLIB = flags
322 return flags
323 return []
324
325 def getoutput(conf, cmd, stdin=False):
326 """
327 TODO a bit redundant, can be removed anytime
328 """
329 if stdin:
330 stdin = Utils.subprocess.PIPE
331 else:
332 stdin = None
333 env = conf.env.env or None
334 try:
335 p = Utils.subprocess.Popen(cmd, stdin=stdin, stdout=Utils.subprocess.PIPE, stderr=Utils.subprocess.PIPE, env=env)
336 if stdin:
337 p.stdin.write('\n'.encode())
338 stdout, stderr = p.communicate()
339 except:
340 conf.fatal('could not determine the compiler version %r' % cmd)
341 else:
342 if not isinstance(stdout, str):
343 stdout = stdout.decode(sys.stdout.encoding)
344 if not isinstance(stderr, str):
345 stderr = stderr.decode(sys.stdout.encoding)
346 return stdout, stderr
347
348 # ------------------------------------------------------------------------
349
350 ROUTINES_CODE = """\
351 subroutine foobar()
352 return
353 end
354 subroutine foo_bar()
355 return
356 end
357 """
358
359 MAIN_CODE = """
360 void %(dummy_func_nounder)s(void);
361 void %(dummy_func_under)s(void);
362 int %(main_func_name)s() {
363 %(dummy_func_nounder)s();
364 %(dummy_func_under)s();
365 return 0;
366 }
367 """
368
369 @feature('link_main_routines_func')
370 @before_method('process_source')
371 def link_main_routines_tg_method(self):
372 """
373 The configuration test declares a unique task generator,
374 so we create other task generators from there for fortran link tests
375 """
376 def write_test_file(task):
377 task.outputs[0].write(task.generator.code)
378 bld = self.bld
379 bld(rule=write_test_file, target='main.c', code=MAIN_CODE % self.__dict__)
380 bld(rule=write_test_file, target='test.f', code=ROUTINES_CODE)
381 bld(features='fc fcstlib', source='test.f', target='test')
382 bld(features='c fcprogram', source='main.c', target='app', use='test')
383
384 def mangling_schemes():
385 """
386 Generate triplets for use with mangle_name
387 (used in check_fortran_mangling)
388 the order is tuned for gfortan
389 """
390 for u in ['_', '']:
391 for du in ['', '_']:
392 for c in ["lower", "upper"]:
393 yield (u, du, c)
394
395 def mangle_name(u, du, c, name):
396 """Mangle a name from a triplet (used in check_fortran_mangling)"""
397 return getattr(name, c)() + u + (name.find('_') != -1 and du or '')
398
399 @conf
400 def check_fortran_mangling(self, *k, **kw):
401 """
402 Detect the mangling scheme, sets FORTRAN_MANGLING to the triplet found
403
404 This test will compile a fortran static library, then link a c app against it
405 """
406 if not self.env.CC:
407 self.fatal('A c compiler is required for link_main_routines')
408 if not self.env.FC:
409 self.fatal('A fortran compiler is required for link_main_routines')
410 if not self.env.FC_MAIN:
411 self.fatal('Checking for mangling requires self.env.FC_MAIN (execute "check_fortran_dummy_main" first?)')
412
413 self.start_msg('Getting fortran mangling scheme')
414 for (u, du, c) in mangling_schemes():
415 try:
416 self.check_cc(
417 compile_filename = [],
418 features = 'link_main_routines_func',
419 msg = 'nomsg',
420 errmsg = 'nomsg',
421 mandatory=True,
422 dummy_func_nounder = mangle_name(u, du, c, "foobar"),
423 dummy_func_under = mangle_name(u, du, c, "foo_bar"),
424 main_func_name = self.env.FC_MAIN
425 )
426 except self.errors.ConfigurationError:
427 pass
428 else:
429 self.end_msg("ok ('%s', '%s', '%s-case')" % (u, du, c))
430 self.env.FORTRAN_MANGLING = (u, du, c)
431 break
432 else:
433 self.end_msg(False)
434 self.fatal('mangler not found')
435
436 return (u, du, c)
437
438 @feature('pyext')
439 @before_method('propagate_uselib_vars', 'apply_link')
440 def set_lib_pat(self):
441 """Set the fortran flags for linking with the python library"""
442 self.env['fcshlib_PATTERN'] = self.env['pyext_PATTERN']
443
444 @conf
445 def detect_openmp(self):
446 for x in ['-fopenmp','-openmp','-mp','-xopenmp','-omp','-qsmp=omp']:
447 try:
448 self.check_fc(
449 msg='Checking for OpenMP flag %s' % x,
450 fragment='program main\n call omp_get_num_threads()\nend program main',
451 fcflags=x,
452 linkflags=x,
453 uselib_store='OPENMP'
454 )
455 except self.errors.ConfigurationError:
456 pass
457 else:
458 break
459 else:
460 self.fatal('Could not find OpenMP')
461
0 #! /usr/bin/env python
1 # encoding: utf-8
2 # DC 2008
3 # Thomas Nagy 2010 (ita)
4
5 import re
6
7 from waflib import Utils, Task, TaskGen, Logs
8 from waflib.TaskGen import feature, before_method, after_method, extension
9 from waflib.Configure import conf
10
11 INC_REGEX = """(?:^|['">]\s*;)\s*INCLUDE\s+(?:\w+_)?[<"'](.+?)(?=["'>])"""
12 USE_REGEX = """(?:^|;)\s*USE(?:\s+|(?:(?:\s*,\s*(?:NON_)?INTRINSIC)?\s*::))\s*(\w+)"""
13 MOD_REGEX = """(?:^|;)\s*MODULE(?!\s*PROCEDURE)(?:\s+|(?:(?:\s*,\s*(?:NON_)?INTRINSIC)?\s*::))\s*(\w+)"""
14
15 # TODO (DC)
16 # - handle pre-processed files (FORTRANPPCOM in scons)
17 # - handle multiple dialects
18 # TODO (ita) understand what the above is supposed to mean ^^
19
20 re_inc = re.compile(INC_REGEX, re.I)
21 re_use = re.compile(USE_REGEX, re.I)
22 re_mod = re.compile(MOD_REGEX, re.I)
23
24 class fortran_parser(object):
25 """
26 This parser will return:
27
28 * the nodes corresponding to the module names that will be produced
29 * the nodes corresponding to the include files used
30 * the module names used by the fortran file
31 """
32
33 def __init__(self, incpaths):
34 self.seen = []
35 """Files already parsed"""
36
37 self.nodes = []
38 """List of :py:class:`waflib.Node.Node` representing the dependencies to return"""
39
40 self.names = []
41 """List of module names to return"""
42
43 self.incpaths = incpaths
44 """List of :py:class:`waflib.Node.Node` representing the include paths"""
45
46 def find_deps(self, node):
47 """
48 Parse a fortran file to read the dependencies used and provided
49
50 :param node: fortran file to read
51 :type node: :py:class:`waflib.Node.Node`
52 :return: lists representing the includes, the modules used, and the modules created by a fortran file
53 :rtype: tuple of list of strings
54 """
55 txt = node.read()
56 incs = []
57 uses = []
58 mods = []
59 for line in txt.splitlines():
60 # line by line regexp search? optimize?
61 m = re_inc.search(line)
62 if m:
63 incs.append(m.group(1))
64 m = re_use.search(line)
65 if m:
66 uses.append(m.group(1))
67 m = re_mod.search(line)
68 if m:
69 mods.append(m.group(1))
70 return (incs, uses, mods)
71
72 def start(self, node):
73 """
74 Start the parsing. Use the stack self.waiting to hold the nodes to iterate on
75
76 :param node: fortran file
77 :type node: :py:class:`waflib.Node.Node`
78 """
79 self.waiting = [node]
80 while self.waiting:
81 nd = self.waiting.pop(0)
82 self.iter(nd)
83
84 def iter(self, node):
85 """
86 Process a single file in the search for dependencies, extract the files used
87 the modules used, and the modules provided.
88 """
89 path = node.abspath()
90 incs, uses, mods = self.find_deps(node)
91 for x in incs:
92 if x in self.seen:
93 continue
94 self.seen.append(x)
95 self.tryfind_header(x)
96
97 for x in uses:
98 name = "USE@%s" % x
99 if not name in self.names:
100 self.names.append(name)
101
102 for x in mods:
103 name = "MOD@%s" % x
104 if not name in self.names:
105 self.names.append(name)
106
107 def tryfind_header(self, filename):
108 """
109 Try to find an include and add it the nodes to process
110
111 :param filename: file name
112 :type filename: string
113 """
114 found = None
115 for n in self.incpaths:
116 found = n.find_resource(filename)
117 if found:
118 self.nodes.append(found)
119 self.waiting.append(found)
120 break
121 if not found:
122 if not filename in self.names:
123 self.names.append(filename)
124
125
0 #!/usr/bin/env python
1 # encoding: utf-8
2 # John O'Meara, 2006
3 # Thomas Nagy, 2006-2010 (ita)
4
5 """
6 The **flex** program is a code generator which creates C or C++ files.
7 The generated files are compiled into object files.
8 """
9
10 import waflib.TaskGen
11
12 def decide_ext(self, node):
13 if 'cxx' in self.features:
14 return ['.lex.cc']
15 return ['.lex.c']
16
17 def flexfun(tsk):
18 env = tsk.env
19 bld = tsk.generator.bld
20 wd = bld.variant_dir
21 def to_list(xx):
22 if isinstance(xx, str): return [xx]
23 return xx
24 tsk.last_cmd = lst = []
25 lst.extend(to_list(env['FLEX']))
26 lst.extend(to_list(env['FLEXFLAGS']))
27 lst.extend([a.path_from(bld.bldnode) for a in tsk.inputs])
28 lst = [x for x in lst if x]
29 txt = bld.cmd_and_log(lst, cwd=wd, env=env.env or None, quiet=0)
30 tsk.outputs[0].write(txt)
31
32 waflib.TaskGen.declare_chain(
33 name = 'flex',
34 rule = flexfun, # issue #854
35 ext_in = '.l',
36 decider = decide_ext,
37 )
38
39 def configure(conf):
40 """
41 Detect the *flex* program
42 """
43 conf.find_program('flex', var='FLEX')
44 conf.env.FLEXFLAGS = ['-t']
45
0 #! /usr/bin/env python
1 # encoding: utf-8
2 # KWS 2010
3 # Thomas Nagy 2010 (ita)
4
5 import re
6 from waflib import Utils
7 from waflib.Tools import fc, fc_config, fc_scan
8 from waflib.Configure import conf
9
10 @conf
11 def find_g95(conf):
12 fc = conf.find_program('g95', var='FC')
13 fc = conf.cmd_to_list(fc)
14 conf.get_g95_version(fc)
15 conf.env.FC_NAME = 'G95'
16
17 @conf
18 def g95_flags(conf):
19 v = conf.env
20 v['FCFLAGS_fcshlib'] = ['-fPIC']
21 v['FORTRANMODFLAG'] = ['-fmod=', ''] # template for module path
22 v['FCFLAGS_DEBUG'] = ['-Werror'] # why not
23
24 @conf
25 def g95_modifier_win32(conf):
26 fc_config.fortran_modifier_win32(conf)
27
28 @conf
29 def g95_modifier_cygwin(conf):
30 fc_config.fortran_modifier_cygwin(conf)
31
32 @conf
33 def g95_modifier_darwin(conf):
34 fc_config.fortran_modifier_darwin(conf)
35
36 @conf
37 def g95_modifier_platform(conf):
38 dest_os = conf.env['DEST_OS'] or Utils.unversioned_sys_platform()
39 g95_modifier_func = getattr(conf, 'g95_modifier_' + dest_os, None)
40 if g95_modifier_func:
41 g95_modifier_func()
42
43 @conf
44 def get_g95_version(conf, fc):
45 """get the compiler version"""
46
47 version_re = re.compile(r"g95\s*(?P<major>\d*)\.(?P<minor>\d*)").search
48 cmd = fc + ['--version']
49 out, err = fc_config.getoutput(conf, cmd, stdin=False)
50 if out:
51 match = version_re(out)
52 else:
53 match = version_re(err)
54 if not match:
55 conf.fatal('cannot determine g95 version')
56 k = match.groupdict()
57 conf.env['FC_VERSION'] = (k['major'], k['minor'])
58
59 def configure(conf):
60 conf.find_g95()
61 conf.find_ar()
62 conf.fc_flags()
63 conf.g95_flags()
64 conf.g95_modifier_platform()
0 #!/usr/bin/env python
1 # encoding: utf-8
2 # Thomas Nagy, 2008-2010 (ita)
3
4 "Detect as/gas/gcc for compiling assembly files"
5
6 import waflib.Tools.asm # - leave this
7 from waflib.Tools import ar
8
9 def configure(conf):
10 """
11 Find the programs gas/as/gcc and set the variable *AS*
12 """
13 conf.find_program(['gas', 'as', 'gcc'], var='AS')
14 conf.env.AS_TGT_F = ['-o']
15 conf.env.ASLNK_TGT_F = ['-o']
16 conf.find_ar()
0 #!/usr/bin/env python
1 # encoding: utf-8
2 # Thomas Nagy, 2006-2010 (ita)
3 # Ralf Habacker, 2006 (rh)
4 # Yinon Ehrlich, 2009
5
6 """
7 gcc/llvm detection.
8 """
9
10 import os, sys
11 from waflib import Configure, Options, Utils
12 from waflib.Tools import ccroot, ar
13 from waflib.Configure import conf
14
15 @conf
16 def find_gcc(conf):
17 """
18 Find the program gcc, and if present, try to detect its version number
19 """
20 cc = conf.find_program(['gcc', 'cc'], var='CC')
21 cc = conf.cmd_to_list(cc)
22 conf.get_cc_version(cc, gcc=True)
23 conf.env.CC_NAME = 'gcc'
24 conf.env.CC = cc
25
26 @conf
27 def gcc_common_flags(conf):
28 """
29 Common flags for gcc on nearly all platforms
30 """
31 v = conf.env
32
33 v['CC_SRC_F'] = []
34 v['CC_TGT_F'] = ['-c', '-o']
35
36 # linker
37 if not v['LINK_CC']: v['LINK_CC'] = v['CC']
38 v['CCLNK_SRC_F'] = []
39 v['CCLNK_TGT_F'] = ['-o']
40 v['CPPPATH_ST'] = '-I%s'
41 v['DEFINES_ST'] = '-D%s'
42
43 v['LIB_ST'] = '-l%s' # template for adding libs
44 v['LIBPATH_ST'] = '-L%s' # template for adding libpaths
45 v['STLIB_ST'] = '-l%s'
46 v['STLIBPATH_ST'] = '-L%s'
47 v['RPATH_ST'] = '-Wl,-rpath,%s'
48
49 v['SONAME_ST'] = '-Wl,-h,%s'
50 v['SHLIB_MARKER'] = '-Wl,-Bdynamic'
51 v['STLIB_MARKER'] = '-Wl,-Bstatic'
52
53 # program
54 v['cprogram_PATTERN'] = '%s'
55
56 # shared librar
57 v['CFLAGS_cshlib'] = ['-fPIC']
58 v['LINKFLAGS_cshlib'] = ['-shared']
59 v['cshlib_PATTERN'] = 'lib%s.so'
60
61 # static lib
62 v['LINKFLAGS_cstlib'] = ['-Wl,-Bstatic']
63 v['cstlib_PATTERN'] = 'lib%s.a'
64
65 # osx stuff
66 v['LINKFLAGS_MACBUNDLE'] = ['-bundle', '-undefined', 'dynamic_lookup']
67 v['CFLAGS_MACBUNDLE'] = ['-fPIC']
68 v['macbundle_PATTERN'] = '%s.bundle'
69
70 @conf
71 def gcc_modifier_win32(conf):
72 """Configuration flags for executing gcc on Windows"""
73 v = conf.env
74 v['cprogram_PATTERN'] = '%s.exe'
75
76 v['cshlib_PATTERN'] = '%s.dll'
77 v['implib_PATTERN'] = 'lib%s.dll.a'
78 v['IMPLIB_ST'] = '-Wl,--out-implib,%s'
79
80 v['CFLAGS_cshlib'] = []
81
82 v.append_value('CFLAGS_cshlib', ['-DDLL_EXPORT']) # TODO adding nonstandard defines like this DLL_EXPORT is not a good idea
83
84 # Auto-import is enabled by default even without this option,
85 # but enabling it explicitly has the nice effect of suppressing the rather boring, debug-level messages
86 # that the linker emits otherwise.
87 v.append_value('LINKFLAGS', ['-Wl,--enable-auto-import'])
88
89 @conf
90 def gcc_modifier_cygwin(conf):
91 """Configuration flags for executing gcc on Cygwin"""
92 gcc_modifier_win32(conf)
93 v = conf.env
94 v['cshlib_PATTERN'] = 'cyg%s.dll'
95 v.append_value('LINKFLAGS_cshlib', ['-Wl,--enable-auto-image-base'])
96 v['CFLAGS_cshlib'] = []
97
98 @conf
99 def gcc_modifier_darwin(conf):
100 """Configuration flags for executing gcc on MacOS"""
101 v = conf.env
102 v['CFLAGS_cshlib'] = ['-fPIC', '-compatibility_version', '1', '-current_version', '1']
103 v['LINKFLAGS_cshlib'] = ['-dynamiclib']
104 v['cshlib_PATTERN'] = 'lib%s.dylib'
105 v['FRAMEWORKPATH_ST'] = '-F%s'
106 v['FRAMEWORK_ST'] = ['-framework']
107 v['ARCH_ST'] = ['-arch']
108
109 v['LINKFLAGS_cstlib'] = []
110
111 v['SHLIB_MARKER'] = []
112 v['STLIB_MARKER'] = []
113 v['SONAME_ST'] = []
114
115 @conf
116 def gcc_modifier_aix(conf):
117 """Configuration flags for executing gcc on AIX"""
118 v = conf.env
119 v['LINKFLAGS_cprogram'] = ['-Wl,-brtl']
120 v['LINKFLAGS_cshlib'] = ['-shared','-Wl,-brtl,-bexpfull']
121 v['SHLIB_MARKER'] = []
122
123 @conf
124 def gcc_modifier_hpux(conf):
125 v = conf.env
126 v['SHLIB_MARKER'] = []
127 v['CFLAGS_cshlib'] = ['-fPIC','-DPIC']
128 v['cshlib_PATTERN'] = 'lib%s.sl'
129
130 @conf
131 def gcc_modifier_platform(conf):
132 """Execute platform-specific functions based on *gcc_modifier_+NAME*"""
133 # * set configurations specific for a platform.
134 # * the destination platform is detected automatically by looking at the macros the compiler predefines,
135 # and if it's not recognised, it fallbacks to sys.platform.
136 gcc_modifier_func = getattr(conf, 'gcc_modifier_' + conf.env.DEST_OS, None)
137 if gcc_modifier_func:
138 gcc_modifier_func()
139
140 def configure(conf):
141 """
142 Configuration for gcc
143 """
144 conf.find_gcc()
145 conf.find_ar()
146 conf.gcc_common_flags()
147 conf.gcc_modifier_platform()
148 conf.cc_load_tools()
149 conf.cc_add_flags()
150 conf.link_add_flags()
151
152
0 #!/usr/bin/env python
1 # encoding: utf-8
2 # Carlos Rafael Giani, 2007 (dv)
3
4 import sys
5 from waflib.Tools import ar, d
6 from waflib.Configure import conf
7
8 @conf
9 def find_gdc(conf):
10 """
11 Find the program gdc and set the variable *D*
12 """
13 conf.find_program('gdc', var='D')
14
15 @conf
16 def common_flags_gdc(conf):
17 """
18 Set the flags required by *gdc*
19 """
20 v = conf.env
21
22 # _DFLAGS _DIMPORTFLAGS
23
24 # for mory info about the meaning of this dict see dmd.py
25 v['DFLAGS'] = []
26
27 v['D_SRC_F'] = ['-c']
28 v['D_TGT_F'] = '-o%s'
29
30 # linker
31 v['D_LINKER'] = v['D']
32 v['DLNK_SRC_F'] = ''
33 v['DLNK_TGT_F'] = '-o%s'
34 v['DINC_ST'] = '-I%s'
35
36 v['DSHLIB_MARKER'] = v['DSTLIB_MARKER'] = ''
37 v['DSTLIB_ST'] = v['DSHLIB_ST'] = '-l%s'
38 v['DSTLIBPATH_ST'] = v['DLIBPATH_ST'] = '-L%s'
39
40 v['LINKFLAGS_dshlib'] = ['-shared']
41
42 v['DHEADER_ext'] = '.di'
43 v.DFLAGS_d_with_header = '-fintfc'
44 v['D_HDR_F'] = '-fintfc-file=%s'
45
46 def configure(conf):
47 """
48 Configuration for gdc
49 """
50 conf.find_gdc()
51 conf.load('ar')
52 conf.load('d')
53 conf.common_flags_gdc()
54 conf.d_platform_flags()
55
0 #! /usr/bin/env python
1 # encoding: utf-8
2 # DC 2008
3 # Thomas Nagy 2010 (ita)
4
5 import re
6 from waflib import Utils
7 from waflib.Tools import fc, fc_config, fc_scan
8 from waflib.Configure import conf
9
10 @conf
11 def find_gfortran(conf):
12 """Find the gfortran program (will look in the environment variable 'FC')"""
13 fc = conf.find_program(['gfortran','g77'], var='FC')
14 # (fallback to g77 for systems, where no gfortran is available)
15 fc = conf.cmd_to_list(fc)
16 conf.get_gfortran_version(fc)
17 conf.env.FC_NAME = 'GFORTRAN'
18
19 @conf
20 def gfortran_flags(conf):
21 v = conf.env
22 v['FCFLAGS_fcshlib'] = ['-fPIC']
23 v['FORTRANMODFLAG'] = ['-J', ''] # template for module path
24 v['FCFLAGS_DEBUG'] = ['-Werror'] # why not
25
26 @conf
27 def gfortran_modifier_win32(conf):
28 fc_config.fortran_modifier_win32(conf)
29
30 @conf
31 def gfortran_modifier_cygwin(conf):
32 fc_config.fortran_modifier_cygwin(conf)
33
34 @conf
35 def gfortran_modifier_darwin(conf):
36 fc_config.fortran_modifier_darwin(conf)
37
38 @conf
39 def gfortran_modifier_platform(conf):
40 dest_os = conf.env['DEST_OS'] or Utils.unversioned_sys_platform()
41 gfortran_modifier_func = getattr(conf, 'gfortran_modifier_' + dest_os, None)
42 if gfortran_modifier_func:
43 gfortran_modifier_func()
44
45 @conf
46 def get_gfortran_version(conf, fc):
47 """Get the compiler version"""
48
49 # ensure this is actually gfortran, not an imposter.
50 version_re = re.compile(r"GNU\s*Fortran", re.I).search
51 cmd = fc + ['--version']
52 out, err = fc_config.getoutput(conf, cmd, stdin=False)
53 if out: match = version_re(out)
54 else: match = version_re(err)
55 if not match:
56 conf.fatal('Could not determine the compiler type')
57
58 # --- now get more detailed info -- see c_config.get_cc_version
59 cmd = fc + ['-dM', '-E', '-']
60 out, err = fc_config.getoutput(conf, cmd, stdin=True)
61
62 if out.find('__GNUC__') < 0:
63 conf.fatal('Could not determine the compiler type')
64
65 k = {}
66 out = out.split('\n')
67 import shlex
68
69 for line in out:
70 lst = shlex.split(line)
71 if len(lst)>2:
72 key = lst[1]
73 val = lst[2]
74 k[key] = val
75
76 def isD(var):
77 return var in k
78
79 def isT(var):
80 return var in k and k[var] != '0'
81
82 conf.env['FC_VERSION'] = (k['__GNUC__'], k['__GNUC_MINOR__'], k['__GNUC_PATCHLEVEL__'])
83
84 def configure(conf):
85 conf.find_gfortran()
86 conf.find_ar()
87 conf.fc_flags()
88 conf.gfortran_flags()
89 conf.gfortran_modifier_platform()
0 #! /usr/bin/env python
1 # encoding: utf-8
2 # Thomas Nagy, 2006-2010 (ita)
3
4 """
5 Support for GLib2 tools:
6
7 * marshal
8 * enums
9 * gsettings
10 """
11
12 import os
13 from waflib import Task, Utils, Options, Errors, Logs
14 from waflib.TaskGen import taskgen_method, before_method, after_method, feature
15
16 ################## marshal files
17
18 @taskgen_method
19 def add_marshal_file(self, filename, prefix):
20 """
21 Add a file to the list of marshal files to process. Store them in the attribute *marshal_list*.
22
23 :param filename: xml file to compile
24 :type filename: string
25 :param prefix: marshal prefix (--prefix=prefix)
26 :type prefix: string
27 """
28 if not hasattr(self, 'marshal_list'):
29 self.marshal_list = []
30 self.meths.append('process_marshal')
31 self.marshal_list.append((filename, prefix))
32
33 @before_method('process_source')
34 def process_marshal(self):
35 """
36 Process the marshal files stored in the attribute *marshal_list* to create :py:class:`waflib.Tools.glib2.glib_genmarshal` instances.
37 Add the c file created to the list of source to process.
38 """
39 for f, prefix in getattr(self, 'marshal_list', []):
40 node = self.path.find_resource(f)
41
42 if not node:
43 raise Errors.WafError('file not found %r' % f)
44
45 h_node = node.change_ext('.h')
46 c_node = node.change_ext('.c')
47
48 task = self.create_task('glib_genmarshal', node, [h_node, c_node])
49 task.env.GLIB_GENMARSHAL_PREFIX = prefix
50 self.source = self.to_nodes(getattr(self, 'source', []))
51 self.source.append(c_node)
52
53 class glib_genmarshal(Task.Task):
54
55 def run(self):
56
57 bld = self.inputs[0].__class__.ctx
58
59 get = self.env.get_flat
60 cmd1 = "%s %s --prefix=%s --header > %s" % (
61 get('GLIB_GENMARSHAL'),
62 self.inputs[0].srcpath(),
63 get('GLIB_GENMARSHAL_PREFIX'),
64 self.outputs[0].abspath()
65 )
66
67 ret = bld.exec_command(cmd1)
68 if ret: return ret
69
70 #print self.outputs[1].abspath()
71 c = '''#include "%s"\n''' % self.outputs[0].name
72 self.outputs[1].write(c)
73
74 cmd2 = "%s %s --prefix=%s --body >> %s" % (
75 get('GLIB_GENMARSHAL'),
76 self.inputs[0].srcpath(),
77 get('GLIB_GENMARSHAL_PREFIX'),
78 self.outputs[1].abspath()
79 )
80 return bld.exec_command(cmd2)
81
82 vars = ['GLIB_GENMARSHAL_PREFIX', 'GLIB_GENMARSHAL']
83 color = 'BLUE'
84 ext_out = ['.h']
85
86 ########################## glib-mkenums
87
88 @taskgen_method
89 def add_enums_from_template(self, source='', target='', template='', comments=''):
90 """
91 Add a file to the list of enum files to process. Store them in the attribute *enums_list*.
92
93 :param source: enum file to process
94 :type source: string
95 :param target: target file
96 :type target: string
97 :param template: template file
98 :type template: string
99 :param comments: comments
100 :type comments: string
101 """
102 if not hasattr(self, 'enums_list'):
103 self.enums_list = []
104 self.meths.append('process_enums')
105 self.enums_list.append({'source': source,
106 'target': target,
107 'template': template,
108 'file-head': '',
109 'file-prod': '',
110 'file-tail': '',
111 'enum-prod': '',
112 'value-head': '',
113 'value-prod': '',
114 'value-tail': '',
115 'comments': comments})
116
117 @taskgen_method
118 def add_enums(self, source='', target='',
119 file_head='', file_prod='', file_tail='', enum_prod='',
120 value_head='', value_prod='', value_tail='', comments=''):
121 """
122 Add a file to the list of enum files to process. Store them in the attribute *enums_list*.
123
124 :param source: enum file to process
125 :type source: string
126 :param target: target file
127 :type target: string
128 :param file_head: unused
129 :param file_prod: unused
130 :param file_tail: unused
131 :param enum_prod: unused
132 :param value_head: unused
133 :param value_prod: unused
134 :param value_tail: unused
135 :param comments: comments
136 :type comments: string
137 """
138 if not hasattr(self, 'enums_list'):
139 self.enums_list = []
140 self.meths.append('process_enums')
141 self.enums_list.append({'source': source,
142 'template': '',
143 'target': target,
144 'file-head': file_head,
145 'file-prod': file_prod,
146 'file-tail': file_tail,
147 'enum-prod': enum_prod,
148 'value-head': value_head,
149 'value-prod': value_prod,
150 'value-tail': value_tail,
151 'comments': comments})
152
153 @before_method('process_source')
154 def process_enums(self):
155 """
156 Process the enum files stored in the attribute *enum_list* to create :py:class:`waflib.Tools.glib2.glib_mkenums` instances.
157 """
158 for enum in getattr(self, 'enums_list', []):
159 task = self.create_task('glib_mkenums')
160 env = task.env
161
162 inputs = []
163
164 # process the source
165 source_list = self.to_list(enum['source'])
166 if not source_list:
167 raise Errors.WafError('missing source ' + str(enum))
168 source_list = [self.path.find_resource(k) for k in source_list]
169 inputs += source_list
170 env['GLIB_MKENUMS_SOURCE'] = [k.abspath() for k in source_list]
171
172 # find the target
173 if not enum['target']:
174 raise Errors.WafError('missing target ' + str(enum))
175 tgt_node = self.path.find_or_declare(enum['target'])
176 if tgt_node.name.endswith('.c'):
177 self.source.append(tgt_node)
178 env['GLIB_MKENUMS_TARGET'] = tgt_node.abspath()
179
180
181 options = []
182
183 if enum['template']: # template, if provided
184 template_node = self.path.find_resource(enum['template'])
185 options.append('--template %s' % (template_node.abspath()))
186 inputs.append(template_node)
187 params = {'file-head' : '--fhead',
188 'file-prod' : '--fprod',
189 'file-tail' : '--ftail',
190 'enum-prod' : '--eprod',
191 'value-head' : '--vhead',
192 'value-prod' : '--vprod',
193 'value-tail' : '--vtail',
194 'comments': '--comments'}
195 for param, option in params.items():
196 if enum[param]:
197 options.append('%s %r' % (option, enum[param]))
198
199 env['GLIB_MKENUMS_OPTIONS'] = ' '.join(options)
200
201 # update the task instance
202 task.set_inputs(inputs)
203 task.set_outputs(tgt_node)
204
205 class glib_mkenums(Task.Task):
206 """
207 Process enum files
208 """
209 run_str = '${GLIB_MKENUMS} ${GLIB_MKENUMS_OPTIONS} ${GLIB_MKENUMS_SOURCE} > ${GLIB_MKENUMS_TARGET}'
210 color = 'PINK'
211 ext_out = ['.h']
212
213 ######################################### gsettings
214
215 @taskgen_method
216 def add_settings_schemas(self, filename_list):
217 """
218 Add settings files to process, add them to *settings_schema_files*
219
220 :param filename_list: files
221 :type filename_list: list of string
222 """
223 if not hasattr(self, 'settings_schema_files'):
224 self.settings_schema_files = []
225
226 if not isinstance(filename_list, list):
227 filename_list = [filename_list]
228
229 self.settings_schema_files.extend(filename_list)
230
231 @taskgen_method
232 def add_settings_enums(self, namespace, filename_list):
233 """
234 This function may be called only once by task generator to set the enums namespace.
235
236 :param namespace: namespace
237 :type namespace: string
238 :param filename_list: enum files to process
239 :type filename_list: file list
240 """
241 if hasattr(self, 'settings_enum_namespace'):
242 raise Errors.WafError("Tried to add gsettings enums to '%s' more than once" % self.name)
243 self.settings_enum_namespace = namespace
244
245 if type(filename_list) != 'list':
246 filename_list = [filename_list]
247 self.settings_enum_files = filename_list
248
249
250 def r_change_ext(self, ext):
251 """
252 Change the extension from the *last* dot in the filename. The gsettings schemas
253 often have names of the form org.gsettings.test.gschema.xml
254 """
255 name = self.name
256 k = name.rfind('.')
257 if k >= 0:
258 name = name[:k] + ext
259 else:
260 name = name + ext
261 return self.parent.find_or_declare([name])
262
263 @feature('glib2')
264 def process_settings(self):
265 """
266 Process the schema files in *settings_schema_files* to create :py:class:`waflib.Tools.glib2.glib_mkenums` instances. The
267 same files are validated through :py:class:`waflib.Tools.glib2.glib_validate_schema` tasks.
268
269 """
270 enums_tgt_node = []
271 install_files = []
272
273 settings_schema_files = getattr(self, 'settings_schema_files', [])
274 if settings_schema_files and not self.env['GLIB_COMPILE_SCHEMAS']:
275 raise Errors.WafError ("Unable to process GSettings schemas - glib-compile-schemas was not found during configure")
276
277 # 1. process gsettings_enum_files (generate .enums.xml)
278 #
279 if hasattr(self, 'settings_enum_files'):
280 enums_task = self.create_task('glib_mkenums')
281
282 source_list = self.settings_enum_files
283 source_list = [self.path.find_resource(k) for k in source_list]
284 enums_task.set_inputs(source_list)
285 enums_task.env['GLIB_MKENUMS_SOURCE'] = [k.abspath() for k in source_list]
286
287 target = self.settings_enum_namespace + '.enums.xml'
288 tgt_node = self.path.find_or_declare(target)
289 enums_task.set_outputs(tgt_node)
290 enums_task.env['GLIB_MKENUMS_TARGET'] = tgt_node.abspath()
291 enums_tgt_node = [tgt_node]
292
293 install_files.append (tgt_node)
294
295 options = '--comments "<!-- @comment@ -->" --fhead "<schemalist>" --vhead " <@type@ id=\\"%s.@EnumName@\\">" --vprod " <value nick=\\"@valuenick@\\" value=\\"@valuenum@\\"/>" --vtail " </@type@>" --ftail "</schemalist>" ' % (self.settings_enum_namespace)
296 enums_task.env['GLIB_MKENUMS_OPTIONS'] = options
297
298 # 2. process gsettings_schema_files (validate .gschema.xml files)
299 #
300 for schema in settings_schema_files:
301 schema_task = self.create_task ('glib_validate_schema')
302
303 schema_node = self.path.find_resource(schema)
304 if not schema_node:
305 raise Errors.WafError("Cannot find the schema file '%s'" % schema)
306 install_files.append(schema_node)
307 source_list = enums_tgt_node + [schema_node]
308
309 schema_task.set_inputs (source_list)
310 schema_task.env['GLIB_COMPILE_SCHEMAS_OPTIONS'] = [("--schema-file=" + k.abspath()) for k in source_list]
311
312 target_node = r_change_ext (schema_node, '.xml.valid')
313 schema_task.set_outputs (target_node)
314 schema_task.env['GLIB_VALIDATE_SCHEMA_OUTPUT'] = target_node.abspath()
315
316 # 3. schemas install task
317 def compile_schemas_callback(bld):
318 if not bld.is_install: return
319 Logs.pprint ('YELLOW','Updating GSettings schema cache')
320 command = Utils.subst_vars("${GLIB_COMPILE_SCHEMAS} ${GSETTINGSSCHEMADIR}", bld.env)
321 ret = self.bld.exec_command(command)
322
323 if self.bld.is_install:
324 if not self.env['GSETTINGSSCHEMADIR']:
325 raise Errors.WafError ('GSETTINGSSCHEMADIR not defined (should have been set up automatically during configure)')
326
327 if install_files:
328 self.bld.install_files (self.env['GSETTINGSSCHEMADIR'], install_files)
329
330 if not hasattr(self.bld, '_compile_schemas_registered'):
331 self.bld.add_post_fun (compile_schemas_callback)
332 self.bld._compile_schemas_registered = True
333
334 class glib_validate_schema(Task.Task):
335 """
336 Validate schema files
337 """
338 run_str = 'rm -f ${GLIB_VALIDATE_SCHEMA_OUTPUT} && ${GLIB_COMPILE_SCHEMAS} --dry-run ${GLIB_COMPILE_SCHEMAS_OPTIONS} && touch ${GLIB_VALIDATE_SCHEMA_OUTPUT}'
339 color = 'PINK'
340
341 def configure(conf):
342 """
343 Find the following programs:
344
345 * *glib-genmarshal* and set *GLIB_GENMARSHAL*
346 * *glib-mkenums* and set *GLIB_MKENUMS*
347 * *glib-compile-schemas* and set *GLIB_COMPILE_SCHEMAS* (not mandatory)
348
349 And set the variable *GSETTINGSSCHEMADIR*
350 """
351 conf.find_program('glib-genmarshal', var='GLIB_GENMARSHAL')
352 conf.find_perl_program('glib-mkenums', var='GLIB_MKENUMS')
353
354 # when cross-compiling, gsettings.m4 locates the program with the following:
355 # pkg-config --variable glib_compile_schemas gio-2.0
356 conf.find_program('glib-compile-schemas', var='GLIB_COMPILE_SCHEMAS', mandatory=False)
357
358 def getstr(varname):
359 return getattr(Options.options, varname, getattr(conf.env,varname, ''))
360
361 # TODO make this dependent on the gnu_dirs tool?
362 gsettingsschemadir = getstr('GSETTINGSSCHEMADIR')
363 if not gsettingsschemadir:
364 datadir = getstr('DATADIR')
365 if not datadir:
366 prefix = conf.env['PREFIX']
367 datadir = os.path.join(prefix, 'share')
368 gsettingsschemadir = os.path.join(datadir, 'glib-2.0', 'schemas')
369
370 conf.env['GSETTINGSSCHEMADIR'] = gsettingsschemadir
371
372 def options(opt):
373 """
374 Add the ``--gsettingsschemadir`` command-line option
375 """
376 opt.add_option('--gsettingsschemadir', help='GSettings schema location [Default: ${datadir}/glib-2.0/schemas]',default='',dest='GSETTINGSSCHEMADIR')
377
0 #!/usr/bin/env python
1 # encoding: utf-8
2 # Ali Sabil, 2007
3
4 """
5 Sets various standard variables such as INCLUDEDIR. SBINDIR and others. To use this module just call::
6
7 opt.load('gnu_dirs')
8
9 and::
10
11 conf.load('gnu_dirs')
12
13 Add options for the standard GNU directories, this tool will add the options
14 found in autotools, and will update the environment with the following
15 installation variables:
16
17 ============== ========================================= =======================
18 Variable Description Value
19 ============== ========================================= =======================
20 PREFIX architecture-independent files /usr/local
21 EXEC_PREFIX architecture-dependent files PREFIX
22 BINDIR user executables EXEC_PREFIX/bin
23 SBINDIR user executables EXEC_PREFIX/sbin
24 LIBEXECDIR program executables EXEC_PREFIX/libexec
25 SYSCONFDIR read-only single-machine data PREFIX/etc
26 SHAREDSTATEDIR modifiable architecture-independent data PREFIX/com
27 LOCALSTATEDIR modifiable single-machine data PREFIX/var
28 LIBDIR object code libraries EXEC_PREFIX/lib
29 INCLUDEDIR C header files PREFIX/include
30 OLDINCLUDEDIR C header files for non-gcc /usr/include
31 DATAROOTDIR read-only arch.-independent data root PREFIX/share
32 DATADIR read-only architecture-independent data DATAROOTDIR
33 INFODIR info documentation DATAROOTDIR/info
34 LOCALEDIR locale-dependent data DATAROOTDIR/locale
35 MANDIR man documentation DATAROOTDIR/man
36 DOCDIR documentation root DATAROOTDIR/doc/APPNAME
37 HTMLDIR html documentation DOCDIR
38 DVIDIR dvi documentation DOCDIR
39 PDFDIR pdf documentation DOCDIR
40 PSDIR ps documentation DOCDIR
41 ============== ========================================= =======================
42 """
43
44 import os
45 from waflib import Utils, Options, Context
46
47 _options = [x.split(', ') for x in '''
48 bindir, user executables, ${EXEC_PREFIX}/bin
49 sbindir, system admin executables, ${EXEC_PREFIX}/sbin
50 libexecdir, program executables, ${EXEC_PREFIX}/libexec
51 sysconfdir, read-only single-machine data, ${PREFIX}/etc
52 sharedstatedir, modifiable architecture-independent data, ${PREFIX}/com
53 localstatedir, modifiable single-machine data, ${PREFIX}/var
54 libdir, object code libraries, ${EXEC_PREFIX}/lib
55 includedir, C header files, ${PREFIX}/include
56 oldincludedir, C header files for non-gcc, /usr/include
57 datarootdir, read-only arch.-independent data root, ${PREFIX}/share
58 datadir, read-only architecture-independent data, ${DATAROOTDIR}
59 infodir, info documentation, ${DATAROOTDIR}/info
60 localedir, locale-dependent data, ${DATAROOTDIR}/locale
61 mandir, man documentation, ${DATAROOTDIR}/man
62 docdir, documentation root, ${DATAROOTDIR}/doc/${PACKAGE}
63 htmldir, html documentation, ${DOCDIR}
64 dvidir, dvi documentation, ${DOCDIR}
65 pdfdir, pdf documentation, ${DOCDIR}
66 psdir, ps documentation, ${DOCDIR}
67 '''.split('\n') if x]
68
69 def configure(conf):
70 """
71 Read the command-line options to set lots of variables in *conf.env*. The variables
72 BINDIR and LIBDIR will be overwritten.
73 """
74 def get_param(varname, default):
75 return getattr(Options.options, varname, '') or default
76
77 env = conf.env
78 conf.env.LIBDIR = conf.env.BINDIR = []
79 env['EXEC_PREFIX'] = get_param('EXEC_PREFIX', env['PREFIX'])
80 env['PACKAGE'] = getattr(Context.g_module, 'APPNAME', None) or env['PACKAGE']
81
82 complete = False
83 iter = 0
84 while not complete and iter < len(_options) + 1:
85 iter += 1
86 complete = True
87 for name, help, default in _options:
88 name = name.upper()
89 if not env[name]:
90 try:
91 env[name] = Utils.subst_vars(get_param(name, default).replace('/', os.sep), env)
92 except TypeError:
93 complete = False
94 if not complete:
95 lst = [name for name, _, _ in _options if not env[name.upper()]]
96 raise conf.errors.WafError('Variable substitution failure %r' % lst)
97
98 def options(opt):
99 """
100 Add lots of command-line options, for example::
101
102 --exec-prefix: EXEC_PREFIX
103 """
104 inst_dir = opt.add_option_group('Installation directories',
105 'By default, "waf install" will put the files in\
106 "/usr/local/bin", "/usr/local/lib" etc. An installation prefix other\
107 than "/usr/local" can be given using "--prefix", for example "--prefix=$HOME"')
108
109 for k in ('--prefix', '--destdir'):
110 option = opt.parser.get_option(k)
111 if option:
112 opt.parser.remove_option(k)
113 inst_dir.add_option(option)
114
115 inst_dir.add_option('--exec-prefix',
116 help = 'installation prefix [Default: ${PREFIX}]',
117 default = '',
118 dest = 'EXEC_PREFIX')
119
120 dirs_options = opt.add_option_group('Pre-defined installation directories', '')
121
122 for name, help, default in _options:
123 option_name = '--' + name
124 str_default = default
125 str_help = '%s [Default: %s]' % (help, str_default)
126 dirs_options.add_option(option_name, help=str_help, default='', dest=name.upper())
127
0 #!/usr/bin/env python
1 # encoding: utf-8
2 # Thomas Nagy, 2006-2010 (ita)
3 # Ralf Habacker, 2006 (rh)
4 # Yinon Ehrlich, 2009
5
6 """
7 g++/llvm detection.
8 """
9
10 import os, sys
11 from waflib import Configure, Options, Utils
12 from waflib.Tools import ccroot, ar
13 from waflib.Configure import conf
14
15 @conf
16 def find_gxx(conf):
17 """
18 Find the program g++, and if present, try to detect its version number
19 """
20 cxx = conf.find_program(['g++', 'c++'], var='CXX')
21 cxx = conf.cmd_to_list(cxx)
22 conf.get_cc_version(cxx, gcc=True)
23 conf.env.CXX_NAME = 'gcc'
24 conf.env.CXX = cxx
25
26 @conf
27 def gxx_common_flags(conf):
28 """
29 Common flags for g++ on nearly all platforms
30 """
31 v = conf.env
32
33 v['CXX_SRC_F'] = []
34 v['CXX_TGT_F'] = ['-c', '-o']
35
36 # linker
37 if not v['LINK_CXX']: v['LINK_CXX'] = v['CXX']
38 v['CXXLNK_SRC_F'] = []
39 v['CXXLNK_TGT_F'] = ['-o']
40 v['CPPPATH_ST'] = '-I%s'
41 v['DEFINES_ST'] = '-D%s'
42
43 v['LIB_ST'] = '-l%s' # template for adding libs
44 v['LIBPATH_ST'] = '-L%s' # template for adding libpaths
45 v['STLIB_ST'] = '-l%s'
46 v['STLIBPATH_ST'] = '-L%s'
47 v['RPATH_ST'] = '-Wl,-rpath,%s'
48
49 v['SONAME_ST'] = '-Wl,-h,%s'
50 v['SHLIB_MARKER'] = '-Wl,-Bdynamic'
51 v['STLIB_MARKER'] = '-Wl,-Bstatic'
52
53 # program
54 v['cxxprogram_PATTERN'] = '%s'
55
56 # shared library
57 v['CXXFLAGS_cxxshlib'] = ['-fPIC']
58 v['LINKFLAGS_cxxshlib'] = ['-shared']
59 v['cxxshlib_PATTERN'] = 'lib%s.so'
60
61 # static lib
62 v['LINKFLAGS_cxxstlib'] = ['-Wl,-Bstatic']
63 v['cxxstlib_PATTERN'] = 'lib%s.a'
64
65 # osx stuff
66 v['LINKFLAGS_MACBUNDLE'] = ['-bundle', '-undefined', 'dynamic_lookup']
67 v['CXXFLAGS_MACBUNDLE'] = ['-fPIC']
68 v['macbundle_PATTERN'] = '%s.bundle'
69
70 @conf
71 def gxx_modifier_win32(conf):
72 """Configuration flags for executing gcc on Windows"""
73 v = conf.env
74 v['cxxprogram_PATTERN'] = '%s.exe'
75
76 v['cxxshlib_PATTERN'] = '%s.dll'
77 v['implib_PATTERN'] = 'lib%s.dll.a'
78 v['IMPLIB_ST'] = '-Wl,--out-implib,%s'
79
80 v['CXXFLAGS_cxxshlib'] = []
81
82 v.append_value('CXXFLAGS_cxxshlib', ['-DDLL_EXPORT']) # TODO adding nonstandard defines like this DLL_EXPORT is not a good idea
83
84 # Auto-import is enabled by default even without this option,
85 # but enabling it explicitly has the nice effect of suppressing the rather boring, debug-level messages
86 # that the linker emits otherwise.
87 v.append_value('LINKFLAGS', ['-Wl,--enable-auto-import'])
88
89 @conf
90 def gxx_modifier_cygwin(conf):
91 """Configuration flags for executing g++ on Cygwin"""
92 gxx_modifier_win32(conf)
93 v = conf.env
94 v['cxxshlib_PATTERN'] = 'cyg%s.dll'
95 v.append_value('LINKFLAGS_cxxshlib', ['-Wl,--enable-auto-image-base'])
96 v['CXXFLAGS_cxxshlib'] = []
97
98 @conf
99 def gxx_modifier_darwin(conf):
100 """Configuration flags for executing g++ on MacOS"""
101 v = conf.env
102 v['CXXFLAGS_cxxshlib'] = ['-fPIC', '-compatibility_version', '1', '-current_version', '1']
103 v['LINKFLAGS_cxxshlib'] = ['-dynamiclib']
104 v['cxxshlib_PATTERN'] = 'lib%s.dylib'
105 v['FRAMEWORKPATH_ST'] = '-F%s'
106 v['FRAMEWORK_ST'] = ['-framework']
107 v['ARCH_ST'] = ['-arch']
108
109 v['LINKFLAGS_cxxstlib'] = []
110
111 v['SHLIB_MARKER'] = []
112 v['STLIB_MARKER'] = []
113 v['SONAME_ST'] = []
114
115 @conf
116 def gxx_modifier_aix(conf):
117 """Configuration flags for executing g++ on AIX"""
118 v = conf.env
119 v['LINKFLAGS_cxxprogram']= ['-Wl,-brtl']
120
121 v['LINKFLAGS_cxxshlib'] = ['-shared', '-Wl,-brtl,-bexpfull']
122 v['SHLIB_MARKER'] = []
123
124 @conf
125 def gxx_modifier_hpux(conf):
126 v = conf.env
127 v['SHLIB_MARKER'] = []
128 v['CFLAGS_cxxshlib'] = ['-fPIC','-DPIC']
129 v['cxxshlib_PATTERN'] = 'lib%s.sl'
130
131 @conf
132 def gxx_modifier_platform(conf):
133 """Execute platform-specific functions based on *gxx_modifier_+NAME*"""
134 # * set configurations specific for a platform.
135 # * the destination platform is detected automatically by looking at the macros the compiler predefines,
136 # and if it's not recognised, it fallbacks to sys.platform.
137 gxx_modifier_func = getattr(conf, 'gxx_modifier_' + conf.env.DEST_OS, None)
138 if gxx_modifier_func:
139 gxx_modifier_func()
140
141 def configure(conf):
142 """
143 Configuration for g++
144 """
145 conf.find_gxx()
146 conf.find_ar()
147 conf.gxx_common_flags()
148 conf.gxx_modifier_platform()
149 conf.cxx_load_tools()
150 conf.cxx_add_flags()
151 conf.link_add_flags()
152
0 #!/usr/bin/env python
1 # encoding: utf-8
2 # Stian Selnes, 2008
3 # Thomas Nagy 2009-2010 (ita)
4
5 """
6 Detect the Intel C compiler
7 """
8
9 import os, sys
10 from waflib.Tools import ccroot, ar, gcc
11 from waflib.Configure import conf
12
13 @conf
14 def find_icc(conf):
15 """
16 Find the program icc and execute it to ensure it really is icc
17 """
18 if sys.platform == 'cygwin':
19 conf.fatal('The Intel compiler does not work on Cygwin')
20
21 v = conf.env
22 cc = None
23 if v['CC']: cc = v['CC']
24 elif 'CC' in conf.environ: cc = conf.environ['CC']
25 if not cc: cc = conf.find_program('icc', var='CC')
26 if not cc: cc = conf.find_program('ICL', var='CC')
27 if not cc: conf.fatal('Intel C Compiler (icc) was not found')
28 cc = conf.cmd_to_list(cc)
29
30 conf.get_cc_version(cc, icc=True)
31 v['CC'] = cc
32 v['CC_NAME'] = 'icc'
33
34 def configure(conf):
35 conf.find_icc()
36 conf.find_ar()
37 conf.gcc_common_flags()
38 conf.gcc_modifier_platform()
39 conf.cc_load_tools()
40 conf.cc_add_flags()
41 conf.link_add_flags()
0 #!/usr/bin/env python
1 # encoding: utf-8
2 # Thomas Nagy 2009-2010 (ita)
3
4 """
5 Detect the Intel C++ compiler
6 """
7
8 import os, sys
9 from waflib.Tools import ccroot, ar, gxx
10 from waflib.Configure import conf
11
12 @conf
13 def find_icpc(conf):
14 """
15 Find the program icpc, and execute it to ensure it really is icpc
16 """
17 if sys.platform == 'cygwin':
18 conf.fatal('The Intel compiler does not work on Cygwin')
19
20 v = conf.env
21 cxx = None
22 if v['CXX']: cxx = v['CXX']
23 elif 'CXX' in conf.environ: cxx = conf.environ['CXX']
24 if not cxx: cxx = conf.find_program('icpc', var='CXX')
25 if not cxx: conf.fatal('Intel C++ Compiler (icpc) was not found')
26 cxx = conf.cmd_to_list(cxx)
27
28 conf.get_cc_version(cxx, icc=True)
29 v['CXX'] = cxx
30 v['CXX_NAME'] = 'icc'
31
32 def configure(conf):
33 conf.find_icpc()
34 conf.find_ar()
35 conf.gxx_common_flags()
36 conf.gxx_modifier_platform()
37 conf.cxx_load_tools()
38 conf.cxx_add_flags()
39 conf.link_add_flags()
40
0 #! /usr/bin/env python
1 # encoding: utf-8
2 # DC 2008
3 # Thomas Nagy 2010 (ita)
4
5 import re
6 from waflib import Utils
7 from waflib.Tools import fc, fc_config, fc_scan
8 from waflib.Configure import conf
9
10 @conf
11 def find_ifort(conf):
12 fc = conf.find_program('ifort', var='FC')
13 fc = conf.cmd_to_list(fc)
14 conf.get_ifort_version(fc)
15 conf.env.FC_NAME = 'IFORT'
16
17 @conf
18 def ifort_modifier_cygwin(conf):
19 raise NotImplementedError("Ifort on cygwin not yet implemented")
20
21 @conf
22 def ifort_modifier_win32(conf):
23 fc_config.fortran_modifier_win32(conf)
24
25 @conf
26 def ifort_modifier_darwin(conf):
27 fc_config.fortran_modifier_darwin(conf)
28
29 @conf
30 def ifort_modifier_platform(conf):
31 dest_os = conf.env['DEST_OS'] or Utils.unversioned_sys_platform()
32 ifort_modifier_func = getattr(conf, 'ifort_modifier_' + dest_os, None)
33 if ifort_modifier_func:
34 ifort_modifier_func()
35
36 @conf
37 def get_ifort_version(conf, fc):
38 """get the compiler version"""
39
40 version_re = re.compile(r"ifort\s*\(IFORT\)\s*(?P<major>\d*)\.(?P<minor>\d*)", re.I).search
41 cmd = fc + ['--version']
42 out, err = fc_config.getoutput(conf, cmd, stdin=False)
43 if out:
44 match = version_re(out)
45 else:
46 match = version_re(err)
47 if not match:
48 conf.fatal('cannot determine ifort version.')
49 k = match.groupdict()
50 conf.env['FC_VERSION'] = (k['major'], k['minor'])
51
52 def configure(conf):
53 conf.find_ifort()
54 conf.find_program('xiar', var='AR')
55 conf.env.ARFLAGS = 'rcs'
56 conf.fc_flags()
57 conf.ifort_modifier_platform()
58
0 #!/usr/bin/env python
1 # encoding: utf-8
2 # Thomas Nagy, 2006-2010 (ita)
3
4 """
5 Support for translation tools such as msgfmt and intltool
6
7 Usage::
8
9 def configure(conf):
10 conf.load('gnu_dirs intltool')
11
12 def build(bld):
13 # process the .po files into .gmo files, and install them in LOCALEDIR
14 bld(features='intltool_po', appname='myapp', podir='po', install_path="${LOCALEDIR}")
15
16 # process an input file, substituting the translations from the po dir
17 bld(
18 features = "intltool_in",
19 podir = "../po",
20 flags = ["-d", "-q", "-u", "-c"],
21 source = 'kupfer.desktop.in',
22 install_path = "${DATADIR}/applications",
23 )
24
25 Usage of the :py:mod:`waflib.Tools.gnu_dirs` is recommended, but not obligatory.
26 """
27
28 import os, re
29 from waflib import Configure, TaskGen, Task, Utils, Runner, Options, Build, Logs
30 import waflib.Tools.ccroot
31 from waflib.TaskGen import feature, before_method
32 from waflib.Logs import error
33
34 @before_method('process_source')
35 @feature('intltool_in')
36 def apply_intltool_in_f(self):
37 """
38 Create tasks to translate files by intltool-merge::
39
40 def build(bld):
41 bld(
42 features = "intltool_in",
43 podir = "../po",
44 flags = ["-d", "-q", "-u", "-c"],
45 source = 'kupfer.desktop.in',
46 install_path = "${DATADIR}/applications",
47 )
48
49 :param podir: location of the .po files
50 :type podir: string
51 :param source: source files to process
52 :type source: list of string
53 :param flags: compilation flags ("-quc" by default)
54 :type flags: list of string
55 :param install_path: installation path
56 :type install_path: string
57 """
58 try: self.meths.remove('process_source')
59 except ValueError: pass
60
61 if not self.env.LOCALEDIR:
62 self.env.LOCALEDIR = self.env.PREFIX + '/share/locale'
63
64 for i in self.to_list(self.source):
65 node = self.path.find_resource(i)
66
67 podir = getattr(self, 'podir', 'po')
68 podirnode = self.path.find_dir(podir)
69 if not podirnode:
70 error("could not find the podir %r" % podir)
71 continue
72
73 cache = getattr(self, 'intlcache', '.intlcache')
74 self.env['INTLCACHE'] = os.path.join(self.path.bldpath(), podir, cache)
75 self.env['INTLPODIR'] = podirnode.bldpath()
76 self.env['INTLFLAGS'] = getattr(self, 'flags', ['-q', '-u', '-c'])
77
78 task = self.create_task('intltool', node, node.change_ext(''))
79 inst = getattr(self, 'install_path', '${LOCALEDIR}')
80 if inst:
81 self.bld.install_files(inst, task.outputs)
82
83 @feature('intltool_po')
84 def apply_intltool_po(self):
85 """
86 Create tasks to process po files::
87
88 def build(bld):
89 bld(features='intltool_po', appname='myapp', podir='po', install_path="${LOCALEDIR}")
90
91 The relevant task generator arguments are:
92
93 :param podir: directory of the .po files
94 :type podir: string
95 :param appname: name of the application
96 :type appname: string
97 :param install_path: installation directory
98 :type install_path: string
99
100 The file LINGUAS must be present in the directory pointed by *podir* and list the translation files to process.
101 """
102 try: self.meths.remove('process_source')
103 except ValueError: pass
104
105 if not self.env.LOCALEDIR:
106 self.env.LOCALEDIR = self.env.PREFIX + '/share/locale'
107
108 appname = getattr(self, 'appname', 'set_your_app_name')
109 podir = getattr(self, 'podir', '')
110 inst = getattr(self, 'install_path', '${LOCALEDIR}')
111
112 linguas = self.path.find_node(os.path.join(podir, 'LINGUAS'))
113 if linguas:
114 # scan LINGUAS file for locales to process
115 file = open(linguas.abspath())
116 langs = []
117 for line in file.readlines():
118 # ignore lines containing comments
119 if not line.startswith('#'):
120 langs += line.split()
121 file.close()
122 re_linguas = re.compile('[-a-zA-Z_@.]+')
123 for lang in langs:
124 # Make sure that we only process lines which contain locales
125 if re_linguas.match(lang):
126 node = self.path.find_resource(os.path.join(podir, re_linguas.match(lang).group() + '.po'))
127 task = self.create_task('po', node, node.change_ext('.mo'))
128
129 if inst:
130 filename = task.outputs[0].name
131 (langname, ext) = os.path.splitext(filename)
132 inst_file = inst + os.sep + langname + os.sep + 'LC_MESSAGES' + os.sep + appname + '.mo'
133 self.bld.install_as(inst_file, task.outputs[0], chmod=getattr(self, 'chmod', Utils.O644), env=task.env)
134
135 else:
136 Logs.pprint('RED', "Error no LINGUAS file found in po directory")
137
138 class po(Task.Task):
139 """
140 Compile .po files into .gmo files
141 """
142 run_str = '${MSGFMT} -o ${TGT} ${SRC}'
143 color = 'BLUE'
144
145 class intltool(Task.Task):
146 """
147 Let intltool-merge translate an input file
148 """
149 run_str = '${INTLTOOL} ${INTLFLAGS} ${INTLCACHE} ${INTLPODIR} ${SRC} ${TGT}'
150 color = 'BLUE'
151
152 def configure(conf):
153 """
154 Detect the program *msgfmt* and set *conf.env.MSGFMT*.
155 Detect the program *intltool-merge* and set *conf.env.INTLTOOL*.
156 It is possible to set INTLTOOL in the environment, but it must not have spaces in it::
157
158 $ INTLTOOL="/path/to/the program/intltool" waf configure
159
160 If a C/C++ compiler is present, execute a compilation test to find the header *locale.h*.
161 """
162 conf.find_program('msgfmt', var='MSGFMT')
163 conf.find_perl_program('intltool-merge', var='INTLTOOL')
164
165 prefix = conf.env.PREFIX
166 datadir = conf.env.DATADIR
167 if not datadir:
168 datadir = os.path.join(prefix,'share')
169
170 conf.define('LOCALEDIR', os.path.join(datadir, 'locale').replace('\\', '\\\\'))
171 conf.define('DATADIR', datadir.replace('\\', '\\\\'))
172
173 if conf.env.CC or conf.env.CXX:
174 conf.check(header_name='locale.h')
175
0 #! /usr/bin/env python
1 # imported from samba
2
3 """
4 compiler definition for irix/MIPSpro cc compiler
5 based on suncc.py from waf
6 """
7
8 import os
9 from waflib import Utils
10 from waflib.Tools import ccroot, ar
11 from waflib.Configure import conf
12
13 @conf
14 def find_irixcc(conf):
15 v = conf.env
16 cc = None
17 if v['CC']: cc = v['CC']
18 elif 'CC' in conf.environ: cc = conf.environ['CC']
19 if not cc: cc = conf.find_program('cc', var='CC')
20 if not cc: conf.fatal('irixcc was not found')
21 cc = conf.cmd_to_list(cc)
22
23 try:
24 conf.cmd_and_log(cc + ['-version'])
25 except:
26 conf.fatal('%r -version could not be executed' % cc)
27
28 v['CC'] = cc
29 v['CC_NAME'] = 'irix'
30
31 @conf
32 def irixcc_common_flags(conf):
33 v = conf.env
34
35 v['CC_SRC_F'] = ''
36 v['CC_TGT_F'] = ['-c', '-o']
37 v['CPPPATH_ST'] = '-I%s'
38 v['DEFINES_ST'] = '-D%s'
39
40 # linker
41 if not v['LINK_CC']: v['LINK_CC'] = v['CC']
42 v['CCLNK_SRC_F'] = ''
43 v['CCLNK_TGT_F'] = ['-o']
44
45 v['LIB_ST'] = '-l%s' # template for adding libs
46 v['LIBPATH_ST'] = '-L%s' # template for adding libpaths
47 v['STLIB_ST'] = '-l%s'
48 v['STLIBPATH_ST'] = '-L%s'
49
50 v['cprogram_PATTERN'] = '%s'
51 v['cshlib_PATTERN'] = 'lib%s.so'
52 v['cstlib_PATTERN'] = 'lib%s.a'
53
54 def configure(conf):
55 conf.find_irixcc()
56 conf.find_cpp()
57 conf.find_ar()
58 conf.irixcc_common_flags()
59 conf.cc_load_tools()
60 conf.cc_add_flags()
61 conf.link_add_flags()
62
0 #!/usr/bin/env python
1 # encoding: utf-8
2 # Thomas Nagy, 2006-2010 (ita)
3
4 """
5 Java support
6
7 Javac is one of the few compilers that behaves very badly:
8
9 #. it outputs files where it wants to (-d is only for the package root)
10
11 #. it recompiles files silently behind your back
12
13 #. it outputs an undefined amount of files (inner classes)
14
15 Remember that the compilation can be performed using Jython[1] rather than regular Python. Instead of
16 running one of the following commands::
17
18 ./waf configure
19 python waf configure
20
21 You would have to run::
22
23 java -jar /path/to/jython.jar waf configure
24
25 [1] http://www.jython.org/
26 """
27
28 import os, re, tempfile, shutil
29 from waflib.Configure import conf
30 from waflib import TaskGen, Task, Utils, Options, Build, Errors, Node, Logs
31 from waflib.TaskGen import feature, before_method, after_method
32
33 from waflib.Tools import ccroot
34 ccroot.USELIB_VARS['javac'] = set(['CLASSPATH', 'JAVACFLAGS'])
35
36
37 SOURCE_RE = '**/*.java'
38 JAR_RE = '**/*'
39
40 class_check_source = '''
41 public class Test {
42 public static void main(String[] argv) {
43 Class lib;
44 if (argv.length < 1) {
45 System.err.println("Missing argument");
46 System.exit(77);
47 }
48 try {
49 lib = Class.forName(argv[0]);
50 } catch (ClassNotFoundException e) {
51 System.err.println("ClassNotFoundException");
52 System.exit(1);
53 }
54 lib = null;
55 System.exit(0);
56 }
57 }
58 '''
59
60 @feature('javac')
61 @before_method('process_source')
62 def apply_java(self):
63 """
64 Create a javac task for compiling *.java files*. There can be
65 only one javac task by task generator.
66 """
67 Utils.def_attrs(self, jarname='', classpath='',
68 sourcepath='.', srcdir='.',
69 jar_mf_attributes={}, jar_mf_classpath=[])
70
71 nodes_lst = []
72
73 outdir = getattr(self, 'outdir', None)
74 if outdir:
75 if not isinstance(outdir, Node.Node):
76 outdir = self.path.get_bld().make_node(self.outdir)
77 else:
78 outdir = self.path.get_bld()
79 outdir.mkdir()
80 self.outdir = outdir
81 self.env['OUTDIR'] = outdir.abspath()
82
83 self.javac_task = tsk = self.create_task('javac')
84 tmp = []
85
86 srcdir = getattr(self, 'srcdir', '')
87 if isinstance(srcdir, Node.Node):
88 srcdir = [srcdir]
89 for x in Utils.to_list(srcdir):
90 if isinstance(x, Node.Node):
91 y = x
92 else:
93 y = self.path.find_dir(x)
94 if not y:
95 self.bld.fatal('Could not find the folder %s from %s' % (x, self.path))
96 tmp.append(y)
97 tsk.srcdir = tmp
98
99 if getattr(self, 'compat', None):
100 tsk.env.append_value('JAVACFLAGS', ['-source', self.compat])
101
102 if hasattr(self, 'sourcepath'):
103 fold = [isinstance(x, Node.Node) and x or self.path.find_dir(x) for x in self.to_list(self.sourcepath)]
104 names = os.pathsep.join([x.srcpath() for x in fold])
105 else:
106 names = [x.srcpath() for x in tsk.srcdir]
107
108 if names:
109 tsk.env.append_value('JAVACFLAGS', ['-sourcepath', names])
110
111 @feature('javac')
112 @after_method('apply_java')
113 def use_javac_files(self):
114 """
115 Process the *use* attribute referring to other java compilations
116 """
117 lst = []
118 self.uselib = self.to_list(getattr(self, 'uselib', []))
119 names = self.to_list(getattr(self, 'use', []))
120 get = self.bld.get_tgen_by_name
121 for x in names:
122 try:
123 y = get(x)
124 except:
125 self.uselib.append(x)
126 else:
127 y.post()
128 lst.append(y.jar_task.outputs[0].abspath())
129 self.javac_task.set_run_after(y.jar_task)
130
131 if lst:
132 self.env.append_value('CLASSPATH', lst)
133
134 @feature('javac')
135 @after_method('apply_java', 'propagate_uselib_vars', 'use_javac_files')
136 def set_classpath(self):
137 """
138 Set the CLASSPATH value on the *javac* task previously created.
139 """
140 self.env.append_value('CLASSPATH', getattr(self, 'classpath', []))
141 for x in self.tasks:
142 x.env.CLASSPATH = os.pathsep.join(self.env.CLASSPATH) + os.pathsep
143
144 @feature('jar')
145 @after_method('apply_java', 'use_javac_files')
146 @before_method('process_source')
147 def jar_files(self):
148 """
149 Create a jar task. There can be only one jar task by task generator.
150 """
151 destfile = getattr(self, 'destfile', 'test.jar')
152 jaropts = getattr(self, 'jaropts', [])
153 manifest = getattr(self, 'manifest', None)
154
155 basedir = getattr(self, 'basedir', None)
156 if basedir:
157 if not isinstance(self.basedir, Node.Node):
158 basedir = self.path.get_bld().make_node(basedir)
159 else:
160 basedir = self.path.get_bld()
161 if not basedir:
162 self.bld.fatal('Could not find the basedir %r for %r' % (self.basedir, self))
163
164 self.jar_task = tsk = self.create_task('jar_create')
165 if manifest:
166 jarcreate = getattr(self, 'jarcreate', 'cfm')
167 node = self.path.find_node(manifest)
168 tsk.dep_nodes.append(node)
169 jaropts.insert(0, node.abspath())
170 else:
171 jarcreate = getattr(self, 'jarcreate', 'cf')
172 if not isinstance(destfile, Node.Node):
173 destfile = self.path.find_or_declare(destfile)
174 if not destfile:
175 self.bld.fatal('invalid destfile %r for %r' % (destfile, self))
176 tsk.set_outputs(destfile)
177 tsk.basedir = basedir
178
179 jaropts.append('-C')
180 jaropts.append(basedir.bldpath())
181 jaropts.append('.')
182
183 tsk.env['JAROPTS'] = jaropts
184 tsk.env['JARCREATE'] = jarcreate
185
186 if getattr(self, 'javac_task', None):
187 tsk.set_run_after(self.javac_task)
188
189 @feature('jar')
190 @after_method('jar_files')
191 def use_jar_files(self):
192 """
193 Process the *use* attribute to set the build order on the
194 tasks created by another task generator.
195 """
196 lst = []
197 self.uselib = self.to_list(getattr(self, 'uselib', []))
198 names = self.to_list(getattr(self, 'use', []))
199 get = self.bld.get_tgen_by_name
200 for x in names:
201 try:
202 y = get(x)
203 except:
204 self.uselib.append(x)
205 else:
206 y.post()
207 self.jar_task.run_after.update(y.tasks)
208
209 class jar_create(Task.Task):
210 """
211 Create a jar file
212 """
213 color = 'GREEN'
214 run_str = '${JAR} ${JARCREATE} ${TGT} ${JAROPTS}'
215
216 def runnable_status(self):
217 """
218 Wait for dependent tasks to be executed, then read the
219 files to update the list of inputs.
220 """
221 for t in self.run_after:
222 if not t.hasrun:
223 return Task.ASK_LATER
224 if not self.inputs:
225 global JAR_RE
226 try:
227 self.inputs = [x for x in self.basedir.ant_glob(JAR_RE, remove=False) if id(x) != id(self.outputs[0])]
228 except:
229 raise Errors.WafError('Could not find the basedir %r for %r' % (self.basedir, self))
230 return super(jar_create, self).runnable_status()
231
232 class javac(Task.Task):
233 """
234 Compile java files
235 """
236 color = 'BLUE'
237
238 nocache = True
239 """
240 The .class files cannot be put into a cache at the moment
241 """
242
243 vars = ['CLASSPATH', 'JAVACFLAGS', 'JAVAC', 'OUTDIR']
244 """
245 The javac task will be executed again if the variables CLASSPATH, JAVACFLAGS, JAVAC or OUTDIR change.
246 """
247
248 def runnable_status(self):
249 """
250 Wait for dependent tasks to be complete, then read the file system to find the input nodes.
251 """
252 for t in self.run_after:
253 if not t.hasrun:
254 return Task.ASK_LATER
255
256 if not self.inputs:
257 global SOURCE_RE
258 self.inputs = []
259 for x in self.srcdir:
260 self.inputs.extend(x.ant_glob(SOURCE_RE, remove=False))
261 return super(javac, self).runnable_status()
262
263 def run(self):
264 """
265 Execute the javac compiler
266 """
267 env = self.env
268 gen = self.generator
269 bld = gen.bld
270 wd = bld.bldnode.abspath()
271 def to_list(xx):
272 if isinstance(xx, str): return [xx]
273 return xx
274 cmd = []
275 cmd.extend(to_list(env['JAVAC']))
276 cmd.extend(['-classpath'])
277 cmd.extend(to_list(env['CLASSPATH']))
278 cmd.extend(['-d'])
279 cmd.extend(to_list(env['OUTDIR']))
280 cmd.extend(to_list(env['JAVACFLAGS']))
281
282 files = [a.path_from(bld.bldnode) for a in self.inputs]
283
284 # workaround for command line length limit:
285 # http://support.microsoft.com/kb/830473
286 tmp = None
287 try:
288 if len(str(files)) + len(str(cmd)) > 8192:
289 (fd, tmp) = tempfile.mkstemp(dir=bld.bldnode.abspath())
290 try:
291 os.write(fd, '\n'.join(files).encode())
292 finally:
293 if tmp:
294 os.close(fd)
295 if Logs.verbose:
296 Logs.debug('runner: %r' % (cmd + files))
297 cmd.append('@' + tmp)
298 else:
299 cmd += files
300
301 ret = self.exec_command(cmd, cwd=wd, env=env.env or None)
302 finally:
303 if tmp:
304 os.unlink(tmp)
305 return ret
306
307 def post_run(self):
308 """
309 """
310 for n in self.generator.outdir.ant_glob('**/*.class'):
311 n.sig = Utils.h_file(n.abspath()) # careful with this
312 self.generator.bld.task_sigs[self.uid()] = self.cache_sig
313
314 def configure(self):
315 """
316 Detect the javac, java and jar programs
317 """
318 # If JAVA_PATH is set, we prepend it to the path list
319 java_path = self.environ['PATH'].split(os.pathsep)
320 v = self.env
321
322 if 'JAVA_HOME' in self.environ:
323 java_path = [os.path.join(self.environ['JAVA_HOME'], 'bin')] + java_path
324 self.env['JAVA_HOME'] = [self.environ['JAVA_HOME']]
325
326 for x in 'javac java jar'.split():
327 self.find_program(x, var=x.upper(), path_list=java_path)
328 self.env[x.upper()] = self.cmd_to_list(self.env[x.upper()])
329
330 if 'CLASSPATH' in self.environ:
331 v['CLASSPATH'] = self.environ['CLASSPATH']
332
333 if not v['JAR']: self.fatal('jar is required for making java packages')
334 if not v['JAVAC']: self.fatal('javac is required for compiling java classes')
335 v['JARCREATE'] = 'cf' # can use cvf
336 v['JAVACFLAGS'] = []
337
338 @conf
339 def check_java_class(self, classname, with_classpath=None):
340 """
341 Check if the specified java class exists
342
343 :param classname: class to check, like java.util.HashMap
344 :type classname: string
345 :param with_classpath: additional classpath to give
346 :type with_classpath: string
347 """
348
349 javatestdir = '.waf-javatest'
350
351 classpath = javatestdir
352 if self.env['CLASSPATH']:
353 classpath += os.pathsep + self.env['CLASSPATH']
354 if isinstance(with_classpath, str):
355 classpath += os.pathsep + with_classpath
356
357 shutil.rmtree(javatestdir, True)
358 os.mkdir(javatestdir)
359
360 java_file = open(os.path.join(javatestdir, 'Test.java'), 'w')
361 java_file.write(class_check_source)
362 java_file.close()
363
364 # Compile the source
365 self.exec_command(self.env['JAVAC'] + [os.path.join(javatestdir, 'Test.java')], shell=False)
366
367 # Try to run the app
368 cmd = self.env['JAVA'] + ['-cp', classpath, 'Test', classname]
369 self.to_log("%s\n" % str(cmd))
370 found = self.exec_command(cmd, shell=False)
371
372 self.msg('Checking for java class %s' % classname, not found)
373
374 shutil.rmtree(javatestdir, True)
375
376 return found
377
378 @conf
379 def check_jni_headers(conf):
380 """
381 Check for jni headers and libraries. On success the conf.env variables xxx_JAVA are added for use in C/C++ targets::
382
383 def options(opt):
384 opt.load('compiler_c')
385
386 def configure(conf):
387 conf.load('compiler_c java')
388 conf.check_jni_headers()
389
390 def build(bld):
391 bld.shlib(source='a.c', target='app', use='JAVA')
392 """
393
394 if not conf.env.CC_NAME and not conf.env.CXX_NAME:
395 conf.fatal('load a compiler first (gcc, g++, ..)')
396
397 if not conf.env.JAVA_HOME:
398 conf.fatal('set JAVA_HOME in the system environment')
399
400 # jni requires the jvm
401 javaHome = conf.env['JAVA_HOME'][0]
402
403 dir = conf.root.find_dir(conf.env.JAVA_HOME[0] + '/include')
404 if dir is None:
405 conf.fatal('JAVA_HOME does not seem to be set properly')
406
407 f = dir.ant_glob('**/(jni|jni_md).h')
408 incDirs = [x.parent.abspath() for x in f]
409
410 dir = conf.root.find_dir(conf.env.JAVA_HOME[0])
411 f = dir.ant_glob('**/*jvm.(so|dll|dylib)')
412 libDirs = [x.parent.abspath() for x in f] or [javaHome]
413
414 # On windows, we need both the .dll and .lib to link. On my JDK, they are
415 # in different directories...
416 f = dir.ant_glob('**/*jvm.(lib)')
417 if f:
418 libDirs = [[x, y.parent.abspath()] for x in libDirs for y in f]
419
420 for d in libDirs:
421 try:
422 conf.check(header_name='jni.h', define_name='HAVE_JNI_H', lib='jvm',
423 libpath=d, includes=incDirs, uselib_store='JAVA', uselib='JAVA')
424 except:
425 pass
426 else:
427 break
428 else:
429 conf.fatal('could not find lib jvm in %r (see config.log)' % libDirs)
430
0 #!/usr/bin/env python
1 # encoding: utf-8
2 # Thomas Nagy, 2006-2010 (ita)
3
4 """
5 Support for the KDE4 libraries and msgfmt
6 """
7
8 import os, sys, re
9 from waflib import Options, TaskGen, Task, Utils
10 from waflib.TaskGen import feature, after_method
11
12 @feature('msgfmt')
13 def apply_msgfmt(self):
14 """
15 Process all languages to create .mo files and to install them::
16
17 def build(bld):
18 bld(features='msgfmt', langs='es de fr', appname='myapp', install_path='${KDE4_LOCALE_INSTALL_DIR}')
19 """
20 for lang in self.to_list(self.langs):
21 node = self.path.find_resource(lang+'.po')
22 task = self.create_task('msgfmt', node, node.change_ext('.mo'))
23
24 langname = lang.split('/')
25 langname = langname[-1]
26
27 inst = getattr(self, 'install_path', '${KDE4_LOCALE_INSTALL_DIR}')
28
29 self.bld.install_as(
30 inst + os.sep + langname + os.sep + 'LC_MESSAGES' + os.sep + getattr(self, 'appname', 'set_your_appname') + '.mo',
31 task.outputs[0],
32 chmod = getattr(self, 'chmod', Utils.O644))
33
34 class msgfmt(Task.Task):
35 """
36 Transform .po files into .mo files
37 """
38 color = 'BLUE'
39 run_str = '${MSGFMT} ${SRC} -o ${TGT}'
40
41 def configure(self):
42 """
43 Detect kde4-config and set various variables for the *use* system::
44
45 def options(opt):
46 opt.load('compiler_cxx kde4')
47 def configure(conf):
48 conf.load('compiler_cxx kde4')
49 def build(bld):
50 bld.program(source='main.c', target='app', use='KDECORE KIO KHTML')
51 """
52 kdeconfig = self.find_program('kde4-config')
53 prefix = self.cmd_and_log('%s --prefix' % kdeconfig).strip()
54 fname = '%s/share/apps/cmake/modules/KDELibsDependencies.cmake' % prefix
55 try: os.stat(fname)
56 except OSError:
57 fname = '%s/share/kde4/apps/cmake/modules/KDELibsDependencies.cmake' % prefix
58 try: os.stat(fname)
59 except OSError: self.fatal('could not open %s' % fname)
60
61 try:
62 txt = Utils.readf(fname)
63 except (OSError, IOError):
64 self.fatal('could not read %s' % fname)
65
66 txt = txt.replace('\\\n', '\n')
67 fu = re.compile('#(.*)\n')
68 txt = fu.sub('', txt)
69
70 setregexp = re.compile('([sS][eE][tT]\s*\()\s*([^\s]+)\s+\"([^"]+)\"\)')
71 found = setregexp.findall(txt)
72
73 for (_, key, val) in found:
74 #print key, val
75 self.env[key] = val
76
77 # well well, i could just write an interpreter for cmake files
78 self.env['LIB_KDECORE']= ['kdecore']
79 self.env['LIB_KDEUI'] = ['kdeui']
80 self.env['LIB_KIO'] = ['kio']
81 self.env['LIB_KHTML'] = ['khtml']
82 self.env['LIB_KPARTS'] = ['kparts']
83
84 self.env['LIBPATH_KDECORE'] = [self.env['KDE4_LIB_INSTALL_DIR']]
85 self.env['INCLUDES_KDECORE'] = [self.env['KDE4_INCLUDE_INSTALL_DIR']]
86 self.env.append_value('INCLUDES_KDECORE', [self.env['KDE4_INCLUDE_INSTALL_DIR']+ os.sep + 'KDE'])
87
88 self.find_program('msgfmt', var='MSGFMT')
89
0 #!/usr/bin/env python
1 # encoding: utf-8
2 # Sebastian Schlingmann, 2008
3 # Thomas Nagy, 2008-2010 (ita)
4
5 """
6 Lua support.
7
8 Compile *.lua* files into *.luac*::
9
10 def configure(conf):
11 conf.load('lua')
12 conf.env.LUADIR = '/usr/local/share/myapp/scripts/'
13 def build(bld):
14 bld(source='foo.lua')
15 """
16
17 from waflib.TaskGen import extension
18 from waflib import Task, Utils
19
20 @extension('.lua')
21 def add_lua(self, node):
22 tsk = self.create_task('luac', node, node.change_ext('.luac'))
23 inst_to = getattr(self, 'install_path', self.env.LUADIR and '${LUADIR}' or None)
24 if inst_to:
25 self.bld.install_files(inst_to, tsk.outputs)
26 return tsk
27
28 class luac(Task.Task):
29 run_str = '${LUAC} -s -o ${TGT} ${SRC}'
30 color = 'PINK'
31
32 def configure(conf):
33 """
34 Detect the luac compiler and set *conf.env.LUAC*
35 """
36 conf.find_program('luac', var='LUAC')
37
0 #!/usr/bin/env python
1 # encoding: utf-8
2 # Carlos Rafael Giani, 2006 (dv)
3 # Tamas Pal, 2007 (folti)
4 # Nicolas Mercier, 2009
5
6 """
7 Microsoft Visual C++/Intel C++ compiler support
8
9 Usage::
10
11 $ waf configure --msvc_version="msvc 10.0,msvc 9.0" --msvc_target="x64"
12
13 or::
14
15 def configure(conf):
16 conf.env['MSVC_VERSIONS'] = ['msvc 10.0', 'msvc 9.0', 'msvc 8.0', 'msvc 7.1', 'msvc 7.0', 'msvc 6.0', 'wsdk 7.0', 'intel 11', 'PocketPC 9.0', 'Smartphone 8.0']
17 conf.env['MSVC_TARGETS'] = ['x64']
18 conf.load('msvc')
19
20 or::
21
22 def configure(conf):
23 conf.load('msvc', funs='no_autodetect')
24 conf.check_lib_msvc('gdi32')
25 conf.check_libs_msvc('kernel32 user32')
26 def build(bld):
27 tg = bld.program(source='main.c', target='app', use='KERNEL32 USER32 GDI32')
28
29 Platforms and targets will be tested in the order they appear;
30 the first good configuration will be used.
31 Supported platforms: ia64, x64, x86, x86_amd64, x86_ia64
32
33 Compilers supported:
34
35 * msvc => Visual Studio, versions 6.0 (VC 98, VC .NET 2002) to 10.0 (Visual Studio 2010)
36 * wsdk => Windows SDK, versions 6.0, 6.1, 7.0
37 * icl => Intel compiler, versions 9,10,11
38 * Smartphone => Compiler/SDK for Smartphone devices (armv4/v4i)
39 * PocketPC => Compiler/SDK for PocketPC devices (armv4/v4i)
40
41 To use WAF in a VS2008 Make file project (see http://code.google.com/p/waf/issues/detail?id=894)
42 You may consider to set the environment variable "VS_UNICODE_OUTPUT" to nothing before calling waf.
43 So in your project settings use something like 'cmd.exe /C "set VS_UNICODE_OUTPUT=& set PYTHONUNBUFFERED=true & waf build"'.
44 cmd.exe /C "chcp 1252 & set PYTHONUNBUFFERED=true && set && waf configure"
45 Setting PYTHONUNBUFFERED gives the unbuffered output.
46 """
47
48 import os, sys, re, tempfile
49 try:
50 import _winreg
51 except:
52 try:
53 import winreg as _winreg
54 except:
55 _winreg = None
56
57 from waflib import Utils, TaskGen, Runner, Configure, Task, Options
58 from waflib.Logs import debug, info, warn, error
59 from waflib.TaskGen import after_method, before_method, feature
60
61 from waflib.Configure import conf
62 from waflib.Tools import ccroot, c, cxx, ar, winres
63
64
65 g_msvc_systemlibs = '''
66 aclui activeds ad1 adptif adsiid advapi32 asycfilt authz bhsupp bits bufferoverflowu cabinet
67 cap certadm certidl ciuuid clusapi comctl32 comdlg32 comsupp comsuppd comsuppw comsuppwd comsvcs
68 credui crypt32 cryptnet cryptui d3d8thk daouuid dbgeng dbghelp dciman32 ddao35 ddao35d
69 ddao35u ddao35ud delayimp dhcpcsvc dhcpsapi dlcapi dnsapi dsprop dsuiext dtchelp
70 faultrep fcachdll fci fdi framedyd framedyn gdi32 gdiplus glauxglu32 gpedit gpmuuid
71 gtrts32w gtrtst32hlink htmlhelp httpapi icm32 icmui imagehlp imm32 iphlpapi iprop
72 kernel32 ksguid ksproxy ksuser libcmt libcmtd libcpmt libcpmtd loadperf lz32 mapi
73 mapi32 mgmtapi minidump mmc mobsync mpr mprapi mqoa mqrt msacm32 mscms mscoree
74 msdasc msimg32 msrating mstask msvcmrt msvcurt msvcurtd mswsock msxml2 mtx mtxdm
75 netapi32 nmapinmsupp npptools ntdsapi ntdsbcli ntmsapi ntquery odbc32 odbcbcp
76 odbccp32 oldnames ole32 oleacc oleaut32 oledb oledlgolepro32 opends60 opengl32
77 osptk parser pdh penter pgobootrun pgort powrprof psapi ptrustm ptrustmd ptrustu
78 ptrustud qosname rasapi32 rasdlg rassapi resutils riched20 rpcndr rpcns4 rpcrt4 rtm
79 rtutils runtmchk scarddlg scrnsave scrnsavw secur32 sensapi setupapi sfc shell32
80 shfolder shlwapi sisbkup snmpapi sporder srclient sti strsafe svcguid tapi32 thunk32
81 traffic unicows url urlmon user32 userenv usp10 uuid uxtheme vcomp vcompd vdmdbg
82 version vfw32 wbemuuid webpost wiaguid wininet winmm winscard winspool winstrm
83 wintrust wldap32 wmiutils wow32 ws2_32 wsnmp32 wsock32 wst wtsapi32 xaswitch xolehlp
84 '''.split()
85 """importlibs provided by MSVC/Platform SDK. Do NOT search them"""
86
87 all_msvc_platforms = [ ('x64', 'amd64'), ('x86', 'x86'), ('ia64', 'ia64'), ('x86_amd64', 'amd64'), ('x86_ia64', 'ia64') ]
88 """List of msvc platforms"""
89
90 all_wince_platforms = [ ('armv4', 'arm'), ('armv4i', 'arm'), ('mipsii', 'mips'), ('mipsii_fp', 'mips'), ('mipsiv', 'mips'), ('mipsiv_fp', 'mips'), ('sh4', 'sh'), ('x86', 'cex86') ]
91 """List of wince platforms"""
92
93 all_icl_platforms = [ ('intel64', 'amd64'), ('em64t', 'amd64'), ('ia32', 'x86'), ('Itanium', 'ia64')]
94 """List of icl platforms"""
95
96 def options(opt):
97 opt.add_option('--msvc_version', type='string', help = 'msvc version, eg: "msvc 10.0,msvc 9.0"', default='')
98 opt.add_option('--msvc_targets', type='string', help = 'msvc targets, eg: "x64,arm"', default='')
99
100 def setup_msvc(conf, versions):
101 platforms = getattr(Options.options, 'msvc_targets', '').split(',')
102 if platforms == ['']:
103 platforms=Utils.to_list(conf.env['MSVC_TARGETS']) or [i for i,j in all_msvc_platforms+all_icl_platforms+all_wince_platforms]
104 desired_versions = getattr(Options.options, 'msvc_version', '').split(',')
105 if desired_versions == ['']:
106 desired_versions = conf.env['MSVC_VERSIONS'] or [v for v,_ in versions][::-1]
107 versiondict = dict(versions)
108
109 for version in desired_versions:
110 try:
111 targets = dict(versiondict [version])
112 for target in platforms:
113 try:
114 arch,(p1,p2,p3) = targets[target]
115 compiler,revision = version.rsplit(' ', 1)
116 return compiler,revision,p1,p2,p3
117 except KeyError: continue
118 except KeyError: continue
119 conf.fatal('msvc: Impossible to find a valid architecture for building (in setup_msvc)')
120
121 @conf
122 def get_msvc_version(conf, compiler, version, target, vcvars):
123 """
124 Create a bat file to obtain the location of the libraries
125
126 :param compiler: ?
127 :param version: ?
128 :target: ?
129 :vcvars: ?
130 :return: the location of msvc, the location of include dirs, and the library paths
131 :rtype: tuple of strings
132 """
133 debug('msvc: get_msvc_version: %r %r %r', compiler, version, target)
134 batfile = conf.bldnode.make_node('waf-print-msvc.bat')
135 batfile.write("""@echo off
136 set INCLUDE=
137 set LIB=
138 call "%s" %s
139 echo PATH=%%PATH%%
140 echo INCLUDE=%%INCLUDE%%
141 echo LIB=%%LIB%%
142 """ % (vcvars,target))
143 sout = conf.cmd_and_log(['cmd', '/E:on', '/V:on', '/C', batfile.abspath()])
144 lines = sout.splitlines()
145
146 if not lines[0]: lines=lines[1:]
147 for x in ('Setting environment', 'Setting SDK environment', 'Intel(R) C++ Compiler', 'Intel Parallel Studio'):
148 if lines[0].find(x) != -1:
149 break
150 else:
151 debug('msvc: get_msvc_version: %r %r %r -> not found', compiler, version, target)
152 conf.fatal('msvc: Impossible to find a valid architecture for building (in get_msvc_version)')
153
154 for line in lines[1:]:
155 if line.startswith('PATH='):
156 path = line[5:]
157 MSVC_PATH = path.split(';')
158 elif line.startswith('INCLUDE='):
159 MSVC_INCDIR = [i for i in line[8:].split(';') if i]
160 elif line.startswith('LIB='):
161 MSVC_LIBDIR = [i for i in line[4:].split(';') if i]
162
163 # Check if the compiler is usable at all.
164 # The detection may return 64-bit versions even on 32-bit systems, and these would fail to run.
165 env = {}
166 env.update(os.environ)
167 env.update(PATH = path)
168 compiler_name, linker_name, lib_name = _get_prog_names(conf, compiler)
169 cxx = conf.find_program(compiler_name, path_list=MSVC_PATH)
170 cxx = conf.cmd_to_list(cxx)
171
172 # delete CL if exists. because it could contain parameters wich can change cl's behaviour rather catastrophically.
173 if 'CL' in env:
174 del(env['CL'])
175
176 try:
177 try:
178 conf.cmd_and_log(cxx + ['/help'], env=env)
179 except Exception as e:
180 debug('msvc: get_msvc_version: %r %r %r -> failure' % (compiler, version, target))
181 debug(str(e))
182 conf.fatal('msvc: cannot run the compiler (in get_msvc_version)')
183 else:
184 debug('msvc: get_msvc_version: %r %r %r -> OK', compiler, version, target)
185 finally:
186 conf.env[compiler_name] = ''
187
188 return (MSVC_PATH, MSVC_INCDIR, MSVC_LIBDIR)
189
190 @conf
191 def gather_wsdk_versions(conf, versions):
192 """
193 Use winreg to add the msvc versions to the input list
194
195 :param versions: list to modify
196 :type versions: list
197 """
198 version_pattern = re.compile('^v..?.?\...?.?')
199 try:
200 all_versions = _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, 'SOFTWARE\\Wow6432node\\Microsoft\\Microsoft SDKs\\Windows')
201 except WindowsError:
202 try:
203 all_versions = _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, 'SOFTWARE\\Microsoft\\Microsoft SDKs\\Windows')
204 except WindowsError:
205 return
206 index = 0
207 while 1:
208 try:
209 version = _winreg.EnumKey(all_versions, index)
210 except WindowsError:
211 break
212 index = index + 1
213 if not version_pattern.match(version):
214 continue
215 try:
216 msvc_version = _winreg.OpenKey(all_versions, version)
217 path,type = _winreg.QueryValueEx(msvc_version,'InstallationFolder')
218 except WindowsError:
219 continue
220 if os.path.isfile(os.path.join(path, 'bin', 'SetEnv.cmd')):
221 targets = []
222 for target,arch in all_msvc_platforms:
223 try:
224 targets.append((target, (arch, conf.get_msvc_version('wsdk', version, '/'+target, os.path.join(path, 'bin', 'SetEnv.cmd')))))
225 except conf.errors.ConfigurationError:
226 pass
227 versions.append(('wsdk ' + version[1:], targets))
228
229 def gather_wince_supported_platforms():
230 """
231 Checks SmartPhones SDKs
232
233 :param versions: list to modify
234 :type versions: list
235 """
236 supported_wince_platforms = []
237 try:
238 ce_sdk = _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, 'SOFTWARE\\Wow6432node\\Microsoft\\Windows CE Tools\\SDKs')
239 except WindowsError:
240 try:
241 ce_sdk = _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, 'SOFTWARE\\Microsoft\\Windows CE Tools\\SDKs')
242 except WindowsError:
243 ce_sdk = ''
244 if not ce_sdk:
245 return supported_wince_platforms
246
247 ce_index = 0
248 while 1:
249 try:
250 sdk_device = _winreg.EnumKey(ce_sdk, ce_index)
251 except WindowsError:
252 break
253 ce_index = ce_index + 1
254 sdk = _winreg.OpenKey(ce_sdk, sdk_device)
255 try:
256 path,type = _winreg.QueryValueEx(sdk, 'SDKRootDir')
257 except WindowsError:
258 try:
259 path,type = _winreg.QueryValueEx(sdk,'SDKInformation')
260 path,xml = os.path.split(path)
261 except WindowsError:
262 continue
263 path=str(path)
264 path,device = os.path.split(path)
265 if not device:
266 path,device = os.path.split(path)
267 for arch,compiler in all_wince_platforms:
268 platforms = []
269 if os.path.isdir(os.path.join(path, device, 'Lib', arch)):
270 platforms.append((arch, compiler, os.path.join(path, device, 'Include', arch), os.path.join(path, device, 'Lib', arch)))
271 if platforms:
272 supported_wince_platforms.append((device, platforms))
273 return supported_wince_platforms
274
275 def gather_msvc_detected_versions():
276 #Detected MSVC versions!
277 version_pattern = re.compile('^(\d\d?\.\d\d?)(Exp)?$')
278 detected_versions = []
279 for vcver,vcvar in [('VCExpress','Exp'), ('VisualStudio','')]:
280 try:
281 prefix = 'SOFTWARE\\Wow6432node\\Microsoft\\'+vcver
282 all_versions = _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, prefix)
283 except WindowsError:
284 try:
285 prefix = 'SOFTWARE\\Microsoft\\'+vcver
286 all_versions = _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, prefix)
287 except WindowsError:
288 continue
289
290 index = 0
291 while 1:
292 try:
293 version = _winreg.EnumKey(all_versions, index)
294 except WindowsError:
295 break
296 index = index + 1
297 match = version_pattern.match(version)
298 if not match:
299 continue
300 else:
301 versionnumber = float(match.group(1))
302 detected_versions.append((versionnumber, version+vcvar, prefix+"\\"+version))
303 def fun(tup):
304 return tup[0]
305
306 try:
307 detected_versions.sort(key = fun)
308 except:
309 # old python sort
310 detected_versions.sort(lambda x,y: cmp(x[0], y[0]))
311 return detected_versions
312
313 @conf
314 def gather_msvc_targets(conf, versions, version, vc_path):
315 #Looking for normal MSVC compilers!
316 targets = []
317 if os.path.isfile(os.path.join(vc_path, 'vcvarsall.bat')):
318 for target,realtarget in all_msvc_platforms[::-1]:
319 try:
320 targets.append((target, (realtarget, conf.get_msvc_version('msvc', version, target, os.path.join(vc_path, 'vcvarsall.bat')))))
321 except conf.errors.ConfigurationError:
322 pass
323 elif os.path.isfile(os.path.join(vc_path, 'Common7', 'Tools', 'vsvars32.bat')):
324 try:
325 targets.append(('x86', ('x86', conf.get_msvc_version('msvc', version, 'x86', os.path.join(vc_path, 'Common7', 'Tools', 'vsvars32.bat')))))
326 except conf.errors.ConfigurationError:
327 pass
328 elif os.path.isfile(os.path.join(vc_path, 'Bin', 'vcvars32.bat')):
329 try:
330 targets.append(('x86', ('x86', conf.get_msvc_version('msvc', version, '', os.path.join(vc_path, 'Bin', 'vcvars32.bat')))))
331 except conf.errors.ConfigurationError:
332 pass
333 versions.append(('msvc '+ version, targets))
334
335 @conf
336 def gather_wince_targets(conf, versions, version, vc_path, vsvars, supported_platforms):
337 #Looking for Win CE compilers!
338 for device,platforms in supported_platforms:
339 cetargets = []
340 for platform,compiler,include,lib in platforms:
341 winCEpath = os.path.join(vc_path, 'ce')
342 if not os.path.isdir(winCEpath):
343 continue
344 try:
345 common_bindirs,_1,_2 = conf.get_msvc_version('msvc', version, 'x86', vsvars)
346 except conf.errors.ConfigurationError:
347 continue
348 if os.path.isdir(os.path.join(winCEpath, 'lib', platform)):
349 bindirs = [os.path.join(winCEpath, 'bin', compiler), os.path.join(winCEpath, 'bin', 'x86_'+compiler)] + common_bindirs
350 incdirs = [os.path.join(winCEpath, 'include'), os.path.join(winCEpath, 'atlmfc', 'include'), include]
351 libdirs = [os.path.join(winCEpath, 'lib', platform), os.path.join(winCEpath, 'atlmfc', 'lib', platform), lib]
352 cetargets.append((platform, (platform, (bindirs,incdirs,libdirs))))
353 if cetargets:
354 versions.append((device + ' ' + version, cetargets))
355
356 @conf
357 def gather_msvc_versions(conf, versions):
358 vc_paths = []
359 for (v,version,reg) in gather_msvc_detected_versions():
360 try:
361 try:
362 msvc_version = _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, reg + "\\Setup\\VC")
363 except WindowsError:
364 msvc_version = _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, reg + "\\Setup\\Microsoft Visual C++")
365 path,type = _winreg.QueryValueEx(msvc_version, 'ProductDir')
366 vc_paths.append((version, os.path.abspath(str(path))))
367 except WindowsError:
368 continue
369
370 wince_supported_platforms = gather_wince_supported_platforms()
371
372 for version,vc_path in vc_paths:
373 vs_path = os.path.dirname(vc_path)
374 vsvars = os.path.join(vs_path, 'Common7', 'Tools', 'vsvars32.bat')
375 if wince_supported_platforms and os.path.isfile(vsvars):
376 conf.gather_wince_targets(versions, version, vc_path, vsvars, wince_supported_platforms)
377
378 for version,vc_path in vc_paths:
379 vs_path = os.path.dirname(vc_path)
380 conf.gather_msvc_targets(versions, version, vc_path)
381
382 @conf
383 def gather_icl_versions(conf, versions):
384 """
385 Checks ICL compilers
386
387 :param versions: list to modify
388 :type versions: list
389 """
390 version_pattern = re.compile('^...?.?\....?.?')
391 try:
392 all_versions = _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, 'SOFTWARE\\Wow6432node\\Intel\\Compilers\\C++')
393 except WindowsError:
394 try:
395 all_versions = _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, 'SOFTWARE\\Intel\\Compilers\\C++')
396 except WindowsError:
397 return
398 index = 0
399 while 1:
400 try:
401 version = _winreg.EnumKey(all_versions, index)
402 except WindowsError:
403 break
404 index = index + 1
405 if not version_pattern.match(version):
406 continue
407 targets = []
408 for target,arch in all_icl_platforms:
409 try:
410 if target=='intel64': targetDir='EM64T_NATIVE'
411 else: targetDir=target
412 _winreg.OpenKey(all_versions,version+'\\'+targetDir)
413 icl_version=_winreg.OpenKey(all_versions,version)
414 path,type=_winreg.QueryValueEx(icl_version,'ProductDir')
415 if os.path.isfile(os.path.join(path,'bin','iclvars.bat')):
416 try:
417 targets.append((target,(arch,conf.get_msvc_version('intel',version,target,os.path.join(path,'bin','iclvars.bat')))))
418 except conf.errors.ConfigurationError:
419 pass
420 except WindowsError:
421 pass
422 for target,arch in all_icl_platforms:
423 try:
424 icl_version = _winreg.OpenKey(all_versions, version+'\\'+target)
425 path,type = _winreg.QueryValueEx(icl_version,'ProductDir')
426 if os.path.isfile(os.path.join(path, 'bin', 'iclvars.bat')):
427 try:
428 targets.append((target, (arch, conf.get_msvc_version('intel', version, target, os.path.join(path, 'bin', 'iclvars.bat')))))
429 except conf.errors.ConfigurationError:
430 pass
431 except WindowsError:
432 continue
433 major = version[0:2]
434 versions.append(('intel ' + major, targets))
435
436 @conf
437 def get_msvc_versions(conf):
438 """
439 :return: list of compilers installed
440 :rtype: list of string
441 """
442 if not conf.env['MSVC_INSTALLED_VERSIONS']:
443 lst = []
444 conf.gather_icl_versions(lst)
445 conf.gather_wsdk_versions(lst)
446 conf.gather_msvc_versions(lst)
447 conf.env['MSVC_INSTALLED_VERSIONS'] = lst
448 return conf.env['MSVC_INSTALLED_VERSIONS']
449
450 @conf
451 def print_all_msvc_detected(conf):
452 """
453 Print the contents of *conf.env.MSVC_INSTALLED_VERSIONS*
454 """
455 for version,targets in conf.env['MSVC_INSTALLED_VERSIONS']:
456 info(version)
457 for target,l in targets:
458 info("\t"+target)
459
460 @conf
461 def detect_msvc(conf):
462 versions = get_msvc_versions(conf)
463 return setup_msvc(conf, versions)
464
465 @conf
466 def find_lt_names_msvc(self, libname, is_static=False):
467 """
468 Win32/MSVC specific code to glean out information from libtool la files.
469 this function is not attached to the task_gen class
470 """
471 lt_names=[
472 'lib%s.la' % libname,
473 '%s.la' % libname,
474 ]
475
476 for path in self.env['LIBPATH']:
477 for la in lt_names:
478 laf=os.path.join(path,la)
479 dll=None
480 if os.path.exists(laf):
481 ltdict = Utils.read_la_file(laf)
482 lt_libdir=None
483 if ltdict.get('libdir', ''):
484 lt_libdir = ltdict['libdir']
485 if not is_static and ltdict.get('library_names', ''):
486 dllnames=ltdict['library_names'].split()
487 dll=dllnames[0].lower()
488 dll=re.sub('\.dll$', '', dll)
489 return (lt_libdir, dll, False)
490 elif ltdict.get('old_library', ''):
491 olib=ltdict['old_library']
492 if os.path.exists(os.path.join(path,olib)):
493 return (path, olib, True)
494 elif lt_libdir != '' and os.path.exists(os.path.join(lt_libdir,olib)):
495 return (lt_libdir, olib, True)
496 else:
497 return (None, olib, True)
498 else:
499 raise self.errors.WafError('invalid libtool object file: %s' % laf)
500 return (None, None, None)
501
502 @conf
503 def libname_msvc(self, libname, is_static=False):
504 lib = libname.lower()
505 lib = re.sub('\.lib$','',lib)
506
507 if lib in g_msvc_systemlibs:
508 return lib
509
510 lib=re.sub('^lib','',lib)
511
512 if lib == 'm':
513 return None
514
515 (lt_path, lt_libname, lt_static) = self.find_lt_names_msvc(lib, is_static)
516
517 if lt_path != None and lt_libname != None:
518 if lt_static == True:
519 # file existance check has been made by find_lt_names
520 return os.path.join(lt_path,lt_libname)
521
522 if lt_path != None:
523 _libpaths=[lt_path] + self.env['LIBPATH']
524 else:
525 _libpaths=self.env['LIBPATH']
526
527 static_libs=[
528 'lib%ss.lib' % lib,
529 'lib%s.lib' % lib,
530 '%ss.lib' % lib,
531 '%s.lib' %lib,
532 ]
533
534 dynamic_libs=[
535 'lib%s.dll.lib' % lib,
536 'lib%s.dll.a' % lib,
537 '%s.dll.lib' % lib,
538 '%s.dll.a' % lib,
539 'lib%s_d.lib' % lib,
540 '%s_d.lib' % lib,
541 '%s.lib' %lib,
542 ]
543
544 libnames=static_libs
545 if not is_static:
546 libnames=dynamic_libs + static_libs
547
548 for path in _libpaths:
549 for libn in libnames:
550 if os.path.exists(os.path.join(path, libn)):
551 debug('msvc: lib found: %s' % os.path.join(path,libn))
552 return re.sub('\.lib$', '',libn)
553
554 #if no lib can be found, just return the libname as msvc expects it
555 self.fatal("The library %r could not be found" % libname)
556 return re.sub('\.lib$', '', libname)
557
558 @conf
559 def check_lib_msvc(self, libname, is_static=False, uselib_store=None):
560 """
561 Ideally we should be able to place the lib in the right env var, either STLIB or LIB,
562 but we don't distinguish static libs from shared libs.
563 This is ok since msvc doesn't have any special linker flag to select static libs (no env['STLIB_MARKER'])
564 """
565 libn = self.libname_msvc(libname, is_static)
566
567 if not uselib_store:
568 uselib_store = libname.upper()
569
570 if False and is_static: # disabled
571 self.env['STLIB_' + uselib_store] = [libn]
572 else:
573 self.env['LIB_' + uselib_store] = [libn]
574
575 @conf
576 def check_libs_msvc(self, libnames, is_static=False):
577 for libname in Utils.to_list(libnames):
578 self.check_lib_msvc(libname, is_static)
579
580 def configure(conf):
581 """
582 Configuration methods to call for detecting msvc
583 """
584 conf.autodetect()
585 conf.find_msvc()
586 conf.msvc_common_flags()
587 conf.cc_load_tools()
588 conf.cxx_load_tools()
589 conf.cc_add_flags()
590 conf.cxx_add_flags()
591 conf.link_add_flags()
592 conf.visual_studio_add_flags()
593
594 @conf
595 def no_autodetect(conf):
596 conf.env.NO_MSVC_DETECT = 1
597 configure(conf)
598
599 @conf
600 def autodetect(conf):
601 v = conf.env
602 if v.NO_MSVC_DETECT:
603 return
604 compiler, version, path, includes, libdirs = conf.detect_msvc()
605 v['PATH'] = path
606 v['INCLUDES'] = includes
607 v['LIBPATH'] = libdirs
608 v['MSVC_COMPILER'] = compiler
609 try:
610 v['MSVC_VERSION'] = float(version)
611 except:
612 v['MSVC_VERSION'] = float(version[:-3])
613
614 def _get_prog_names(conf, compiler):
615 if compiler=='intel':
616 compiler_name = 'ICL'
617 linker_name = 'XILINK'
618 lib_name = 'XILIB'
619 else:
620 # assumes CL.exe
621 compiler_name = 'CL'
622 linker_name = 'LINK'
623 lib_name = 'LIB'
624 return compiler_name, linker_name, lib_name
625
626 @conf
627 def find_msvc(conf):
628 """Due to path format limitations, limit operation only to native Win32. Yeah it sucks."""
629 if sys.platform == 'cygwin':
630 conf.fatal('MSVC module does not work under cygwin Python!')
631
632 # the autodetection is supposed to be performed before entering in this method
633 v = conf.env
634 path = v['PATH']
635 compiler = v['MSVC_COMPILER']
636 version = v['MSVC_VERSION']
637
638 compiler_name, linker_name, lib_name = _get_prog_names(conf, compiler)
639 v.MSVC_MANIFEST = (compiler == 'msvc' and version >= 8) or (compiler == 'wsdk' and version >= 6) or (compiler == 'intel' and version >= 11)
640
641 # compiler
642 cxx = None
643 if v['CXX']: cxx = v['CXX']
644 elif 'CXX' in conf.environ: cxx = conf.environ['CXX']
645 cxx = conf.find_program(compiler_name, var='CXX', path_list=path)
646 cxx = conf.cmd_to_list(cxx)
647
648 # before setting anything, check if the compiler is really msvc
649 env = dict(conf.environ)
650 if path: env.update(PATH = ';'.join(path))
651 if not conf.cmd_and_log(cxx + ['/nologo', '/help'], env=env):
652 conf.fatal('the msvc compiler could not be identified')
653
654 # c/c++ compiler
655 v['CC'] = v['CXX'] = cxx
656 v['CC_NAME'] = v['CXX_NAME'] = 'msvc'
657
658 # linker
659 if not v['LINK_CXX']:
660 link = conf.find_program(linker_name, path_list=path)
661 if link: v['LINK_CXX'] = link
662 else: conf.fatal('%s was not found (linker)' % linker_name)
663 v['LINK'] = link
664
665 if not v['LINK_CC']:
666 v['LINK_CC'] = v['LINK_CXX']
667
668 # staticlib linker
669 if not v['AR']:
670 stliblink = conf.find_program(lib_name, path_list=path, var='AR')
671 if not stliblink: return
672 v['ARFLAGS'] = ['/NOLOGO']
673
674 # manifest tool. Not required for VS 2003 and below. Must have for VS 2005 and later
675 if v.MSVC_MANIFEST:
676 mt = conf.find_program('MT', path_list=path, var='MT')
677 v['MTFLAGS'] = ['/NOLOGO']
678
679 conf.load('winres')
680
681 if not conf.env['WINRC']:
682 warn('Resource compiler not found. Compiling resource file is disabled')
683
684 @conf
685 def visual_studio_add_flags(self):
686 """visual studio flags found in the system environment"""
687 v = self.env
688 try: v.prepend_value('INCLUDES', self.environ['INCLUDE'].split(';')) # notice the 'S'
689 except: pass
690 try: v.prepend_value('LIBPATH', self.environ['LIB'].split(';'))
691 except: pass
692
693 @conf
694 def msvc_common_flags(conf):
695 """
696 Setup the flags required for executing the msvc compiler
697
698 The default is to allow a static and a shared library having the same name in the same directory, the static one being prefixed by 'lib'. If you feel that this
699 is incorrect, just change the extension (issue #824)::
700
701 bld.env.STLIB_ST = bld.env.SHLIB_ST = '%s.lib'
702 bld.stlib(..., name='libfoo')
703 bld.shlib(..., name='foo')
704 """
705 v = conf.env
706
707 v['DEST_BINFMT'] = 'pe'
708 v.append_value('CFLAGS', ['/nologo'])
709 v.append_value('CXXFLAGS', ['/nologo'])
710 v['DEFINES_ST'] = '/D%s'
711
712 v['CC_SRC_F'] = ''
713 v['CC_TGT_F'] = ['/c', '/Fo']
714 if v['MSVC_VERSION'] >= 8:
715 v['CC_TGT_F']= ['/FC'] + v['CC_TGT_F']
716 v['CXX_SRC_F'] = ''
717 v['CXX_TGT_F'] = ['/c', '/Fo']
718 if v['MSVC_VERSION'] >= 8:
719 v['CXX_TGT_F']= ['/FC'] + v['CXX_TGT_F']
720
721 v['CPPPATH_ST'] = '/I%s' # template for adding include paths
722
723 v['AR_TGT_F'] = v['CCLNK_TGT_F'] = v['CXXLNK_TGT_F'] = '/OUT:'
724
725 # Subsystem specific flags
726 v['CFLAGS_CONSOLE'] = v['CXXFLAGS_CONSOLE'] = ['/SUBSYSTEM:CONSOLE']
727 v['CFLAGS_NATIVE'] = v['CXXFLAGS_NATIVE'] = ['/SUBSYSTEM:NATIVE']
728 v['CFLAGS_POSIX'] = v['CXXFLAGS_POSIX'] = ['/SUBSYSTEM:POSIX']
729 v['CFLAGS_WINDOWS'] = v['CXXFLAGS_WINDOWS'] = ['/SUBSYSTEM:WINDOWS']
730 v['CFLAGS_WINDOWSCE'] = v['CXXFLAGS_WINDOWSCE'] = ['/SUBSYSTEM:WINDOWSCE']
731
732 # CRT specific flags
733 v['CFLAGS_CRT_MULTITHREADED'] = v['CXXFLAGS_CRT_MULTITHREADED'] = ['/MT']
734 v['CFLAGS_CRT_MULTITHREADED_DLL'] = v['CXXFLAGS_CRT_MULTITHREADED_DLL'] = ['/MD']
735
736 v['CFLAGS_CRT_MULTITHREADED_DBG'] = v['CXXFLAGS_CRT_MULTITHREADED_DBG'] = ['/MTd']
737 v['CFLAGS_CRT_MULTITHREADED_DLL_DBG'] = v['CXXFLAGS_CRT_MULTITHREADED_DLL_DBG'] = ['/MDd']
738
739 # linker
740 v['LIB_ST'] = '%s.lib' # template for adding shared libs
741 v['LIBPATH_ST'] = '/LIBPATH:%s' # template for adding libpaths
742 v['STLIB_ST'] = 'lib%s.lib'
743 v['STLIBPATH_ST'] = '/LIBPATH:%s'
744
745 v.append_value('LINKFLAGS', ['/NOLOGO'])
746 if v['MSVC_MANIFEST']:
747 v.append_value('LINKFLAGS', ['/MANIFEST'])
748
749 # shared library
750 v['CFLAGS_cshlib'] = []
751 v['CXXFLAGS_cxxshlib'] = []
752 v['LINKFLAGS_cshlib'] = v['LINKFLAGS_cxxshlib'] = ['/DLL']
753 v['cshlib_PATTERN'] = v['cxxshlib_PATTERN'] = '%s.dll'
754 v['implib_PATTERN'] = '%s.lib'
755 v['IMPLIB_ST'] = '/IMPLIB:%s'
756
757 # static library
758 v['LINKFLAGS_cstlib'] = []
759 v['cstlib_PATTERN'] = v['cxxstlib_PATTERN'] = 'lib%s.lib'
760
761 # program
762 v['cprogram_PATTERN'] = v['cxxprogram_PATTERN'] = '%s.exe'
763
764
765 #######################################################################################################
766 ##### conf above, build below
767
768 @after_method('apply_link')
769 @feature('c', 'cxx')
770 def apply_flags_msvc(self):
771 """
772 Add additional flags implied by msvc, such as subsystems and pdb files::
773
774 def build(bld):
775 bld.stlib(source='main.c', target='bar', subsystem='gruik')
776 """
777 if self.env.CC_NAME != 'msvc' or not getattr(self, 'link_task', None):
778 return
779
780 is_static = isinstance(self.link_task, ccroot.stlink_task)
781
782 subsystem = getattr(self, 'subsystem', '')
783 if subsystem:
784 subsystem = '/subsystem:%s' % subsystem
785 flags = is_static and 'ARFLAGS' or 'LINKFLAGS'
786 self.env.append_value(flags, subsystem)
787
788 if not is_static:
789 for f in self.env.LINKFLAGS:
790 d = f.lower()
791 if d[1:] == 'debug':
792 pdbnode = self.link_task.outputs[0].change_ext('.pdb')
793 self.link_task.outputs.append(pdbnode)
794
795 try:
796 self.install_task.source.append(pdbnode)
797 except AttributeError:
798 pass
799
800 break
801
802 # split the manifest file processing from the link task, like for the rc processing
803
804 @feature('cprogram', 'cshlib', 'cxxprogram', 'cxxshlib')
805 @after_method('apply_link')
806 def apply_manifest(self):
807 """
808 Special linker for MSVC with support for embedding manifests into DLL's
809 and executables compiled by Visual Studio 2005 or probably later. Without
810 the manifest file, the binaries are unusable.
811 See: http://msdn2.microsoft.com/en-us/library/ms235542(VS.80).aspx
812 """
813
814 if self.env.CC_NAME == 'msvc' and self.env.MSVC_MANIFEST and getattr(self, 'link_task', None):
815 out_node = self.link_task.outputs[0]
816 man_node = out_node.parent.find_or_declare(out_node.name + '.manifest')
817 self.link_task.outputs.append(man_node)
818 self.link_task.do_manifest = True
819
820 def exec_mf(self):
821 """
822 Create the manifest file
823 """
824 env = self.env
825 mtool = env['MT']
826 if not mtool:
827 return 0
828
829 self.do_manifest = False
830
831 outfile = self.outputs[0].abspath()
832
833 manifest = None
834 for out_node in self.outputs:
835 if out_node.name.endswith('.manifest'):
836 manifest = out_node.abspath()
837 break
838 if manifest is None:
839 # Should never get here. If we do, it means the manifest file was
840 # never added to the outputs list, thus we don't have a manifest file
841 # to embed, so we just return.
842 return 0
843
844 # embedding mode. Different for EXE's and DLL's.
845 # see: http://msdn2.microsoft.com/en-us/library/ms235591(VS.80).aspx
846 mode = ''
847 if 'cprogram' in self.generator.features or 'cxxprogram' in self.generator.features:
848 mode = '1'
849 elif 'cshlib' in self.generator.features or 'cxxshlib' in self.generator.features:
850 mode = '2'
851
852 debug('msvc: embedding manifest in mode %r' % mode)
853
854 lst = []
855 lst.append(env['MT'])
856 lst.extend(Utils.to_list(env['MTFLAGS']))
857 lst.extend(['-manifest', manifest])
858 lst.append('-outputresource:%s;%s' % (outfile, mode))
859
860 lst = [lst]
861 return self.exec_command(*lst)
862
863 def quote_response_command(self, flag):
864 if flag.find(' ') > -1:
865 for x in ('/LIBPATH:', '/IMPLIB:', '/OUT:', '/I'):
866 if flag.startswith(x):
867 flag = '%s"%s"' % (x, flag[len(x):])
868 break
869 else:
870 flag = '"%s"' % flag
871 return flag
872
873 def exec_response_command(self, cmd, **kw):
874 # not public yet
875 try:
876 tmp = None
877 if sys.platform.startswith('win') and isinstance(cmd, list) and len(' '.join(cmd)) >= 8192:
878 program = cmd[0] #unquoted program name, otherwise exec_command will fail
879 cmd = [self.quote_response_command(x) for x in cmd]
880 (fd, tmp) = tempfile.mkstemp()
881 os.write(fd, '\r\n'.join(i.replace('\\', '\\\\') for i in cmd[1:]).encode())
882 os.close(fd)
883 cmd = [program, '@' + tmp]
884 # no return here, that's on purpose
885 ret = self.generator.bld.exec_command(cmd, **kw)
886 finally:
887 if tmp:
888 try:
889 os.remove(tmp)
890 except:
891 pass # anti-virus and indexers can keep the files open -_-
892 return ret
893
894 ########## stupid evil command modification: concatenate the tokens /Fx, /doc, and /x: with the next token
895
896 def exec_command_msvc(self, *k, **kw):
897 """
898 Change the command-line execution for msvc programs.
899 Instead of quoting all the paths and keep using the shell, we can just join the options msvc is interested in
900 """
901 if self.env['CC_NAME'] == 'msvc':
902 if isinstance(k[0], list):
903 lst = []
904 carry = ''
905 for a in k[0]:
906 if a == '/Fo' or a == '/doc' or a[-1] == ':':
907 carry = a
908 else:
909 lst.append(carry + a)
910 carry = ''
911 k = [lst]
912
913 if self.env['PATH']:
914 env = dict(os.environ)
915 env.update(PATH = ';'.join(self.env['PATH']))
916 kw['env'] = env
917
918 bld = self.generator.bld
919 try:
920 if not kw.get('cwd', None):
921 kw['cwd'] = bld.cwd
922 except AttributeError:
923 bld.cwd = kw['cwd'] = bld.variant_dir
924
925 ret = self.exec_response_command(k[0], **kw)
926 if not ret and getattr(self, 'do_manifest', None):
927 ret = self.exec_mf()
928 return ret
929
930 for k in 'c cxx cprogram cxxprogram cshlib cxxshlib cstlib cxxstlib'.split():
931 cls = Task.classes.get(k, None)
932 if cls:
933 cls.exec_command = exec_command_msvc
934 cls.exec_response_command = exec_response_command
935 cls.quote_response_command = quote_response_command
936 cls.exec_mf = exec_mf
937
0 #!/usr/bin/env python
1 # encoding: utf-8
2 # Thomas Nagy, 2008-2010 (ita)
3
4 """
5 Nasm tool (asm processing)
6 """
7
8 import waflib.Tools.asm # leave this
9 from waflib.TaskGen import feature
10
11 @feature('asm')
12 def apply_nasm_vars(self):
13 """provided for compatibility"""
14 self.env.append_value('ASFLAGS', self.to_list(getattr(self, 'nasm_flags', [])))
15
16 def configure(conf):
17 """
18 Detect nasm/yasm and set the variable *AS*
19 """
20 nasm = conf.find_program(['nasm', 'yasm'], var='AS')
21 conf.env.AS_TGT_F = ['-o']
22 conf.env.ASLNK_TGT_F = ['-o']
0 #!/usr/bin/env python
1 # encoding: utf-8
2 # andersg at 0x63.nu 2007
3 # Thomas Nagy 2010 (ita)
4
5 """
6 Support for Perl extensions. A C/C++ compiler is required::
7
8 def options(opt):
9 opt.load('compiler_c perl')
10 def configure(conf):
11 conf.load('compiler_c perl')
12 conf.check_perl_version((5,6,0))
13 conf.check_perl_ext_devel()
14 conf.check_perl_module('Cairo')
15 conf.check_perl_module('Devel::PPPort 4.89')
16 def build(bld):
17 bld(
18 features = 'c cshlib perlext',
19 source = 'Mytest.xs',
20 target = 'Mytest',
21 install_path = '${ARCHDIR_PERL}/auto')
22 bld.install_files('${ARCHDIR_PERL}', 'Mytest.pm')
23 """
24
25 import os
26 from waflib import Task, Options, Utils
27 from waflib.Configure import conf
28 from waflib.TaskGen import extension, feature, before_method
29
30 @before_method('apply_incpaths', 'apply_link', 'propagate_uselib_vars')
31 @feature('perlext')
32 def init_perlext(self):
33 """
34 Change the values of *cshlib_PATTERN* and *cxxshlib_PATTERN* to remove the
35 *lib* prefix from library names.
36 """
37 self.uselib = self.to_list(getattr(self, 'uselib', []))
38 if not 'PERLEXT' in self.uselib: self.uselib.append('PERLEXT')
39 self.env['cshlib_PATTERN'] = self.env['cxxshlib_PATTERN'] = self.env['perlext_PATTERN']
40
41 @extension('.xs')
42 def xsubpp_file(self, node):
43 """
44 Create :py:class:`waflib.Tools.perl.xsubpp` tasks to process *.xs* files
45 """
46 outnode = node.change_ext('.c')
47 self.create_task('xsubpp', node, outnode)
48 self.source.append(outnode)
49
50 class xsubpp(Task.Task):
51 """
52 Process *.xs* files
53 """
54 run_str = '${PERL} ${XSUBPP} -noprototypes -typemap ${EXTUTILS_TYPEMAP} ${SRC} > ${TGT}'
55 color = 'BLUE'
56 ext_out = ['.h']
57
58 @conf
59 def check_perl_version(self, minver=None):
60 """
61 Check if Perl is installed, and set the variable PERL.
62 minver is supposed to be a tuple
63 """
64 res = True
65
66 if minver:
67 cver = '.'.join(map(str,minver))
68 else:
69 cver = ''
70
71 self.start_msg('Checking for minimum perl version %s' % cver)
72
73 perl = getattr(Options.options, 'perlbinary', None)
74
75 if not perl:
76 perl = self.find_program('perl', var='PERL')
77
78 if not perl:
79 self.end_msg("Perl not found", color="YELLOW")
80 return False
81
82 self.env['PERL'] = perl
83
84 version = self.cmd_and_log([perl, "-e", 'printf \"%vd\", $^V'])
85 if not version:
86 res = False
87 version = "Unknown"
88 elif not minver is None:
89 ver = tuple(map(int, version.split(".")))
90 if ver < minver:
91 res = False
92
93 self.end_msg(version, color=res and "GREEN" or "YELLOW")
94 return res
95
96 @conf
97 def check_perl_module(self, module):
98 """
99 Check if specified perlmodule is installed.
100
101 The minimum version can be specified by specifying it after modulename
102 like this::
103
104 def configure(conf):
105 conf.check_perl_module("Some::Module 2.92")
106 """
107 cmd = [self.env['PERL'], '-e', 'use %s' % module]
108 self.start_msg('perl module %s' % module)
109 try:
110 r = self.cmd_and_log(cmd)
111 except:
112 self.end_msg(False)
113 return None
114 self.end_msg(r or True)
115 return r
116
117 @conf
118 def check_perl_ext_devel(self):
119 """
120 Check for configuration needed to build perl extensions.
121
122 Sets different xxx_PERLEXT variables in the environment.
123
124 Also sets the ARCHDIR_PERL variable useful as installation path,
125 which can be overridden by ``--with-perl-archdir`` option.
126 """
127
128 env = self.env
129 perl = env.PERL
130 if not perl:
131 self.fatal('find perl first')
132
133 def read_out(cmd):
134 return Utils.to_list(self.cmd_and_log(perl + cmd))
135
136 env['LINKFLAGS_PERLEXT'] = read_out(" -MConfig -e'print $Config{lddlflags}'")
137 env['INCLUDES_PERLEXT'] = read_out(" -MConfig -e'print \"$Config{archlib}/CORE\"'")
138 env['CFLAGS_PERLEXT'] = read_out(" -MConfig -e'print \"$Config{ccflags} $Config{cccdlflags}\"'")
139
140 env['XSUBPP'] = read_out(" -MConfig -e'print \"$Config{privlib}/ExtUtils/xsubpp$Config{exe_ext}\"'")
141 env['EXTUTILS_TYPEMAP'] = read_out(" -MConfig -e'print \"$Config{privlib}/ExtUtils/typemap\"'")
142
143 if not getattr(Options.options, 'perlarchdir', None):
144 env['ARCHDIR_PERL'] = self.cmd_and_log(perl + " -MConfig -e'print $Config{sitearch}'")
145 else:
146 env['ARCHDIR_PERL'] = getattr(Options.options, 'perlarchdir')
147
148 env['perlext_PATTERN'] = '%s.' + self.cmd_and_log(perl + " -MConfig -e'print $Config{dlext}'")
149
150 def options(opt):
151 """
152 Add the ``--with-perl-archdir`` and ``--with-perl-binary`` command-line options.
153 """
154 opt.add_option('--with-perl-binary', type='string', dest='perlbinary', help = 'Specify alternate perl binary', default=None)
155 opt.add_option('--with-perl-archdir', type='string', dest='perlarchdir', help = 'Specify directory where to install arch specific files', default=None)
156
0 #!/usr/bin/env python
1 # encoding: utf-8
2 # Thomas Nagy, 2007-2010 (ita)
3 # Gustavo Carneiro (gjc), 2007
4
5 """
6 Support for Python, detect the headers and libraries and provide
7 *use* variables to link C/C++ programs against them::
8
9 def options(opt):
10 opt.load('compiler_c python')
11 def configure(conf):
12 conf.load('compiler_c python')
13 conf.check_python_version((2,4,2))
14 conf.check_python_headers()
15 def build(bld):
16 bld.program(features='pyembed', source='a.c', target='myprog')
17 bld.shlib(features='pyext', source='b.c', target='mylib')
18 """
19
20 import os, sys
21 from waflib import Utils, Options, Errors
22 from waflib.Logs import debug, warn, info, error
23 from waflib.TaskGen import extension, before_method, after_method, feature
24 from waflib.Configure import conf
25
26 FRAG = '''
27 #include <Python.h>
28 #ifdef __cplusplus
29 extern "C" {
30 #endif
31 void Py_Initialize(void);
32 void Py_Finalize(void);
33 #ifdef __cplusplus
34 }
35 #endif
36 int main()
37 {
38 Py_Initialize();
39 Py_Finalize();
40 return 0;
41 }
42 '''
43 """
44 Piece of C/C++ code used in :py:func:`waflib.Tools.python.check_python_headers`
45 """
46
47 INST = '''
48 import sys, py_compile
49 py_compile.compile(sys.argv[1], sys.argv[2], sys.argv[3])
50 '''
51 """
52 Piece of Python code used in :py:func:`waflib.Tools.python.install_pyfile` for installing python files
53 """
54
55 DISTUTILS_IMP = ['from distutils.sysconfig import get_config_var, get_python_lib']
56
57 @extension('.py')
58 def process_py(self, node):
59 """
60 Add a callback using :py:func:`waflib.Tools.python.install_pyfile` to install a python file
61 """
62 try:
63 if not self.bld.is_install:
64 return
65 except:
66 return
67
68 try:
69 if not self.install_path:
70 return
71 except AttributeError:
72 self.install_path = '${PYTHONDIR}'
73
74 # i wonder now why we wanted to do this after the build is over
75 # issue #901: people want to preserve the structure of installed files
76 def inst_py(ctx):
77 install_from = getattr(self, 'install_from', None)
78 if install_from:
79 install_from = self.path.find_dir(install_from)
80 install_pyfile(self, node, install_from)
81 self.bld.add_post_fun(inst_py)
82
83 def install_pyfile(self, node, install_from=None):
84 """
85 Execute the installation of a python file
86
87 :param node: python file
88 :type node: :py:class:`waflib.Node.Node`
89 """
90
91 from_node = install_from or node.parent
92 tsk = self.bld.install_as(self.install_path + '/' + node.path_from(from_node), node, postpone=False)
93 path = tsk.get_install_path()
94
95 if self.bld.is_install < 0:
96 info("+ removing byte compiled python files")
97 for x in 'co':
98 try:
99 os.remove(path + x)
100 except OSError:
101 pass
102
103 if self.bld.is_install > 0:
104 try:
105 st1 = os.stat(path)
106 except:
107 error('The python file is missing, this should not happen')
108
109 for x in ['c', 'o']:
110 do_inst = self.env['PY' + x.upper()]
111 try:
112 st2 = os.stat(path + x)
113 except OSError:
114 pass
115 else:
116 if st1.st_mtime <= st2.st_mtime:
117 do_inst = False
118
119 if do_inst:
120 lst = (x == 'o') and [self.env['PYFLAGS_OPT']] or []
121 (a, b, c) = (path, path + x, tsk.get_install_path(destdir=False) + x)
122 argv = self.env['PYTHON'] + lst + ['-c', INST, a, b, c]
123 info('+ byte compiling %r' % (path + x))
124 env = self.env.env or None
125 ret = Utils.subprocess.Popen(argv, env=env).wait()
126 if ret:
127 raise Errors.WafError('py%s compilation failed %r' % (x, path))
128
129 @feature('py')
130 def feature_py(self):
131 """
132 Dummy feature which does nothing
133 """
134 pass
135
136 @feature('pyext')
137 @before_method('propagate_uselib_vars', 'apply_link')
138 @after_method('apply_bundle')
139 def init_pyext(self):
140 """
141 Change the values of *cshlib_PATTERN* and *cxxshlib_PATTERN* to remove the
142 *lib* prefix from library names.
143 """
144 try:
145 if not self.install_path:
146 return
147 except AttributeError:
148 self.install_path = '${PYTHONARCHDIR}'
149 self.uselib = self.to_list(getattr(self, 'uselib', []))
150 if not 'PYEXT' in self.uselib:
151 self.uselib.append('PYEXT')
152 # override shlib_PATTERN set by the osx module
153 self.env['cshlib_PATTERN'] = self.env['cxxshlib_PATTERN'] = self.env['macbundle_PATTERN'] = self.env['pyext_PATTERN']
154
155 @feature('pyext')
156 @before_method('apply_link', 'apply_bundle')
157 def set_bundle(self):
158 if Utils.unversioned_sys_platform() == 'darwin':
159 self.mac_bundle = True
160
161 @before_method('propagate_uselib_vars')
162 @feature('pyembed')
163 def init_pyembed(self):
164 """
165 Add the PYEMBED variable.
166 """
167 self.uselib = self.to_list(getattr(self, 'uselib', []))
168 if not 'PYEMBED' in self.uselib:
169 self.uselib.append('PYEMBED')
170
171 @conf
172 def get_python_variables(self, variables, imports=None):
173 """
174 Spawn a new python process to dump configuration variables
175
176 :param variables: variables to print
177 :type variables: list of string
178 :param imports: one import by element
179 :type imports: list of string
180 :return: the variable values
181 :rtype: list of string
182 """
183 if not imports:
184 try:
185 imports = self.python_imports
186 except AttributeError:
187 imports = DISTUTILS_IMP
188
189 program = list(imports) # copy
190 program.append('')
191 for v in variables:
192 program.append("print(repr(%s))" % v)
193 os_env = dict(os.environ)
194 try:
195 del os_env['MACOSX_DEPLOYMENT_TARGET'] # see comments in the OSX tool
196 except KeyError:
197 pass
198
199 try:
200 out = self.cmd_and_log(self.env.PYTHON + ['-c', '\n'.join(program)], env=os_env)
201 except Errors.WafError:
202 self.fatal('The distutils module is unusable: install "python-devel"?')
203 return_values = []
204 for s in out.split('\n'):
205 s = s.strip()
206 if not s:
207 continue
208 if s == 'None':
209 return_values.append(None)
210 elif s[0] == "'" and s[-1] == "'":
211 return_values.append(s[1:-1])
212 elif s[0].isdigit():
213 return_values.append(int(s))
214 else: break
215 return return_values
216
217 @conf
218 def check_python_headers(conf):
219 """
220 Check for headers and libraries necessary to extend or embed python by using the module *distutils*.
221 On success the environment variables xxx_PYEXT and xxx_PYEMBED are added:
222
223 * PYEXT: for compiling python extensions
224 * PYEMBED: for embedding a python interpreter
225 """
226
227 # FIXME rewrite
228
229 if not conf.env['CC_NAME'] and not conf.env['CXX_NAME']:
230 conf.fatal('load a compiler first (gcc, g++, ..)')
231
232 if not conf.env['PYTHON_VERSION']:
233 conf.check_python_version()
234
235 env = conf.env
236 pybin = conf.env.PYTHON
237 if not pybin:
238 conf.fatal('could not find the python executable')
239
240 v = 'prefix SO LDFLAGS LIBDIR LIBPL INCLUDEPY Py_ENABLE_SHARED MACOSX_DEPLOYMENT_TARGET LDSHARED CFLAGS'.split()
241 try:
242 lst = conf.get_python_variables(["get_config_var('%s') or ''" % x for x in v])
243 except RuntimeError:
244 conf.fatal("Python development headers not found (-v for details).")
245
246 vals = ['%s = %r' % (x, y) for (x, y) in zip(v, lst)]
247 conf.to_log("Configuration returned from %r:\n%r\n" % (pybin, '\n'.join(vals)))
248
249 dct = dict(zip(v, lst))
250 x = 'MACOSX_DEPLOYMENT_TARGET'
251 if dct[x]:
252 conf.env[x] = conf.environ[x] = dct[x]
253
254 env['pyext_PATTERN'] = '%s' + dct['SO'] # not a mistake
255
256 # Check for python libraries for embedding
257
258 all_flags = dct['LDFLAGS'] + ' ' + dct['CFLAGS']
259 conf.parse_flags(all_flags, 'PYEMBED')
260
261 all_flags = dct['LDFLAGS'] + ' ' + dct['LDSHARED'] + ' ' + dct['CFLAGS']
262 conf.parse_flags(all_flags, 'PYEXT')
263
264 result = None
265 #name = 'python' + env['PYTHON_VERSION']
266
267 # TODO simplify this
268 for name in ('python' + env['PYTHON_VERSION'], 'python' + env['PYTHON_VERSION'].replace('.', '')):
269
270 # LIBPATH_PYEMBED is already set; see if it works.
271 if not result and env['LIBPATH_PYEMBED']:
272 path = env['LIBPATH_PYEMBED']
273 conf.to_log("\n\n# Trying default LIBPATH_PYEMBED: %r\n" % path)
274 result = conf.check(lib=name, uselib='PYEMBED', libpath=path, mandatory=False, msg='Checking for library %s in LIBPATH_PYEMBED' % name)
275
276 if not result and dct['LIBDIR']:
277 path = [dct['LIBDIR']]
278 conf.to_log("\n\n# try again with -L$python_LIBDIR: %r\n" % path)
279 result = conf.check(lib=name, uselib='PYEMBED', libpath=path, mandatory=False, msg='Checking for library %s in LIBDIR' % name)
280
281 if not result and dct['LIBPL']:
282 path = [dct['LIBPL']]
283 conf.to_log("\n\n# try again with -L$python_LIBPL (some systems don't install the python library in $prefix/lib)\n")
284 result = conf.check(lib=name, uselib='PYEMBED', libpath=path, mandatory=False, msg='Checking for library %s in python_LIBPL' % name)
285
286 if not result:
287 path = [os.path.join(dct['prefix'], "libs")]
288 conf.to_log("\n\n# try again with -L$prefix/libs, and pythonXY name rather than pythonX.Y (win32)\n")
289 result = conf.check(lib=name, uselib='PYEMBED', libpath=path, mandatory=False, msg='Checking for library %s in $prefix/libs' % name)
290
291 if result:
292 break # do not forget to set LIBPATH_PYEMBED
293
294 if result:
295 env['LIBPATH_PYEMBED'] = path
296 env.append_value('LIB_PYEMBED', [name])
297 else:
298 conf.to_log("\n\n### LIB NOT FOUND\n")
299
300 # under certain conditions, python extensions must link to
301 # python libraries, not just python embedding programs.
302 if (Utils.is_win32 or sys.platform.startswith('os2')
303 or dct['Py_ENABLE_SHARED']):
304 env['LIBPATH_PYEXT'] = env['LIBPATH_PYEMBED']
305 env['LIB_PYEXT'] = env['LIB_PYEMBED']
306
307 # We check that pythonX.Y-config exists, and if it exists we
308 # use it to get only the includes, else fall back to distutils.
309 num = '.'.join(env['PYTHON_VERSION'].split('.')[:2])
310 conf.find_program(['python%s-config' % num, 'python-config-%s' % num, 'python%sm-config' % num], var='PYTHON_CONFIG', mandatory=False)
311
312 includes = []
313 if conf.env.PYTHON_CONFIG:
314 for incstr in conf.cmd_and_log([ conf.env.PYTHON_CONFIG, '--includes']).strip().split():
315 # strip the -I or /I
316 if (incstr.startswith('-I') or incstr.startswith('/I')):
317 incstr = incstr[2:]
318 # append include path, unless already given
319 if incstr not in includes:
320 includes.append(incstr)
321 conf.to_log("Include path for Python extensions (found via python-config --includes): %r\n" % (includes,))
322 env['INCLUDES_PYEXT'] = includes
323 env['INCLUDES_PYEMBED'] = includes
324 else:
325 conf.to_log("Include path for Python extensions "
326 "(found via distutils module): %r\n" % (dct['INCLUDEPY'],))
327 env['INCLUDES_PYEXT'] = [dct['INCLUDEPY']]
328 env['INCLUDES_PYEMBED'] = [dct['INCLUDEPY']]
329
330 # Code using the Python API needs to be compiled with -fno-strict-aliasing
331 if env['CC_NAME'] == 'gcc':
332 env.append_value('CFLAGS_PYEMBED', ['-fno-strict-aliasing'])
333 env.append_value('CFLAGS_PYEXT', ['-fno-strict-aliasing'])
334 if env['CXX_NAME'] == 'gcc':
335 env.append_value('CXXFLAGS_PYEMBED', ['-fno-strict-aliasing'])
336 env.append_value('CXXFLAGS_PYEXT', ['-fno-strict-aliasing'])
337
338 if env.CC_NAME == "msvc":
339 from distutils.msvccompiler import MSVCCompiler
340 dist_compiler = MSVCCompiler()
341 dist_compiler.initialize()
342 env.append_value('CFLAGS_PYEXT', dist_compiler.compile_options)
343 env.append_value('CXXFLAGS_PYEXT', dist_compiler.compile_options)
344 env.append_value('LINKFLAGS_PYEXT', dist_compiler.ldflags_shared)
345
346 # See if it compiles
347 try:
348 conf.check(header_name='Python.h', define_name='HAVE_PYTHON_H',
349 uselib='PYEMBED', fragment=FRAG,
350 errmsg='Could not find the python development headers')
351 except conf.errors.ConfigurationError:
352 # python3.2, oh yeah
353 conf.check_cfg(path=conf.env.PYTHON_CONFIG, package='', uselib_store='PYEMBED', args=['--cflags', '--libs'])
354 conf.check(header_name='Python.h', define_name='HAVE_PYTHON_H', msg='Getting the python flags from python-config',
355 uselib='PYEMBED', fragment=FRAG, errmsg='Could not find the python development headers elsewhere')
356
357 @conf
358 def check_python_version(conf, minver=None):
359 """
360 Check if the python interpreter is found matching a given minimum version.
361 minver should be a tuple, eg. to check for python >= 2.4.2 pass (2,4,2) as minver.
362
363 If successful, PYTHON_VERSION is defined as 'MAJOR.MINOR'
364 (eg. '2.4') of the actual python version found, and PYTHONDIR is
365 defined, pointing to the site-packages directory appropriate for
366 this python version, where modules/packages/extensions should be
367 installed.
368
369 :param minver: minimum version
370 :type minver: tuple of int
371 """
372 assert minver is None or isinstance(minver, tuple)
373 pybin = conf.env['PYTHON']
374 if not pybin:
375 conf.fatal('could not find the python executable')
376
377 # Get python version string
378 cmd = pybin + ['-c', 'import sys\nfor x in sys.version_info: print(str(x))']
379 debug('python: Running python command %r' % cmd)
380 lines = conf.cmd_and_log(cmd).split()
381 assert len(lines) == 5, "found %i lines, expected 5: %r" % (len(lines), lines)
382 pyver_tuple = (int(lines[0]), int(lines[1]), int(lines[2]), lines[3], int(lines[4]))
383
384 # compare python version with the minimum required
385 result = (minver is None) or (pyver_tuple >= minver)
386
387 if result:
388 # define useful environment variables
389 pyver = '.'.join([str(x) for x in pyver_tuple[:2]])
390 conf.env['PYTHON_VERSION'] = pyver
391
392 if 'PYTHONDIR' in conf.environ:
393 pydir = conf.environ['PYTHONDIR']
394 else:
395 if Utils.is_win32:
396 (python_LIBDEST, pydir) = conf.get_python_variables(
397 ["get_config_var('LIBDEST') or ''",
398 "get_python_lib(standard_lib=0, prefix=%r) or ''" % conf.env['PREFIX']])
399 else:
400 python_LIBDEST = None
401 (pydir,) = conf.get_python_variables( ["get_python_lib(standard_lib=0, prefix=%r) or ''" % conf.env['PREFIX']])
402 if python_LIBDEST is None:
403 if conf.env['LIBDIR']:
404 python_LIBDEST = os.path.join(conf.env['LIBDIR'], "python" + pyver)
405 else:
406 python_LIBDEST = os.path.join(conf.env['PREFIX'], "lib", "python" + pyver)
407
408
409 if 'PYTHONARCHDIR' in conf.environ:
410 pyarchdir = conf.environ['PYTHONARCHDIR']
411 else:
412 (pyarchdir, ) = conf.get_python_variables( ["get_python_lib(plat_specific=1, standard_lib=0, prefix=%r) or ''" % conf.env['PREFIX']])
413 if not pyarchdir:
414 pyarchdir = pydir
415
416 if hasattr(conf, 'define'): # conf.define is added by the C tool, so may not exist
417 conf.define('PYTHONDIR', pydir)
418 conf.define('PYTHONARCHDIR', pyarchdir)
419
420 conf.env['PYTHONDIR'] = pydir
421 conf.env['PYTHONARCHDIR'] = pyarchdir
422
423 # Feedback
424 pyver_full = '.'.join(map(str, pyver_tuple[:3]))
425 if minver is None:
426 conf.msg('Checking for python version', pyver_full)
427 else:
428 minver_str = '.'.join(map(str, minver))
429 conf.msg('Checking for python version', pyver_tuple, ">= %s" % (minver_str,) and 'GREEN' or 'YELLOW')
430
431 if not result:
432 conf.fatal('The python version is too old, expecting %r' % (minver,))
433
434 PYTHON_MODULE_TEMPLATE = '''
435 import %s as current_module
436 version = getattr(current_module, '__version__', None)
437 if version is not None:
438 print(str(version))
439 else:
440 print('unknown version')
441 '''
442
443 @conf
444 def check_python_module(conf, module_name, condition=''):
445 """
446 Check if the selected python interpreter can import the given python module::
447
448 def configure(conf):
449 conf.check_python_module('pygccxml')
450 conf.check_python_module('re', condition="ver > num(2, 0, 4) and ver <= num(3, 0, 0)")
451
452 :param module_name: module
453 :type module_name: string
454 """
455 msg = 'Python module %s' % module_name
456 if condition:
457 msg = '%s (%s)' % (msg, condition)
458 conf.start_msg(msg)
459 try:
460 ret = conf.cmd_and_log(conf.env['PYTHON'] + ['-c', PYTHON_MODULE_TEMPLATE % module_name])
461 except Exception:
462 conf.end_msg(False)
463 conf.fatal('Could not find the python module %r' % module_name)
464
465 ret = ret.strip()
466 if condition:
467 conf.end_msg(ret)
468 if ret == 'unknown version':
469 conf.fatal('Could not check the %s version' % module_name)
470
471 from distutils.version import LooseVersion
472 def num(*k):
473 if isinstance(k[0], int):
474 return LooseVersion('.'.join([str(x) for x in k]))
475 else:
476 return LooseVersion(k[0])
477 d = {'num': num, 'ver': LooseVersion(ret)}
478 ev = eval(condition, {}, d)
479 if not ev:
480 conf.fatal('The %s version does not satisfy the requirements' % module_name)
481 else:
482 if ret == 'unknown version':
483 conf.end_msg(True)
484 else:
485 conf.end_msg(ret)
486
487 def configure(conf):
488 """
489 Detect the python interpreter
490 """
491 try:
492 conf.find_program('python', var='PYTHON')
493 except conf.errors.ConfigurationError:
494 warn("could not find a python executable, setting to sys.executable '%s'" % sys.executable)
495 conf.env.PYTHON = sys.executable
496
497 if conf.env.PYTHON != sys.executable:
498 warn("python executable '%s' different from sys.executable '%s'" % (conf.env.PYTHON, sys.executable))
499 conf.env.PYTHON = conf.cmd_to_list(conf.env.PYTHON)
500
501 v = conf.env
502 v['PYCMD'] = '"import sys, py_compile;py_compile.compile(sys.argv[1], sys.argv[2])"'
503 v['PYFLAGS'] = ''
504 v['PYFLAGS_OPT'] = '-O'
505
506 v['PYC'] = getattr(Options.options, 'pyc', 1)
507 v['PYO'] = getattr(Options.options, 'pyo', 1)
508
509 def options(opt):
510 """
511 Add the options ``--nopyc`` and ``--nopyo``
512 """
513 opt.add_option('--nopyc',
514 action='store_false',
515 default=1,
516 help = 'Do not install bytecode compiled .pyc files (configuration) [Default:install]',
517 dest = 'pyc')
518 opt.add_option('--nopyo',
519 action='store_false',
520 default=1,
521 help='Do not install optimised compiled .pyo files (configuration) [Default:install]',
522 dest='pyo')
523
0 #!/usr/bin/env python
1 # encoding: utf-8
2 # Thomas Nagy, 2006-2010 (ita)
3
4 """
5 Support for the Qt4 libraries and tools::
6
7 def options(opt):
8 opt.load('compiler_cxx qt4')
9 def configure(conf):
10 conf.load('compiler_cxx qt4')
11 conf.env.append_value('CXXFLAGS', ['-g']) # test
12 def build(bld):
13 bld(
14 features = 'qt4 cxx cxxprogram',
15 uselib = 'QTCORE QTGUI QTOPENGL QTSVG',
16 source = 'main.cpp textures.qrc aboutDialog.ui',
17 target = 'window',
18 )
19
20 The C++ files must include the .moc files, which is regarded as the
21 best practice (much faster compilations). This also implies that the
22 include paths have to be set properly. To have the include paths added
23 automatically, use the following::
24
25 from waflib.TaskGen import feature, before_method, after_method
26 @feature('cxx')
27 @after_method('process_source')
28 @before_method('apply_incpaths')
29 def add_includes_paths(self):
30 incs = set(self.to_list(getattr(self, 'includes', '')))
31 for x in self.compiled_tasks:
32 incs.add(x.inputs[0].parent.path_from(self.path))
33 self.includes = list(incs)
34
35 Another tool provides a Qt processing that does not require the moc
36 includes. See http://code.google.com/p/waf/source/browse/trunk/playground/slow_qt/
37 """
38
39 try:
40 from xml.sax import make_parser
41 from xml.sax.handler import ContentHandler
42 except ImportError:
43 has_xml = False
44 ContentHandler = object
45 else:
46 has_xml = True
47
48 import os, sys
49 from waflib.Tools import c_preproc, cxx
50 from waflib import Task, Utils, Options, Errors
51 from waflib.TaskGen import feature, after_method, extension
52 from waflib.Configure import conf
53 from waflib import Logs
54
55 MOC_H = ['.h', '.hpp', '.hxx', '.hh']
56 """
57 File extensions associated to the .moc files
58 """
59
60 EXT_RCC = ['.qrc']
61 """
62 File extension for the resource (.qrc) files
63 """
64
65 EXT_UI = ['.ui']
66 """
67 File extension for the user interface (.ui) files
68 """
69
70 EXT_QT4 = ['.cpp', '.cc', '.cxx', '.C']
71 """
72 File extensions of C++ files that may require a .moc processing
73 """
74
75 QT4_LIBS = "QtCore QtGui QtUiTools QtNetwork QtOpenGL QtSql QtSvg QtTest QtXml QtXmlPatterns QtWebKit Qt3Support QtHelp QtScript QtDeclarative"
76
77 class qxx(cxx.cxx):
78 """
79 Each C++ file can have zero or several .moc files to create.
80 They are known only when the files are scanned (preprocessor)
81 To avoid scanning the c++ files each time (parsing C/C++), the results
82 are retrieved from the task cache (bld.node_deps/bld.raw_deps).
83 The moc tasks are also created *dynamically* during the build.
84 """
85
86 def __init__(self, *k, **kw):
87 Task.Task.__init__(self, *k, **kw)
88 self.moc_done = 0
89
90 def scan(self):
91 """Re-use the C/C++ scanner, but remove the moc files from the dependencies"""
92 (nodes, names) = c_preproc.scan(self)
93 # for some reasons (variants) the moc node may end in the list of node deps
94 for x in nodes:
95 if x.name.endswith('.moc'):
96 nodes.remove(x)
97 names.append(x.path_from(self.inputs[0].parent.get_bld()))
98 return (nodes, names)
99
100 def runnable_status(self):
101 """
102 Compute the task signature to make sure the scanner was executed. Create the
103 moc tasks by using :py:meth:`waflib.Tools.qt4.qxx.add_moc_tasks` (if necessary),
104 then postpone the task execution (there is no need to recompute the task signature).
105 """
106 if self.moc_done:
107 return Task.Task.runnable_status(self)
108 else:
109 for t in self.run_after:
110 if not t.hasrun:
111 return Task.ASK_LATER
112 self.add_moc_tasks()
113 return Task.Task.runnable_status(self)
114
115 def add_moc_tasks(self):
116 """
117 Create the moc tasks by looking in ``bld.raw_deps[self.uid()]``
118 """
119 node = self.inputs[0]
120 bld = self.generator.bld
121
122 try:
123 # compute the signature once to know if there is a moc file to create
124 self.signature()
125 except KeyError:
126 # the moc file may be referenced somewhere else
127 pass
128 else:
129 # remove the signature, it must be recomputed with the moc task
130 delattr(self, 'cache_sig')
131
132 moctasks=[]
133 mocfiles=[]
134 try:
135 tmp_lst = bld.raw_deps[self.uid()]
136 bld.raw_deps[self.uid()] = []
137 except KeyError:
138 tmp_lst = []
139 for d in tmp_lst:
140 if not d.endswith('.moc'):
141 continue
142 # paranoid check
143 if d in mocfiles:
144 Logs.error("paranoia owns")
145 continue
146 # process that base.moc only once
147 mocfiles.append(d)
148
149 # find the extension - this search is done only once
150
151 h_node = None
152 try: ext = Options.options.qt_header_ext.split()
153 except AttributeError: pass
154 if not ext: ext = MOC_H
155
156 base2 = d[:-4]
157 for x in [node.parent] + self.generator.includes_nodes:
158 for e in ext:
159 h_node = x.find_node(base2 + e)
160 if h_node:
161 break
162 if h_node:
163 m_node = h_node.change_ext('.moc')
164 break
165 else:
166 for k in EXT_QT4:
167 if base2.endswith(k):
168 for x in [node.parent] + self.generator.includes_nodes:
169 h_node = x.find_node(base2)
170 if h_node:
171 break
172 if h_node:
173 m_node = h_node.change_ext(k + '.moc')
174 break
175 if not h_node:
176 raise Errors.WafError('no header found for %r which is a moc file' % d)
177
178 # next time we will not search for the extension (look at the 'for' loop below)
179 bld.node_deps[(self.inputs[0].parent.abspath(), m_node.name)] = h_node
180
181 # create the task
182 task = Task.classes['moc'](env=self.env, generator=self.generator)
183 task.set_inputs(h_node)
184 task.set_outputs(m_node)
185
186 # direct injection in the build phase (safe because called from the main thread)
187 gen = bld.producer
188 gen.outstanding.insert(0, task)
189 gen.total += 1
190
191 moctasks.append(task)
192
193 # remove raw deps except the moc files to save space (optimization)
194 tmp_lst = bld.raw_deps[self.uid()] = mocfiles
195
196 # look at the file inputs, it is set right above
197 lst = bld.node_deps.get(self.uid(), ())
198 for d in lst:
199 name = d.name
200 if name.endswith('.moc'):
201 task = Task.classes['moc'](env=self.env, generator=self.generator)
202 task.set_inputs(bld.node_deps[(self.inputs[0].parent.abspath(), name)]) # 1st element in a tuple
203 task.set_outputs(d)
204
205 gen = bld.producer
206 gen.outstanding.insert(0, task)
207 gen.total += 1
208
209 moctasks.append(task)
210
211 # simple scheduler dependency: run the moc task before others
212 self.run_after.update(set(moctasks))
213 self.moc_done = 1
214
215 run = Task.classes['cxx'].__dict__['run']
216
217 class trans_update(Task.Task):
218 """Update a .ts files from a list of C++ files"""
219 run_str = '${QT_LUPDATE} ${SRC} -ts ${TGT}'
220 color = 'BLUE'
221 Task.update_outputs(trans_update)
222
223 class XMLHandler(ContentHandler):
224 """
225 Parser for *.qrc* files
226 """
227 def __init__(self):
228 self.buf = []
229 self.files = []
230 def startElement(self, name, attrs):
231 if name == 'file':
232 self.buf = []
233 def endElement(self, name):
234 if name == 'file':
235 self.files.append(str(''.join(self.buf)))
236 def characters(self, cars):
237 self.buf.append(cars)
238
239 @extension(*EXT_RCC)
240 def create_rcc_task(self, node):
241 "Create rcc and cxx tasks for *.qrc* files"
242 rcnode = node.change_ext('_rc.cpp')
243 rcctask = self.create_task('rcc', node, rcnode)
244 cpptask = self.create_task('cxx', rcnode, rcnode.change_ext('.o'))
245 try:
246 self.compiled_tasks.append(cpptask)
247 except AttributeError:
248 self.compiled_tasks = [cpptask]
249 return cpptask
250
251 @extension(*EXT_UI)
252 def create_uic_task(self, node):
253 "hook for uic tasks"
254 uictask = self.create_task('ui4', node)
255 uictask.outputs = [self.path.find_or_declare(self.env['ui_PATTERN'] % node.name[:-3])]
256
257 @extension('.ts')
258 def add_lang(self, node):
259 """add all the .ts file into self.lang"""
260 self.lang = self.to_list(getattr(self, 'lang', [])) + [node]
261
262 @feature('qt4')
263 @after_method('apply_link')
264 def apply_qt4(self):
265 """
266 Add MOC_FLAGS which may be necessary for moc::
267
268 def build(bld):
269 bld.program(features='qt4', source='main.cpp', target='app', use='QTCORE')
270
271 The additional parameters are:
272
273 :param lang: list of translation files (\*.ts) to process
274 :type lang: list of :py:class:`waflib.Node.Node` or string without the .ts extension
275 :param update: whether to process the C++ files to update the \*.ts files (use **waf --translate**)
276 :type update: bool
277 :param langname: if given, transform the \*.ts files into a .qrc files to include in the binary file
278 :type langname: :py:class:`waflib.Node.Node` or string without the .qrc extension
279 """
280 if getattr(self, 'lang', None):
281 qmtasks = []
282 for x in self.to_list(self.lang):
283 if isinstance(x, str):
284 x = self.path.find_resource(x + '.ts')
285 qmtasks.append(self.create_task('ts2qm', x, x.change_ext('.qm')))
286
287 if getattr(self, 'update', None) and Options.options.trans_qt4:
288 cxxnodes = [a.inputs[0] for a in self.compiled_tasks] + [
289 a.inputs[0] for a in self.tasks if getattr(a, 'inputs', None) and a.inputs[0].name.endswith('.ui')]
290 for x in qmtasks:
291 self.create_task('trans_update', cxxnodes, x.inputs)
292
293 if getattr(self, 'langname', None):
294 qmnodes = [x.outputs[0] for x in qmtasks]
295 rcnode = self.langname
296 if isinstance(rcnode, str):
297 rcnode = self.path.find_or_declare(rcnode + '.qrc')
298 t = self.create_task('qm2rcc', qmnodes, rcnode)
299 k = create_rcc_task(self, t.outputs[0])
300 self.link_task.inputs.append(k.outputs[0])
301
302 lst = []
303 for flag in self.to_list(self.env['CXXFLAGS']):
304 if len(flag) < 2: continue
305 f = flag[0:2]
306 if f in ['-D', '-I', '/D', '/I']:
307 if (f[0] == '/'):
308 lst.append('-' + flag[1:])
309 else:
310 lst.append(flag)
311 self.env['MOC_FLAGS'] = lst
312
313 @extension(*EXT_QT4)
314 def cxx_hook(self, node):
315 """
316 Re-map C++ file extensions to the :py:class:`waflib.Tools.qt4.qxx` task.
317 """
318 return self.create_compiled_task('qxx', node)
319
320 class rcc(Task.Task):
321 """
322 Process *.qrc* files
323 """
324 color = 'BLUE'
325 run_str = '${QT_RCC} -name ${SRC[0].name} ${SRC[0].abspath()} ${RCC_ST} -o ${TGT}'
326 ext_out = ['.h']
327
328 def scan(self):
329 """Parse the *.qrc* files"""
330 node = self.inputs[0]
331
332 if not has_xml:
333 Logs.error('no xml support was found, the rcc dependencies will be incomplete!')
334 return ([], [])
335
336 parser = make_parser()
337 curHandler = XMLHandler()
338 parser.setContentHandler(curHandler)
339 fi = open(self.inputs[0].abspath())
340 parser.parse(fi)
341 fi.close()
342
343 nodes = []
344 names = []
345 root = self.inputs[0].parent
346 for x in curHandler.files:
347 nd = root.find_resource(x)
348 if nd: nodes.append(nd)
349 else: names.append(x)
350 return (nodes, names)
351
352 class moc(Task.Task):
353 """
354 Create *.moc* files
355 """
356 color = 'BLUE'
357 run_str = '${QT_MOC} ${MOC_FLAGS} ${MOCCPPPATH_ST:INCPATHS} ${MOCDEFINES_ST:DEFINES} ${SRC} ${MOC_ST} ${TGT}'
358
359 class ui4(Task.Task):
360 """
361 Process *.ui* files
362 """
363 color = 'BLUE'
364 run_str = '${QT_UIC} ${SRC} -o ${TGT}'
365 ext_out = ['.h']
366
367 class ts2qm(Task.Task):
368 """
369 Create *.qm* files from *.ts* files
370 """
371 color = 'BLUE'
372 run_str = '${QT_LRELEASE} ${QT_LRELEASE_FLAGS} ${SRC} -qm ${TGT}'
373
374 class qm2rcc(Task.Task):
375 """
376 Transform *.qm* files into *.rc* files
377 """
378 color = 'BLUE'
379 after = 'ts2qm'
380
381 def run(self):
382 """Create a qrc file including the inputs"""
383 txt = '\n'.join(['<file>%s</file>' % k.path_from(self.outputs[0].parent) for k in self.inputs])
384 code = '<!DOCTYPE RCC><RCC version="1.0">\n<qresource>\n%s\n</qresource>\n</RCC>' % txt
385 self.outputs[0].write(code)
386
387 def configure(self):
388 """
389 Besides the configuration options, the environment variable QT4_ROOT may be used
390 to give the location of the qt4 libraries (absolute path).
391
392 The detection will use the program *pkg-config* through :py:func:`waflib.Tools.config_c.check_cfg`
393 """
394 self.find_qt4_binaries()
395 self.set_qt4_libs_to_check()
396 self.find_qt4_libraries()
397 self.add_qt4_rpath()
398 self.simplify_qt4_libs()
399
400 @conf
401 def find_qt4_binaries(self):
402 env = self.env
403 opt = Options.options
404
405 qtdir = getattr(opt, 'qtdir', '')
406 qtbin = getattr(opt, 'qtbin', '')
407
408 paths = []
409
410 if qtdir:
411 qtbin = os.path.join(qtdir, 'bin')
412
413 # the qt directory has been given from QT4_ROOT - deduce the qt binary path
414 if not qtdir:
415 qtdir = self.environ.get('QT4_ROOT', '')
416 qtbin = os.path.join(qtdir, 'bin')
417
418 if qtbin:
419 paths = [qtbin]
420
421 # no qtdir, look in the path and in /usr/local/Trolltech
422 if not qtdir:
423 paths = os.environ.get('PATH', '').split(os.pathsep)
424 paths.append('/usr/share/qt4/bin/')
425 try:
426 lst = Utils.listdir('/usr/local/Trolltech/')
427 except OSError:
428 pass
429 else:
430 if lst:
431 lst.sort()
432 lst.reverse()
433
434 # keep the highest version
435 qtdir = '/usr/local/Trolltech/%s/' % lst[0]
436 qtbin = os.path.join(qtdir, 'bin')
437 paths.append(qtbin)
438
439 # at the end, try to find qmake in the paths given
440 # keep the one with the highest version
441 cand = None
442 prev_ver = ['4', '0', '0']
443 for qmk in ['qmake-qt4', 'qmake4', 'qmake']:
444 try:
445 qmake = self.find_program(qmk, path_list=paths)
446 except self.errors.ConfigurationError:
447 pass
448 else:
449 try:
450 version = self.cmd_and_log([qmake, '-query', 'QT_VERSION']).strip()
451 except self.errors.ConfigurationError:
452 pass
453 else:
454 if version:
455 new_ver = version.split('.')
456 if new_ver > prev_ver:
457 cand = qmake
458 prev_ver = new_ver
459 if cand:
460 self.env.QMAKE = cand
461 else:
462 self.fatal('Could not find qmake for qt4')
463
464 qtbin = self.cmd_and_log([self.env.QMAKE, '-query', 'QT_INSTALL_BINS']).strip() + os.sep
465
466 def find_bin(lst, var):
467 for f in lst:
468 try:
469 ret = self.find_program(f, path_list=paths)
470 except self.errors.ConfigurationError:
471 pass
472 else:
473 env[var]=ret
474 break
475
476 find_bin(['uic-qt3', 'uic3'], 'QT_UIC3')
477 find_bin(['uic-qt4', 'uic'], 'QT_UIC')
478 if not env['QT_UIC']:
479 self.fatal('cannot find the uic compiler for qt4')
480
481 try:
482 uicver = self.cmd_and_log(env['QT_UIC'] + " -version 2>&1").strip()
483 except self.errors.ConfigurationError:
484 self.fatal('this uic compiler is for qt3, add uic for qt4 to your path')
485 uicver = uicver.replace('Qt User Interface Compiler ','').replace('User Interface Compiler for Qt', '')
486 self.msg('Checking for uic version', '%s' % uicver)
487 if uicver.find(' 3.') != -1:
488 self.fatal('this uic compiler is for qt3, add uic for qt4 to your path')
489
490 find_bin(['moc-qt4', 'moc'], 'QT_MOC')
491 find_bin(['rcc'], 'QT_RCC')
492 find_bin(['lrelease-qt4', 'lrelease'], 'QT_LRELEASE')
493 find_bin(['lupdate-qt4', 'lupdate'], 'QT_LUPDATE')
494
495 env['UIC3_ST']= '%s -o %s'
496 env['UIC_ST'] = '%s -o %s'
497 env['MOC_ST'] = '-o'
498 env['ui_PATTERN'] = 'ui_%s.h'
499 env['QT_LRELEASE_FLAGS'] = ['-silent']
500 env.MOCCPPPATH_ST = '-I%s'
501 env.MOCDEFINES_ST = '-D%s'
502
503 @conf
504 def find_qt4_libraries(self):
505 qtlibs = getattr(Options.options, 'qtlibs', '')
506 if not qtlibs:
507 try:
508 qtlibs = self.cmd_and_log([self.env.QMAKE, '-query', 'QT_INSTALL_LIBS']).strip()
509 except Errors.WafError:
510 qtdir = self.cmd_and_log([self.env.QMAKE, '-query', 'QT_INSTALL_PREFIX']).strip() + os.sep
511 qtlibs = os.path.join(qtdir, 'lib')
512 self.msg('Found the Qt4 libraries in', qtlibs)
513
514 qtincludes = self.cmd_and_log([self.env.QMAKE, '-query', 'QT_INSTALL_HEADERS']).strip()
515 env = self.env
516 if not 'PKG_CONFIG_PATH' in os.environ:
517 os.environ['PKG_CONFIG_PATH'] = '%s:%s/pkgconfig:/usr/lib/qt4/lib/pkgconfig:/opt/qt4/lib/pkgconfig:/usr/lib/qt4/lib:/opt/qt4/lib' % (qtlibs, qtlibs)
518
519 try:
520 self.check_cfg(atleast_pkgconfig_version='0.1')
521 except self.errors.ConfigurationError:
522 for i in self.qt4_vars:
523 uselib = i.upper()
524 if Utils.unversioned_sys_platform() == "darwin":
525 # Since at least qt 4.7.3 each library locates in separate directory
526 frameworkName = i + ".framework"
527 qtDynamicLib = os.path.join(qtlibs, frameworkName, i)
528 if os.path.exists(qtDynamicLib):
529 env.append_unique('FRAMEWORK_' + uselib, i)
530 self.msg('Checking for %s' % i, qtDynamicLib, 'GREEN')
531 else:
532 self.msg('Checking for %s' % i, False, 'YELLOW')
533 env.append_unique('INCLUDES_' + uselib, os.path.join(qtlibs, frameworkName, 'Headers'))
534 elif sys.platform != "win32":
535 qtDynamicLib = os.path.join(qtlibs, "lib" + i + ".so")
536 qtStaticLib = os.path.join(qtlibs, "lib" + i + ".a")
537 if os.path.exists(qtDynamicLib):
538 env.append_unique('LIB_' + uselib, i)
539 self.msg('Checking for %s' % i, qtDynamicLib, 'GREEN')
540 elif os.path.exists(qtStaticLib):
541 env.append_unique('LIB_' + uselib, i)
542 self.msg('Checking for %s' % i, qtStaticLib, 'GREEN')
543 else:
544 self.msg('Checking for %s' % i, False, 'YELLOW')
545
546 env.append_unique('LIBPATH_' + uselib, qtlibs)
547 env.append_unique('INCLUDES_' + uselib, qtincludes)
548 env.append_unique('INCLUDES_' + uselib, os.path.join(qtincludes, i))
549 else:
550 # Release library names are like QtCore4
551 for k in ("lib%s.a", "lib%s4.a", "%s.lib", "%s4.lib"):
552 lib = os.path.join(qtlibs, k % i)
553 if os.path.exists(lib):
554 env.append_unique('LIB_' + uselib, i + k[k.find("%s") + 2 : k.find('.')])
555 self.msg('Checking for %s' % i, lib, 'GREEN')
556 break
557 else:
558 self.msg('Checking for %s' % i, False, 'YELLOW')
559
560 env.append_unique('LIBPATH_' + uselib, qtlibs)
561 env.append_unique('INCLUDES_' + uselib, qtincludes)
562 env.append_unique('INCLUDES_' + uselib, os.path.join(qtincludes, i))
563
564 # Debug library names are like QtCore4d
565 uselib = i.upper() + "_debug"
566 for k in ("lib%sd.a", "lib%sd4.a", "%sd.lib", "%sd4.lib"):
567 lib = os.path.join(qtlibs, k % i)
568 if os.path.exists(lib):
569 env.append_unique('LIB_' + uselib, i + k[k.find("%s") + 2 : k.find('.')])
570 self.msg('Checking for %s' % i, lib, 'GREEN')
571 break
572 else:
573 self.msg('Checking for %s' % i, False, 'YELLOW')
574
575 env.append_unique('LIBPATH_' + uselib, qtlibs)
576 env.append_unique('INCLUDES_' + uselib, qtincludes)
577 env.append_unique('INCLUDES_' + uselib, os.path.join(qtincludes, i))
578 else:
579 for i in self.qt4_vars_debug + self.qt4_vars:
580 self.check_cfg(package=i, args='--cflags --libs', mandatory=False)
581
582 @conf
583 def simplify_qt4_libs(self):
584 # the libpaths make really long command-lines
585 # remove the qtcore ones from qtgui, etc
586 env = self.env
587 def process_lib(vars_, coreval):
588 for d in vars_:
589 var = d.upper()
590 if var == 'QTCORE':
591 continue
592
593 value = env['LIBPATH_'+var]
594 if value:
595 core = env[coreval]
596 accu = []
597 for lib in value:
598 if lib in core:
599 continue
600 accu.append(lib)
601 env['LIBPATH_'+var] = accu
602
603 process_lib(self.qt4_vars, 'LIBPATH_QTCORE')
604 process_lib(self.qt4_vars_debug, 'LIBPATH_QTCORE_DEBUG')
605
606 @conf
607 def add_qt4_rpath(self):
608 # rpath if wanted
609 env = self.env
610 if Options.options.want_rpath:
611 def process_rpath(vars_, coreval):
612 for d in vars_:
613 var = d.upper()
614 value = env['LIBPATH_'+var]
615 if value:
616 core = env[coreval]
617 accu = []
618 for lib in value:
619 if var != 'QTCORE':
620 if lib in core:
621 continue
622 accu.append('-Wl,--rpath='+lib)
623 env['RPATH_'+var] = accu
624 process_rpath(self.qt4_vars, 'LIBPATH_QTCORE')
625 process_rpath(self.qt4_vars_debug, 'LIBPATH_QTCORE_DEBUG')
626
627 @conf
628 def set_qt4_libs_to_check(self):
629 if not hasattr(self, 'qt4_vars'):
630 self.qt4_vars = QT4_LIBS
631 self.qt4_vars = Utils.to_list(self.qt4_vars)
632 if not hasattr(self, 'qt4_vars_debug'):
633 self.qt4_vars_debug = [a + '_debug' for a in self.qt4_vars]
634 self.qt4_vars_debug = Utils.to_list(self.qt4_vars_debug)
635
636 def options(opt):
637 """
638 Command-line options
639 """
640 opt.add_option('--want-rpath', action='store_true', default=False, dest='want_rpath', help='enable the rpath for qt libraries')
641
642 opt.add_option('--header-ext',
643 type='string',
644 default='',
645 help='header extension for moc files',
646 dest='qt_header_ext')
647
648 for i in 'qtdir qtbin qtlibs'.split():
649 opt.add_option('--'+i, type='string', default='', dest=i)
650
651 opt.add_option('--translate', action="store_true", help="collect translation strings", dest="trans_qt4", default=False)
652
0 #!/usr/bin/env python
1 # encoding: utf-8
2 # daniel.svensson at purplescout.se 2008
3 # Thomas Nagy 2010 (ita)
4
5 """
6 Support for Ruby extensions. A C/C++ compiler is required::
7
8 def options(opt):
9 opt.load('compiler_c ruby')
10 def configure(conf):
11 conf.load('compiler_c ruby')
12 conf.check_ruby_version((1,8,0))
13 conf.check_ruby_ext_devel()
14 conf.check_ruby_module('libxml')
15 def build(bld):
16 bld(
17 features = 'c cshlib rubyext',
18 source = 'rb_mytest.c',
19 target = 'mytest_ext',
20 install_path = '${ARCHDIR_RUBY}')
21 bld.install_files('${LIBDIR_RUBY}', 'Mytest.rb')
22 """
23
24 import os
25 from waflib import Task, Options, Utils
26 from waflib.TaskGen import before_method, feature, after_method, Task, extension
27 from waflib.Configure import conf
28
29 @feature('rubyext')
30 @before_method('apply_incpaths', 'apply_lib_vars', 'apply_bundle', 'apply_link')
31 def init_rubyext(self):
32 """
33 Add required variables for ruby extensions
34 """
35 self.install_path = '${ARCHDIR_RUBY}'
36 self.uselib = self.to_list(getattr(self, 'uselib', ''))
37 if not 'RUBY' in self.uselib:
38 self.uselib.append('RUBY')
39 if not 'RUBYEXT' in self.uselib:
40 self.uselib.append('RUBYEXT')
41
42 @feature('rubyext')
43 @before_method('apply_link', 'propagate_uselib')
44 def apply_ruby_so_name(self):
45 """
46 Strip the *lib* prefix from ruby extensions
47 """
48 self.env['cshlib_PATTERN'] = self.env['cxxshlib_PATTERN'] = self.env['rubyext_PATTERN']
49
50 @conf
51 def check_ruby_version(self, minver=()):
52 """
53 Checks if ruby is installed.
54 If installed the variable RUBY will be set in environment.
55 The ruby binary can be overridden by ``--with-ruby-binary`` command-line option.
56 """
57
58 if Options.options.rubybinary:
59 self.env.RUBY = Options.options.rubybinary
60 else:
61 self.find_program('ruby', var='RUBY')
62
63 ruby = self.env.RUBY
64
65 try:
66 version = self.cmd_and_log([ruby, '-e', 'puts defined?(VERSION) ? VERSION : RUBY_VERSION']).strip()
67 except:
68 self.fatal('could not determine ruby version')
69 self.env.RUBY_VERSION = version
70
71 try:
72 ver = tuple(map(int, version.split(".")))
73 except:
74 self.fatal('unsupported ruby version %r' % version)
75
76 cver = ''
77 if minver:
78 if ver < minver:
79 self.fatal('ruby is too old %r' % ver)
80 cver = '.'.join([str(x) for x in minver])
81 else:
82 cver = ver
83
84 self.msg('Checking for ruby version %s' % str(minver or ''), cver)
85
86 @conf
87 def check_ruby_ext_devel(self):
88 """
89 Check if a ruby extension can be created
90 """
91 if not self.env.RUBY:
92 self.fatal('ruby detection is required first')
93
94 if not self.env.CC_NAME and not self.env.CXX_NAME:
95 self.fatal('load a c/c++ compiler first')
96
97 version = tuple(map(int, self.env.RUBY_VERSION.split(".")))
98
99 def read_out(cmd):
100 return Utils.to_list(self.cmd_and_log([self.env.RUBY, '-rrbconfig', '-e', cmd]))
101
102 def read_config(key):
103 return read_out('puts Config::CONFIG[%r]' % key)
104
105 ruby = self.env['RUBY']
106 archdir = read_config('archdir')
107 cpppath = archdir
108
109 if version >= (1, 9, 0):
110 ruby_hdrdir = read_config('rubyhdrdir')
111 cpppath += ruby_hdrdir
112 cpppath += [os.path.join(ruby_hdrdir[0], read_config('arch')[0])]
113
114 self.check(header_name='ruby.h', includes=cpppath, errmsg='could not find ruby header file')
115
116 self.env.LIBPATH_RUBYEXT = read_config('libdir')
117 self.env.LIBPATH_RUBYEXT += archdir
118 self.env.INCLUDES_RUBYEXT = cpppath
119 self.env.CFLAGS_RUBYEXT = read_config('CCDLFLAGS')
120 self.env.rubyext_PATTERN = '%s.' + read_config('DLEXT')[0]
121
122 # ok this is really stupid, but the command and flags are combined.
123 # so we try to find the first argument...
124 flags = read_config('LDSHARED')
125 while flags and flags[0][0] != '-':
126 flags = flags[1:]
127
128 # we also want to strip out the deprecated ppc flags
129 if len(flags) > 1 and flags[1] == "ppc":
130 flags = flags[2:]
131
132 self.env.LINKFLAGS_RUBYEXT = flags
133 self.env.LINKFLAGS_RUBYEXT += read_config('LIBS')
134 self.env.LINKFLAGS_RUBYEXT += read_config('LIBRUBYARG_SHARED')
135
136 if Options.options.rubyarchdir:
137 self.env.ARCHDIR_RUBY = Options.options.rubyarchdir
138 else:
139 self.env.ARCHDIR_RUBY = read_config('sitearchdir')[0]
140
141 if Options.options.rubylibdir:
142 self.env.LIBDIR_RUBY = Options.options.rubylibdir
143 else:
144 self.env.LIBDIR_RUBY = read_config('sitelibdir')[0]
145
146 @conf
147 def check_ruby_module(self, module_name):
148 """
149 Check if the selected ruby interpreter can require the given ruby module::
150
151 def configure(conf):
152 conf.check_ruby_module('libxml')
153
154 :param module_name: module
155 :type module_name: string
156 """
157 self.start_msg('Ruby module %s' % module_name)
158 try:
159 self.cmd_and_log([self.env['RUBY'], '-e', 'require \'%s\';puts 1' % module_name])
160 except:
161 self.end_msg(False)
162 self.fatal('Could not find the ruby module %r' % module_name)
163 self.end_msg(True)
164
165 @extension('.rb')
166 def process(self, node):
167 tsk = self.create_task('run_ruby', node)
168
169 class run_ruby(Task.Task):
170 """
171 Task to run ruby files detected by file extension .rb::
172
173 def options(opt):
174 opt.load('ruby')
175
176 def configure(ctx):
177 ctx.check_ruby_version()
178
179 def build(bld):
180 bld.env['RBFLAGS'] = '-e puts "hello world"'
181 bld(source='a_ruby_file.rb')
182 """
183 run_str = '${RUBY} ${RBFLAGS} -I ${SRC[0].parent.abspath()} ${SRC}'
184
185 def options(opt):
186 """
187 Add the ``--with-ruby-archdir``, ``--with-ruby-libdir`` and ``--with-ruby-binary`` options
188 """
189 opt.add_option('--with-ruby-archdir', type='string', dest='rubyarchdir', help='Specify directory where to install arch specific files')
190 opt.add_option('--with-ruby-libdir', type='string', dest='rubylibdir', help='Specify alternate ruby library path')
191 opt.add_option('--with-ruby-binary', type='string', dest='rubybinary', help='Specify alternate ruby binary')
192
0 #!/usr/bin/env python
1 # encoding: utf-8
2 # Thomas Nagy, 2006-2010 (ita)
3 # Ralf Habacker, 2006 (rh)
4
5 import os
6 from waflib import Utils
7 from waflib.Tools import ccroot, ar
8 from waflib.Configure import conf
9
10 @conf
11 def find_scc(conf):
12 """
13 Detect the Sun C compiler
14 """
15 v = conf.env
16 cc = None
17 if v['CC']: cc = v['CC']
18 elif 'CC' in conf.environ: cc = conf.environ['CC']
19 if not cc: cc = conf.find_program('cc', var='CC')
20 if not cc: conf.fatal('Could not find a Sun C compiler')
21 cc = conf.cmd_to_list(cc)
22
23 try:
24 conf.cmd_and_log(cc + ['-flags'])
25 except:
26 conf.fatal('%r is not a Sun compiler' % cc)
27
28 v['CC'] = cc
29 v['CC_NAME'] = 'sun'
30
31 @conf
32 def scc_common_flags(conf):
33 """
34 Flags required for executing the sun C compiler
35 """
36 v = conf.env
37
38 v['CC_SRC_F'] = []
39 v['CC_TGT_F'] = ['-c', '-o']
40
41 # linker
42 if not v['LINK_CC']: v['LINK_CC'] = v['CC']
43 v['CCLNK_SRC_F'] = ''
44 v['CCLNK_TGT_F'] = ['-o']
45 v['CPPPATH_ST'] = '-I%s'
46 v['DEFINES_ST'] = '-D%s'
47
48 v['LIB_ST'] = '-l%s' # template for adding libs
49 v['LIBPATH_ST'] = '-L%s' # template for adding libpaths
50 v['STLIB_ST'] = '-l%s'
51 v['STLIBPATH_ST'] = '-L%s'
52
53 v['SONAME_ST'] = '-Wl,-h,%s'
54 v['SHLIB_MARKER'] = '-Bdynamic'
55 v['STLIB_MARKER'] = '-Bstatic'
56
57 # program
58 v['cprogram_PATTERN'] = '%s'
59
60 # shared library
61 v['CFLAGS_cshlib'] = ['-Kpic', '-DPIC']
62 v['LINKFLAGS_cshlib'] = ['-G']
63 v['cshlib_PATTERN'] = 'lib%s.so'
64
65 # static lib
66 v['LINKFLAGS_cstlib'] = ['-Bstatic']
67 v['cstlib_PATTERN'] = 'lib%s.a'
68
69 def configure(conf):
70 conf.find_scc()
71 conf.find_ar()
72 conf.scc_common_flags()
73 conf.cc_load_tools()
74 conf.cc_add_flags()
75 conf.link_add_flags()
76
0 #!/usr/bin/env python
1 # encoding: utf-8
2 # Thomas Nagy, 2006-2010 (ita)
3 # Ralf Habacker, 2006 (rh)
4
5 import os
6 from waflib import Utils
7 from waflib.Tools import ccroot, ar
8 from waflib.Configure import conf
9
10 @conf
11 def find_sxx(conf):
12 """
13 Detect the sun C++ compiler
14 """
15 v = conf.env
16 cc = None
17 if v['CXX']: cc = v['CXX']
18 elif 'CXX' in conf.environ: cc = conf.environ['CXX']
19 if not cc: cc = conf.find_program('CC', var='CXX') #studio
20 if not cc: cc = conf.find_program('c++', var='CXX')
21 if not cc: conf.fatal('Could not find a Sun C++ compiler')
22 cc = conf.cmd_to_list(cc)
23
24 try:
25 conf.cmd_and_log(cc + ['-flags'])
26 except:
27 conf.fatal('%r is not a Sun compiler' % cc)
28
29 v['CXX'] = cc
30 v['CXX_NAME'] = 'sun'
31
32 @conf
33 def sxx_common_flags(conf):
34 """
35 Flags required for executing the sun C++ compiler
36 """
37 v = conf.env
38
39 v['CXX_SRC_F'] = []
40 v['CXX_TGT_F'] = ['-c', '-o']
41
42 # linker
43 if not v['LINK_CXX']: v['LINK_CXX'] = v['CXX']
44 v['CXXLNK_SRC_F'] = []
45 v['CXXLNK_TGT_F'] = ['-o']
46 v['CPPPATH_ST'] = '-I%s'
47 v['DEFINES_ST'] = '-D%s'
48
49 v['LIB_ST'] = '-l%s' # template for adding libs
50 v['LIBPATH_ST'] = '-L%s' # template for adding libpaths
51 v['STLIB_ST'] = '-l%s'
52 v['STLIBPATH_ST'] = '-L%s'
53
54 v['SONAME_ST'] = '-Wl,-h,%s'
55 v['SHLIB_MARKER'] = '-Bdynamic'
56 v['STLIB_MARKER'] = '-Bstatic'
57
58 # program
59 v['cxxprogram_PATTERN'] = '%s'
60
61 # shared library
62 v['CXXFLAGS_cxxshlib'] = ['-Kpic', '-DPIC']
63 v['LINKFLAGS_cxxshlib'] = ['-G']
64 v['cxxshlib_PATTERN'] = 'lib%s.so'
65
66 # static lib
67 v['LINKFLAGS_cxxstlib'] = ['-Bstatic']
68 v['cxxstlib_PATTERN'] = 'lib%s.a'
69
70 def configure(conf):
71 conf.find_sxx()
72 conf.find_ar()
73 conf.sxx_common_flags()
74 conf.cxx_load_tools()
75 conf.cxx_add_flags()
76 conf.link_add_flags()
77
0 #!/usr/bin/env python
1 # encoding: utf-8
2 # Thomas Nagy, 2006-2010 (ita)
3
4 """
5 TeX/LaTeX/PDFLaTeX/XeLaTeX support
6
7 Example::
8
9 def configure(conf):
10 conf.load('tex')
11 if not conf.env.LATEX:
12 conf.fatal('The program LaTex is required')
13
14 def build(bld):
15 bld(
16 features = 'tex',
17 type = 'latex', # pdflatex or xelatex
18 source = 'document.ltx', # mandatory, the source
19 outs = 'ps', # 'pdf' or 'ps pdf'
20 deps = 'crossreferencing.lst', # to give dependencies directly
21 prompt = 1, # 0 for the batch mode
22 )
23
24 To configure with a special program use::
25
26 $ PDFLATEX=luatex waf configure
27 """
28
29 import os, re
30 from waflib import Utils, Task, Errors
31 from waflib.TaskGen import feature, before_method
32 from waflib.Logs import error, warn, debug
33
34 re_bibunit = re.compile(r'\\(?P<type>putbib)\[(?P<file>[^\[\]]*)\]',re.M)
35 def bibunitscan(self):
36 """
37 Parse the inputs and try to find the *bibunit* dependencies
38
39 :return: list of bibunit files
40 :rtype: list of :py:class:`waflib.Node.Node`
41 """
42 node = self.inputs[0]
43
44 nodes = []
45 if not node: return nodes
46
47 code = Utils.readf(node.abspath())
48
49 for match in re_bibunit.finditer(code):
50 path = match.group('file')
51 if path:
52 for k in ['', '.bib']:
53 # add another loop for the tex include paths?
54 debug('tex: trying %s%s' % (path, k))
55 fi = node.parent.find_resource(path + k)
56 if fi:
57 nodes.append(fi)
58 # no break, people are crazy
59 else:
60 debug('tex: could not find %s' % path)
61
62 debug("tex: found the following bibunit files: %s" % nodes)
63 return nodes
64
65 exts_deps_tex = ['', '.ltx', '.tex', '.bib', '.pdf', '.png', '.eps', '.ps']
66 """List of typical file extensions included in latex files"""
67
68 exts_tex = ['.ltx', '.tex']
69 """List of typical file extensions that contain latex"""
70
71 re_tex = re.compile(r'\\(?P<type>include|bibliography|putbib|includegraphics|input|import|bringin|lstinputlisting)(\[[^\[\]]*\])?{(?P<file>[^{}]*)}',re.M)
72 """Regexp for expressions that may include latex files"""
73
74 g_bibtex_re = re.compile('bibdata', re.M)
75 """Regexp for bibtex files"""
76
77 class tex(Task.Task):
78 """
79 Compile a tex/latex file.
80
81 .. inheritance-diagram:: waflib.Tools.tex.latex waflib.Tools.tex.xelatex waflib.Tools.tex.pdflatex
82 """
83
84 bibtex_fun, _ = Task.compile_fun('${BIBTEX} ${BIBTEXFLAGS} ${SRCFILE}', shell=False)
85 bibtex_fun.__doc__ = """
86 Execute the program **bibtex**
87 """
88
89 makeindex_fun, _ = Task.compile_fun('${MAKEINDEX} ${MAKEINDEXFLAGS} ${SRCFILE}', shell=False)
90 makeindex_fun.__doc__ = """
91 Execute the program **makeindex**
92 """
93
94 def scan_aux(self, node):
95 """
96 A recursive regex-based scanner that finds included auxiliary files.
97 """
98 nodes = [node]
99 re_aux = re.compile(r'\\@input{(?P<file>[^{}]*)}', re.M)
100
101 def parse_node(node):
102 code = node.read()
103 for match in re_aux.finditer(code):
104 path = match.group('file')
105 found = node.parent.find_or_declare(path)
106 if found and found not in nodes:
107 debug('tex: found aux node ' + found.abspath())
108 nodes.append(found)
109 parse_node(found)
110
111 parse_node(node)
112 return nodes
113
114 def scan(self):
115 """
116 A recursive regex-based scanner that finds latex dependencies. It uses :py:attr:`waflib.Tools.tex.re_tex`
117
118 Depending on your needs you might want:
119
120 * to change re_tex::
121
122 from waflib.Tools import tex
123 tex.re_tex = myregex
124
125 * or to change the method scan from the latex tasks::
126
127 from waflib.Task import classes
128 classes['latex'].scan = myscanfunction
129 """
130 node = self.inputs[0]
131
132 nodes = []
133 names = []
134 seen = []
135 if not node: return (nodes, names)
136
137 def parse_node(node):
138 if node in seen:
139 return
140 seen.append(node)
141 code = node.read()
142 global re_tex
143 for match in re_tex.finditer(code):
144 for path in match.group('file').split(','):
145 if path:
146 add_name = True
147 found = None
148 for k in exts_deps_tex:
149 debug('tex: trying %s%s' % (path, k))
150 found = node.parent.find_resource(path + k)
151 if found and not found in self.outputs:
152 nodes.append(found)
153 add_name = False
154 for ext in exts_tex:
155 if found.name.endswith(ext):
156 parse_node(found)
157 break
158 # no break, people are crazy
159 if add_name:
160 names.append(path)
161 parse_node(node)
162
163 for x in nodes:
164 x.parent.get_bld().mkdir()
165
166 debug("tex: found the following : %s and names %s" % (nodes, names))
167 return (nodes, names)
168
169 def check_status(self, msg, retcode):
170 """
171 Check an exit status and raise an error with a particular message
172
173 :param msg: message to display if the code is non-zero
174 :type msg: string
175 :param retcode: condition
176 :type retcode: boolean
177 """
178 if retcode != 0:
179 raise Errors.WafError("%r command exit status %r" % (msg, retcode))
180
181 def bibfile(self):
182 """
183 Parse the *.aux* files to find a bibfile to process.
184 If yes, execute :py:meth:`waflib.Tools.tex.tex.bibtex_fun`
185 """
186 need_bibtex = False
187 try:
188 for aux_node in self.aux_nodes:
189 ct = aux_node.read()
190 if g_bibtex_re.findall(ct):
191 need_bibtex = True
192 break
193 except (OSError, IOError):
194 error('error bibtex scan')
195 else:
196 # only the main .aux file needs to be processed
197 if need_bibtex:
198 warn('calling bibtex')
199
200 self.env.env = {}
201 self.env.env.update(os.environ)
202 self.env.env.update({'BIBINPUTS': self.TEXINPUTS, 'BSTINPUTS': self.TEXINPUTS})
203 self.env.SRCFILE = self.aux_nodes[0].name[:-4]
204 self.check_status('error when calling bibtex', self.bibtex_fun())
205
206 def bibunits(self):
207 """
208 Parse the *.aux* file to find bibunit files. If there are bibunit files,
209 execute :py:meth:`waflib.Tools.tex.tex.bibtex_fun`.
210 """
211 try:
212 bibunits = bibunitscan(self)
213 except FSError:
214 error('error bibunitscan')
215 else:
216 if bibunits:
217 fn = ['bu' + str(i) for i in xrange(1, len(bibunits) + 1)]
218 if fn:
219 warn('calling bibtex on bibunits')
220
221 for f in fn:
222 self.env.env = {'BIBINPUTS': self.TEXINPUTS, 'BSTINPUTS': self.TEXINPUTS}
223 self.env.SRCFILE = f
224 self.check_status('error when calling bibtex', self.bibtex_fun())
225
226 def makeindex(self):
227 """
228 Look on the filesystem if there is a *.idx* file to process. If yes, execute
229 :py:meth:`waflib.Tools.tex.tex.makeindex_fun`
230 """
231 try:
232 idx_path = self.idx_node.abspath()
233 os.stat(idx_path)
234 except OSError:
235 warn('index file %s absent, not calling makeindex' % idx_path)
236 else:
237 warn('calling makeindex')
238
239 self.env.SRCFILE = self.idx_node.name
240 self.env.env = {}
241 self.check_status('error when calling makeindex %s' % idx_path, self.makeindex_fun())
242
243 def run(self):
244 """
245 Runs the TeX build process.
246
247 It may require multiple passes, depending on the usage of cross-references,
248 bibliographies, content susceptible of needing such passes.
249 The appropriate TeX compiler is called until the *.aux* files stop changing.
250
251 Makeindex and bibtex are called if necessary.
252 """
253 env = self.env
254
255 if not env['PROMPT_LATEX']:
256 env.append_value('LATEXFLAGS', '-interaction=batchmode')
257 env.append_value('PDFLATEXFLAGS', '-interaction=batchmode')
258 env.append_value('XELATEXFLAGS', '-interaction=batchmode')
259
260 fun = self.texfun
261
262 node = self.inputs[0]
263 srcfile = node.abspath()
264
265 texinputs = self.env.TEXINPUTS or ''
266 self.TEXINPUTS = node.parent.get_bld().abspath() + os.pathsep + node.parent.get_src().abspath() + os.pathsep + texinputs + os.pathsep
267
268 self.aux_node = node.change_ext('.aux') # TODO waf 1.7 remove (left for compatibility)
269
270 # important, set the cwd for everybody
271 self.cwd = self.inputs[0].parent.get_bld().abspath()
272
273 warn('first pass on %s' % self.__class__.__name__)
274
275 self.env.env = {}
276 self.env.env.update(os.environ)
277 self.env.env.update({'TEXINPUTS': self.TEXINPUTS})
278 self.env.SRCFILE = srcfile
279 self.check_status('error when calling latex', fun())
280
281 self.aux_nodes = self.scan_aux(node.change_ext('.aux'))
282 self.idx_node = node.change_ext('.idx')
283
284 self.bibfile()
285 self.bibunits()
286 self.makeindex()
287
288 hash = ''
289 for i in range(10):
290 # prevent against infinite loops - one never knows
291
292 # watch the contents of file.aux and stop if file.aux does not change anymore
293 prev_hash = hash
294 try:
295 hashes = [Utils.h_file(x.abspath()) for x in self.aux_nodes]
296 hash = Utils.h_list(hashes)
297 except (OSError, IOError):
298 error('could not read aux.h')
299 pass
300 if hash and hash == prev_hash:
301 break
302
303 # run the command
304 warn('calling %s' % self.__class__.__name__)
305
306 self.env.env = {}
307 self.env.env.update(os.environ)
308 self.env.env.update({'TEXINPUTS': self.TEXINPUTS})
309 self.env.SRCFILE = srcfile
310 self.check_status('error when calling %s' % self.__class__.__name__, fun())
311
312 class latex(tex):
313 texfun, vars = Task.compile_fun('${LATEX} ${LATEXFLAGS} ${SRCFILE}', shell=False)
314 class pdflatex(tex):
315 texfun, vars = Task.compile_fun('${PDFLATEX} ${PDFLATEXFLAGS} ${SRCFILE}', shell=False)
316 class xelatex(tex):
317 texfun, vars = Task.compile_fun('${XELATEX} ${XELATEXFLAGS} ${SRCFILE}', shell=False)
318
319 class dvips(Task.Task):
320 run_str = '${DVIPS} ${DVIPSFLAGS} ${SRC} -o ${TGT}'
321 color = 'BLUE'
322 after = ['latex', 'pdflatex', 'xelatex']
323
324 class dvipdf(Task.Task):
325 run_str = '${DVIPDF} ${DVIPDFFLAGS} ${SRC} ${TGT}'
326 color = 'BLUE'
327 after = ['latex', 'pdflatex', 'xelatex']
328
329 class pdf2ps(Task.Task):
330 run_str = '${PDF2PS} ${PDF2PSFLAGS} ${SRC} ${TGT}'
331 color = 'BLUE'
332 after = ['latex', 'pdflatex', 'xelatex']
333
334 @feature('tex')
335 @before_method('process_source')
336 def apply_tex(self):
337 """
338 Create :py:class:`waflib.Tools.tex.tex` objects, and dvips/dvipdf/pdf2ps tasks if necessary (outs='ps', etc).
339 """
340 if not getattr(self, 'type', None) in ['latex', 'pdflatex', 'xelatex']:
341 self.type = 'pdflatex'
342
343 tree = self.bld
344 outs = Utils.to_list(getattr(self, 'outs', []))
345
346 # prompt for incomplete files (else the batchmode is used)
347 self.env['PROMPT_LATEX'] = getattr(self, 'prompt', 1)
348
349 deps_lst = []
350
351 if getattr(self, 'deps', None):
352 deps = self.to_list(self.deps)
353 for filename in deps:
354 n = self.path.find_resource(filename)
355 if not n in deps_lst: deps_lst.append(n)
356
357 for node in self.to_nodes(self.source):
358
359 if self.type == 'latex':
360 task = self.create_task('latex', node, node.change_ext('.dvi'))
361 elif self.type == 'pdflatex':
362 task = self.create_task('pdflatex', node, node.change_ext('.pdf'))
363 elif self.type == 'xelatex':
364 task = self.create_task('xelatex', node, node.change_ext('.pdf'))
365
366 task.env = self.env
367
368 # add the manual dependencies
369 if deps_lst:
370 try:
371 lst = tree.node_deps[task.uid()]
372 for n in deps_lst:
373 if not n in lst:
374 lst.append(n)
375 except KeyError:
376 tree.node_deps[task.uid()] = deps_lst
377
378 if self.type == 'latex':
379 if 'ps' in outs:
380 tsk = self.create_task('dvips', task.outputs, node.change_ext('.ps'))
381 tsk.env.env = {'TEXINPUTS' : node.parent.abspath() + os.pathsep + self.path.abspath() + os.pathsep + self.path.get_bld().abspath()}
382 if 'pdf' in outs:
383 tsk = self.create_task('dvipdf', task.outputs, node.change_ext('.pdf'))
384 tsk.env.env = {'TEXINPUTS' : node.parent.abspath() + os.pathsep + self.path.abspath() + os.pathsep + self.path.get_bld().abspath()}
385 elif self.type == 'pdflatex':
386 if 'ps' in outs:
387 self.create_task('pdf2ps', task.outputs, node.change_ext('.ps'))
388 self.source = []
389
390 def configure(self):
391 """
392 Try to find the programs tex, latex and others. Do not raise any error if they
393 are not found.
394 """
395 v = self.env
396 for p in 'tex latex pdflatex xelatex bibtex dvips dvipdf ps2pdf makeindex pdf2ps'.split():
397 try:
398 self.find_program(p, var=p.upper())
399 except self.errors.ConfigurationError:
400 pass
401 v['DVIPSFLAGS'] = '-Ppdf'
402
0 #!/usr/bin/env python
1 # encoding: utf-8
2 # Ali Sabil, 2007
3 # Radosław Szkodziński, 2010
4
5 """
6 At this point, vala is still unstable, so do not expect
7 this tool to be too stable either (apis, etc)
8 """
9
10 import os.path, shutil, re
11 from waflib import Context, Task, Utils, Logs, Options, Errors
12 from waflib.TaskGen import extension
13 from waflib.Configure import conf
14
15 class valac(Task.Task):
16 """
17 Task to compile vala files.
18 """
19 vars = ["VALAC", "VALAC_VERSION", "VALAFLAGS"]
20 ext_out = ['.h']
21
22 def run(self):
23 env = self.env
24
25 cmd = [env['VALAC'], '-C', '--quiet']
26 cmd.extend(Utils.to_list(env['VALAFLAGS']))
27
28 if self.threading:
29 cmd.append('--thread')
30
31 if self.profile:
32 cmd.append('--profile=%s' % self.profile)
33
34 if self.target_glib:
35 cmd.append('--target-glib=%s' % self.target_glib)
36
37 if self.is_lib:
38 cmd.append('--library=' + self.target)
39 for x in self.outputs:
40 if x.name.endswith('.h'):
41 cmd.append('--header=' + x.name)
42 if self.gir:
43 cmd.append('--gir=%s.gir' % self.gir)
44
45 for vapi_dir in self.vapi_dirs:
46 cmd.append('--vapidir=%s' % vapi_dir)
47
48 for package in self.packages:
49 cmd.append('--pkg=%s' % package)
50
51 for package in self.packages_private:
52 cmd.append('--pkg=%s' % package)
53
54 for define in self.vala_defines:
55 cmd.append('--define=%s' % define)
56
57 cmd.extend([a.abspath() for a in self.inputs])
58 ret = self.exec_command(cmd, cwd=self.outputs[0].parent.abspath())
59
60 if ret:
61 return ret
62
63 for x in self.outputs:
64 if id(x.parent) != id(self.outputs[0].parent):
65 shutil.move(self.outputs[0].parent.abspath() + os.sep + x.name, x.abspath())
66
67 if self.packages and getattr(self, 'deps_node', None):
68 self.deps_node.write('\n'.join(self.packages))
69
70 return ret
71
72 @extension('.vala', '.gs')
73 def vala_file(self, node):
74 """
75 Compile a vala file and bind the task to *self.valatask*. If an existing vala task is already set, add the node
76 to its inputs. The typical example is::
77
78 def build(bld):
79 bld.program(
80 packages = 'gtk+-2.0',
81 target = 'vala-gtk-example',
82 uselib = 'GTK GLIB',
83 source = 'vala-gtk-example.vala foo.vala',
84 vala_defines = ['DEBUG']
85 # the following arguments are for libraries
86 #gir = 'hello-1.0',
87 #gir_path = '/tmp',
88 #vapi_path = '/tmp',
89 #pkg_name = 'hello'
90 # disable installing of gir, vapi and header
91 #install_binding = False
92 )
93
94
95 :param node: vala file
96 :type node: :py:class:`waflib.Node.Node`
97 """
98 # TODO: the vala task should use self.generator.attribute instead of copying attributes from self to the task
99 valatask = getattr(self, "valatask", None)
100 # there is only one vala task and it compiles all vala files .. :-/
101 if not valatask:
102 def _get_api_version():
103 api_version = '1.0'
104 if hasattr(Context.g_module, 'API_VERSION'):
105 version = Context.g_module.API_VERSION.split(".")
106 if version[0] == "0":
107 api_version = "0." + version[1]
108 else:
109 api_version = version[0] + ".0"
110 return api_version
111
112 valatask = self.create_task('valac')
113 self.valatask = valatask # this assumes one vala task by task generator
114 self.includes = Utils.to_list(getattr(self, 'includes', []))
115 self.uselib = self.to_list(getattr(self, 'uselib', []))
116 valatask.packages = []
117 valatask.packages_private = Utils.to_list(getattr(self, 'packages_private', []))
118 valatask.vapi_dirs = []
119 valatask.target = self.target
120 valatask.threading = False
121 valatask.install_path = getattr(self, 'install_path', '')
122 valatask.profile = getattr(self, 'profile', 'gobject')
123 valatask.vala_defines = getattr(self, 'vala_defines', [])
124 valatask.target_glib = None
125 valatask.gir = getattr(self, 'gir', None)
126 valatask.gir_path = getattr(self, 'gir_path', '${DATAROOTDIR}/gir-1.0')
127 valatask.vapi_path = getattr(self, 'vapi_path', '${DATAROOTDIR}/vala/vapi')
128 valatask.pkg_name = getattr(self, 'pkg_name', self.env['PACKAGE'])
129 valatask.header_path = getattr(self, 'header_path', '${INCLUDEDIR}/%s-%s' % (valatask.pkg_name, _get_api_version()))
130 valatask.install_binding = getattr(self, 'install_binding', True)
131
132 valatask.is_lib = False
133 if not 'cprogram' in self.features:
134 valatask.is_lib = True
135
136 packages = Utils.to_list(getattr(self, 'packages', []))
137 vapi_dirs = Utils.to_list(getattr(self, 'vapi_dirs', []))
138 includes = []
139
140 if hasattr(self, 'use'):
141 local_packages = Utils.to_list(self.use)[:] # make sure to have a copy
142 seen = []
143 while len(local_packages) > 0:
144 package = local_packages.pop()
145 if package in seen:
146 continue
147 seen.append(package)
148
149 # check if the package exists
150 try:
151 package_obj = self.bld.get_tgen_by_name(package)
152 except Errors.WafError:
153 continue
154 package_name = package_obj.target
155 package_node = package_obj.path
156 package_dir = package_node.path_from(self.path)
157
158 for task in package_obj.tasks:
159 for output in task.outputs:
160 if output.name == package_name + ".vapi":
161 valatask.set_run_after(task)
162 if package_name not in packages:
163 packages.append(package_name)
164 if package_dir not in vapi_dirs:
165 vapi_dirs.append(package_dir)
166 if package_dir not in includes:
167 includes.append(package_dir)
168
169 if hasattr(package_obj, 'use'):
170 lst = self.to_list(package_obj.use)
171 lst.reverse()
172 local_packages = [pkg for pkg in lst if pkg not in seen] + local_packages
173
174 valatask.packages = packages
175 for vapi_dir in vapi_dirs:
176 try:
177 valatask.vapi_dirs.append(self.path.find_dir(vapi_dir).abspath())
178 valatask.vapi_dirs.append(self.path.find_dir(vapi_dir).get_bld().abspath())
179 except AttributeError:
180 Logs.warn("Unable to locate Vala API directory: '%s'" % vapi_dir)
181
182 self.includes.append(self.bld.srcnode.abspath())
183 self.includes.append(self.bld.bldnode.abspath())
184 for include in includes:
185 try:
186 self.includes.append(self.path.find_dir(include).abspath())
187 self.includes.append(self.path.find_dir(include).get_bld().abspath())
188 except AttributeError:
189 Logs.warn("Unable to locate include directory: '%s'" % include)
190
191
192 if valatask.profile == 'gobject':
193 if hasattr(self, 'target_glib'):
194 Logs.warn('target_glib on vala tasks is not supported --vala-target-glib=MAJOR.MINOR from the vala tool options')
195
196 if getattr(Options.options, 'vala_target_glib', None):
197 valatask.target_glib = Options.options.vala_target_glib
198
199 if not 'GOBJECT' in self.uselib:
200 self.uselib.append('GOBJECT')
201
202 if hasattr(self, 'threading'):
203 if valatask.profile == 'gobject':
204 valatask.threading = self.threading
205 if not 'GTHREAD' in self.uselib:
206 self.uselib.append('GTHREAD')
207 else:
208 #Vala doesn't have threading support for dova nor posix
209 Logs.warn("Profile %s does not have threading support" % valatask.profile)
210
211 if valatask.is_lib:
212 valatask.outputs.append(self.path.find_or_declare('%s.h' % self.target))
213 valatask.outputs.append(self.path.find_or_declare('%s.vapi' % self.target))
214
215 if valatask.gir:
216 valatask.outputs.append(self.path.find_or_declare('%s.gir' % self.gir))
217
218 if valatask.packages:
219 d = self.path.find_or_declare('%s.deps' % self.target)
220 valatask.outputs.append(d)
221 valatask.deps_node = d
222
223 valatask.inputs.append(node)
224 c_node = node.change_ext('.c')
225
226 valatask.outputs.append(c_node)
227 self.source.append(c_node)
228
229 if valatask.is_lib and valatask.install_binding:
230 headers_list = [o for o in valatask.outputs if o.suffix() == ".h"]
231 try:
232 self.install_vheader.source = headers_list
233 except AttributeError:
234 self.install_vheader = self.bld.install_files(valatask.header_path, headers_list, self.env)
235
236 vapi_list = [o for o in valatask.outputs if (o.suffix() in (".vapi", ".deps"))]
237 try:
238 self.install_vapi.source = vapi_list
239 except AttributeError:
240 self.install_vapi = self.bld.install_files(valatask.vapi_path, vapi_list, self.env)
241
242 gir_list = [o for o in valatask.outputs if o.suffix() == ".gir"]
243 try:
244 self.install_gir.source = gir_list
245 except AttributeError:
246 self.install_gir = self.bld.install_files(valatask.gir_path, gir_list, self.env)
247
248 valac = Task.update_outputs(valac) # no decorators for python2 classes
249
250 @conf
251 def find_valac(self, valac_name, min_version):
252 """
253 Find the valac program, and execute it to store the version
254 number in *conf.env.VALAC_VERSION*
255
256 :param valac_name: program name
257 :type valac_name: string or list of string
258 :param min_version: minimum version acceptable
259 :type min_version: tuple of int
260 """
261 valac = self.find_program(valac_name, var='VALAC')
262 try:
263 output = self.cmd_and_log(valac + ' --version')
264 except Exception:
265 valac_version = None
266 else:
267 ver = re.search(r'\d+.\d+.\d+', output).group(0).split('.')
268 valac_version = tuple([int(x) for x in ver])
269
270 self.msg('Checking for %s version >= %r' % (valac_name, min_version),
271 valac_version, valac_version and valac_version >= min_version)
272 if valac and valac_version < min_version:
273 self.fatal("%s version %r is too old, need >= %r" % (valac_name, valac_version, min_version))
274
275 self.env['VALAC_VERSION'] = valac_version
276 return valac
277
278 @conf
279 def check_vala(self, min_version=(0,8,0), branch=None):
280 """
281 Check if vala compiler from a given branch exists of at least a given
282 version.
283
284 :param min_version: minimum version acceptable (0.8.0)
285 :type min_version: tuple
286 :param branch: first part of the version number, in case a snapshot is used (0, 8)
287 :type branch: tuple of int
288 """
289 if not branch:
290 branch = min_version[:2]
291 try:
292 find_valac(self, 'valac-%d.%d' % (branch[0], branch[1]), min_version)
293 except self.errors.ConfigurationError:
294 find_valac(self, 'valac', min_version)
295
296 @conf
297 def check_vala_deps(self):
298 """
299 Load the gobject and gthread packages if they are missing.
300 """
301 if not self.env['HAVE_GOBJECT']:
302 pkg_args = {'package': 'gobject-2.0',
303 'uselib_store': 'GOBJECT',
304 'args': '--cflags --libs'}
305 if getattr(Options.options, 'vala_target_glib', None):
306 pkg_args['atleast_version'] = Options.options.vala_target_glib
307 self.check_cfg(**pkg_args)
308
309 if not self.env['HAVE_GTHREAD']:
310 pkg_args = {'package': 'gthread-2.0',
311 'uselib_store': 'GTHREAD',
312 'args': '--cflags --libs'}
313 if getattr(Options.options, 'vala_target_glib', None):
314 pkg_args['atleast_version'] = Options.options.vala_target_glib
315 self.check_cfg(**pkg_args)
316
317 def configure(self):
318 """
319 Use the following to enforce minimum vala version::
320
321 def configure(conf):
322 conf.load('vala', funs='')
323 conf.check_vala(min_version=(0,10,0))
324 """
325 self.load('gnu_dirs')
326 self.check_vala_deps()
327 self.check_vala()
328
329 def options(opt):
330 """
331 Load the :py:mod:`waflib.Tools.gnu_dirs` tool and add the ``--vala-target-glib`` command-line option
332 """
333 opt.load('gnu_dirs')
334 valaopts = opt.add_option_group('Vala Compiler Options')
335 valaopts.add_option ('--vala-target-glib', default=None,
336 dest='vala_target_glib', metavar='MAJOR.MINOR',
337 help='Target version of glib for Vala GObject code generation')
338
0 #!/usr/bin/env python
1 # encoding: utf-8
2 # Carlos Rafael Giani, 2006
3 # Thomas Nagy, 2010
4
5 """
6 Unit testing system for C/C++/D providing test execution:
7
8 * in parallel, by using ``waf -j``
9 * partial (only the tests that have changed) or full (by using ``waf --alltests``)
10
11 The tests are declared by adding the **test** feature to programs::
12
13 def options(opt):
14 opt.load('compiler_cxx waf_unit_test')
15 def configure(conf):
16 conf.load('compiler_cxx waf_unit_test')
17 def build(bld):
18 bld(features='cxx cxxprogram test', source='main.cpp', target='app')
19 # or
20 bld.program(features='test', source='main2.cpp', target='app2')
21
22 When the build is executed, the program 'test' will be built and executed without arguments.
23 The success/failure is detected by looking at the return code. The status and the standard output/error
24 are stored on the build context.
25
26 The results can be displayed by registering a callback function. Here is how to call
27 the predefined callback::
28
29 def build(bld):
30 bld(features='cxx cxxprogram test', source='main.c', target='app')
31 from waflib.Tools import waf_unit_test
32 bld.add_post_fun(waf_unit_test.summary)
33 """
34
35 import os
36 from waflib.TaskGen import feature, after_method, taskgen_method
37 from waflib import Utils, Task, Logs, Options
38 testlock = Utils.threading.Lock()
39
40 @feature('test')
41 @after_method('apply_link')
42 def make_test(self):
43 """Create the unit test task. There can be only one unit test task by task generator."""
44 if getattr(self, 'link_task', None):
45 self.create_task('utest', self.link_task.outputs)
46
47
48 @taskgen_method
49 def add_test_results(self, tup):
50 """Override and return tup[1] to interrupt the build immediately if a test does not run"""
51 Logs.debug("ut: %r", tup)
52 self.utest_result = tup
53 try:
54 self.bld.utest_results.append(tup)
55 except AttributeError:
56 self.bld.utest_results = [tup]
57
58 class utest(Task.Task):
59 """
60 Execute a unit test
61 """
62 color = 'PINK'
63 after = ['vnum', 'inst']
64 vars = []
65 def runnable_status(self):
66 """
67 Always execute the task if `waf --alltests` was used or no
68 tests if ``waf --notests`` was used
69 """
70 if getattr(Options.options, 'no_tests', False):
71 return Task.SKIP_ME
72
73 ret = super(utest, self).runnable_status()
74 if ret == Task.SKIP_ME:
75 if getattr(Options.options, 'all_tests', False):
76 return Task.RUN_ME
77 return ret
78
79 def add_path(self, dct, path, var):
80 dct[var] = os.pathsep.join(Utils.to_list(path) + [os.environ.get(var, '')])
81
82 def get_test_env(self):
83 """
84 In general, tests may require any library built anywhere in the project.
85 Override this method if fewer paths are needed
86 """
87 try:
88 fu = getattr(self.generator.bld, 'all_test_paths')
89 except AttributeError:
90 # this operation may be performed by at most #maxjobs
91 fu = os.environ.copy()
92
93 lst = []
94 for g in self.generator.bld.groups:
95 for tg in g:
96 if getattr(tg, 'link_task', None):
97 s = tg.link_task.outputs[0].parent.abspath()
98 if s not in lst:
99 lst.append(s)
100
101 if Utils.is_win32:
102 self.add_path(fu, lst, 'PATH')
103 elif Utils.unversioned_sys_platform() == 'darwin':
104 self.add_path(fu, lst, 'DYLD_LIBRARY_PATH')
105 self.add_path(fu, lst, 'LD_LIBRARY_PATH')
106 else:
107 self.add_path(fu, lst, 'LD_LIBRARY_PATH')
108 self.generator.bld.all_test_paths = fu
109 return fu
110
111 def run(self):
112 """
113 Execute the test. The execution is always successful, and the results
114 are stored on ``self.generator.bld.utest_results`` for postprocessing.
115
116 Override ``add_test_results`` to interrupt the build
117 """
118
119 filename = self.inputs[0].abspath()
120 self.ut_exec = getattr(self.generator, 'ut_exec', [filename])
121 if getattr(self.generator, 'ut_fun', None):
122 self.generator.ut_fun(self)
123
124
125 cwd = getattr(self.generator, 'ut_cwd', '') or self.inputs[0].parent.abspath()
126
127 testcmd = getattr(self.generator, 'ut_cmd', False) or getattr(Options.options, 'testcmd', False)
128 if testcmd:
129 self.ut_exec = (testcmd % self.ut_exec[0]).split(' ')
130
131 proc = Utils.subprocess.Popen(self.ut_exec, cwd=cwd, env=self.get_test_env(), stderr=Utils.subprocess.PIPE, stdout=Utils.subprocess.PIPE)
132 (stdout, stderr) = proc.communicate()
133
134 tup = (filename, proc.returncode, stdout, stderr)
135 testlock.acquire()
136 try:
137 return self.generator.add_test_results(tup)
138 finally:
139 testlock.release()
140
141 def summary(bld):
142 """
143 Display an execution summary::
144
145 def build(bld):
146 bld(features='cxx cxxprogram test', source='main.c', target='app')
147 from waflib.Tools import waf_unit_test
148 bld.add_post_fun(waf_unit_test.summary)
149 """
150 lst = getattr(bld, 'utest_results', [])
151 if lst:
152 Logs.pprint('CYAN', 'execution summary')
153
154 total = len(lst)
155 tfail = len([x for x in lst if x[1]])
156
157 Logs.pprint('CYAN', ' tests that pass %d/%d' % (total-tfail, total))
158 for (f, code, out, err) in lst:
159 if not code:
160 Logs.pprint('CYAN', ' %s' % f)
161
162 Logs.pprint('CYAN', ' tests that fail %d/%d' % (tfail, total))
163 for (f, code, out, err) in lst:
164 if code:
165 Logs.pprint('CYAN', ' %s' % f)
166
167 def set_exit_code(bld):
168 """
169 If any of the tests fail waf will exit with that exit code.
170 This is useful if you have an automated build system which need
171 to report on errors from the tests.
172 You may use it like this:
173
174 def build(bld):
175 bld(features='cxx cxxprogram test', source='main.c', target='app')
176 from waflib.Tools import waf_unit_test
177 bld.add_post_fun(waf_unit_test.set_exit_code)
178 """
179 lst = getattr(bld, 'utest_results', [])
180 for (f, code, out, err) in lst:
181 if code:
182 msg = []
183 if out:
184 msg.append('stdout:%s%s' % (os.linesep, out.decode('utf-8')))
185 if err:
186 msg.append('stderr:%s%s' % (os.linesep, err.decode('utf-8')))
187 bld.fatal(os.linesep.join(msg))
188
189
190 def options(opt):
191 """
192 Provide the ``--alltests``, ``--notests`` and ``--testcmd`` command-line options.
193 """
194 opt.add_option('--notests', action='store_true', default=False, help='Exec no unit tests', dest='no_tests')
195 opt.add_option('--alltests', action='store_true', default=False, help='Exec all unit tests', dest='all_tests')
196 opt.add_option('--testcmd', action='store', default=False,
197 help = 'Run the unit tests using the test-cmd string'
198 ' example "--test-cmd="valgrind --error-exitcode=1'
199 ' %s" to run under valgrind', dest='testcmd')
200
0 #!/usr/bin/env python
1 # encoding: utf-8
2 # Brant Young, 2007
3
4 "Process *.rc* files for C/C++: X{.rc -> [.res|.rc.o]}"
5
6 from waflib import Task
7 from waflib.TaskGen import extension
8
9 @extension('.rc')
10 def rc_file(self, node):
11 """
12 Bind the .rc extension to a winrc task
13 """
14 obj_ext = '.rc.o'
15 if self.env['WINRC_TGT_F'] == '/fo':
16 obj_ext = '.res'
17 rctask = self.create_task('winrc', node, node.change_ext(obj_ext))
18 try:
19 self.compiled_tasks.append(rctask)
20 except AttributeError:
21 self.compiled_tasks = [rctask]
22
23 class winrc(Task.Task):
24 """
25 Task for compiling resource files
26 """
27 run_str = '${WINRC} ${WINRCFLAGS} ${CPPPATH_ST:INCPATHS} ${DEFINES_ST:DEFINES} ${WINRC_TGT_F} ${TGT} ${WINRC_SRC_F} ${SRC}'
28 color = 'BLUE'
29
30 def configure(conf):
31 """
32 Detect the programs RC or windres, depending on the C/C++ compiler in use
33 """
34 v = conf.env
35 v['WINRC_TGT_F'] = '-o'
36 v['WINRC_SRC_F'] = '-i'
37
38 # find rc.exe
39 if not conf.env.WINRC:
40 if v.CC_NAME == 'msvc':
41 conf.find_program('RC', var='WINRC', path_list = v['PATH'])
42 v['WINRC_TGT_F'] = '/fo'
43 v['WINRC_SRC_F'] = ''
44 else:
45 conf.find_program('windres', var='WINRC', path_list = v['PATH'])
46 if not conf.env.WINRC:
47 conf.fatal('winrc was not found!')
48
49 v['WINRCFLAGS'] = []
50
0 #!/usr/bin/env python
1 # encoding: utf-8
2 # Thomas Nagy, 2006-2010 (ita)
3 # Ralf Habacker, 2006 (rh)
4 # Yinon Ehrlich, 2009
5 # Michael Kuhn, 2009
6
7 from waflib.Tools import ccroot, ar
8 from waflib.Configure import conf
9
10 @conf
11 def find_xlc(conf):
12 """
13 Detect the Aix C compiler
14 """
15 cc = conf.find_program(['xlc_r', 'xlc'], var='CC')
16 cc = conf.cmd_to_list(cc)
17 conf.get_xlc_version(cc)
18 conf.env.CC_NAME = 'xlc'
19 conf.env.CC = cc
20
21 @conf
22 def xlc_common_flags(conf):
23 """
24 Flags required for executing the Aix C compiler
25 """
26 v = conf.env
27
28 v['CC_SRC_F'] = []
29 v['CC_TGT_F'] = ['-c', '-o']
30
31 # linker
32 if not v['LINK_CC']: v['LINK_CC'] = v['CC']
33 v['CCLNK_SRC_F'] = []
34 v['CCLNK_TGT_F'] = ['-o']
35 v['CPPPATH_ST'] = '-I%s'
36 v['DEFINES_ST'] = '-D%s'
37
38 v['LIB_ST'] = '-l%s' # template for adding libs
39 v['LIBPATH_ST'] = '-L%s' # template for adding libpaths
40 v['STLIB_ST'] = '-l%s'
41 v['STLIBPATH_ST'] = '-L%s'
42 v['RPATH_ST'] = '-Wl,-rpath,%s'
43
44 v['SONAME_ST'] = []
45 v['SHLIB_MARKER'] = []
46 v['STLIB_MARKER'] = []
47
48 # program
49 v['LINKFLAGS_cprogram'] = ['-Wl,-brtl']
50 v['cprogram_PATTERN'] = '%s'
51
52 # shared library
53 v['CFLAGS_cshlib'] = ['-fPIC']
54 v['LINKFLAGS_cshlib'] = ['-G', '-Wl,-brtl,-bexpfull']
55 v['cshlib_PATTERN'] = 'lib%s.so'
56
57 # static lib
58 v['LINKFLAGS_cstlib'] = []
59 v['cstlib_PATTERN'] = 'lib%s.a'
60
61 def configure(conf):
62 conf.find_xlc()
63 conf.find_ar()
64 conf.xlc_common_flags()
65 conf.cc_load_tools()
66 conf.cc_add_flags()
67 conf.link_add_flags()
68
0 #!/usr/bin/env python
1 # encoding: utf-8
2 # Thomas Nagy, 2006-2010 (ita)
3 # Ralf Habacker, 2006 (rh)
4 # Yinon Ehrlich, 2009
5 # Michael Kuhn, 2009
6
7 from waflib.Tools import ccroot, ar
8 from waflib.Configure import conf
9
10 @conf
11 def find_xlcxx(conf):
12 """
13 Detect the Aix C++ compiler
14 """
15 cxx = conf.find_program(['xlc++_r', 'xlc++'], var='CXX')
16 cxx = conf.cmd_to_list(cxx)
17 conf.get_xlc_version(cxx)
18 conf.env.CXX_NAME = 'xlc++'
19 conf.env.CXX = cxx
20
21 @conf
22 def xlcxx_common_flags(conf):
23 """
24 Flags required for executing the Aix C++ compiler
25 """
26 v = conf.env
27
28 v['CXX_SRC_F'] = []
29 v['CXX_TGT_F'] = ['-c', '-o']
30
31 # linker
32 if not v['LINK_CXX']: v['LINK_CXX'] = v['CXX']
33 v['CXXLNK_SRC_F'] = []
34 v['CXXLNK_TGT_F'] = ['-o']
35 v['CPPPATH_ST'] = '-I%s'
36 v['DEFINES_ST'] = '-D%s'
37
38 v['LIB_ST'] = '-l%s' # template for adding libs
39 v['LIBPATH_ST'] = '-L%s' # template for adding libpaths
40 v['STLIB_ST'] = '-l%s'
41 v['STLIBPATH_ST'] = '-L%s'
42 v['RPATH_ST'] = '-Wl,-rpath,%s'
43
44 v['SONAME_ST'] = []
45 v['SHLIB_MARKER'] = []
46 v['STLIB_MARKER'] = []
47
48 # program
49 v['LINKFLAGS_cxxprogram']= ['-Wl,-brtl']
50 v['cxxprogram_PATTERN'] = '%s'
51
52 # shared library
53 v['CXXFLAGS_cxxshlib'] = ['-fPIC']
54 v['LINKFLAGS_cxxshlib'] = ['-G', '-Wl,-brtl,-bexpfull']
55 v['cxxshlib_PATTERN'] = 'lib%s.so'
56
57 # static lib
58 v['LINKFLAGS_cxxstlib'] = []
59 v['cxxstlib_PATTERN'] = 'lib%s.a'
60
61 def configure(conf):
62 conf.find_xlcxx()
63 conf.find_ar()
64 conf.xlcxx_common_flags()
65 conf.cxx_load_tools()
66 conf.cxx_add_flags()
67 conf.link_add_flags()
68
0 #!/usr/bin/env python
1 # encoding: utf-8
2 # Thomas Nagy, 2005-2010 (ita)
3
4 """
5 Utilities and platform-specific fixes
6
7 The portability fixes try to provide a consistent behavior of the Waf API
8 through Python versions 2.3 to 3.X and across different platforms (win32, linux, etc)
9 """
10
11 import os, sys, errno, traceback, inspect, re, shutil, datetime, gc
12 try:
13 import subprocess
14 except:
15 try:
16 import waflib.extras.subprocess as subprocess
17 except:
18 print("The subprocess module is missing (python2.3?):\n try calling 'waf update --files=subprocess'\n or add a copy of subprocess.py to the python libraries")
19
20 try:
21 from collections import deque
22 except ImportError:
23 class deque(list):
24 """A deque for Python 2.3 which does not have one"""
25 def popleft(self):
26 return self.pop(0)
27 try:
28 import _winreg as winreg
29 except:
30 try:
31 import winreg
32 except:
33 winreg = None
34
35 from waflib import Errors
36
37 try:
38 from collections import UserDict
39 except:
40 from UserDict import UserDict
41
42 try:
43 from hashlib import md5
44 except:
45 try:
46 from md5 import md5
47 except:
48 # never fail to enable fixes from another module
49 pass
50
51 try:
52 import threading
53 except:
54 class threading(object):
55 """
56 A fake threading class for platforms lacking the threading module.
57 Use ``waf -j1`` on those platforms
58 """
59 pass
60 class Lock(object):
61 """Fake Lock class"""
62 def acquire(self):
63 pass
64 def release(self):
65 pass
66 threading.Lock = threading.Thread = Lock
67 else:
68 run_old = threading.Thread.run
69 def run(*args, **kwargs):
70 try:
71 run_old(*args, **kwargs)
72 except (KeyboardInterrupt, SystemExit):
73 raise
74 except:
75 sys.excepthook(*sys.exc_info())
76 threading.Thread.run = run
77
78 SIG_NIL = 'iluvcuteoverload'.encode()
79 """Arbitrary null value for a md5 hash. This value must be changed when the hash value is replaced (size)"""
80
81 O644 = 420
82 """Constant representing the permissions for regular files (0644 raises a syntax error on python 3)"""
83
84 O755 = 493
85 """Constant representing the permissions for executable files (0755 raises a syntax error on python 3)"""
86
87 rot_chr = ['\\', '|', '/', '-']
88 "List of characters to use when displaying the throbber (progress bar)"
89
90 rot_idx = 0
91 "Index of the current throbber character (progress bar)"
92
93 try:
94 from collections import defaultdict
95 except ImportError:
96 class defaultdict(dict):
97 """
98 defaultdict was introduced in python 2.5, so we leave it for python 2.4 and 2.3
99 """
100 def __init__(self, default_factory):
101 super(defaultdict, self).__init__()
102 self.default_factory = default_factory
103 def __getitem__(self, key):
104 try:
105 return super(defaultdict, self).__getitem__(key)
106 except KeyError:
107 value = self.default_factory()
108 self[key] = value
109 return value
110
111 is_win32 = sys.platform in ('win32', 'cli')
112
113 # we should have put this in the Logs.py file instead :-/
114 indicator = '\x1b[K%s%s%s\r'
115 if is_win32 and 'NOCOLOR' in os.environ:
116 indicator = '%s%s%s\r'
117
118 def readf(fname, m='r'):
119 """
120 Read an entire file into a string, in practice the wrapper
121 node.read(..) should be used instead of this method::
122
123 def build(ctx):
124 from waflib import Utils
125 txt = Utils.readf(self.path.find_node('wscript').abspath())
126 txt = ctx.path.find_node('wscript').read()
127
128 :type fname: string
129 :param fname: Path to file
130 :type m: string
131 :param m: Open mode
132 :rtype: string
133 :return: Content of the file
134 """
135 f = open(fname, m)
136 try:
137 txt = f.read()
138 finally:
139 f.close()
140 return txt
141
142 def h_file(filename):
143 """
144 Compute a hash value for a file by using md5. This method may be replaced by
145 a faster version if necessary. The following uses the file size and the timestamp value::
146
147 import stat
148 from waflib import Utils
149 def h_file(filename):
150 st = os.stat(filename)
151 if stat.S_ISDIR(st[stat.ST_MODE]): raise IOError('not a file')
152 m = Utils.md5()
153 m.update(str(st.st_mtime))
154 m.update(str(st.st_size))
155 m.update(filename)
156 return m.digest()
157 Utils.h_file = h_file
158
159 :type filename: string
160 :param filename: path to the file to hash
161 :return: hash of the file contents
162 """
163 f = open(filename, 'rb')
164 m = md5()
165 try:
166 while filename:
167 filename = f.read(100000)
168 m.update(filename)
169 finally:
170 f.close()
171 return m.digest()
172
173 try:
174 x = ''.encode('hex')
175 except:
176 import binascii
177 def to_hex(s):
178 ret = binascii.hexlify(s)
179 if not isinstance(ret, str):
180 ret = ret.decode('utf-8')
181 return ret
182 else:
183 def to_hex(s):
184 return s.encode('hex')
185
186 to_hex.__doc__ = """
187 Return the hexadecimal representation of a string
188
189 :param s: string to convert
190 :type s: string
191 """
192
193 listdir = os.listdir
194 if is_win32:
195 def listdir_win32(s):
196 """
197 List the contents of a folder in a portable manner.
198
199 :type s: string
200 :param s: a string, which can be empty on Windows for listing the drive letters
201 """
202 if not s:
203 try:
204 import ctypes
205 except:
206 # there is nothing much we can do
207 return [x + ':\\' for x in list('ABCDEFGHIJKLMNOPQRSTUVWXYZ')]
208 else:
209 dlen = 4 # length of "?:\\x00"
210 maxdrives = 26
211 buf = ctypes.create_string_buffer(maxdrives * dlen)
212 ndrives = ctypes.windll.kernel32.GetLogicalDriveStringsA(maxdrives, ctypes.byref(buf))
213 return [ buf.raw[4*i:4*i+3].decode('ascii') for i in range(int(ndrives/dlen)) ]
214
215 if len(s) == 2 and s[1] == ":":
216 s += os.sep
217
218 if not os.path.isdir(s):
219 e = OSError()
220 e.errno = errno.ENOENT
221 raise e
222 return os.listdir(s)
223 listdir = listdir_win32
224
225 def num2ver(ver):
226 """
227 Convert a string, tuple or version number into an integer. The number is supposed to have at most 4 digits::
228
229 from waflib.Utils import num2ver
230 num2ver('1.3.2') == num2ver((1,3,2)) == num2ver((1,3,2,0))
231
232 :type ver: string or tuple of numbers
233 :param ver: a version number
234 """
235 if isinstance(ver, str):
236 ver = tuple(ver.split('.'))
237 if isinstance(ver, tuple):
238 ret = 0
239 for i in range(4):
240 if i < len(ver):
241 ret += 256**(3 - i) * int(ver[i])
242 return ret
243 return ver
244
245 def ex_stack():
246 """
247 Extract the stack to display exceptions
248
249 :return: a string represening the last exception
250 """
251 exc_type, exc_value, tb = sys.exc_info()
252 exc_lines = traceback.format_exception(exc_type, exc_value, tb)
253 return ''.join(exc_lines)
254
255 def to_list(sth):
256 """
257 Convert a string argument to a list by splitting on spaces, and pass
258 through a list argument unchanged::
259
260 from waflib.Utils import to_list
261 lst = to_list("a b c d")
262
263 :param sth: List or a string of items separated by spaces
264 :rtype: list
265 :return: Argument converted to list
266
267 """
268 if isinstance(sth, str):
269 return sth.split()
270 else:
271 return sth
272
273 re_nl = re.compile('\r*\n', re.M)
274 def str_to_dict(txt):
275 """
276 Parse a string with key = value pairs into a dictionary::
277
278 from waflib import Utils
279 x = Utils.str_to_dict('''
280 a = 1
281 b = test
282 ''')
283
284 :type s: string
285 :param s: String to parse
286 :rtype: dict
287 :return: Dictionary containing parsed key-value pairs
288 """
289 tbl = {}
290
291 lines = re_nl.split(txt)
292 for x in lines:
293 x = x.strip()
294 if not x or x.startswith('#') or x.find('=') < 0:
295 continue
296 tmp = x.split('=')
297 tbl[tmp[0].strip()] = '='.join(tmp[1:]).strip()
298 return tbl
299
300 def split_path(path):
301 return path.split('/')
302
303 def split_path_cygwin(path):
304 if path.startswith('//'):
305 ret = path.split('/')[2:]
306 ret[0] = '/' + ret[0]
307 return ret
308 return path.split('/')
309
310 re_sp = re.compile('[/\\\\]')
311 def split_path_win32(path):
312 if path.startswith('\\\\'):
313 ret = re.split(re_sp, path)[2:]
314 ret[0] = '\\' + ret[0]
315 return ret
316 return re.split(re_sp, path)
317
318 if sys.platform == 'cygwin':
319 split_path = split_path_cygwin
320 elif is_win32:
321 split_path = split_path_win32
322
323 split_path.__doc__ = """
324 Split a path by / or \\. This function is not like os.path.split
325
326 :type path: string
327 :param path: path to split
328 :return: list of strings
329 """
330
331 def check_dir(path):
332 """
333 Ensure that a directory exists (similar to ``mkdir -p``).
334
335 :type dir: string
336 :param dir: Path to directory
337 """
338 if not os.path.isdir(path):
339 try:
340 os.makedirs(path)
341 except OSError as e:
342 if not os.path.isdir(path):
343 raise Errors.WafError('Cannot create the folder %r' % path, ex=e)
344
345 def def_attrs(cls, **kw):
346 """
347 Set default attributes on a class instance
348
349 :type cls: class
350 :param cls: the class to update the given attributes in.
351 :type kw: dict
352 :param kw: dictionary of attributes names and values.
353 """
354 for k, v in kw.items():
355 if not hasattr(cls, k):
356 setattr(cls, k, v)
357
358 def quote_define_name(s):
359 """
360 Convert a string to an identifier suitable for C defines.
361
362 :type s: string
363 :param s: String to convert
364 :rtype: string
365 :return: Identifier suitable for C defines
366 """
367 fu = re.compile("[^a-zA-Z0-9]").sub("_", s)
368 fu = fu.upper()
369 return fu
370
371 def h_list(lst):
372 """
373 Hash lists. For tuples, using hash(tup) is much more efficient
374
375 :param lst: list to hash
376 :type lst: list of strings
377 :return: hash of the list
378 """
379 m = md5()
380 m.update(str(lst).encode())
381 return m.digest()
382
383 def h_fun(fun):
384 """
385 Hash functions
386
387 :param fun: function to hash
388 :type fun: function
389 :return: hash of the function
390 """
391 try:
392 return fun.code
393 except AttributeError:
394 try:
395 h = inspect.getsource(fun)
396 except IOError:
397 h = "nocode"
398 try:
399 fun.code = h
400 except AttributeError:
401 pass
402 return h
403
404 reg_subst = re.compile(r"(\\\\)|(\$\$)|\$\{([^}]+)\}")
405 def subst_vars(expr, params):
406 """
407 Replace ${VAR} with the value of VAR taken from a dict or a config set::
408
409 from waflib import Utils
410 s = Utils.subst_vars('${PREFIX}/bin', env)
411
412 :type expr: string
413 :param expr: String to perform substitution on
414 :param params: Dictionary or config set to look up variable values.
415 """
416 def repl_var(m):
417 if m.group(1):
418 return '\\'
419 if m.group(2):
420 return '$'
421 try:
422 # ConfigSet instances may contain lists
423 return params.get_flat(m.group(3))
424 except AttributeError:
425 return params[m.group(3)]
426 return reg_subst.sub(repl_var, expr)
427
428 def destos_to_binfmt(key):
429 """
430 Return the binary format based on the unversioned platform name.
431
432 :param key: platform name
433 :type key: string
434 :return: string representing the binary format
435 """
436 if key == 'darwin':
437 return 'mac-o'
438 elif key in ('win32', 'cygwin', 'uwin', 'msys'):
439 return 'pe'
440 return 'elf'
441
442 def unversioned_sys_platform():
443 """
444 Return the unversioned platform name.
445 Some Python platform names contain versions, that depend on
446 the build environment, e.g. linux2, freebsd6, etc.
447 This returns the name without the version number. Exceptions are
448 os2 and win32, which are returned verbatim.
449
450 :rtype: string
451 :return: Unversioned platform name
452 """
453 s = sys.platform
454 if s == 'java':
455 # The real OS is hidden under the JVM.
456 from java.lang import System
457 s = System.getProperty('os.name')
458 # see http://lopica.sourceforge.net/os.html for a list of possible values
459 if s == 'Mac OS X':
460 return 'darwin'
461 elif s.startswith('Windows '):
462 return 'win32'
463 elif s == 'OS/2':
464 return 'os2'
465 elif s == 'HP-UX':
466 return 'hpux'
467 elif s in ('SunOS', 'Solaris'):
468 return 'sunos'
469 else: s = s.lower()
470
471 # powerpc == darwin for our purposes
472 if s == 'powerpc':
473 return 'darwin'
474 if s == 'win32' or s.endswith('os2') and s != 'sunos2': return s
475 return re.split('\d+$', s)[0]
476
477 def nada(*k, **kw):
478 """
479 A function that does nothing
480
481 :return: None
482 """
483 pass
484
485 class Timer(object):
486 """
487 Simple object for timing the execution of commands.
488 Its string representation is the current time::
489
490 from waflib.Utils import Timer
491 timer = Timer()
492 a_few_operations()
493 s = str(timer)
494 """
495 def __init__(self):
496 self.start_time = datetime.datetime.utcnow()
497
498 def __str__(self):
499 delta = datetime.datetime.utcnow() - self.start_time
500 days = int(delta.days)
501 hours = delta.seconds // 3600
502 minutes = (delta.seconds - hours * 3600) // 60
503 seconds = delta.seconds - hours * 3600 - minutes * 60 + float(delta.microseconds) / 1000 / 1000
504 result = ''
505 if days:
506 result += '%dd' % days
507 if days or hours:
508 result += '%dh' % hours
509 if days or hours or minutes:
510 result += '%dm' % minutes
511 return '%s%.3fs' % (result, seconds)
512
513 if is_win32:
514 old = shutil.copy2
515 def copy2(src, dst):
516 """
517 shutil.copy2 does not copy the file attributes on windows, so we
518 hack into the shutil module to fix the problem
519 """
520 old(src, dst)
521 shutil.copystat(src, dst)
522 setattr(shutil, 'copy2', copy2)
523
524 if os.name == 'java':
525 # Jython cannot disable the gc but they can enable it ... wtf?
526 try:
527 gc.disable()
528 gc.enable()
529 except NotImplementedError:
530 gc.disable = gc.enable
531
532 def read_la_file(path):
533 """
534 Read property files, used by msvc.py
535
536 :param path: file to read
537 :type path: string
538 """
539 sp = re.compile(r'^([^=]+)=\'(.*)\'$')
540 dc = {}
541 for line in readf(path).splitlines():
542 try:
543 _, left, right, _ = sp.split(line.strip())
544 dc[left] = right
545 except ValueError:
546 pass
547 return dc
548
549 def nogc(fun):
550 """
551 Decorator: let a function disable the garbage collector during its execution.
552 It is used in the build context when storing/loading the build cache file (pickle)
553
554 :param fun: function to execute
555 :type fun: function
556 :return: the return value of the function executed
557 """
558 def f(*k, **kw):
559 try:
560 gc.disable()
561 ret = fun(*k, **kw)
562 finally:
563 gc.enable()
564 return ret
565 f.__doc__ = fun.__doc__
566 return f
567
568 def run_once(fun):
569 """
570 Decorator: let a function cache its results, use like this::
571
572 @run_once
573 def foo(k):
574 return 345*2343
575
576 :param fun: function to execute
577 :type fun: function
578 :return: the return value of the function executed
579 """
580 cache = {}
581 def wrap(k):
582 try:
583 return cache[k]
584 except KeyError:
585 ret = fun(k)
586 cache[k] = ret
587 return ret
588 wrap.__cache__ = cache
589 return wrap
590
591 def get_registry_app_path(key, filename):
592 if not winreg:
593 return None
594 try:
595 result = winreg.QueryValue(key, "Software\\Microsoft\\Windows\\CurrentVersion\\App Paths\\%s.exe" % filename[0])
596 except WindowsError:
597 pass
598 else:
599 if os.path.isfile(result):
600 return result
601
0 #!/usr/bin/env python
1 # encoding: utf-8
2 # Thomas Nagy, 2005-2010 (ita)
0 import sys, os
1 try:
2 if not (sys.stderr.isatty() and sys.stdout.isatty()):
3 raise ValueError('not a tty')
4
5 from ctypes import *
6
7 class COORD(Structure):
8 _fields_ = [("X", c_short), ("Y", c_short)]
9
10 class SMALL_RECT(Structure):
11 _fields_ = [("Left", c_short), ("Top", c_short), ("Right", c_short), ("Bottom", c_short)]
12
13 class CONSOLE_SCREEN_BUFFER_INFO(Structure):
14 _fields_ = [("Size", COORD), ("CursorPosition", COORD), ("Attributes", c_short), ("Window", SMALL_RECT), ("MaximumWindowSize", COORD)]
15
16 class CONSOLE_CURSOR_INFO(Structure):
17 _fields_ = [('dwSize',c_ulong), ('bVisible', c_int)]
18
19 sbinfo = CONSOLE_SCREEN_BUFFER_INFO()
20 csinfo = CONSOLE_CURSOR_INFO()
21 hconsole = windll.kernel32.GetStdHandle(-11)
22 windll.kernel32.GetConsoleScreenBufferInfo(hconsole, byref(sbinfo))
23 if sbinfo.Size.X < 9 or sbinfo.Size.Y < 9: raise ValueError('small console')
24 windll.kernel32.GetConsoleCursorInfo(hconsole, byref(csinfo))
25 except Exception:
26 pass
27 else:
28 import re, threading
29
30 is_vista = getattr(sys, "getwindowsversion", None) and sys.getwindowsversion()[0] >= 6
31
32 try:
33 _type = unicode
34 except:
35 _type = str
36
37 to_int = lambda number, default: number and int(number) or default
38 wlock = threading.Lock()
39
40 STD_OUTPUT_HANDLE = -11
41 STD_ERROR_HANDLE = -12
42
43 class AnsiTerm(object):
44 """
45 emulate a vt100 terminal in cmd.exe
46 """
47 def __init__(self):
48 self.encoding = sys.stdout.encoding
49 self.hconsole = windll.kernel32.GetStdHandle(STD_OUTPUT_HANDLE)
50 self.cursor_history = []
51 self.orig_sbinfo = CONSOLE_SCREEN_BUFFER_INFO()
52 self.orig_csinfo = CONSOLE_CURSOR_INFO()
53 windll.kernel32.GetConsoleScreenBufferInfo(self.hconsole, byref(self.orig_sbinfo))
54 windll.kernel32.GetConsoleCursorInfo(hconsole, byref(self.orig_csinfo))
55
56 def screen_buffer_info(self):
57 sbinfo = CONSOLE_SCREEN_BUFFER_INFO()
58 windll.kernel32.GetConsoleScreenBufferInfo(self.hconsole, byref(sbinfo))
59 return sbinfo
60
61 def clear_line(self, param):
62 mode = param and int(param) or 0
63 sbinfo = self.screen_buffer_info()
64 if mode == 1: # Clear from begining of line to cursor position
65 line_start = COORD(0, sbinfo.CursorPosition.Y)
66 line_length = sbinfo.Size.X
67 elif mode == 2: # Clear entire line
68 line_start = COORD(sbinfo.CursorPosition.X, sbinfo.CursorPosition.Y)
69 line_length = sbinfo.Size.X - sbinfo.CursorPosition.X
70 else: # Clear from cursor position to end of line
71 line_start = sbinfo.CursorPosition
72 line_length = sbinfo.Size.X - sbinfo.CursorPosition.X
73 chars_written = c_int()
74 windll.kernel32.FillConsoleOutputCharacterA(self.hconsole, c_wchar(' '), line_length, line_start, byref(chars_written))
75 windll.kernel32.FillConsoleOutputAttribute(self.hconsole, sbinfo.Attributes, line_length, line_start, byref(chars_written))
76
77 def clear_screen(self, param):
78 mode = to_int(param, 0)
79 sbinfo = self.screen_buffer_info()
80 if mode == 1: # Clear from begining of screen to cursor position
81 clear_start = COORD(0, 0)
82 clear_length = sbinfo.CursorPosition.X * sbinfo.CursorPosition.Y
83 elif mode == 2: # Clear entire screen and return cursor to home
84 clear_start = COORD(0, 0)
85 clear_length = sbinfo.Size.X * sbinfo.Size.Y
86 windll.kernel32.SetConsoleCursorPosition(self.hconsole, clear_start)
87 else: # Clear from cursor position to end of screen
88 clear_start = sbinfo.CursorPosition
89 clear_length = ((sbinfo.Size.X - sbinfo.CursorPosition.X) + sbinfo.Size.X * (sbinfo.Size.Y - sbinfo.CursorPosition.Y))
90 chars_written = c_int()
91 windll.kernel32.FillConsoleOutputCharacterA(self.hconsole, c_wchar(' '), clear_length, clear_start, byref(chars_written))
92 windll.kernel32.FillConsoleOutputAttribute(self.hconsole, sbinfo.Attributes, clear_length, clear_start, byref(chars_written))
93
94 def push_cursor(self, param):
95 sbinfo = self.screen_buffer_info()
96 self.cursor_history.append(sbinfo.CursorPosition)
97
98 def pop_cursor(self, param):
99 if self.cursor_history:
100 old_pos = self.cursor_history.pop()
101 windll.kernel32.SetConsoleCursorPosition(self.hconsole, old_pos)
102
103 def set_cursor(self, param):
104 y, sep, x = param.partition(';')
105 x = to_int(x, 1) - 1
106 y = to_int(y, 1) - 1
107 sbinfo = self.screen_buffer_info()
108 new_pos = COORD(
109 min(max(0, x), sbinfo.Size.X),
110 min(max(0, y), sbinfo.Size.Y)
111 )
112 windll.kernel32.SetConsoleCursorPosition(self.hconsole, new_pos)
113
114 def set_column(self, param):
115 x = to_int(param, 1) - 1
116 sbinfo = self.screen_buffer_info()
117 new_pos = COORD(
118 min(max(0, x), sbinfo.Size.X),
119 sbinfo.CursorPosition.Y
120 )
121 windll.kernel32.SetConsoleCursorPosition(self.hconsole, new_pos)
122
123 def move_cursor(self, x_offset=0, y_offset=0):
124 sbinfo = self.screen_buffer_info()
125 new_pos = COORD(
126 min(max(0, sbinfo.CursorPosition.X + x_offset), sbinfo.Size.X),
127 min(max(0, sbinfo.CursorPosition.Y + y_offset), sbinfo.Size.Y)
128 )
129 windll.kernel32.SetConsoleCursorPosition(self.hconsole, new_pos)
130
131 def move_up(self, param):
132 self.move_cursor(y_offset = -to_int(param, 1))
133
134 def move_down(self, param):
135 self.move_cursor(y_offset = to_int(param, 1))
136
137 def move_left(self, param):
138 self.move_cursor(x_offset = -to_int(param, 1))
139
140 def move_right(self, param):
141 self.move_cursor(x_offset = to_int(param, 1))
142
143 def next_line(self, param):
144 sbinfo = self.screen_buffer_info()
145 self.move_cursor(
146 x_offset = -sbinfo.CursorPosition.X,
147 y_offset = to_int(param, 1)
148 )
149
150 def prev_line(self, param):
151 sbinfo = self.screen_buffer_info()
152 self.move_cursor(
153 x_offset = -sbinfo.CursorPosition.X,
154 y_offset = -to_int(param, 1)
155 )
156
157 def rgb2bgr(self, c):
158 return ((c&1) << 2) | (c&2) | ((c&4)>>2)
159
160 def set_color(self, param):
161 cols = param.split(';')
162 sbinfo = CONSOLE_SCREEN_BUFFER_INFO()
163 windll.kernel32.GetConsoleScreenBufferInfo(self.hconsole, byref(sbinfo))
164 attr = sbinfo.Attributes
165 for c in cols:
166 if is_vista:
167 c = int(c)
168 else:
169 c = to_int(c, 0)
170 if c in range(30,38): # fgcolor
171 attr = (attr & 0xfff0) | self.rgb2bgr(c-30)
172 elif c in range(40,48): # bgcolor
173 attr = (attr & 0xff0f) | (self.rgb2bgr(c-40) << 4)
174 elif c == 0: # reset
175 attr = self.orig_sbinfo.Attributes
176 elif c == 1: # strong
177 attr |= 0x08
178 elif c == 4: # blink not available -> bg intensity
179 attr |= 0x80
180 elif c == 7: # negative
181 attr = (attr & 0xff88) | ((attr & 0x70) >> 4) | ((attr & 0x07) << 4)
182 windll.kernel32.SetConsoleTextAttribute(self.hconsole, attr)
183
184 def show_cursor(self,param):
185 csinfo.bVisible = 1
186 windll.kernel32.SetConsoleCursorInfo(self.hconsole, byref(csinfo))
187
188 def hide_cursor(self,param):
189 csinfo.bVisible = 0
190 windll.kernel32.SetConsoleCursorInfo(self.hconsole, byref(csinfo))
191
192 ansi_command_table = {
193 'A': move_up,
194 'B': move_down,
195 'C': move_right,
196 'D': move_left,
197 'E': next_line,
198 'F': prev_line,
199 'G': set_column,
200 'H': set_cursor,
201 'f': set_cursor,
202 'J': clear_screen,
203 'K': clear_line,
204 'h': show_cursor,
205 'l': hide_cursor,
206 'm': set_color,
207 's': push_cursor,
208 'u': pop_cursor,
209 }
210 # Match either the escape sequence or text not containing escape sequence
211 ansi_tokens = re.compile('(?:\x1b\[([0-9?;]*)([a-zA-Z])|([^\x1b]+))')
212 def write(self, text):
213 try:
214 wlock.acquire()
215 for param, cmd, txt in self.ansi_tokens.findall(text):
216 if cmd:
217 cmd_func = self.ansi_command_table.get(cmd)
218 if cmd_func:
219 cmd_func(self, param)
220 else:
221 self.writeconsole(txt)
222 finally:
223 wlock.release()
224
225 def writeconsole(self, txt):
226 chars_written = c_int()
227 writeconsole = windll.kernel32.WriteConsoleA
228 if isinstance(txt, _type):
229 writeconsole = windll.kernel32.WriteConsoleW
230
231 TINY_STEP = 3000
232 for x in range(0, len(txt), TINY_STEP):
233 # According MSDN, size should NOT exceed 64 kb (issue #746)
234 tiny = txt[x : x + TINY_STEP]
235 writeconsole(self.hconsole, tiny, len(tiny), byref(chars_written), None)
236
237 def flush(self):
238 pass
239
240 def isatty(self):
241 return True
242
243 sys.stderr = sys.stdout = AnsiTerm()
244 os.environ['TERM'] = 'vt100'
245
0 #!/usr/bin/env python
1 # encoding: utf-8
2 # Thomas Nagy, 2005-2010 (ita)
0 #! /usr/bin/env python
1 # encoding: utf-8
2 # Thomas Nagy, 2011 (ita)
3
4 from waflib import Logs
5 Logs.warn('This tool has been merged to the main library, remove the references to "add_objects"')
6
0 #!/usr/bin/env python
1 # encoding: utf-8
2 # Thomas Nagy, 2006-2010 (ita)
3
4 """
5 Batched builds - compile faster
6 instead of compiling object files one by one, c/c++ compilers are often able to compile at once:
7 cc -c ../file1.c ../file2.c ../file3.c
8
9 Files are output on the directory where the compiler is called, and dependencies are more difficult
10 to track (do not run the command on all source files if only one file changes)
11
12 As such, we do as if the files were compiled one by one, but no command is actually run:
13 replace each cc/cpp Task by a TaskSlave. A new task called TaskMaster collects the
14 signatures from each slave and finds out the command-line to run.
15
16 It is only necessary to import this module in the configuration (no other change required)
17 """
18
19 import os
20 from waflib import TaskGen, Task, Build, Logs
21 from waflib.TaskGen import extension, feature, before_method, after_method
22
23 MAX_BATCH = 50
24
25 c_str = '${CC} ${CFLAGS} ${CPPFLAGS} ${FRAMEWORKPATH_ST:FRAMEWORKPATH} ${CPPPATH_ST:INCPATHS} ${DEFINES_ST:DEFINES} -c ${SRCLST}'
26 #c_str = '${CC} ${CCFLAGS} ${CPPFLAGS} ${_CCINCFLAGS} ${_CCDEFFLAGS} -c ${SRCLST}'
27 c_fun, _ = Task.compile_fun_noshell(c_str)
28
29 cxx_str = '${CXX} ${CXXFLAGS} ${CPPFLAGS} ${FRAMEWORKPATH_ST:FRAMEWORKPATH} ${CPPPATH_ST:INCPATHS} ${DEFINES_ST:DEFINES} -c ${SRCLST}'
30 #cxx_str = '${CXX} ${CXXFLAGS} ${CPPFLAGS} ${_CXXINCFLAGS} ${_CXXDEFFLAGS} -c ${SRCLST}'
31 cxx_fun, _ = Task.compile_fun_noshell(cxx_str)
32
33 count = 70000
34 class batch_task(Task.Task):
35 color = 'RED'
36
37 after = ['c', 'cxx']
38 before = ['cprogram', 'cshlib', 'cstlib', 'cxxprogram', 'cxxshlib', 'cxxstlib']
39
40 def __str__(self):
41 return '(batch compilation for %d slaves)\n' % len(self.slaves)
42
43 def __init__(self, *k, **kw):
44 Task.Task.__init__(self, *k, **kw)
45 self.slaves = []
46 self.inputs = []
47 self.hasrun = 0
48
49 global count
50 count += 1
51 self.idx = count
52
53 def add_slave(self, slave):
54 self.slaves.append(slave)
55 self.set_run_after(slave)
56
57 def runnable_status(self):
58 for t in self.run_after:
59 if not t.hasrun:
60 return Task.ASK_LATER
61
62 for t in self.slaves:
63 #if t.executed:
64 if t.hasrun != Task.SKIPPED:
65 return Task.RUN_ME
66
67 return Task.SKIP_ME
68
69 def run(self):
70 outputs = []
71 self.outputs = []
72
73 srclst = []
74 slaves = []
75 for t in self.slaves:
76 if t.hasrun != Task.SKIPPED:
77 slaves.append(t)
78 srclst.append(t.inputs[0].abspath())
79
80 self.env.SRCLST = srclst
81 self.cwd = slaves[0].inputs[0].parent.get_bld().abspath()
82
83 if self.slaves[0].__class__.__name__ == 'c':
84 ret = c_fun(self)
85 else:
86 ret = cxx_fun(self)
87
88 if ret:
89 return ret
90
91 for t in slaves:
92 t.old_post_run()
93
94 from waflib.Tools import c, cxx
95
96 def hook(name):
97 def n_hook(self, node):
98 task = self.create_task(name, node, node.change_ext('.o'))
99 try:
100 self.compiled_tasks.append(task)
101 except AttributeError:
102 self.compiled_tasks = [task]
103
104 if not getattr(self, 'masters', None):
105 self.masters = {}
106 self.allmasters = []
107
108 if not node.parent in self.masters:
109 m = self.masters[node.parent] = self.master = self.create_task('batch')
110 self.allmasters.append(m)
111 else:
112 m = self.masters[node.parent]
113 if len(m.slaves) > MAX_BATCH:
114 m = self.masters[node.parent] = self.master = self.create_task('batch')
115 self.allmasters.append(m)
116
117 m.add_slave(task)
118 return task
119 return n_hook
120
121 extension('.c')(hook('c'))
122 extension('.cpp','.cc','.cxx','.C','.c++')(hook('cxx'))
123
124 @feature('cprogram', 'cshlib', 'cstaticlib', 'cxxprogram', 'cxxshlib', 'cxxstlib')
125 @after_method('apply_link')
126 def link_after_masters(self):
127 if getattr(self, 'allmasters', None):
128 for m in self.allmasters:
129 self.link_task.set_run_after(m)
130
131 # Modify the c and cxx task classes - in theory it would be better to
132 # create subclasses and to re-map the c/c++ extensions
133 #
134 for x in ['c', 'cxx']:
135 t = Task.classes[x]
136 def run(self):
137 pass
138
139 def post_run(self):
140 #self.executed=1
141 pass
142
143 def can_retrieve_cache(self):
144 if self.old_can_retrieve_cache():
145 for m in self.generator.allmasters:
146 try:
147 m.slaves.remove(self)
148 except ValueError:
149 pass #this task wasn't included in that master
150 return 1
151 else:
152 return None
153
154 setattr(t, 'oldrun', t.__dict__['run'])
155 setattr(t, 'run', run)
156 setattr(t, 'old_post_run', t.post_run)
157 setattr(t, 'post_run', post_run)
158 setattr(t, 'old_can_retrieve_cache', t.can_retrieve_cache)
159 setattr(t, 'can_retrieve_cache', can_retrieve_cache)
160
0 #!/usr/bin/env python
1 # encoding: utf-8
2 # Thomas Nagy, 2011 (ita)
3
4 """
5 Latex processing using "biber"
6 """
7
8 import os
9 from waflib import Task
10 from waflib.Logs import warn
11
12 from waflib.Tools import tex as texmodule
13
14 class tex(texmodule.tex):
15 biber_fun, _ = Task.compile_fun('${BIBER} ${BIBERFLAGS} ${SRCFILE}',shell=False)
16 biber_fun.__doc__ = """
17 Execute the program **biber**
18 """
19
20 def bibfile(self):
21 return None
22
23 def bibunits(self):
24 self.env.env = {}
25 self.env.env.update(os.environ)
26 self.env.env.update({'BIBINPUTS': self.TEXINPUTS, 'BSTINPUTS': self.TEXINPUTS})
27 self.env.SRCFILE = self.aux_node.name[:-4]
28
29 if not self.env['PROMPT_LATEX']:
30 self.env.append_unique('BIBERFLAGS', '--quiet')
31
32 path = self.aux_node.abspath()[:-4] + '.bcf'
33 if os.path.isfile(path):
34 warn('calling biber')
35 self.check_status('error when calling biber, check %s.blg for errors' % (self.env.SRCFILE), self.biber_fun())
36 else:
37 super(tex, self).bibfile()
38 super(tex, self).bibunits()
39
40 class latex(tex):
41 texfun, vars = Task.compile_fun('${LATEX} ${LATEXFLAGS} ${SRCFILE}', shell=False)
42 class pdflatex(tex):
43 texfun, vars = Task.compile_fun('${PDFLATEX} ${PDFLATEXFLAGS} ${SRCFILE}', shell=False)
44 class xelatex(tex):
45 texfun, vars = Task.compile_fun('${XELATEX} ${XELATEXFLAGS} ${SRCFILE}', shell=False)
46
47 def configure(self):
48 """
49 Almost the same as in tex.py, but try to detect 'biber'
50 """
51 v = self.env
52 for p in ' biber tex latex pdflatex xelatex bibtex dvips dvipdf ps2pdf makeindex pdf2ps'.split():
53 try:
54 self.find_program(p, var=p.upper())
55 except self.errors.ConfigurationError:
56 pass
57 v['DVIPSFLAGS'] = '-Ppdf'
58
0 #! /usr/bin/env python
1 # per rosengren 2011
2
3 from waflib.Logs import error,warn,info,debug
4 from waflib.TaskGen import feature, after_method
5 from waflib.Task import Task, always_run
6 from os import sep, readlink
7 from os.path import abspath
8
9 def options(opt):
10 grp = opt.add_option_group('Bjam Options')
11 grp.add_option('--bjam_src', default=None, help='You can find it in <boost root>/tools/jam/src')
12 grp.add_option('--bjam_uname', default='linuxx86_64', help='bjam is built in <src>/bin.<uname>/bjam')
13 grp.add_option('--bjam_config', default=None)
14 grp.add_option('--bjam_toolset', default=None)
15
16 def configure(cnf):
17 if not cnf.env.BJAM_SRC:
18 cnf.env.BJAM_SRC = cnf.options.bjam_src
19 if not cnf.env.BJAM_UNAME:
20 cnf.env.BJAM_UNAME = cnf.options.bjam_uname
21 try:
22 cnf.find_program('bjam', path_list=[
23 cnf.env.BJAM_SRC + sep + 'bin.' + cnf.env.BJAM_UNAME
24 ])
25 except Exception as e:
26 cnf.env.BJAM = None
27 if not cnf.env.BJAM_CONFIG:
28 cnf.env.BJAM_CONFIG = cnf.options.bjam_config
29 if not cnf.env.BJAM_TOOLSET:
30 cnf.env.BJAM_TOOLSET = cnf.options.bjam_toolset
31
32 @feature('bjam')
33 @after_method('process_rule')
34 def process_bjam(self):
35 if not self.bld.env.BJAM:
36 self.create_task('bjam_creator')
37 self.create_task('bjam_build')
38 self.create_task('bjam_installer')
39 if getattr(self, 'always', False):
40 always_run(bjam_creator)
41 always_run(bjam_build)
42 always_run(bjam_installer)
43
44 class bjam_creator(Task):
45 ext_out = 'bjam_exe'
46 vars=['BJAM_SRC', 'BJAM_UNAME']
47 def run(self):
48 env = self.env
49 gen = self.generator
50 path = gen.path
51 bld = gen.bld
52 bjam = gen.bld.root.find_dir(env.BJAM_SRC)
53 if not bjam:
54 error('Can not find bjam source')
55 return -1
56 bjam_exe_relpath = 'bin.' + env.BJAM_UNAME + '/bjam'
57 bjam_exe = bjam.find_resource(bjam_exe_relpath)
58 if bjam_exe:
59 env.BJAM = bjam_exe.srcpath()
60 return 0
61 bjam_cmd = ['./build.sh']
62 debug('runner: ' + bjam.srcpath() + '> ' + str(bjam_cmd))
63 result = self.exec_command(bjam_cmd, cwd=bjam.srcpath())
64 if not result == 0:
65 error('bjam failed')
66 return -1
67 bjam_exe = bjam.find_resource(bjam_exe_relpath)
68 if bjam_exe:
69 env.BJAM = bjam_exe.srcpath()
70 return 0
71 error('bjam failed')
72 return -1
73
74 class bjam_build(Task):
75 ext_in = 'bjam_exe'
76 ext_out = 'install'
77 vars = ['BJAM_TOOLSET']
78 def run(self):
79 env = self.env
80 gen = self.generator
81 path = gen.path
82 bld = gen.bld
83 if hasattr(gen, 'root'):
84 build_root = path.find_node(gen.root)
85 else:
86 build_root = path
87 jam = bld.srcnode.find_resource(env.BJAM_CONFIG)
88 if jam:
89 debug('bjam: Using jam configuration from ' + jam.srcpath())
90 jam_rel = jam.relpath_gen(build_root)
91 else:
92 warn('No build configuration in build_config/user-config.jam. Using default')
93 jam_rel = None
94 bjam_exe = bld.srcnode.find_node(env.BJAM)
95 if not bjam_exe:
96 error('env.BJAM is not set')
97 return -1
98 bjam_exe_rel = bjam_exe.relpath_gen(build_root)
99 cmd = ([bjam_exe_rel] +
100 (['--user-config=' + jam_rel] if jam_rel else []) +
101 ['--stagedir=' + path.get_bld().path_from(build_root)] +
102 ['--debug-configuration'] +
103 ['--with-' + lib for lib in self.generator.target] +
104 (['toolset=' + env.BJAM_TOOLSET] if env.BJAM_TOOLSET else []) +
105 ['link=' + 'shared'] +
106 ['variant=' + 'release']
107 )
108 debug('runner: ' + build_root.srcpath() + '> ' + str(cmd))
109 ret = self.exec_command(cmd, cwd=build_root.srcpath())
110 if ret != 0:
111 return ret
112 self.set_outputs(path.get_bld().ant_glob('lib/*') + path.get_bld().ant_glob('bin/*'))
113 return 0
114
115 class bjam_installer(Task):
116 ext_in = 'install'
117 def run(self):
118 gen = self.generator
119 path = gen.path
120 for idir, pat in [('${LIBDIR}', 'lib/*'), ('${BINDIR}', 'bin/*')]:
121 files = []
122 for n in path.get_bld().ant_glob(pat):
123 try:
124 t = readlink(n.srcpath())
125 gen.bld.symlink_as(sep.join([idir, n.name]), t, postpone=False)
126 except OSError:
127 files.append(n)
128 gen.bld.install_files(idir, files, postpone=False)
129 return 0
130
0 #! /usr/bin/env python
1 # encoding: utf-8
2 # Yannick LM 2011
3
4 """
5 Support for the boo programming language, for example::
6
7 bld(features = "boo", # necessary feature
8 source = "src.boo", # list of boo files
9 gen = "world.dll", # target
10 type = "library", # library/exe ("-target:xyz" flag)
11 name = "world" # necessary if the target is referenced by 'use'
12 )
13 """
14
15 from waflib import Task
16 from waflib.Configure import conf
17 from waflib.TaskGen import feature, after, before, extension
18
19 @extension('.boo')
20 def boo_hook(self, node):
21 # Nothing here yet ...
22 # TODO filter the non-boo source files in 'apply_booc' and remove this method
23 pass
24
25 @feature('boo')
26 @before('process_source')
27 def apply_booc(self):
28 """Create a booc task """
29 src_nodes = self.to_nodes(self.source)
30 out_node = self.path.find_or_declare(self.gen)
31
32 self.boo_task = self.create_task('booc', src_nodes, [out_node])
33
34 # Set variables used by the 'booc' task
35 self.boo_task.env.OUT = '-o:%s' % out_node.abspath()
36
37 # type is "exe" by default
38 type = getattr(self, "type", "exe")
39 self.boo_task.env.BOO_TARGET_TYPE = "-target:%s" % type
40
41 @feature('boo')
42 @after('apply_boo')
43 def use_boo(self):
44 """"
45 boo applications honor the **use** keyword::
46 """
47 dep_names = self.to_list(getattr(self, 'use', []))
48 for dep_name in dep_names:
49 dep_task_gen = self.bld.get_tgen_by_name(dep_name)
50 if not dep_task_gen:
51 continue
52 dep_task_gen.post()
53 dep_task = getattr(dep_task_gen, 'boo_task', None)
54 if not dep_task:
55 # Try a cs task:
56 dep_task = getattr(dep_task_gen, 'cs_task', None)
57 if not dep_task:
58 # Try a link task:
59 dep_task = getattr(dep_task, 'link_task', None)
60 if not dep_task:
61 # Abort ...
62 continue
63 self.boo_task.set_run_after(dep_task) # order
64 self.boo_task.dep_nodes.extend(dep_task.outputs) # dependency
65 self.boo_task.env.append_value('BOO_FLAGS', '-reference:%s' % dep_task.outputs[0].abspath())
66
67 class booc(Task.Task):
68 """Compiles .boo files """
69 color = 'YELLOW'
70 run_str = '${BOOC} ${BOO_FLAGS} ${BOO_TARGET_TYPE} ${OUT} ${SRC}'
71
72 @conf
73 def check_booc(self):
74 self.find_program('booc', 'BOOC')
75 self.env.BOO_FLAGS = ['-nologo']
76
77 def configure(self):
78 """Check that booc is available """
79 self.check_booc()
80
0 #!/usr/bin/env python
1 # encoding: utf-8
2 #
3 # partially based on boost.py written by Gernot Vormayr
4 # written by Ruediger Sonderfeld <ruediger@c-plusplus.de>, 2008
5 # modified by Bjoern Michaelsen, 2008
6 # modified by Luca Fossati, 2008
7 # rewritten for waf 1.5.1, Thomas Nagy, 2008
8 # rewritten for waf 1.6.2, Sylvain Rouquette, 2011
9
10 '''
11
12 This is an extra tool, not bundled with the default waf binary.
13 To add the boost tool to the waf file:
14 $ ./waf-light --tools=compat15,boost
15 or, if you have waf >= 1.6.2
16 $ ./waf update --files=boost
17
18 When using this tool, the wscript will look like:
19
20 def options(opt):
21 opt.load('compiler_cxx boost')
22
23 def configure(conf):
24 conf.load('compiler_cxx boost')
25 conf.check_boost(lib='system filesystem')
26
27 def build(bld):
28 bld(source='main.cpp', target='app', use='BOOST')
29
30 Options are generated, in order to specify the location of boost includes/libraries.
31 The `check_boost` configuration function allows to specify the used boost libraries.
32 It can also provide default arguments to the --boost-static and --boost-mt command-line arguments.
33 Everything will be packaged together in a BOOST component that you can use.
34
35 When using MSVC, a lot of compilation flags need to match your BOOST build configuration:
36 - you may have to add /EHsc to your CXXFLAGS or define boost::throw_exception if BOOST_NO_EXCEPTIONS is defined.
37 Errors: C4530
38 - boost libraries will try to be smart and use the (pretty but often not useful) auto-linking feature of MSVC
39 So before calling `conf.check_boost` you might want to disabling by adding:
40 conf.env.DEFINES_BOOST += ['BOOST_ALL_NO_LIB']
41 Errors:
42 - boost might also be compiled with /MT, which links the runtime statically.
43 If you have problems with redefined symbols,
44 self.env['DEFINES_%s' % var] += ['BOOST_ALL_NO_LIB']
45 self.env['CXXFLAGS_%s' % var] += ['/MD', '/EHsc']
46 Passing `--boost-linkage_autodetect` might help ensuring having a correct linkage in some basic cases.
47
48 '''
49
50 import sys
51 import re
52 from waflib import Utils, Logs, Errors
53 from waflib.Configure import conf
54
55 BOOST_LIBS = ['/usr/lib', '/usr/local/lib', '/opt/local/lib', '/sw/lib', '/lib']
56 BOOST_INCLUDES = ['/usr/include', '/usr/local/include', '/opt/local/include', '/sw/include']
57 BOOST_VERSION_FILE = 'boost/version.hpp'
58 BOOST_VERSION_CODE = '''
59 #include <iostream>
60 #include <boost/version.hpp>
61 int main() { std::cout << BOOST_LIB_VERSION << std::endl; }
62 '''
63
64 # toolsets from {boost_dir}/tools/build/v2/tools/common.jam
65 PLATFORM = Utils.unversioned_sys_platform()
66 detect_intel = lambda env: (PLATFORM == 'win32') and 'iw' or 'il'
67 detect_clang = lambda env: (PLATFORM == 'darwin') and 'clang-darwin' or 'clang'
68 detect_mingw = lambda env: (re.search('MinGW', env.CXX[0])) and 'mgw' or 'gcc'
69 BOOST_TOOLSETS = {
70 'borland': 'bcb',
71 'clang': detect_clang,
72 'como': 'como',
73 'cw': 'cw',
74 'darwin': 'xgcc',
75 'edg': 'edg',
76 'g++': detect_mingw,
77 'gcc': detect_mingw,
78 'icpc': detect_intel,
79 'intel': detect_intel,
80 'kcc': 'kcc',
81 'kylix': 'bck',
82 'mipspro': 'mp',
83 'mingw': 'mgw',
84 'msvc': 'vc',
85 'qcc': 'qcc',
86 'sun': 'sw',
87 'sunc++': 'sw',
88 'tru64cxx': 'tru',
89 'vacpp': 'xlc'
90 }
91
92
93 def options(opt):
94 opt.add_option('--boost-includes', type='string',
95 default='', dest='boost_includes',
96 help='''path to the boost includes root (~boost root)
97 e.g. /path/to/boost_1_47_0''')
98 opt.add_option('--boost-libs', type='string',
99 default='', dest='boost_libs',
100 help='''path to the directory where the boost libs are
101 e.g. /path/to/boost_1_47_0/stage/lib''')
102 opt.add_option('--boost-static', action='store_true',
103 default=False, dest='boost_static',
104 help='link with static boost libraries (.lib/.a)')
105 opt.add_option('--boost-mt', action='store_true',
106 default=False, dest='boost_mt',
107 help='select multi-threaded libraries')
108 opt.add_option('--boost-abi', type='string', default='', dest='boost_abi',
109 help='''select libraries with tags (dgsyp, d for debug),
110 see doc Boost, Getting Started, chapter 6.1''')
111 opt.add_option('--boost-linkage_autodetect', action="store_true", dest='boost_linkage_autodetect',
112 help="auto-detect boost linkage options (don't get used to it / might break other stuff)")
113 opt.add_option('--boost-toolset', type='string',
114 default='', dest='boost_toolset',
115 help='force a toolset e.g. msvc, vc90, \
116 gcc, mingw, mgw45 (default: auto)')
117 py_version = '%d%d' % (sys.version_info[0], sys.version_info[1])
118 opt.add_option('--boost-python', type='string',
119 default=py_version, dest='boost_python',
120 help='select the lib python with this version \
121 (default: %s)' % py_version)
122
123
124 @conf
125 def __boost_get_version_file(self, dir):
126 try:
127 return self.root.find_dir(dir).find_node(BOOST_VERSION_FILE)
128 except:
129 return None
130
131
132 @conf
133 def boost_get_version(self, dir):
134 """silently retrieve the boost version number"""
135 re_but = re.compile('^#define\\s+BOOST_LIB_VERSION\\s+"(.*)"$', re.M)
136 try:
137 val = re_but.search(self.__boost_get_version_file(dir).read()).group(1)
138 except:
139 val = self.check_cxx(fragment=BOOST_VERSION_CODE, includes=[dir], execute=False, define_ret=True)
140 return val
141
142
143 @conf
144 def boost_get_includes(self, *k, **kw):
145 includes = k and k[0] or kw.get('includes', None)
146 if includes and self.__boost_get_version_file(includes):
147 return includes
148 for dir in BOOST_INCLUDES:
149 if self.__boost_get_version_file(dir):
150 return dir
151 if includes:
152 self.fatal('headers not found in %s' % includes)
153 else:
154 self.fatal('headers not found, please provide a --boost-includes argument (see help)')
155
156
157 @conf
158 def boost_get_toolset(self, cc):
159 toolset = cc
160 if not cc:
161 build_platform = Utils.unversioned_sys_platform()
162 if build_platform in BOOST_TOOLSETS:
163 cc = build_platform
164 else:
165 cc = self.env.CXX_NAME
166 if cc in BOOST_TOOLSETS:
167 toolset = BOOST_TOOLSETS[cc]
168 return isinstance(toolset, str) and toolset or toolset(self.env)
169
170
171 @conf
172 def __boost_get_libs_path(self, *k, **kw):
173 ''' return the lib path and all the files in it '''
174 if 'files' in kw:
175 return self.root.find_dir('.'), Utils.to_list(kw['files'])
176 libs = k and k[0] or kw.get('libs', None)
177 if libs:
178 path = self.root.find_dir(libs)
179 files = path.ant_glob('*boost_*')
180 if not libs or not files:
181 for dir in BOOST_LIBS:
182 try:
183 path = self.root.find_dir(dir)
184 files = path.ant_glob('*boost_*')
185 if files:
186 break
187 path = self.root.find_dir(dir + '64')
188 files = path.ant_glob('*boost_*')
189 if files:
190 break
191 except:
192 path = None
193 if not path:
194 if libs:
195 self.fatal('libs not found in %s' % libs)
196 else:
197 self.fatal('libs not found, please provide a --boost-libs argument (see help)')
198
199 self.to_log('Found the boost path in %r with the libraries:' % path)
200 for x in files:
201 self.to_log(' %r' % x)
202 return path, files
203
204 @conf
205 def boost_get_libs(self, *k, **kw):
206 '''
207 return the lib path and the required libs
208 according to the parameters
209 '''
210 path, files = self.__boost_get_libs_path(**kw)
211 t = []
212 if kw.get('mt', False):
213 t.append('mt')
214 if kw.get('abi', None):
215 t.append(kw['abi'])
216 tags = t and '(-%s)+' % '-'.join(t) or ''
217 toolset = self.boost_get_toolset(kw.get('toolset', ''))
218 toolset_pat = '(-%s[0-9]{0,3})+' % toolset
219 version = '(-%s)+' % self.env.BOOST_VERSION
220
221 def find_lib(re_lib, files):
222 for file in files:
223 if re_lib.search(file.name):
224 self.to_log('Found boost lib %s' % file)
225 return file
226 return None
227
228 def format_lib_name(name):
229 if name.startswith('lib'):
230 name = name[3:]
231 return name.split('.')[0]
232
233 libs = []
234 for lib in Utils.to_list(k and k[0] or kw.get('lib', None)):
235 py = (lib == 'python') and '(-py%s)+' % kw['python'] or ''
236 # Trying libraries, from most strict match to least one
237 for pattern in ['boost_%s%s%s%s%s' % (lib, toolset_pat, tags, py, version),
238 'boost_%s%s%s%s' % (lib, tags, py, version),
239 'boost_%s%s%s' % (lib, tags, version),
240 # Give up trying to find the right version
241 'boost_%s%s%s%s' % (lib, toolset_pat, tags, py),
242 'boost_%s%s%s' % (lib, tags, py),
243 'boost_%s%s' % (lib, tags)]:
244 self.to_log('Trying pattern %s' % pattern)
245 file = find_lib(re.compile(pattern), files)
246 if file:
247 libs.append(format_lib_name(file.name))
248 break
249 else:
250 self.fatal('lib %s not found in %s' % (lib, path.abspath()))
251
252 return path.abspath(), libs
253
254
255 @conf
256 def check_boost(self, *k, **kw):
257 """
258 Initialize boost libraries to be used.
259
260 Keywords: you can pass the same parameters as with the command line (without "--boost-").
261 Note that the command line has the priority, and should preferably be used.
262 """
263 if not self.env['CXX']:
264 self.fatal('load a c++ compiler first, conf.load("compiler_cxx")')
265
266 params = {'lib': k and k[0] or kw.get('lib', None)}
267 for key, value in self.options.__dict__.items():
268 if not key.startswith('boost_'):
269 continue
270 key = key[len('boost_'):]
271 params[key] = value and value or kw.get(key, '')
272
273 var = kw.get('uselib_store', 'BOOST')
274
275 self.start_msg('Checking boost includes')
276 self.env['INCLUDES_%s' % var] = inc = self.boost_get_includes(**params)
277 self.env.BOOST_VERSION = self.boost_get_version(inc)
278 self.end_msg(self.env.BOOST_VERSION)
279 if Logs.verbose:
280 Logs.pprint('CYAN', ' path : %s' % self.env['INCLUDES_%s' % var])
281
282 if not params['lib']:
283 return
284 self.start_msg('Checking boost libs')
285 suffix = params.get('static', None) and 'ST' or ''
286 path, libs = self.boost_get_libs(**params)
287 self.env['%sLIBPATH_%s' % (suffix, var)] = [path]
288 self.env['%sLIB_%s' % (suffix, var)] = libs
289 self.end_msg('ok')
290 if Logs.verbose:
291 Logs.pprint('CYAN', ' path : %s' % path)
292 Logs.pprint('CYAN', ' libs : %s' % libs)
293
294
295 def try_link():
296 if 'system' in params['lib']:
297 self.check_cxx(
298 fragment="\n".join([
299 '#include <boost/system/error_code.hpp>',
300 'int main() { boost::system::error_code c; }',
301 ]),
302 use=var,
303 execute=False,
304 )
305 if 'thread' in params['lib']:
306 self.check_cxx(
307 fragment="\n".join([
308 '#include <boost/thread.hpp>',
309 'int main() { boost::thread t; }',
310 ]),
311 use=var,
312 execute=False,
313 )
314
315 if params.get('linkage_autodetect', False):
316 self.start_msg("Attempting to detect boost linkage flags")
317 toolset = self.boost_get_toolset(kw.get('toolset', ''))
318 if toolset in ['vc']:
319 # disable auto-linking feature, causing error LNK1181
320 # because the code wants to be linked against
321 self.env['DEFINES_%s' % var] += ['BOOST_ALL_NO_LIB']
322
323 # if no dlls are present, we guess the .lib files are not stubs
324 has_dlls = False
325 for x in Utils.listdir(path):
326 if x.endswith(self.env.cxxshlib_PATTERN % ''):
327 has_dlls = True
328 break
329 if not has_dlls:
330 self.env['STLIBPATH_%s' % var] = [path]
331 self.env['STLIB_%s' % var] = libs
332 del self.env['LIB_%s' % var]
333 del self.env['LIBPATH_%s' % var]
334
335 # we attempt to play with some known-to-work CXXFLAGS combinations
336 for cxxflags in (['/MD', '/EHsc'], []):
337 self.env.stash()
338 self.env["CXXFLAGS_%s" % var] += cxxflags
339 try:
340 try_link()
341 self.end_msg("ok: winning cxxflags combination: %s" % (self.env["CXXFLAGS_%s" % var]))
342 e = None
343 break
344 except Errors.ConfigurationError as exc:
345 self.env.revert()
346 e = exc
347
348 if e is not None:
349 self.fatal("Could not auto-detect boost linking flags combination, you may report it to boost.py author", ex=e)
350 else:
351 self.fatal("Boost linkage flags auto-detection not implemented (needed ?) for this toolchain")
352 else:
353 self.start_msg('Checking for boost linkage')
354 try:
355 try_link()
356 except Errors.ConfigurationError as e:
357 self.fatal("Could not link against boost libraries using supplied options")
358 self.end_msg('ok')
359
0 #! /usr/bin/env python
1 # encoding: utf-8
2 # harald at klimachs.de
3
4 import os
5 from waflib.Tools import ccroot,ar
6 from waflib.Configure import conf
7
8 from waflib.Tools import xlc # method xlc_common_flags
9 from waflib.Tools.compiler_c import c_compiler
10 c_compiler['linux'].insert(0, 'c_bgxlc')
11
12 @conf
13 def find_bgxlc(conf):
14 cc = conf.find_program(['bgxlc_r','bgxlc'], var='CC')
15 cc = conf.cmd_to_list(cc)
16 conf.get_xlc_version(cc)
17 conf.env.CC = cc
18 conf.env.CC_NAME = 'bgxlc'
19
20 def configure(conf):
21 conf.find_bgxlc()
22 conf.find_ar()
23 conf.xlc_common_flags()
24 conf.env.LINKFLAGS_cshlib = ['-G','-Wl,-bexpfull']
25 conf.env.LINKFLAGS_cprogram = []
26 conf.cc_load_tools()
27 conf.cc_add_flags()
28 conf.link_add_flags()
29
0 #!/usr/bin/env python
1 # encoding: utf-8
2 # Thomas Nagy, 2006-2010 (ita)
3
4 """
5 Dumb C/C++ preprocessor for finding dependencies
6
7 It will look at all include files it can find after removing the comments, so the following
8 will always add the dependency on both "a.h" and "b.h"::
9
10 #include "a.h"
11 #ifdef B
12 #include "b.h"
13 #endif
14 int main() {
15 return 0;
16 }
17
18 To use::
19
20 def configure(conf):
21 conf.load('compiler_c')
22 conf.load('c_dumbpreproc')
23 """
24
25 import re, sys, os, string, traceback
26 from waflib import Logs, Build, Utils, Errors
27 from waflib.Logs import debug, error
28 from waflib.Tools import c_preproc
29
30 re_inc = re.compile(
31 '^[ \t]*(#|%:)[ \t]*(include)[ \t]*[<"](.*)[>"]\r*$',
32 re.IGNORECASE | re.MULTILINE)
33
34 def lines_includes(node):
35 code = node.read()
36 if c_preproc.use_trigraphs:
37 for (a, b) in c_preproc.trig_def: code = code.split(a).join(b)
38 code = c_preproc.re_nl.sub('', code)
39 code = c_preproc.re_cpp.sub(c_preproc.repl, code)
40 return [(m.group(2), m.group(3)) for m in re.finditer(re_inc, code)]
41
42 parser = c_preproc.c_parser
43 class dumb_parser(parser):
44 def addlines(self, node):
45 if node in self.nodes[:-1]:
46 return
47 self.currentnode_stack.append(node.parent)
48 self.lines = lines_includes(node) + [(c_preproc.POPFILE, '')] + self.lines
49
50 def start(self, node, env):
51 self.addlines(node)
52 while self.lines:
53 (x, y) = self.lines.pop(0)
54 if x == c_preproc.POPFILE:
55 self.currentnode_stack.pop()
56 continue
57 self.tryfind(y)
58
59 c_preproc.c_parser = dumb_parser
60
0 #! /usr/bin/env python
1 # encoding: utf-8
2 # Thomas Nagy, 2010 (ita)
3
4 """
5 This file is provided to enable compatibility with waf 1.5, it will be removed in waf 1.7
6 """
7
8 import sys
9 from waflib import ConfigSet, Logs, Options, Scripting, Task, Build, Configure, Node, Runner, TaskGen, Utils, Errors, Context
10
11 # the following is to bring some compatibility with waf 1.5 "import waflib.Configure → import Configure"
12 sys.modules['Environment'] = ConfigSet
13 ConfigSet.Environment = ConfigSet.ConfigSet
14
15 sys.modules['Logs'] = Logs
16 sys.modules['Options'] = Options
17 sys.modules['Scripting'] = Scripting
18 sys.modules['Task'] = Task
19 sys.modules['Build'] = Build
20 sys.modules['Configure'] = Configure
21 sys.modules['Node'] = Node
22 sys.modules['Runner'] = Runner
23 sys.modules['TaskGen'] = TaskGen
24 sys.modules['Utils'] = Utils
25
26 from waflib.Tools import c_preproc
27 sys.modules['preproc'] = c_preproc
28
29 from waflib.Tools import c_config
30 sys.modules['config_c'] = c_config
31
32 ConfigSet.ConfigSet.copy = ConfigSet.ConfigSet.derive
33 ConfigSet.ConfigSet.set_variant = Utils.nada
34
35 Build.BuildContext.add_subdirs = Build.BuildContext.recurse
36 Build.BuildContext.new_task_gen = Build.BuildContext.__call__
37 Build.BuildContext.is_install = 0
38 Node.Node.relpath_gen = Node.Node.path_from
39
40 def name_to_obj(self, s, env=None):
41 Logs.warn('compat: change "name_to_obj(name, env)" by "get_tgen_by_name(name)"')
42 return self.get_tgen_by_name(s)
43 Build.BuildContext.name_to_obj = name_to_obj
44
45 def env_of_name(self, name):
46 try:
47 return self.all_envs[name]
48 except KeyError:
49 Logs.error('no such environment: '+name)
50 return None
51 Build.BuildContext.env_of_name = env_of_name
52
53
54 def set_env_name(self, name, env):
55 self.all_envs[name] = env
56 return env
57 Configure.ConfigurationContext.set_env_name = set_env_name
58
59 def retrieve(self, name, fromenv=None):
60 try:
61 env = self.all_envs[name]
62 except KeyError:
63 env = ConfigSet.ConfigSet()
64 self.prepare_env(env)
65 self.all_envs[name] = env
66 else:
67 if fromenv: Logs.warn("The environment %s may have been configured already" % name)
68 return env
69 Configure.ConfigurationContext.retrieve = retrieve
70
71 Configure.ConfigurationContext.sub_config = Configure.ConfigurationContext.recurse
72 Configure.ConfigurationContext.check_tool = Configure.ConfigurationContext.load
73 Configure.conftest = Configure.conf
74 Configure.ConfigurationError = Errors.ConfigurationError
75
76 Options.OptionsContext.sub_options = Options.OptionsContext.recurse
77 Options.OptionsContext.tool_options = Context.Context.load
78 Options.Handler = Options.OptionsContext
79
80 Task.simple_task_type = Task.task_type_from_func = Task.task_factory
81 Task.TaskBase.classes = Task.classes
82
83 def setitem(self, key, value):
84 if key.startswith('CCFLAGS'):
85 key = key[1:]
86 self.table[key] = value
87 ConfigSet.ConfigSet.__setitem__ = setitem
88
89 @TaskGen.feature('d')
90 @TaskGen.before('apply_incpaths')
91 def old_importpaths(self):
92 if getattr(self, 'importpaths', []):
93 self.includes = self.importpaths
94
95 from waflib import Context
96 eld = Context.load_tool
97 def load_tool(*k, **kw):
98 ret = eld(*k, **kw)
99 if 'set_options' in ret.__dict__:
100 Logs.warn('compat: rename "set_options" to options')
101 ret.options = ret.set_options
102 if 'detect' in ret.__dict__:
103 Logs.warn('compat: rename "detect" to "configure"')
104 ret.configure = ret.detect
105 return ret
106 Context.load_tool = load_tool
107
108 rev = Context.load_module
109 def load_module(path):
110 ret = rev(path)
111 if 'set_options' in ret.__dict__:
112 Logs.warn('compat: rename "set_options" to "options" (%r)' % path)
113 ret.options = ret.set_options
114 if 'srcdir' in ret.__dict__:
115 Logs.warn('compat: rename "srcdir" to "top" (%r)' % path)
116 ret.top = ret.srcdir
117 if 'blddir' in ret.__dict__:
118 Logs.warn('compat: rename "blddir" to "out" (%r)' % path)
119 ret.out = ret.blddir
120 return ret
121 Context.load_module = load_module
122
123 old_post = TaskGen.task_gen.post
124 def post(self):
125 self.features = self.to_list(self.features)
126 if 'cc' in self.features:
127 Logs.warn('compat: the feature cc does not exist anymore (use "c")')
128 self.features.remove('cc')
129 self.features.append('c')
130 if 'cstaticlib' in self.features:
131 Logs.warn('compat: the feature cstaticlib does not exist anymore (use "cstlib" or "cxxstlib")')
132 self.features.remove('cstaticlib')
133 self.features.append(('cxx' in self.features) and 'cxxstlib' or 'cstlib')
134 if getattr(self, 'ccflags', None):
135 Logs.warn('compat: "ccflags" was renamed to "cflags"')
136 self.cflags = self.ccflags
137 return old_post(self)
138 TaskGen.task_gen.post = post
139
140 def waf_version(*k, **kw):
141 Logs.warn('wrong version (waf_version was removed in waf 1.6)')
142 Utils.waf_version = waf_version
143
144
145 import os
146 @TaskGen.feature('c', 'cxx', 'd')
147 @TaskGen.before('apply_incpaths', 'propagate_uselib_vars')
148 @TaskGen.after('apply_link', 'process_source')
149 def apply_uselib_local(self):
150 """
151 process the uselib_local attribute
152 execute after apply_link because of the execution order set on 'link_task'
153 """
154 env = self.env
155 from waflib.Tools.ccroot import stlink_task
156
157 # 1. the case of the libs defined in the project (visit ancestors first)
158 # the ancestors external libraries (uselib) will be prepended
159 self.uselib = self.to_list(getattr(self, 'uselib', []))
160 self.includes = self.to_list(getattr(self, 'includes', []))
161 names = self.to_list(getattr(self, 'uselib_local', []))
162 get = self.bld.get_tgen_by_name
163 seen = set([])
164 tmp = Utils.deque(names) # consume a copy of the list of names
165 if tmp:
166 Logs.warn('compat: "uselib_local" is deprecated, replace by "use"')
167 while tmp:
168 lib_name = tmp.popleft()
169 # visit dependencies only once
170 if lib_name in seen:
171 continue
172
173 y = get(lib_name)
174 y.post()
175 seen.add(lib_name)
176
177 # object has ancestors to process (shared libraries): add them to the end of the list
178 if getattr(y, 'uselib_local', None):
179 for x in self.to_list(getattr(y, 'uselib_local', [])):
180 obj = get(x)
181 obj.post()
182 if getattr(obj, 'link_task', None):
183 if not isinstance(obj.link_task, stlink_task):
184 tmp.append(x)
185
186 # link task and flags
187 if getattr(y, 'link_task', None):
188
189 link_name = y.target[y.target.rfind(os.sep) + 1:]
190 if isinstance(y.link_task, stlink_task):
191 env.append_value('STLIB', [link_name])
192 else:
193 # some linkers can link against programs
194 env.append_value('LIB', [link_name])
195
196 # the order
197 self.link_task.set_run_after(y.link_task)
198
199 # for the recompilation
200 self.link_task.dep_nodes += y.link_task.outputs
201
202 # add the link path too
203 tmp_path = y.link_task.outputs[0].parent.bldpath()
204 if not tmp_path in env['LIBPATH']:
205 env.prepend_value('LIBPATH', [tmp_path])
206
207 # add ancestors uselib too - but only propagate those that have no staticlib defined
208 for v in self.to_list(getattr(y, 'uselib', [])):
209 if not env['STLIB_' + v]:
210 if not v in self.uselib:
211 self.uselib.insert(0, v)
212
213 # if the library task generator provides 'export_includes', add to the include path
214 # the export_includes must be a list of paths relative to the other library
215 if getattr(y, 'export_includes', None):
216 self.includes.extend(y.to_incnodes(y.export_includes))
217
218 @TaskGen.feature('cprogram', 'cxxprogram', 'cstlib', 'cxxstlib', 'cshlib', 'cxxshlib', 'dprogram', 'dstlib', 'dshlib')
219 @TaskGen.after('apply_link')
220 def apply_objdeps(self):
221 "add the .o files produced by some other object files in the same manner as uselib_local"
222 names = getattr(self, 'add_objects', [])
223 if not names:
224 return
225 names = self.to_list(names)
226
227 get = self.bld.get_tgen_by_name
228 seen = []
229 while names:
230 x = names[0]
231
232 # visit dependencies only once
233 if x in seen:
234 names = names[1:]
235 continue
236
237 # object does not exist ?
238 y = get(x)
239
240 # object has ancestors to process first ? update the list of names
241 if getattr(y, 'add_objects', None):
242 added = 0
243 lst = y.to_list(y.add_objects)
244 lst.reverse()
245 for u in lst:
246 if u in seen: continue
247 added = 1
248 names = [u]+names
249 if added: continue # list of names modified, loop
250
251 # safe to process the current object
252 y.post()
253 seen.append(x)
254
255 for t in getattr(y, 'compiled_tasks', []):
256 self.link_task.inputs.extend(t.outputs)
257
258 @TaskGen.after('apply_link')
259 def process_obj_files(self):
260 if not hasattr(self, 'obj_files'):
261 return
262 for x in self.obj_files:
263 node = self.path.find_resource(x)
264 self.link_task.inputs.append(node)
265
266 @TaskGen.taskgen_method
267 def add_obj_file(self, file):
268 """Small example on how to link object files as if they were source
269 obj = bld.create_obj('cc')
270 obj.add_obj_file('foo.o')"""
271 if not hasattr(self, 'obj_files'): self.obj_files = []
272 if not 'process_obj_files' in self.meths: self.meths.append('process_obj_files')
273 self.obj_files.append(file)
274
275
276 old_define = Configure.ConfigurationContext.__dict__['define']
277
278 @Configure.conf
279 def define(self, key, val, quote=True):
280 old_define(self, key, val, quote)
281 if key.startswith('HAVE_'):
282 self.env[key] = 1
283
284 old_undefine = Configure.ConfigurationContext.__dict__['undefine']
285
286 @Configure.conf
287 def undefine(self, key):
288 old_undefine(self, key)
289 if key.startswith('HAVE_'):
290 self.env[key] = 0
291
292 # some people might want to use export_incdirs, but it was renamed
293 def set_incdirs(self, val):
294 Logs.warn('compat: change "export_incdirs" by "export_includes"')
295 self.export_includes = val
296 TaskGen.task_gen.export_incdirs = property(None, set_incdirs)
297
0 #! /usr/bin/env python
1 # encoding: utf-8
2 # Thomas Nagy, 2010
3
4 import re
5
6 import waflib
7 import waflib.Logs as _msg
8 from waflib import Task
9 from waflib.TaskGen import extension, feature, before_method, after_method
10
11 cy_api_pat = re.compile(r'\s*?cdef\s*?(public|api)\w*')
12 re_cyt = re.compile('import\\s(\\w+)\\s*$', re.M)
13
14 @extension('.pyx')
15 def add_cython_file(self, node):
16 """
17 Process a *.pyx* file given in the list of source files. No additional
18 feature is required::
19
20 def build(bld):
21 bld(features='c cshlib pyext', source='main.c foo.pyx', target='app')
22 """
23 ext = '.c'
24 if 'cxx' in self.features:
25 self.env.append_unique('CYTHONFLAGS', '--cplus')
26 ext = '.cc'
27 tsk = self.create_task('cython', node, node.change_ext(ext))
28 self.source += tsk.outputs
29
30 class cython(Task.Task):
31 run_str = '${CYTHON} ${CYTHONFLAGS} -o ${TGT[0].abspath()} ${SRC}'
32 color = 'GREEN'
33
34 vars = ['INCLUDES']
35 """
36 Rebuild whenever the INCLUDES change. The variables such as CYTHONFLAGS will be appended
37 by the metaclass.
38 """
39
40 ext_out = ['.h']
41 """
42 The creation of a .h file is known only after the build has begun, so it is not
43 possible to compute a build order just by looking at the task inputs/outputs.
44 """
45
46 def runnable_status(self):
47 """
48 Perform a double-check to add the headers created by cython
49 to the output nodes. The scanner is executed only when the cython task
50 must be executed (optimization).
51 """
52 ret = super(cython, self).runnable_status()
53 if ret == Task.ASK_LATER:
54 return ret
55 for x in self.generator.bld.raw_deps[self.uid()]:
56 if x.startswith('header:'):
57 self.outputs.append(self.inputs[0].parent.find_or_declare(x.replace('header:', '')))
58 return super(cython, self).runnable_status()
59
60 def scan(self):
61 """
62 Return the dependent files (.pxd) by looking in the include folders.
63 Put the headers to generate in the custom list "bld.raw_deps".
64 To inspect the scanne results use::
65
66 $ waf clean build --zones=deps
67 """
68 txt = self.inputs[0].read()
69
70 mods = []
71 for m in re_cyt.finditer(txt):
72 mods.append(m.group(1))
73
74 _msg.debug("cython: mods %r" % mods)
75 incs = getattr(self.generator, 'cython_includes', [])
76 incs = [self.generator.path.find_dir(x) for x in incs]
77 incs.append(self.inputs[0].parent)
78
79 found = []
80 missing = []
81 for x in mods:
82 for y in incs:
83 k = y.find_resource(x + '.pxd')
84 if k:
85 found.append(k)
86 break
87 else:
88 missing.append(x)
89 _msg.debug("cython: found %r" % found)
90
91 # Now the .h created - store them in bld.raw_deps for later use
92 has_api = False
93 has_public = False
94 for l in txt.splitlines():
95 if cy_api_pat.match(l):
96 if ' api ' in l:
97 has_api = True
98 if ' public ' in l:
99 has_public = True
100 name = self.inputs[0].name.replace('.pyx', '')
101 if has_api:
102 missing.append('header:%s_api.h' % name)
103 if has_public:
104 missing.append('header:%s.h' % name)
105
106 return (found, missing)
107
108 def options(ctx):
109 ctx.add_option('--cython-flags', action='store', default='', help='space separated list of flags to pass to cython')
110
111 def configure(ctx):
112 if not ctx.env.CC and not ctx.env.CXX:
113 ctx.fatal('Load a C/C++ compiler first')
114 if not ctx.env.PYTHON:
115 ctx.fatal('Load the python tool first!')
116 ctx.find_program('cython', var='CYTHON')
117 if ctx.options.cython_flags:
118 ctx.env.CYTHONFLAGS = ctx.options.cython_flags
119
0 #!/usr/bin/env python
1 # encoding: utf-8
2 # Jérôme Carretero, 2011 (zougloub)
3
4 from waflib import Configure, Options, Utils
5 from waflib.Tools import ccroot
6 from waflib.Configure import conf
7
8 @conf
9 def find_dcc(conf):
10 cc = conf.find_program(['dcc'], var='CC', path_list=getattr(Options.options, 'diabbindir', ""))
11 cc = conf.cmd_to_list(cc)
12 conf.env.CC_NAME = 'dcc'
13 conf.env.CC = cc
14
15 @conf
16 def find_dld(conf):
17 ld = conf.find_program(['dld'], var='LINK_CC', path_list=getattr(Options.options, 'diabbindir', ""))
18 ld = conf.cmd_to_list(ld)
19 conf.env.LINK_CC_NAME = 'dld'
20 conf.env.LINK_CC = ld
21
22 @conf
23 def find_dar(conf):
24 ar = conf.find_program(['dar'], var='DAR', path_list=getattr(Options.options, 'diabbindir', ""))
25 ar = conf.cmd_to_list(ar)
26 conf.env.AR = ar
27 conf.env.AR_NAME = 'dar'
28 conf.env.ARFLAGS = 'rcs'
29
30 @conf
31 def find_ddump(conf):
32 prg = conf.find_program(['ddump'], var='DDUMP', path_list=getattr(Options.options, 'diabbindir', ""))
33 prg = conf.cmd_to_list(prg)
34 conf.env.DDUMP = prg
35
36 @conf
37 def dcc_common_flags(conf):
38 v = conf.env
39 v['CC_SRC_F'] = []
40 v['CC_TGT_F'] = ['-c', '-o']
41
42 # linker
43 if not v['LINK_CC']: v['LINK_CC'] = v['CC']
44 v['CCLNK_SRC_F'] = []
45 v['CCLNK_TGT_F'] = ['-o']
46 v['CPPPATH_ST'] = '-I%s'
47 v['DEFINES_ST'] = '-D%s'
48
49 v['LIB_ST'] = '-l:%s' # template for adding libs
50 v['LIBPATH_ST'] = '-L%s' # template for adding libpaths
51 v['STLIB_ST'] = '-l:%s'
52 v['STLIBPATH_ST'] = '-L%s'
53 v['RPATH_ST'] = '-Wl,-rpath,%s'
54 #v['STLIB_MARKER'] = '-Wl,-Bstatic'
55
56 # program
57 v['cprogram_PATTERN'] = '%s.elf'
58
59 # static lib
60 v['LINKFLAGS_cstlib'] = ['-Wl,-Bstatic']
61 v['cstlib_PATTERN'] = 'lib%s.a'
62
63 def configure(conf):
64 conf.find_dcc()
65 conf.find_dar()
66 conf.find_dld()
67 conf.find_ddump()
68 conf.dcc_common_flags()
69 conf.cc_load_tools()
70 conf.cc_add_flags()
71 conf.link_add_flags()
72
73 def options(opt):
74 """
75 Add the ``--with-diab-bindir`` command-line options.
76 """
77 opt.add_option('--with-diab-bindir', type='string', dest='diabbindir', help = 'Specify alternate diab bin folder', default="")
78
0 #! /usr/bin/env python
1 # encoding: UTF-8
2 # Thomas Nagy 2008-2010 (ita)
3
4 """
5
6 Doxygen support
7
8 Variables passed to bld():
9 * doxyfile -- the Doxyfile to use
10
11 ported from waf 1.5 (incomplete)
12 """
13
14 from fnmatch import fnmatchcase
15 import os, os.path, re, stat
16 from waflib import Task, Utils, Node, Logs
17 from waflib.TaskGen import feature
18
19 DOXY_STR = '${DOXYGEN} - '
20 DOXY_FMTS = 'html latex man rft xml'.split()
21 DOXY_FILE_PATTERNS = '*.' + ' *.'.join('''
22 c cc cxx cpp c++ java ii ixx ipp i++ inl h hh hxx hpp h++ idl odl cs php php3
23 inc m mm py f90c cc cxx cpp c++ java ii ixx ipp i++ inl h hh hxx
24 '''.split())
25
26 re_nl = re.compile('\\\\\r*\n', re.MULTILINE)
27
28 class doxygen(Task.Task):
29 vars = ['DOXYGEN', 'DOXYFLAGS']
30 color = 'BLUE'
31
32 def runnable_status(self):
33 '''
34 self.pars are populated in runnable_status - because this function is being
35 run *before* both self.pars "consumers" - scan() and run()
36
37 set output_dir (node) for the output
38 '''
39
40 for x in self.run_after:
41 if not x.hasrun:
42 return Task.ASK_LATER
43
44 if not getattr(self, 'pars', None):
45 txt = self.inputs[0].read()
46 txt = re_nl.sub('', txt)
47 self.pars = Utils.str_to_dict(txt)
48 if not self.pars.get('OUTPUT_DIRECTORY'):
49 self.pars['OUTPUT_DIRECTORY'] = self.inputs[0].parent.get_bld().abspath()
50 if not self.pars.get('INPUT'):
51 self.pars['INPUT'] = self.inputs[0].parent.abspath()
52
53 if not getattr(self, 'output_dir', None):
54 self.output_dir = self.generator.bld.root.find_dir(self.pars['OUTPUT_DIRECTORY'])
55
56 self.signature()
57 return Task.Task.runnable_status(self)
58
59 def scan(self):
60 if self.pars.get('RECURSIVE') == 'YES':
61 Logs.warn("Doxygen RECURSIVE dependencies are not supported")
62
63 inputs = self.pars.get('INPUT').split()
64 exclude_patterns = self.pars.get('EXCLUDE_PATTERNS', '').split()
65 file_patterns = self.pars.get('FILE_PATTERNS', '').split()
66 if not file_patterns:
67 file_patterns = DOXY_FILE_PATTERNS
68
69 nodes = []
70 names = []
71 for i in inputs:
72 node = self.generator.bld.root.make_node(i)
73 if node:
74 if os.path.isdir(node.abspath()):
75 for m in node.ant_glob(file_patterns):
76 nodes.append(self.generator.bld.root.make_node(m.abspath()))
77 else:
78 nodes.append(node)
79 else:
80 names.append(i)
81
82 return (nodes, names)
83
84 def run(self):
85 code = '\n'.join(['%s = %s' % (x, self.pars[x]) for x in self.pars])
86 code = code.encode() # for python 3
87 #fmt = DOXY_STR % (self.inputs[0].parent.abspath())
88 cmd = Utils.subst_vars(DOXY_STR, self.env)
89 env = self.env.env or None
90 proc = Utils.subprocess.Popen(cmd, shell=True, stdin=Utils.subprocess.PIPE, env=env)
91 proc.communicate(code)
92 return proc.returncode
93
94 def post_run(self):
95 nodes = self.output_dir.ant_glob('**/*')
96 for x in nodes:
97 x.sig = Utils.h_file(x.abspath())
98 self.outputs += nodes
99 return Task.Task.post_run(self)
100
101 #def install(self):
102 # if getattr(self.generator, 'install_to', None):
103 # update_build_dir(self.inputs[0].parent, self.env)
104 # pattern = getattr(self, 'instype', 'html/*')
105 # self.generator.bld.install_files(self.generator.install_to, self.generator.path.ant_glob(pattern, dir=0, src=0))
106
107 class tar(Task.Task):
108 "quick tar creation"
109 run_str = '${TAR} ${TAROPTS} ${TGT} ${SRC}'
110 color = 'RED'
111 after = ['doxygen']
112 def runnable_status(self):
113 for x in getattr(self, 'input_tasks', []):
114 if not x.hasrun:
115 return Task.ASK_LATER
116
117 if not getattr(self, 'tar_done_adding', None):
118 # execute this only once
119 self.tar_done_adding = True
120 for x in getattr(self, 'input_tasks', []):
121 self.set_inputs(x.outputs)
122 if not self.inputs:
123 return Task.SKIP_ME
124 return Task.Task.runnable_status(self)
125
126 def __str__(self):
127 tgt_str = ' '.join([a.nice_path(self.env) for a in self.outputs])
128 return '%s: %s\n' % (self.__class__.__name__, tgt_str)
129
130 @feature('doxygen')
131 def process_doxy(self):
132 if not getattr(self, 'doxyfile', None):
133 self.generator.bld.fatal('no doxyfile??')
134
135 node = self.doxyfile
136 if not isinstance(node, Node.Node):
137 node = self.path.find_resource(node)
138 if not node:
139 raise ValueError('doxygen file not found')
140
141 # the task instance
142 dsk = self.create_task('doxygen', node)
143
144 if getattr(self, 'doxy_tar', None):
145 tsk = self.create_task('tar')
146 tsk.input_tasks = [dsk]
147 tsk.set_outputs(self.path.find_or_declare(self.doxy_tar))
148 if self.doxy_tar.endswith('bz2'):
149 tsk.env['TAROPTS'] = ['cjf']
150 elif self.doxy_tar.endswith('gz'):
151 tsk.env['TAROPTS'] = ['czf']
152 else:
153 tsk.env['TAROPTS'] = ['cf']
154
155 def configure(conf):
156 conf.find_program('doxygen', var='DOXYGEN')
157 conf.find_program('tar', var='TAR')
158
0 #!/usr/bin/env python
1 # encoding: utf-8
2 # Thomas Nagy, 2006-2010 (ita)
3
4 """
5 Dumb C/C++ preprocessor for finding dependencies
6
7 It will look at all include files it can find after removing the comments, so the following
8 will always add the dependency on both "a.h" and "b.h"::
9
10 #include "a.h"
11 #ifdef B
12 #include "b.h"
13 #endif
14 int main() {
15 return 0;
16 }
17
18 To use::
19
20 def configure(conf):
21 conf.load('compiler_c')
22 conf.load('c_dumbpreproc')
23 """
24
25 import re, sys, os, string, traceback
26 from waflib import Logs, Build, Utils, Errors
27 from waflib.Logs import debug, error
28 from waflib.Tools import c_preproc
29
30 re_inc = re.compile(
31 '^[ \t]*(#|%:)[ \t]*(include)[ \t]*[<"](.*)[>"]\r*$',
32 re.IGNORECASE | re.MULTILINE)
33
34 def lines_includes(node):
35 code = node.read()
36 if c_preproc.use_trigraphs:
37 for (a, b) in c_preproc.trig_def: code = code.split(a).join(b)
38 code = c_preproc.re_nl.sub('', code)
39 code = c_preproc.re_cpp.sub(c_preproc.repl, code)
40 return [(m.group(2), m.group(3)) for m in re.finditer(re_inc, code)]
41
42 parser = c_preproc.c_parser
43 class dumb_parser(parser):
44 def addlines(self, node):
45 if node in self.nodes[:-1]:
46 return
47 self.currentnode_stack.append(node.parent)
48 self.lines = lines_includes(node) + [(c_preproc.POPFILE, '')] + self.lines
49
50 def start(self, node, env):
51 self.addlines(node)
52 while self.lines:
53 (x, y) = self.lines.pop(0)
54 if x == c_preproc.POPFILE:
55 self.currentnode_stack.pop()
56 continue
57 self.tryfind(y)
58
59 c_preproc.c_parser = dumb_parser
60
0 #! /usr/bin/env python
1 # encoding: utf-8
2 # Eclipse CDT 5.0 generator for Waf
3 # Richard Quirk 2009-1011 (New BSD License)
4 # Thomas Nagy 2011 (ported to Waf 1.6)
5
6 """
7 Usage:
8
9 def options(opt):
10 opt.load('eclipse')
11
12 $ waf configure eclipse
13 """
14
15 import sys, os
16 from waflib import Utils, Logs, Context, Options, Build, TaskGen, Scripting
17 from xml.dom.minidom import Document
18
19 oe_cdt = 'org.eclipse.cdt'
20 cdt_mk = oe_cdt + '.make.core'
21 cdt_core = oe_cdt + '.core'
22 cdt_bld = oe_cdt + '.build.core'
23
24 class eclipse(Build.BuildContext):
25 cmd = 'eclipse'
26 fun = Scripting.default_cmd
27
28 def execute(self):
29 """
30 Entry point
31 """
32 self.restore()
33 if not self.all_envs:
34 self.load_envs()
35 self.recurse([self.run_dir])
36
37 appname = getattr(Context.g_module, Context.APPNAME, os.path.basename(self.srcnode.abspath()))
38 self.create_cproject(appname, pythonpath=self.env['ECLIPSE_PYTHON_PATH'])
39
40 def create_cproject(self, appname, workspace_includes=[], pythonpath=[]):
41 """
42 Create the Eclipse CDT .project and .cproject files
43 @param appname The name that will appear in the Project Explorer
44 @param build The BuildContext object to extract includes from
45 @param workspace_includes Optional project includes to prevent
46 "Unresolved Inclusion" errors in the Eclipse editor
47 @param pythonpath Optional project specific python paths
48 """
49 source_dirs = []
50 cpppath = self.env['CPPPATH']
51 Logs.warn('Generating Eclipse CDT project files')
52
53 for g in self.groups:
54 for tg in g:
55 if not isinstance(tg, TaskGen.task_gen):
56 continue
57
58 tg.post()
59 if not getattr(tg, 'link_task', None):
60 continue
61
62 l = Utils.to_list(getattr(tg, "includes", ''))
63 sources = Utils.to_list(getattr(tg, 'source', ''))
64 features = Utils.to_list(getattr(tg, 'features', ''))
65
66 is_cc = 'c' in features or 'cxx' in features
67
68 bldpath = tg.path.bldpath()
69
70 base = os.path.normpath(os.path.join(self.bldnode.name, tg.path.srcpath()))
71
72 if is_cc:
73 sources_dirs = set([src.parent for src in tg.to_nodes(sources)])
74
75 incnodes = tg.to_incnodes(tg.to_list(getattr(tg, 'includes', [])) + tg.env['INCLUDES'])
76 for p in incnodes:
77 path = p.path_from(self.srcnode)
78 workspace_includes.append(path)
79
80 if is_cc and path not in source_dirs:
81 source_dirs.append(path)
82
83 project = self.impl_create_project(sys.executable, appname)
84 self.srcnode.make_node('.project').write(project.toprettyxml())
85
86 waf = os.path.abspath(sys.argv[0])
87 project = self.impl_create_cproject(sys.executable, waf, appname, workspace_includes, cpppath, source_dirs)
88 self.srcnode.make_node('.cproject').write(project.toprettyxml())
89
90 project = self.impl_create_pydevproject(appname, sys.path, pythonpath)
91 self.srcnode.make_node('.pydevproject').write(project.toprettyxml())
92
93 def impl_create_project(self, executable, appname):
94 doc = Document()
95 projectDescription = doc.createElement('projectDescription')
96 self.add(doc, projectDescription, 'name', appname)
97 self.add(doc, projectDescription, 'comment')
98 self.add(doc, projectDescription, 'projects')
99 buildSpec = self.add(doc, projectDescription, 'buildSpec')
100 buildCommand = self.add(doc, buildSpec, 'buildCommand')
101 self.add(doc, buildCommand, 'name', oe_cdt + '.managedbuilder.core.genmakebuilder')
102 self.add(doc, buildCommand, 'triggers', 'clean,full,incremental,')
103 arguments = self.add(doc, buildCommand, 'arguments')
104 # the default make-style targets are overwritten by the .cproject values
105 dictionaries = {
106 cdt_mk + '.contents': cdt_mk + '.activeConfigSettings',
107 cdt_mk + '.enableAutoBuild': 'false',
108 cdt_mk + '.enableCleanBuild': 'true',
109 cdt_mk + '.enableFullBuild': 'true',
110 }
111 for k, v in dictionaries.items():
112 self.addDictionary(doc, arguments, k, v)
113
114 natures = self.add(doc, projectDescription, 'natures')
115 nature_list = """
116 core.ccnature
117 managedbuilder.core.ScannerConfigNature
118 managedbuilder.core.managedBuildNature
119 core.cnature
120 """.split()
121 for n in nature_list:
122 self.add(doc, natures, 'nature', oe_cdt + '.' + n)
123
124 self.add(doc, natures, 'nature', 'org.python.pydev.pythonNature')
125
126 doc.appendChild(projectDescription)
127 return doc
128
129 def impl_create_cproject(self, executable, waf, appname, workspace_includes, cpppath, source_dirs=[]):
130 doc = Document()
131 doc.appendChild(doc.createProcessingInstruction('fileVersion', '4.0.0'))
132 cconf_id = cdt_core + '.default.config.1'
133 cproject = doc.createElement('cproject')
134 storageModule = self.add(doc, cproject, 'storageModule',
135 {'moduleId': cdt_core + '.settings'})
136 cconf = self.add(doc, storageModule, 'cconfiguration', {'id':cconf_id})
137
138 storageModule = self.add(doc, cconf, 'storageModule',
139 {'buildSystemId': oe_cdt + '.managedbuilder.core.configurationDataProvider',
140 'id': cconf_id,
141 'moduleId': cdt_core + '.settings',
142 'name': 'Default'})
143
144 self.add(doc, storageModule, 'externalSettings')
145
146 extensions = self.add(doc, storageModule, 'extensions')
147 extension_list = """
148 VCErrorParser
149 MakeErrorParser
150 GCCErrorParser
151 GASErrorParser
152 GLDErrorParser
153 """.split()
154 ext = self.add(doc, extensions, 'extension',
155 {'id': cdt_core + '.ELF', 'point':cdt_core + '.BinaryParser'})
156 for e in extension_list:
157 ext = self.add(doc, extensions, 'extension',
158 {'id': cdt_core + '.' + e, 'point':cdt_core + '.ErrorParser'})
159
160 storageModule = self.add(doc, cconf, 'storageModule',
161 {'moduleId': 'cdtBuildSystem', 'version': '4.0.0'})
162 config = self.add(doc, storageModule, 'configuration',
163 {'artifactName': appname,
164 'id': cconf_id,
165 'name': 'Default',
166 'parent': cdt_bld + '.prefbase.cfg'})
167 folderInfo = self.add(doc, config, 'folderInfo',
168 {'id': cconf_id+'.', 'name': '/', 'resourcePath': ''})
169
170 toolChain = self.add(doc, folderInfo, 'toolChain',
171 {'id': cdt_bld + '.prefbase.toolchain.1',
172 'name': 'No ToolChain',
173 'resourceTypeBasedDiscovery': 'false',
174 'superClass': cdt_bld + '.prefbase.toolchain'})
175
176 targetPlatform = self.add(doc, toolChain, 'targetPlatform',
177 { 'binaryParser': 'org.eclipse.cdt.core.ELF',
178 'id': cdt_bld + '.prefbase.toolchain.1', 'name': ''})
179
180 waf_build = '"%s" %s'%(waf, eclipse.fun)
181 waf_clean = '"%s" clean'%(waf)
182 builder = self.add(doc, toolChain, 'builder',
183 {'autoBuildTarget': waf_build,
184 'command': executable,
185 'enableAutoBuild': 'false',
186 'cleanBuildTarget': waf_clean,
187 'enableIncrementalBuild': 'true',
188 'id': cdt_bld + '.settings.default.builder.1',
189 'incrementalBuildTarget': waf_build,
190 'managedBuildOn': 'false',
191 'name': 'Gnu Make Builder',
192 'superClass': cdt_bld + '.settings.default.builder'})
193
194 for tool_name in ("Assembly", "GNU C++", "GNU C"):
195 tool = self.add(doc, toolChain, 'tool',
196 {'id': cdt_bld + '.settings.holder.1',
197 'name': tool_name,
198 'superClass': cdt_bld + '.settings.holder'})
199 if cpppath or workspace_includes:
200 incpaths = cdt_bld + '.settings.holder.incpaths'
201 option = self.add(doc, tool, 'option',
202 {'id': incpaths+'.1',
203 'name': 'Include Paths',
204 'superClass': incpaths,
205 'valueType': 'includePath'})
206 for i in workspace_includes:
207 self.add(doc, option, 'listOptionValue',
208 {'builtIn': 'false',
209 'value': '"${workspace_loc:/%s/%s}"'%(appname, i)})
210 for i in cpppath:
211 self.add(doc, option, 'listOptionValue',
212 {'builtIn': 'false',
213 'value': '"%s"'%(i)})
214 if source_dirs:
215 sourceEntries = self.add(doc, config, 'sourceEntries')
216 for i in source_dirs:
217 self.add(doc, sourceEntries, 'entry',
218 {'excluding': i,
219 'flags': 'VALUE_WORKSPACE_PATH|RESOLVED',
220 'kind': 'sourcePath',
221 'name': ''})
222 self.add(doc, sourceEntries, 'entry',
223 {
224 'flags': 'VALUE_WORKSPACE_PATH|RESOLVED',
225 'kind': 'sourcePath',
226 'name': i})
227
228 storageModule = self.add(doc, cconf, 'storageModule',
229 {'moduleId': cdt_mk + '.buildtargets'})
230 buildTargets = self.add(doc, storageModule, 'buildTargets')
231 def addTargetWrap(name, runAll):
232 return self.addTarget(doc, buildTargets, executable, name,
233 '"%s" %s'%(waf, name), runAll)
234 addTargetWrap('configure', True)
235 addTargetWrap('dist', False)
236 addTargetWrap('install', False)
237 addTargetWrap('check', False)
238
239 storageModule = self.add(doc, cproject, 'storageModule',
240 {'moduleId': 'cdtBuildSystem',
241 'version': '4.0.0'})
242
243 project = self.add(doc, storageModule, 'project',
244 {'id': '%s.null.1'%appname, 'name': appname})
245
246 doc.appendChild(cproject)
247 return doc
248
249 def impl_create_pydevproject(self, appname, system_path, user_path):
250 # create a pydevproject file
251 doc = Document()
252 doc.appendChild(doc.createProcessingInstruction('eclipse-pydev', 'version="1.0"'))
253 pydevproject = doc.createElement('pydev_project')
254 prop = self.add(doc, pydevproject,
255 'pydev_property',
256 'python %d.%d'%(sys.version_info[0], sys.version_info[1]))
257 prop.setAttribute('name', 'org.python.pydev.PYTHON_PROJECT_VERSION')
258 prop = self.add(doc, pydevproject, 'pydev_property', 'Default')
259 prop.setAttribute('name', 'org.python.pydev.PYTHON_PROJECT_INTERPRETER')
260 # add waf's paths
261 wafadmin = [p for p in system_path if p.find('wafadmin') != -1]
262 if wafadmin:
263 prop = self.add(doc, pydevproject, 'pydev_pathproperty',
264 {'name':'org.python.pydev.PROJECT_EXTERNAL_SOURCE_PATH'})
265 for i in wafadmin:
266 self.add(doc, prop, 'path', i)
267 if user_path:
268 prop = self.add(doc, pydevproject, 'pydev_pathproperty',
269 {'name':'org.python.pydev.PROJECT_SOURCE_PATH'})
270 for i in user_path:
271 self.add(doc, prop, 'path', '/'+appname+'/'+i)
272
273 doc.appendChild(pydevproject)
274 return doc
275
276 def addDictionary(self, doc, parent, k, v):
277 dictionary = self.add(doc, parent, 'dictionary')
278 self.add(doc, dictionary, 'key', k)
279 self.add(doc, dictionary, 'value', v)
280 return dictionary
281
282 def addTarget(self, doc, buildTargets, executable, name, buildTarget, runAllBuilders=True):
283 target = self.add(doc, buildTargets, 'target',
284 {'name': name,
285 'path': '',
286 'targetID': oe_cdt + '.build.MakeTargetBuilder'})
287 self.add(doc, target, 'buildCommand', executable)
288 self.add(doc, target, 'buildArguments', None)
289 self.add(doc, target, 'buildTarget', buildTarget)
290 self.add(doc, target, 'stopOnError', 'true')
291 self.add(doc, target, 'useDefaultCommand', 'false')
292 self.add(doc, target, 'runAllBuilders', str(runAllBuilders).lower())
293
294 def add(self, doc, parent, tag, value = None):
295 el = doc.createElement(tag)
296 if (value):
297 if type(value) == type(str()):
298 el.appendChild(doc.createTextNode(value))
299 elif type(value) == type(dict()):
300 self.setAttributes(el, value)
301 parent.appendChild(el)
302 return el
303
304 def setAttributes(self, node, attrs):
305 for k, v in attrs.items():
306 node.setAttribute(k, v)
307
0 #!/usr/bin/env python
1 # encoding: utf-8
2 # Thomas Nagy, 2010 (ita)
3
4 """
5 Erlang support
6 """
7
8 from waflib import TaskGen
9
10 TaskGen.declare_chain(name = 'erlc',
11 rule = '${ERLC} ${ERLC_FLAGS} ${SRC[0].abspath()} -o ${TGT[0].name}',
12 ext_in = '.erl',
13 ext_out = '.beam')
14
15 def configure(conf):
16 conf.find_program('erlc', var='ERLC')
17 conf.env.ERLC_FLAGS = []
18
0 #! /usr/bin/env python
1 # encoding: utf-8
2 # harald at klimachs.de
3
4 import re
5 from waflib.Tools import fc, fc_config, fc_scan
6 from waflib.Configure import conf
7
8 from waflib.Tools.compiler_fc import fc_compiler
9 fc_compiler['linux'].insert(0, 'fc_bgxlf')
10
11 @conf
12 def find_bgxlf(conf):
13 fc = conf.find_program(['bgxlf2003_r','bgxlf2003'], var='FC')
14 fc = conf.cmd_to_list(fc)
15 conf.get_xlf_version(fc)
16 conf.env.FC_NAME = 'BGXLF'
17
18 @conf
19 def bg_flags(self):
20 self.env.SONAME_ST = ''
21 self.env.FCSHLIB_MARKER = ''
22 self.env.FCSTLIB_MARKER = ''
23 self.env.FCFLAGS_fcshlib = ['-fPIC']
24 self.env.LINKFLAGS_fcshlib = ['-G', '-Wl,-bexpfull']
25
26 def configure(conf):
27 conf.find_bgxlf()
28 conf.find_ar()
29 conf.fc_flags()
30 conf.xlf_flags()
31 conf.bg_flags()
32
0 #! /usr/bin/env python
1 # encoding: utf-8
2 # harald at klimachs.de
3
4 import re
5 from waflib import Utils
6 from waflib.Tools import fc, fc_config, fc_scan
7 from waflib.Configure import conf
8
9 from waflib.Tools.compiler_fc import fc_compiler
10 fc_compiler['linux'].append('fc_cray')
11
12 @conf
13 def find_crayftn(conf):
14 """Find the Cray fortran compiler (will look in the environment variable 'FC')"""
15 fc = conf.find_program(['crayftn'], var='FC')
16 fc = conf.cmd_to_list(fc)
17 conf.get_crayftn_version(fc)
18 conf.env.FC_NAME = 'CRAY'
19 conf.env.FC_MOD_CAPITALIZATION = 'UPPER.mod'
20
21 @conf
22 def crayftn_flags(conf):
23 v = conf.env
24 v['_FCMODOUTFLAGS'] = ['-em', '-J.'] # enable module files and put them in the current directoy
25 v['FCFLAGS_DEBUG'] = ['-m1'] # more verbose compiler warnings
26 v['FCFLAGS_fcshlib'] = ['-h pic']
27 v['LINKFLAGS_fcshlib'] = ['-h shared']
28
29 v['FCSTLIB_MARKER'] = '-h static'
30 v['FCSHLIB_MARKER'] = '-h dynamic'
31
32 @conf
33 def get_crayftn_version(conf, fc):
34 version_re = re.compile(r"Cray Fortran\s*:\s*Version\s*(?P<major>\d*)\.(?P<minor>\d*)", re.I).search
35 cmd = fc + ['-V']
36 out,err = fc_config.getoutput(conf, cmd, stdin=False)
37 if out: match = version_re(out)
38 else: match = version_re(err)
39 if not match:
40 conf.fatal('Could not determine the Cray Fortran compiler version.')
41 k = match.groupdict()
42 conf.env['FC_VERSION'] = (k['major'], k['minor'])
43
44 def configure(conf):
45 conf.find_crayftn()
46 conf.find_ar()
47 conf.fc_flags()
48 conf.crayftn_flags()
49
0 #! /usr/bin/env python
1 # encoding: utf-8
2 # harald at klimachs.de
3
4 import re
5 from waflib import Utils
6 from waflib.Tools import fc,fc_config,fc_scan
7 from waflib.Configure import conf
8
9 from waflib.Tools.compiler_fc import fc_compiler
10 fc_compiler['linux'].insert(0, 'fc_open64')
11
12 @conf
13 def find_openf95(conf):
14 """Find the Open64 Fortran Compiler (will look in the environment variable 'FC')"""
15
16 fc = conf.find_program(['openf95', 'openf90'], var='FC')
17 fc = conf.cmd_to_list(fc)
18 conf.get_open64_version(fc)
19 conf.env.FC_NAME = 'OPEN64'
20 conf.env.FC_MOD_CAPITALIZATION = 'UPPER.mod'
21
22 @conf
23 def openf95_flags(conf):
24 v = conf.env
25 v['FCFLAGS_DEBUG'] = ['-fullwarn']
26
27 @conf
28 def openf95_modifier_platform(conf):
29 dest_os = conf.env['DEST_OS'] or Utils.unversioned_sys_platform()
30 openf95_modifier_func = getattr(conf, 'openf95_modifier_' + dest_os, None)
31 if openf95_modifier_func:
32 openf95_modifier_func()
33
34 @conf
35 def get_open64_version(conf, fc):
36 """Get the Open64 compiler version"""
37
38 version_re = re.compile(r"Open64 Compiler Suite: *Version *(?P<major>\d*)\.(?P<minor>\d*)", re.I).search
39 cmd = fc + ['-version']
40
41 out, err = fc_config.getoutput(conf,cmd,stdin=False)
42 if out: match = version_re(out)
43 else: match = version_re(err)
44 if not match:
45 conf.fatal('Could not determine the Open64 version.')
46 k = match.groupdict()
47 conf.env['FC_VERSION'] = (k['major'], k['minor'])
48
49 def configure(conf):
50 conf.find_openf95()
51 conf.find_ar()
52 conf.fc_flags()
53 conf.openf95_flags()
54 conf.openf95_modifier_platform()
55
0 #! /usr/bin/env python
1 # encoding: utf-8
2 # harald at klimachs.de
3
4 import re
5 from waflib import Utils
6 from waflib.Tools import fc, fc_config, fc_scan
7 from waflib.Configure import conf
8
9 from waflib.Tools.compiler_fc import fc_compiler
10 fc_compiler['linux'].append('fc_pgfortran')
11
12 @conf
13 def find_pgfortran(conf):
14 """Find the PGI fortran compiler (will look in the environment variable 'FC')"""
15 fc = conf.find_program(['pgfortran', 'pgf95', 'pgf90'], var='FC')
16 fc = conf.cmd_to_list(fc)
17 conf.get_pgfortran_version(fc)
18 conf.env.FC_NAME = 'PGFC'
19
20 @conf
21 def pgfortran_flags(conf):
22 v = conf.env
23 v['FCFLAGS_fcshlib'] = ['-shared']
24 v['FCFLAGS_DEBUG'] = ['-Minform=inform', '-Mstandard'] # why not
25 v['FCSTLIB_MARKER'] = '-Bstatic'
26 v['FCSHLIB_MARKER'] = '-Bdynamic'
27 v['SONAME_ST'] = '-soname %s'
28
29 @conf
30 def get_pgfortran_version(conf,fc):
31 version_re = re.compile(r"The Portland Group", re.I).search
32 cmd = fc + ['-V']
33 out,err = fc_config.getoutput(conf, cmd, stdin=False)
34 if out: match = version_re(out)
35 else: match = version_re(err)
36 if not match:
37 conf.fatal('Could not verify PGI signature')
38 cmd = fc + ['-help=variable']
39 out,err = fc_config.getoutput(conf, cmd, stdin=False)
40 if out.find('COMPVER')<0:
41 conf.fatal('Could not determine the compiler type')
42 k = {}
43 prevk = ''
44 out = out.split('\n')
45 for line in out:
46 lst = line.partition('=')
47 if lst[1] == '=':
48 key = lst[0].rstrip()
49 if key == '': key = prevk
50 val = lst[2].rstrip()
51 k[key] = val
52 else: prevk = line.partition(' ')[0]
53 def isD(var):
54 return var in k
55 def isT(var):
56 return var in k and k[var]!='0'
57 conf.env['FC_VERSION'] = (k['COMPVER'].split('.'))
58
59 def configure(conf):
60 conf.find_pgfortran()
61 conf.find_ar()
62 conf.fc_flags()
63 conf.pgfortran_flags()
64
0 #! /usr/bin/env python
1 # encoding: utf-8
2 # harald at klimachs.de
3
4 import re
5 from waflib import Utils
6 from waflib.Tools import fc,fc_config,fc_scan
7 from waflib.Configure import conf
8
9 from waflib.Tools.compiler_fc import fc_compiler
10 fc_compiler['linux'].append('fc_solstudio')
11
12 @conf
13 def find_solstudio(conf):
14 """Find the Solaris Studio compiler (will look in the environment variable 'FC')"""
15
16 fc = conf.find_program(['sunf95', 'f95', 'sunf90', 'f90'], var='FC')
17 fc = conf.cmd_to_list(fc)
18 conf.get_solstudio_version(fc)
19 conf.env.FC_NAME = 'SOL'
20
21 @conf
22 def solstudio_flags(conf):
23 v = conf.env
24 v['FCFLAGS_fcshlib'] = ['-Kpic']
25 v['FCFLAGS_DEBUG'] = ['-w3']
26 v['LINKFLAGS_fcshlib'] = ['-G']
27 v['FCSTLIB_MARKER'] = '-Bstatic'
28 v['FCSHLIB_MARKER'] = '-Bdynamic'
29 v['SONAME_ST'] = '-h %s'
30
31 @conf
32 def solstudio_modifier_platform(conf):
33 dest_os = conf.env['DEST_OS'] or Utils.unversioned_sys_platform()
34 solstudio_modifier_func = getattr(conf, 'solstudio_modifier_' + dest_os, None)
35 if solstudio_modifier_func:
36 solstudio_modifier_func()
37
38 @conf
39 def get_solstudio_version(conf, fc):
40 """Get the compiler version"""
41
42 version_re = re.compile(r"Sun Fortran 95 *(?P<major>\d*)\.(?P<minor>\d*)", re.I).search
43 cmd = fc + ['-V']
44
45 out, err = fc_config.getoutput(conf,cmd,stdin=False)
46 if out: match = version_re(out)
47 else: match = version_re(err)
48 if not match:
49 conf.fatal('Could not determine the Sun Studio Fortran version.')
50 k = match.groupdict()
51 conf.env['FC_VERSION'] = (k['major'], k['minor'])
52
53 def configure(conf):
54 conf.find_solstudio()
55 conf.find_ar()
56 conf.fc_flags()
57 conf.solstudio_flags()
58 conf.solstudio_modifier_platform()
59
0 #! /usr/bin/env python
1 # encoding: utf-8
2 # harald at klimachs.de
3
4 import re
5 from waflib import Utils
6 from waflib.Tools import fc,fc_config,fc_scan
7 from waflib.Configure import conf
8
9 from waflib.Tools.compiler_fc import fc_compiler
10 fc_compiler['aix'].insert(0, 'fc_xlf')
11
12 @conf
13 def find_xlf(conf):
14 """Find the xlf program (will look in the environment variable 'FC')"""
15
16 fc = conf.find_program(['xlf2003_r', 'xlf2003', 'xlf95_r', 'xlf95', 'xlf90_r', 'xlf90', 'xlf_r', 'xlf'], var='FC')
17 fc = conf.cmd_to_list(fc)
18 conf.get_xlf_version(fc)
19 conf.env.FC_NAME='XLF'
20
21 @conf
22 def xlf_flags(conf):
23 v = conf.env
24 v['FCDEFINES_ST'] = '-WF,-D%s'
25 v['FCFLAGS_fcshlib'] = ['-qpic=small']
26 v['FCFLAGS_DEBUG'] = ['-qhalt=w']
27 v['LINKFLAGS_fcshlib'] = ['-Wl,-shared']
28
29 @conf
30 def xlf_modifier_platform(conf):
31 dest_os = conf.env['DEST_OS'] or Utils.unversioned_sys_platform()
32 xlf_modifier_func = getattr(conf, 'xlf_modifier_' + dest_os, None)
33 if xlf_modifier_func:
34 xlf_modifier_func()
35
36 @conf
37 def get_xlf_version(conf, fc):
38 """Get the compiler version"""
39
40 version_re = re.compile(r"IBM XL Fortran.*, V(?P<major>\d*)\.(?P<minor>\d*)", re.I).search
41 cmd = fc + ['-qversion']
42
43 out, err = fc_config.getoutput(conf,cmd,stdin=False)
44 if out: match = version_re(out)
45 else: match = version_re(err)
46 if not match:
47 conf.fatal('Could not determine the XLF version.')
48 k = match.groupdict()
49 conf.env['FC_VERSION'] = (k['major'], k['minor'])
50
51 def configure(conf):
52 conf.find_xlf()
53 conf.find_ar()
54 conf.fc_flags()
55 conf.xlf_flags()
56 conf.xlf_modifier_platform()
57
0 #!/usr/bin/python
1 # encoding: utf-8
2 # Grygoriy Fuchedzhy 2009
3
4 """
5 Compile fluid files (fltk graphic library). Use the 'fluid' feature in conjuction with the 'cxx' feature.
6 """
7
8 from waflib import Task
9 from waflib.TaskGen import extension
10
11 class fluid(Task.Task):
12 color = 'BLUE'
13 ext_out = ['.h']
14 run_str = '${FLUID} -c -o ${TGT[0].abspath()} -h ${TGT[1].abspath()} ${SRC}'
15
16 @extension('.fl')
17 def fluid(self, node):
18 """add the .fl to the source list; the cxx file generated will be compiled when possible"""
19 cpp = node.change_ext('.cpp')
20 hpp = node.change_ext('.hpp')
21 self.create_task('fluid', node, [cpp, hpp])
22
23 if 'cxx' in self.features:
24 self.source.append(cpp)
25
26 def configure(conf):
27 conf.find_program('fluid', var='FLUID')
28 conf.check_cfg(path='fltk-config', package='', args='--cxxflags --ldflags', uselib_store='FLTK', mandatory=True)
29
0 #!/usr/bin/env python
1 # encoding: utf-8
2 #
3 # written by Sylvain Rouquette, 2011
4
5 '''
6 To add the freeimage tool to the waf file:
7 $ ./waf-light --tools=compat15,freeimage
8 or, if you have waf >= 1.6.2
9 $ ./waf update --files=freeimage
10
11 The wscript will look like:
12
13 def options(opt):
14 opt.load('compiler_cxx freeimage')
15
16 def configure(conf):
17 conf.load('compiler_cxx freeimage')
18
19 # you can call check_freeimage with some parameters.
20 # It's optional on Linux, it's 'mandatory' on Windows if
21 # you didn't use --fi-path on the command-line
22
23 # conf.check_freeimage(path='FreeImage/Dist', fip=True)
24
25 def build(bld):
26 bld(source='main.cpp', target='app', use='FREEIMAGE')
27 '''
28
29 from waflib import Utils
30 from waflib.Configure import conf
31
32
33 def options(opt):
34 opt.add_option('--fi-path', type='string', default='', dest='fi_path',
35 help='''path to the FreeImage directory \
36 where the files are e.g. /FreeImage/Dist''')
37 opt.add_option('--fip', action='store_true', default=False, dest='fip',
38 help='link with FreeImagePlus')
39 opt.add_option('--fi-static', action='store_true',
40 default=False, dest='fi_static',
41 help="link as shared libraries")
42
43
44 @conf
45 def check_freeimage(self, path=None, fip=False):
46 self.start_msg('Checking FreeImage')
47 if not self.env['CXX']:
48 self.fatal('you must load compiler_cxx before loading freeimage')
49 prefix = self.options.fi_static and 'ST' or ''
50 platform = Utils.unversioned_sys_platform()
51 if platform == 'win32':
52 if not path:
53 self.fatal('you must specify the path to FreeImage. \
54 use --fi-path=/FreeImage/Dist')
55 else:
56 self.env['INCLUDES_FREEIMAGE'] = path
57 self.env['%sLIBPATH_FREEIMAGE' % prefix] = path
58 libs = ['FreeImage']
59 if self.options.fip:
60 libs.append('FreeImagePlus')
61 if platform == 'win32':
62 self.env['%sLIB_FREEIMAGE' % prefix] = libs
63 else:
64 self.env['%sLIB_FREEIMAGE' % prefix] = [i.lower() for i in libs]
65 self.end_msg('ok')
66
67
68 def configure(conf):
69 platform = Utils.unversioned_sys_platform()
70 if platform == 'win32' and not conf.options.fi_path:
71 return
72 conf.check_freeimage(conf.options.fi_path, conf.options.fip)
73
0 #! /usr/bin/env python
1 # encoding: utf-8
2 # Thomas Nagy, 2011 (ita)
3
4 """
5 Fully sequential builds
6
7 The previous tasks from task generators are re-processed, and this may lead to speed issues
8 Yet, if you are using this, speed is probably a minor concern
9 """
10
11 from waflib import Build
12
13 def options(opt):
14 pass
15
16 def configure(conf):
17 pass
18
19 class FSBContext(Build.BuildContext):
20 def __call__(self, *k, **kw):
21 ret = Build.BuildContext.__call__(self, *k, **kw)
22
23 # evaluate the results immediately
24 Build.BuildContext.compile(self)
25
26 return ret
27
28 def compile(self):
29 pass
30
0 #!/usr/bin/env python
1 # encoding: utf-8
2 # Thomas Nagy, 2011 (ita)
3
4 """
5 Experimental F# stuff
6
7 FSC="mono /path/to/fsc.exe" waf configure build
8 """
9
10 from waflib import Utils, Task, Options, Logs, Errors
11 from waflib.TaskGen import before_method, after_method, feature
12 from waflib.Tools import ccroot, cs
13 from waflib.Configure import conf
14
15 ccroot.USELIB_VARS['fsc'] = set(['CSFLAGS', 'ASSEMBLIES', 'RESOURCES'])
16
17 @feature('fs')
18 @before_method('process_source')
19 def apply_fsc(self):
20 cs_nodes = []
21 no_nodes = []
22 for x in self.to_nodes(self.source):
23 if x.name.endswith('.fs'):
24 cs_nodes.append(x)
25 else:
26 no_nodes.append(x)
27 self.source = no_nodes
28
29 bintype = getattr(self, 'type', self.gen.endswith('.dll') and 'library' or 'exe')
30 self.cs_task = tsk = self.create_task('fsc', cs_nodes, self.path.find_or_declare(self.gen))
31 tsk.env.CSTYPE = '/target:%s' % bintype
32 tsk.env.OUT = '/out:%s' % tsk.outputs[0].abspath()
33
34 inst_to = getattr(self, 'install_path', bintype=='exe' and '${BINDIR}' or '${LIBDIR}')
35 if inst_to:
36 # note: we are making a copy, so the files added to cs_task.outputs won't be installed automatically
37 mod = getattr(self, 'chmod', bintype=='exe' and Utils.O755 or Utils.O644)
38 self.install_task = self.bld.install_files(inst_to, self.cs_task.outputs[:], env=self.env, chmod=mod)
39
40 feature('fs')(cs.use_cs)
41 after_method('apply_fsc')(cs.use_cs)
42
43 feature('fs')(cs.debug_cs)
44 after_method('apply_fsc', 'use_cs')(cs.debug_cs)
45
46 class fsc(Task.Task):
47 """
48 Compile F# files
49 """
50 color = 'YELLOW'
51 run_str = '${FSC} ${CSTYPE} ${CSFLAGS} ${ASS_ST:ASSEMBLIES} ${RES_ST:RESOURCES} ${OUT} ${SRC}'
52
53 def configure(conf):
54 """
55 Find a F# compiler, set the variable FSC for the compiler and FS_NAME (mono or fsc)
56 """
57 conf.find_program(['fsc.exe', 'fsharpc'], var='FSC')
58 conf.env.FSC = conf.cmd_to_list(conf.env.FSC)
59 conf.env.ASS_ST = '/r:%s'
60 conf.env.RES_ST = '/resource:%s'
61
62 conf.env.CS_NAME = 'fsc'
63 if str(conf.env.FSC).lower().find('fsharpc') > -1:
64 conf.env.CS_NAME = 'mono'
65
0 #!/usr/bin/env python
1 # encoding: utf-8
2 # Thomas Nagy, 2008-2010 (ita)
3
4 """
5 Execute the tasks with gcc -MD, read the dependencies from the .d file
6 and prepare the dependency calculation for the next run
7 """
8
9 import os, re, threading
10 from waflib import Task, Logs, Utils, Errors
11 from waflib.Tools import c_preproc
12 from waflib.TaskGen import before_method, after_method, feature
13
14 lock = threading.Lock()
15
16 preprocessor_flag = '-MD'
17
18 @feature('cc')
19 @before_method('apply_core')
20 def add_mmd_cc(self):
21 if self.env.get_flat('CFLAGS').find(preprocessor_flag) < 0:
22 self.env.append_value('CFLAGS', [preprocessor_flag])
23
24 @feature('cxx')
25 @before_method('apply_core')
26 def add_mmd_cxx(self):
27 if self.env.get_flat('CXXFLAGS').find(preprocessor_flag) < 0:
28 self.env.append_value('CXXFLAGS', [preprocessor_flag])
29
30 def scan(self):
31 "the scanner does not do anything initially"
32 nodes = self.generator.bld.node_deps.get(self.uid(), [])
33 names = []
34 return (nodes, names)
35
36 re_o = re.compile("\.o$")
37 def post_run(self):
38 # The following code is executed by threads, it is not safe, so a lock is needed...
39
40 if getattr(self, 'cached', None):
41 return Task.Task.post_run(self)
42
43 name = self.outputs[0].abspath()
44 name = re_o.sub('.d', name)
45 txt = Utils.readf(name)
46 #os.unlink(name)
47
48 txt = txt.replace('\\\n', '')
49
50 lst = txt.strip().split(':')
51 val = ":".join(lst[1:])
52 val = val.split()
53
54 nodes = []
55 bld = self.generator.bld
56
57 f = re.compile("^(\.\.)[\\/](.*)$")
58 for x in val:
59
60 node = None
61 if os.path.isabs(x):
62
63 if not c_preproc.go_absolute:
64 continue
65
66 lock.acquire()
67 try:
68 node = bld.root.find_resource(x)
69 finally:
70 lock.release()
71 else:
72 path = bld.bldnode
73 x = [k for k in Utils.split_path(x) if k and k != '.']
74 while lst and x[0] == '..':
75 x = x[1:]
76 path = path.parent
77
78 # when calling find_resource, make sure the path does not begin by '..'
79 try:
80 lock.acquire()
81 node = path.find_resource(x)
82 finally:
83 lock.release()
84
85 if not node:
86 raise ValueError('could not find %r for %r' % (x, self))
87 else:
88 if id(node) == id(self.inputs[0]):
89 # ignore the source file, it is already in the dependencies
90 # this way, successful config tests may be retrieved from the cache
91 continue
92
93 nodes.append(node)
94
95 Logs.debug('deps: real scanner for %s returned %s' % (str(self), str(nodes)))
96
97 bld.node_deps[self.uid()] = nodes
98 bld.raw_deps[self.uid()] = []
99
100 try:
101 del self.cache_sig
102 except:
103 pass
104
105 Task.Task.post_run(self)
106
107 def sig_implicit_deps(self):
108 try:
109 return Task.Task.sig_implicit_deps(self)
110 except Errors.WafError:
111 return Utils.SIG_NIL
112
113 for name in 'cc cxx'.split():
114 try:
115 cls = Task.classes[name]
116 except KeyError:
117 pass
118 else:
119 cls.post_run = post_run
120 cls.scan = scan
121 cls.sig_implicit_deps = sig_implicit_deps
122
0 #!/usr/bin/env python
1 # encoding: utf-8
2 # Tom Wambold tom5760 gmail.com 2009
3 # Thomas Nagy 2010
4
5 """
6 Go as a language may look nice, but its toolchain is one of the worse a developer
7 has ever seen. It keeps changing though, and I would like to believe that it will get
8 better eventually, but the crude reality is that this tool and the examples are
9 getting broken every few months.
10
11 If you have been lured into trying to use Go, you should stick to their Makefiles.
12 """
13
14 import os, platform
15
16 from waflib import Utils, Task, TaskGen
17 from waflib.TaskGen import feature, extension, after_method, before_method
18 from waflib.Tools.ccroot import link_task, stlink_task, propagate_uselib_vars, process_use
19
20 class go(Task.Task):
21 run_str = '${GOC} ${GOCFLAGS} ${CPPPATH_ST:INCPATHS} -o ${TGT} ${SRC}'
22
23 class gopackage(stlink_task):
24 run_str = '${GOP} grc ${TGT} ${SRC}'
25
26 class goprogram(link_task):
27 run_str = '${GOL} ${GOLFLAGS} -o ${TGT} ${SRC}'
28 inst_to = '${BINDIR}'
29 chmod = Utils.O755
30
31 class cgopackage(stlink_task):
32 color = 'YELLOW'
33 inst_to = '${LIBDIR}'
34 ext_in = ['.go']
35 ext_out = ['.a']
36
37 def run(self):
38 src_dir = self.generator.bld.path
39 source = self.inputs
40 target = self.outputs[0].change_ext('')
41
42 #print ("--> %s" % self.outputs)
43 #print ('++> %s' % self.outputs[1])
44 bld_dir = self.outputs[1]
45 bld_dir.mkdir()
46 obj_dir = bld_dir.make_node('_obj')
47 obj_dir.mkdir()
48
49 bld_srcs = []
50 for s in source:
51 # FIXME: it seems gomake/cgo stumbles on filenames like a/b/c.go
52 # -> for the time being replace '/' with '_'...
53 #b = bld_dir.make_node(s.path_from(src_dir))
54 b = bld_dir.make_node(s.path_from(src_dir).replace(os.sep,'_'))
55 b.parent.mkdir()
56 #print ('++> %s' % (s.path_from(src_dir),))
57 try:
58 try:os.remove(b.abspath())
59 except Exception:pass
60 os.symlink(s.abspath(), b.abspath())
61 except Exception:
62 # if no support for symlinks, copy the file from src
63 b.write(s.read())
64 bld_srcs.append(b)
65 #print("--|> [%s]" % b.abspath())
66 b.sig = Utils.h_file(b.abspath())
67 pass
68 #self.set_inputs(bld_srcs)
69 #self.generator.bld.raw_deps[self.uid()] = [self.signature()] + bld_srcs
70 makefile_node = bld_dir.make_node("Makefile")
71 makefile_tmpl = '''\
72 # Copyright 2009 The Go Authors. All rights reserved.
73 # Use of this source code is governed by a BSD-style
74 # license that can be found in the LICENSE file. ---
75
76 include $(GOROOT)/src/Make.inc
77
78 TARG=%(target)s
79
80 GCIMPORTS= %(gcimports)s
81
82 CGOFILES=\\
83 \t%(source)s
84
85 CGO_CFLAGS= %(cgo_cflags)s
86
87 CGO_LDFLAGS= %(cgo_ldflags)s
88
89 include $(GOROOT)/src/Make.pkg
90
91 %%: install %%.go
92 $(GC) $*.go
93 $(LD) -o $@ $*.$O
94
95 ''' % {
96 'gcimports': ' '.join(l for l in self.env['GOCFLAGS']),
97 'cgo_cflags' : ' '.join(l for l in self.env['GOCFLAGS']),
98 'cgo_ldflags': ' '.join(l for l in self.env['GOLFLAGS']),
99 'target': target.path_from(obj_dir),
100 'source': ' '.join([b.path_from(bld_dir) for b in bld_srcs])
101 }
102 makefile_node.write(makefile_tmpl)
103 #print ("::makefile: %s"%makefile_node.abspath())
104 cmd = Utils.subst_vars('gomake ${GOMAKE_FLAGS}', self.env).strip()
105 o = self.outputs[0].change_ext('.gomake.log')
106 fout_node = bld_dir.find_or_declare(o.name)
107 fout = open(fout_node.abspath(), 'w')
108 rc = self.generator.bld.exec_command(
109 cmd,
110 stdout=fout,
111 stderr=fout,
112 cwd=bld_dir.abspath(),
113 )
114 if rc != 0:
115 import waflib.Logs as msg
116 msg.error('** error running [%s] (cgo-%s)' % (cmd, target))
117 msg.error(fout_node.read())
118 return rc
119 self.generator.bld.read_stlib(
120 target,
121 paths=[obj_dir.abspath(),],
122 )
123 tgt = self.outputs[0]
124 if tgt.parent != obj_dir:
125 install_dir = os.path.join('${LIBDIR}',
126 tgt.parent.path_from(obj_dir))
127 else:
128 install_dir = '${LIBDIR}'
129 #print('===> %s (%s)' % (tgt.abspath(), install_dir))
130 self.generator.bld.install_files(
131 install_dir,
132 tgt.abspath(),
133 relative_trick=False,
134 postpone=False,
135 )
136 return rc
137
138 @extension('.go')
139 def compile_go(self, node):
140 #print('*'*80, self.name)
141 if not ('cgopackage' in self.features):
142 return self.create_compiled_task('go', node)
143 #print ('compile_go-cgo...')
144 bld_dir = node.parent.get_bld()
145 obj_dir = bld_dir.make_node('_obj')
146 target = obj_dir.make_node(node.change_ext('.a').name)
147 return self.create_task('cgopackage',
148 node,
149 node.change_ext('.a'))
150
151 @feature('gopackage', 'goprogram', 'cgopackage')
152 @before_method('process_source')
153 def go_compiler_is_foobar(self):
154 if self.env.GONAME == 'gcc':
155 return
156 self.source = self.to_nodes(self.source)
157 src = []
158 go = []
159 for node in self.source:
160 if node.name.endswith('.go'):
161 go.append(node)
162 else:
163 src.append(node)
164 self.source = src
165 if not ('cgopackage' in self.features):
166 #print('--> [%s]... (%s)' % (go[0], getattr(self, 'target', 'N/A')))
167 tsk = self.create_compiled_task('go', go[0])
168 tsk.inputs.extend(go[1:])
169 else:
170 #print ('+++ [%s] +++' % self.target)
171 bld_dir = self.path.get_bld().make_node('cgopackage--%s' %
172 self.target.replace(os.sep,'_'))
173 obj_dir = bld_dir.make_node('_obj')
174 target = obj_dir.make_node(self.target+'.a')
175 tsk = self.create_task('cgopackage',
176 go,
177 [target, bld_dir])
178 self.link_task = tsk
179
180 @feature('gopackage', 'goprogram', 'cgopackage')
181 @after_method('process_source', 'apply_incpaths',)
182 def go_local_libs(self):
183 names = self.to_list(getattr(self, 'use', []))
184 #print ('== go-local-libs == [%s] == use: %s' % (self.name, names))
185 for name in names:
186 tg = self.bld.get_tgen_by_name(name)
187 if not tg:
188 raise Utils.WafError('no target of name %r necessary for %r in go uselib local' % (name, self))
189 tg.post()
190 #print ("-- tg[%s]: %s" % (self.name,name))
191 lnk_task = getattr(tg, 'link_task', None)
192 if lnk_task:
193 for tsk in self.tasks:
194 if isinstance(tsk, (go, gopackage, cgopackage)):
195 tsk.set_run_after(lnk_task)
196 tsk.dep_nodes.extend(lnk_task.outputs)
197 path = lnk_task.outputs[0].parent.abspath()
198 if isinstance(lnk_task, (go, gopackage)):
199 # handle hierarchical packages
200 path = lnk_task.generator.path.get_bld().abspath()
201 elif isinstance(lnk_task, (cgopackage,)):
202 # handle hierarchical cgopackages
203 cgo_obj_dir = lnk_task.outputs[1].find_or_declare('_obj')
204 path = cgo_obj_dir.abspath()
205 # recursively add parent GOCFLAGS...
206 self.env.append_unique('GOCFLAGS',
207 getattr(lnk_task.env, 'GOCFLAGS',[]))
208 # ditto for GOLFLAGS...
209 self.env.append_unique('GOLFLAGS',
210 getattr(lnk_task.env, 'GOLFLAGS',[]))
211 self.env.append_unique('GOCFLAGS', ['-I%s' % path])
212 self.env.append_unique('GOLFLAGS', ['-L%s' % path])
213 for n in getattr(tg, 'includes_nodes', []):
214 self.env.append_unique('GOCFLAGS', ['-I%s' % n.abspath()])
215 pass
216 pass
217
218 def configure(conf):
219
220 def set_def(var, val):
221 if not conf.env[var]:
222 conf.env[var] = val
223
224 goarch = os.getenv('GOARCH')
225 if goarch == '386':
226 set_def('GO_PLATFORM', 'i386')
227 elif goarch == 'amd64':
228 set_def('GO_PLATFORM', 'x86_64')
229 elif goarch == 'arm':
230 set_def('GO_PLATFORM', 'arm')
231 else:
232 set_def('GO_PLATFORM', platform.machine())
233
234 if conf.env.GO_PLATFORM == 'x86_64':
235 set_def('GO_COMPILER', '6g')
236 set_def('GO_LINKER', '6l')
237 elif conf.env.GO_PLATFORM in ['i386', 'i486', 'i586', 'i686']:
238 set_def('GO_COMPILER', '8g')
239 set_def('GO_LINKER', '8l')
240 elif conf.env.GO_PLATFORM == 'arm':
241 set_def('GO_COMPILER', '5g')
242 set_def('GO_LINKER', '5l')
243 set_def('GO_EXTENSION', '.5')
244
245 if not (conf.env.GO_COMPILER or conf.env.GO_LINKER):
246 raise conf.fatal('Unsupported platform ' + platform.machine())
247
248 set_def('GO_PACK', 'gopack')
249 set_def('gopackage_PATTERN', '%s.a')
250 set_def('CPPPATH_ST', '-I%s')
251
252 set_def('GOMAKE_FLAGS', ['--quiet'])
253 conf.find_program(conf.env.GO_COMPILER, var='GOC')
254 conf.find_program(conf.env.GO_LINKER, var='GOL')
255 conf.find_program(conf.env.GO_PACK, var='GOP')
256
257 conf.find_program('cgo', var='CGO')
258
259 TaskGen.feature('go')(process_use)
260 TaskGen.feature('go')(propagate_uselib_vars)
261
0 #!/usr/bin/env python
1 # encoding: utf-8
2 # Ali Sabil, 2007
3
4 from waflib import TaskGen
5
6 TaskGen.declare_chain(
7 name = 'gob2',
8 rule = '${GOB2} -o ${TGT[0].bld_dir()} ${GOB2FLAGS} ${SRC}',
9 ext_in = '.gob',
10 ext_out = '.c'
11 )
12
13 def configure(conf):
14 conf.find_program('gob2', var='GOB2')
15 conf.env['GOB2FLAGS'] = ''
16
0 #! /usr/bin/env python
1 # encoding: utf-8
2 # Thomas Nagy, 2011 (ita)
3
4 from waflib.TaskGen import after_method, feature
5
6 @after_method('propagate_uselib_vars')
7 @feature('cprogram', 'cshlib', 'cxxprogram', 'cxxshlib', 'fcprogram', 'fcshlib')
8 def add_rpath_stuff(self):
9 all = self.to_list(getattr(self, 'use', []))
10 while all:
11 name = all.pop()
12 try:
13 tg = self.bld.get_tgen_by_name(name)
14 except:
15 continue
16 self.env.append_value('RPATH', tg.link_task.outputs[0].parent.abspath())
17 all.extend(self.to_list(getattr(tg, 'use', [])))
18
0 #! /usr/bin/env python
1 # encoding: utf-8
2 # Thomas Nagy 2011
3
4 import os, shutil, re
5 from waflib import Options, Build, Logs
6
7 """
8 Apply a least recently used policy to the Waf cache.
9
10 For performance reasons, it is called after the build is complete.
11
12 We assume that the the folders are written atomically
13
14 Do export WAFCACHE=/tmp/foo_xyz where xyz represents the cache size in bytes
15 If missing, the default cache size will be set to 10GB
16 """
17
18 re_num = re.compile('[a-zA-Z_-]+(\d+)')
19
20 CACHESIZE = 10*1024*1024*1024 # in bytes
21 CLEANRATIO = 0.8
22 DIRSIZE = 4096
23
24 def compile(self):
25 if Options.cache_global and not Options.options.nocache:
26 try:
27 os.makedirs(Options.cache_global)
28 except:
29 pass
30
31 try:
32 self.raw_compile()
33 finally:
34 if Options.cache_global and not Options.options.nocache:
35 self.sweep()
36
37 def sweep(self):
38 global CACHESIZE
39 CACHEDIR = Options.cache_global
40
41 # get the cache max size from the WAFCACHE filename
42 re_num = re.compile('[a-zA-Z_]+(\d+)')
43 val = re_num.sub('\\1', os.path.basename(Options.cache_global))
44 try:
45 CACHESIZE = int(val)
46 except:
47 pass
48
49 # map folder names to timestamps
50 flist = {}
51 for x in os.listdir(CACHEDIR):
52 j = os.path.join(CACHEDIR, x)
53 if os.path.isdir(j) and len(x) == 64: # dir names are md5 hexdigests
54 flist[x] = [os.stat(j).st_mtime, 0]
55
56 for (x, v) in flist.items():
57 cnt = DIRSIZE # each entry takes 4kB
58 d = os.path.join(CACHEDIR, x)
59 for k in os.listdir(d):
60 cnt += os.stat(os.path.join(d, k)).st_size
61 flist[x][1] = cnt
62
63 total = sum([x[1] for x in flist.values()])
64 Logs.debug('lru: Cache size is %r' % total)
65
66 if total >= CACHESIZE:
67 Logs.debug('lru: Trimming the cache since %r > %r' % (total, CACHESIZE))
68
69 # make a list to sort the folders by timestamp
70 lst = [(p, v[0], v[1]) for (p, v) in flist.items()]
71 lst.sort(key=lambda x: x[1]) # sort by timestamp
72 lst.reverse()
73
74 while total >= CACHESIZE * CLEANRATIO:
75 (k, t, s) = lst.pop()
76 p = os.path.join(CACHEDIR, k)
77 v = p + '.del'
78 try:
79 os.rename(p, v)
80 except:
81 # someone already did it
82 pass
83 else:
84 try:
85 shutil.rmtree(v)
86 except:
87 # this should not happen, but who knows?
88 Logs.warn('If you ever see this message, report it (%r)' % v)
89 total -= s
90 del flist[k]
91
92 Logs.debug('lru: Total at the end %r' % total)
93
94 Build.BuildContext.raw_compile = Build.BuildContext.compile
95 Build.BuildContext.compile = compile
96 Build.BuildContext.sweep = sweep
97
0 #!/usr/bin/env python
1 # encoding: utf-8
2 # Thomas Nagy, 2011 (ita)
3
4 """
5 A make-like way of executing the build, following the relationships between inputs/outputs
6
7 This algorithm will lead to slower builds, will not be as flexible as "waf build", but
8 it might be useful for building data files (?)
9
10 It is likely to break in the following cases:
11 - files are created dynamically (no inputs or outputs)
12 - headers
13 - building two files from different groups
14 """
15
16 import re
17 from waflib import Options, Task, Logs
18 from waflib.Build import BuildContext
19
20 class MakeContext(BuildContext):
21 '''executes tasks in a step-by-step manner, following dependencies between inputs/outputs'''
22 cmd = 'make'
23 fun = 'build'
24
25 def __init__(self, **kw):
26 super(MakeContext, self).__init__(**kw)
27 self.files = Options.options.files
28
29 def get_build_iterator(self):
30 if not self.files:
31 while 1:
32 yield super(MakeContext, self).get_build_iterator()
33
34 for g in self.groups:
35 for tg in g:
36 try:
37 f = tg.post
38 except AttributeError:
39 pass
40 else:
41 f()
42
43 provides = {}
44 uses = {}
45 all_tasks = []
46 tasks = []
47 for pat in self.files.split(','):
48 matcher = self.get_matcher(pat)
49 for tg in g:
50 if isinstance(tg, Task.TaskBase):
51 lst = [tg]
52 else:
53 lst = tg.tasks
54 for tsk in lst:
55 all_tasks.append(tsk)
56
57 do_exec = False
58 for node in getattr(tsk, 'inputs', []):
59 try:
60 uses[node].append(tsk)
61 except:
62 uses[node] = [tsk]
63
64 if matcher(node, output=False):
65 do_exec = True
66 break
67
68 for node in getattr(tsk, 'outputs', []):
69 try:
70 provides[node].append(tsk)
71 except:
72 provides[node] = [tsk]
73
74 if matcher(node, output=True):
75 do_exec = True
76 break
77 if do_exec:
78 tasks.append(tsk)
79
80 # so we have the tasks that we need to process, the list of all tasks,
81 # the map of the tasks providing nodes, and the map of tasks using nodes
82
83 if not tasks:
84 # if there are no tasks matching, return everything in the current group
85 result = all_tasks
86 else:
87 # this is like a big filter...
88 result = set([])
89 seen = set([])
90 cur = set(tasks)
91 while cur:
92 result |= cur
93 tosee = set([])
94 for tsk in cur:
95 for node in getattr(tsk, 'inputs', []):
96 if node in seen:
97 continue
98 seen.add(node)
99 tosee |= set(provides.get(node, []))
100 cur = tosee
101 result = list(result)
102
103 Task.set_file_constraints(result)
104 Task.set_precedence_constraints(result)
105 yield result
106
107 while 1:
108 yield []
109
110 def get_matcher(self, pat):
111 # this returns a function
112 inn = True
113 out = True
114 if pat.startswith('in:'):
115 out = False
116 pat = pat.replace('in:', '')
117 elif pat.startswith('out:'):
118 inn = False
119 pat = pat.replace('out:', '')
120
121 anode = self.root.find_node(pat)
122 pattern = None
123 if not anode:
124 if not pat.startswith('^'):
125 pat = '^.+?%s' % pat
126 if not pat.endswith('$'):
127 pat = '%s$' % pat
128 pattern = re.compile(pat)
129
130 def match(node, output):
131 if output == True and not out:
132 return False
133 if output == False and not inn:
134 return False
135
136 if anode:
137 return anode == node
138 else:
139 return pattern.match(node.abspath())
140 return match
141
0 #! /usr/bin/env python
1 # encoding: utf-8
2
3 """
4 Store some values on the buildcontext mapping file paths to
5 stat values and md5 values (timestamp + md5)
6 this way the md5 hashes are computed only when timestamp change (can be faster)
7 There is usually little or no gain from enabling this, but it can be used to enable
8 the second level cache with timestamps (WAFCACHE)
9
10 You may have to run distclean or to remove the build directory before enabling/disabling
11 this hashing scheme
12 """
13
14 import os, stat
15 try: import cPickle
16 except: import pickle as cPickle
17 from waflib import Utils, Build, Context
18
19 STRONGEST = True
20 Context.DBFILE += '_md5tstamp'
21
22 Build.hashes_md5_tstamp = {}
23 Build.SAVED_ATTRS.append('hashes_md5_tstamp')
24 def store(self):
25 # save the hash cache as part of the default pickle file
26 self.hashes_md5_tstamp = Build.hashes_md5_tstamp
27 self.store_real()
28 Build.BuildContext.store_real = Build.BuildContext.store
29 Build.BuildContext.store = store
30
31 def restore(self):
32 # we need a module variable for h_file below
33 self.restore_real()
34 try:
35 Build.hashes_md5_tstamp = self.hashes_md5_tstamp or {}
36 except Exception as e:
37 Build.hashes_md5_tstamp = {}
38 Build.BuildContext.restore_real = Build.BuildContext.restore
39 Build.BuildContext.restore = restore
40
41 def h_file(filename):
42 st = os.stat(filename)
43 if stat.S_ISDIR(st[stat.ST_MODE]): raise IOError('not a file')
44
45 if filename in Build.hashes_md5_tstamp:
46 if Build.hashes_md5_tstamp[filename][0] == str(st.st_mtime):
47 return Build.hashes_md5_tstamp[filename][1]
48 m = Utils.md5()
49
50 if STRONGEST:
51 f = open(filename, 'rb')
52 read = 1
53 try:
54 while read:
55 read = f.read(100000)
56 m.update(read)
57 finally:
58 f.close()
59 else:
60 m.update(str(st.st_mtime))
61 m.update(str(st.st_size))
62 m.update(filename)
63
64 # ensure that the cache is overwritten
65 Build.hashes_md5_tstamp[filename] = (str(st.st_mtime), m.digest())
66 return m.digest()
67 Utils.h_file = h_file
68
0 #!/usr/bin/env python
1 # encoding: utf-8
2 # Thomas Nagy, 2006-2010 (ita)
3
4 """
5 This tool is totally deprecated
6
7 Try using:
8 .pc.in files for .pc files
9 the feature intltool_in - see demos/intltool
10 make-like rules
11 """
12
13 import shutil, re, os
14 from waflib import TaskGen, Node, Task, Utils, Build, Errors
15 from waflib.TaskGen import feature, after_method, before_method
16 from waflib.Logs import debug
17
18 def copy_attrs(orig, dest, names, only_if_set=False):
19 """
20 copy class attributes from an object to another
21 """
22 for a in Utils.to_list(names):
23 u = getattr(orig, a, ())
24 if u or not only_if_set:
25 setattr(dest, a, u)
26
27 def copy_func(tsk):
28 "Make a file copy. This might be used to make other kinds of file processing (even calling a compiler is possible)"
29 env = tsk.env
30 infile = tsk.inputs[0].abspath()
31 outfile = tsk.outputs[0].abspath()
32 try:
33 shutil.copy2(infile, outfile)
34 except (OSError, IOError):
35 return 1
36 else:
37 if tsk.chmod: os.chmod(outfile, tsk.chmod)
38 return 0
39
40 def action_process_file_func(tsk):
41 "Ask the function attached to the task to process it"
42 if not tsk.fun: raise Errors.WafError('task must have a function attached to it for copy_func to work!')
43 return tsk.fun(tsk)
44
45 @feature('cmd')
46 def apply_cmd(self):
47 "call a command everytime"
48 if not self.fun: raise Errors.WafError('cmdobj needs a function!')
49 tsk = Task.TaskBase()
50 tsk.fun = self.fun
51 tsk.env = self.env
52 self.tasks.append(tsk)
53 tsk.install_path = self.install_path
54
55 @feature('copy')
56 @before_method('process_source')
57 def apply_copy(self):
58 Utils.def_attrs(self, fun=copy_func)
59 self.default_install_path = 0
60
61 lst = self.to_list(self.source)
62 self.meths.remove('process_source')
63
64 for filename in lst:
65 node = self.path.find_resource(filename)
66 if not node: raise Errors.WafError('cannot find input file %s for processing' % filename)
67
68 target = self.target
69 if not target or len(lst)>1: target = node.name
70
71 # TODO the file path may be incorrect
72 newnode = self.path.find_or_declare(target)
73
74 tsk = self.create_task('copy', node, newnode)
75 tsk.fun = self.fun
76 tsk.chmod = getattr(self, 'chmod', Utils.O644)
77
78 if not tsk.env:
79 tsk.debug()
80 raise Errors.WafError('task without an environment')
81
82 def subst_func(tsk):
83 "Substitutes variables in a .in file"
84
85 m4_re = re.compile('@(\w+)@', re.M)
86
87 code = tsk.inputs[0].read() #Utils.readf(infile)
88
89 # replace all % by %% to prevent errors by % signs in the input file while string formatting
90 code = code.replace('%', '%%')
91
92 s = m4_re.sub(r'%(\1)s', code)
93
94 env = tsk.env
95 di = getattr(tsk, 'dict', {}) or getattr(tsk.generator, 'dict', {})
96 if not di:
97 names = m4_re.findall(code)
98 for i in names:
99 di[i] = env.get_flat(i) or env.get_flat(i.upper())
100
101 tsk.outputs[0].write(s % di)
102
103 @feature('subst')
104 @before_method('process_source')
105 def apply_subst(self):
106 Utils.def_attrs(self, fun=subst_func)
107 lst = self.to_list(self.source)
108 self.meths.remove('process_source')
109
110 self.dict = getattr(self, 'dict', {})
111
112 for filename in lst:
113 node = self.path.find_resource(filename)
114 if not node: raise Errors.WafError('cannot find input file %s for processing' % filename)
115
116 if self.target:
117 newnode = self.path.find_or_declare(self.target)
118 else:
119 newnode = node.change_ext('')
120
121 try:
122 self.dict = self.dict.get_merged_dict()
123 except AttributeError:
124 pass
125
126 if self.dict and not self.env['DICT_HASH']:
127 self.env = self.env.derive()
128 keys = list(self.dict.keys())
129 keys.sort()
130 lst = [self.dict[x] for x in keys]
131 self.env['DICT_HASH'] = str(Utils.h_list(lst))
132
133 tsk = self.create_task('copy', node, newnode)
134 tsk.fun = self.fun
135 tsk.dict = self.dict
136 tsk.dep_vars = ['DICT_HASH']
137 tsk.chmod = getattr(self, 'chmod', Utils.O644)
138
139 if not tsk.env:
140 tsk.debug()
141 raise Errors.WafError('task without an environment')
142
143 ####################
144 ## command-output ####
145 ####################
146
147 class cmd_arg(object):
148 """command-output arguments for representing files or folders"""
149 def __init__(self, name, template='%s'):
150 self.name = name
151 self.template = template
152 self.node = None
153
154 class input_file(cmd_arg):
155 def find_node(self, base_path):
156 assert isinstance(base_path, Node.Node)
157 self.node = base_path.find_resource(self.name)
158 if self.node is None:
159 raise Errors.WafError("Input file %s not found in " % (self.name, base_path))
160
161 def get_path(self, env, absolute):
162 if absolute:
163 return self.template % self.node.abspath()
164 else:
165 return self.template % self.node.srcpath()
166
167 class output_file(cmd_arg):
168 def find_node(self, base_path):
169 assert isinstance(base_path, Node.Node)
170 self.node = base_path.find_or_declare(self.name)
171 if self.node is None:
172 raise Errors.WafError("Output file %s not found in " % (self.name, base_path))
173
174 def get_path(self, env, absolute):
175 if absolute:
176 return self.template % self.node.abspath()
177 else:
178 return self.template % self.node.bldpath()
179
180 class cmd_dir_arg(cmd_arg):
181 def find_node(self, base_path):
182 assert isinstance(base_path, Node.Node)
183 self.node = base_path.find_dir(self.name)
184 if self.node is None:
185 raise Errors.WafError("Directory %s not found in " % (self.name, base_path))
186
187 class input_dir(cmd_dir_arg):
188 def get_path(self, dummy_env, dummy_absolute):
189 return self.template % self.node.abspath()
190
191 class output_dir(cmd_dir_arg):
192 def get_path(self, env, dummy_absolute):
193 return self.template % self.node.abspath()
194
195
196 class command_output(Task.Task):
197 color = "BLUE"
198 def __init__(self, env, command, command_node, command_args, stdin, stdout, cwd, os_env, stderr):
199 Task.Task.__init__(self, env=env)
200 assert isinstance(command, (str, Node.Node))
201 self.command = command
202 self.command_args = command_args
203 self.stdin = stdin
204 self.stdout = stdout
205 self.cwd = cwd
206 self.os_env = os_env
207 self.stderr = stderr
208
209 if command_node is not None: self.dep_nodes = [command_node]
210 self.dep_vars = [] # additional environment variables to look
211
212 def run(self):
213 task = self
214 #assert len(task.inputs) > 0
215
216 def input_path(node, template):
217 if task.cwd is None:
218 return template % node.bldpath()
219 else:
220 return template % node.abspath()
221 def output_path(node, template):
222 fun = node.abspath
223 if task.cwd is None: fun = node.bldpath
224 return template % fun()
225
226 if isinstance(task.command, Node.Node):
227 argv = [input_path(task.command, '%s')]
228 else:
229 argv = [task.command]
230
231 for arg in task.command_args:
232 if isinstance(arg, str):
233 argv.append(arg)
234 else:
235 assert isinstance(arg, cmd_arg)
236 argv.append(arg.get_path(task.env, (task.cwd is not None)))
237
238 if task.stdin:
239 stdin = open(input_path(task.stdin, '%s'))
240 else:
241 stdin = None
242
243 if task.stdout:
244 stdout = open(output_path(task.stdout, '%s'), "w")
245 else:
246 stdout = None
247
248 if task.stderr:
249 stderr = open(output_path(task.stderr, '%s'), "w")
250 else:
251 stderr = None
252
253 if task.cwd is None:
254 cwd = ('None (actually %r)' % os.getcwd())
255 else:
256 cwd = repr(task.cwd)
257 debug("command-output: cwd=%s, stdin=%r, stdout=%r, argv=%r" %
258 (cwd, stdin, stdout, argv))
259
260 if task.os_env is None:
261 os_env = os.environ
262 else:
263 os_env = task.os_env
264 command = Utils.subprocess.Popen(argv, stdin=stdin, stdout=stdout, stderr=stderr, cwd=task.cwd, env=os_env)
265 return command.wait()
266
267 @feature('command-output')
268 def init_cmd_output(self):
269 Utils.def_attrs(self,
270 stdin = None,
271 stdout = None,
272 stderr = None,
273 # the command to execute
274 command = None,
275
276 # whether it is an external command; otherwise it is assumed
277 # to be an executable binary or script that lives in the
278 # source or build tree.
279 command_is_external = False,
280
281 # extra parameters (argv) to pass to the command (excluding
282 # the command itself)
283 argv = [],
284
285 # dependencies to other objects -> this is probably not what you want (ita)
286 # values must be 'task_gen' instances (not names!)
287 dependencies = [],
288
289 # dependencies on env variable contents
290 dep_vars = [],
291
292 # input files that are implicit, i.e. they are not
293 # stdin, nor are they mentioned explicitly in argv
294 hidden_inputs = [],
295
296 # output files that are implicit, i.e. they are not
297 # stdout, nor are they mentioned explicitly in argv
298 hidden_outputs = [],
299
300 # change the subprocess to this cwd (must use obj.input_dir() or output_dir() here)
301 cwd = None,
302
303 # OS environment variables to pass to the subprocess
304 # if None, use the default environment variables unchanged
305 os_env = None)
306
307 @feature('command-output')
308 @after_method('init_cmd_output')
309 def apply_cmd_output(self):
310 if self.command is None:
311 raise Errors.WafError("command-output missing command")
312 if self.command_is_external:
313 cmd = self.command
314 cmd_node = None
315 else:
316 cmd_node = self.path.find_resource(self.command)
317 assert cmd_node is not None, ('''Could not find command '%s' in source tree.
318 Hint: if this is an external command,
319 use command_is_external=True''') % (self.command,)
320 cmd = cmd_node
321
322 if self.cwd is None:
323 cwd = None
324 else:
325 assert isinstance(cwd, CmdDirArg)
326 self.cwd.find_node(self.path)
327
328 args = []
329 inputs = []
330 outputs = []
331
332 for arg in self.argv:
333 if isinstance(arg, cmd_arg):
334 arg.find_node(self.path)
335 if isinstance(arg, input_file):
336 inputs.append(arg.node)
337 if isinstance(arg, output_file):
338 outputs.append(arg.node)
339
340 if self.stdout is None:
341 stdout = None
342 else:
343 assert isinstance(self.stdout, str)
344 stdout = self.path.find_or_declare(self.stdout)
345 if stdout is None:
346 raise Errors.WafError("File %s not found" % (self.stdout,))
347 outputs.append(stdout)
348
349 if self.stderr is None:
350 stderr = None
351 else:
352 assert isinstance(self.stderr, str)
353 stderr = self.path.find_or_declare(self.stderr)
354 if stderr is None:
355 raise Errors.WafError("File %s not found" % (self.stderr,))
356 outputs.append(stderr)
357
358 if self.stdin is None:
359 stdin = None
360 else:
361 assert isinstance(self.stdin, str)
362 stdin = self.path.find_resource(self.stdin)
363 if stdin is None:
364 raise Errors.WafError("File %s not found" % (self.stdin,))
365 inputs.append(stdin)
366
367 for hidden_input in self.to_list(self.hidden_inputs):
368 node = self.path.find_resource(hidden_input)
369 if node is None:
370 raise Errors.WafError("File %s not found in dir %s" % (hidden_input, self.path))
371 inputs.append(node)
372
373 for hidden_output in self.to_list(self.hidden_outputs):
374 node = self.path.find_or_declare(hidden_output)
375 if node is None:
376 raise Errors.WafError("File %s not found in dir %s" % (hidden_output, self.path))
377 outputs.append(node)
378
379 if not (inputs or getattr(self, 'no_inputs', None)):
380 raise Errors.WafError('command-output objects must have at least one input file or give self.no_inputs')
381 if not (outputs or getattr(self, 'no_outputs', None)):
382 raise Errors.WafError('command-output objects must have at least one output file or give self.no_outputs')
383
384 cwd = self.bld.variant_dir
385 task = command_output(self.env, cmd, cmd_node, self.argv, stdin, stdout, cwd, self.os_env, stderr)
386 task.generator = self
387 copy_attrs(self, task, 'before after ext_in ext_out', only_if_set=True)
388 self.tasks.append(task)
389
390 task.inputs = inputs
391 task.outputs = outputs
392 task.dep_vars = self.to_list(self.dep_vars)
393
394 for dep in self.dependencies:
395 assert dep is not self
396 dep.post()
397 for dep_task in dep.tasks:
398 task.set_run_after(dep_task)
399
400 if not task.inputs:
401 # the case for svnversion, always run, and update the output nodes
402 task.runnable_status = type(Task.TaskBase.run)(runnable_status, task, task.__class__) # always run
403 task.post_run = type(Task.TaskBase.run)(post_run, task, task.__class__)
404
405 # TODO the case with no outputs?
406
407 def post_run(self):
408 for x in self.outputs:
409 x.sig = Utils.h_file(x.abspath())
410
411 def runnable_status(self):
412 return self.RUN_ME
413
414 Task.task_factory('copy', vars=[], func=action_process_file_func)
415
0 #! /usr/bin/env python
1 # encoding: utf-8
2 # Avalanche Studios 2009-2011
3 # Thomas Nagy 2011
4
5 """
6 Redistribution and use in source and binary forms, with or without
7 modification, are permitted provided that the following conditions
8 are met:
9
10 1. Redistributions of source code must retain the above copyright
11 notice, this list of conditions and the following disclaimer.
12
13 2. Redistributions in binary form must reproduce the above copyright
14 notice, this list of conditions and the following disclaimer in the
15 documentation and/or other materials provided with the distribution.
16
17 3. The name of the author may not be used to endorse or promote products
18 derived from this software without specific prior written permission.
19
20 THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
21 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
22 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23 DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
24 INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
25 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
26 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
28 STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
29 IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 POSSIBILITY OF SUCH DAMAGE.
31 """
32
33 """
34 To add this tool to your project:
35 def options(conf):
36 opt.load('msvs')
37
38 It can be a good idea to add the sync_exec tool too.
39
40 To generate solution files:
41 $ waf configure msvs
42
43 To customize the outputs, provide subclasses in your wscript files:
44
45 from waflib.extras import msvs
46 class vsnode_target(msvs.vsnode_target):
47 def get_build_command(self, props):
48 # likely to be required
49 return "waf.bat build"
50 def collect_source(self):
51 # likely to be required
52 ...
53 class msvs_bar(msvs.msvs_generator):
54 def init(self):
55 msvs.msvs_generator.init(self)
56 self.vsnode_target = vsnode_target
57
58 The msvs class re-uses the same build() function for reading the targets (task generators),
59 you may therefore specify msvs settings on the context object:
60
61 def build(bld):
62 bld.solution_name = 'foo.sln'
63 bld.waf_command = 'waf.bat'
64 bld.projects_dir = bld.srcnode.make_node('.depproj')
65 bld.projects_dir.mkdir()
66
67 For visual studio 2008, the command is called 'msvs2008', and the classes
68 such as vsnode_target are wrapped by a decorator class 'wrap_2008' to
69 provide special functionality.
70
71 ASSUMPTIONS:
72 * a project can be either a directory or a target, vcxproj files are written only for targets that have source files
73 * each project is a vcxproj file, therefore the project uuid needs only to be a hash of the absolute path
74 """
75
76 import os, re, sys
77 import uuid # requires python 2.5
78 from waflib.Build import BuildContext
79 from waflib import Utils, TaskGen, Logs, Task, Context, Node, Options
80
81 HEADERS_GLOB = '**/(*.h|*.hpp|*.H|*.inl)'
82
83 PROJECT_TEMPLATE = r'''<?xml version="1.0" encoding="UTF-8"?>
84 <Project DefaultTargets="Build" ToolsVersion="4.0"
85 xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
86
87 <ItemGroup Label="ProjectConfigurations">
88 ${for b in project.build_properties}
89 <ProjectConfiguration Include="${b.configuration}|${b.platform}">
90 <Configuration>${b.configuration}</Configuration>
91 <Platform>${b.platform}</Platform>
92 </ProjectConfiguration>
93 ${endfor}
94 </ItemGroup>
95
96 <PropertyGroup Label="Globals">
97 <ProjectGuid>{${project.uuid}}</ProjectGuid>
98 <Keyword>MakeFileProj</Keyword>
99 <ProjectName>${project.name}</ProjectName>
100 </PropertyGroup>
101 <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
102
103 ${for b in project.build_properties}
104 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='${b.configuration}|${b.platform}'" Label="Configuration">
105 <ConfigurationType>Makefile</ConfigurationType>
106 <OutDir>${b.outdir}</OutDir>
107 </PropertyGroup>
108 ${endfor}
109
110 <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
111 <ImportGroup Label="ExtensionSettings">
112 </ImportGroup>
113
114 ${for b in project.build_properties}
115 <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='${b.configuration}|${b.platform}'">
116 <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
117 </ImportGroup>
118 ${endfor}
119
120 ${for b in project.build_properties}
121 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='${b.configuration}|${b.platform}'">
122 <NMakeBuildCommandLine>${xml:project.get_build_command(b)}</NMakeBuildCommandLine>
123 <NMakeReBuildCommandLine>${xml:project.get_rebuild_command(b)}</NMakeReBuildCommandLine>
124 <NMakeCleanCommandLine>${xml:project.get_clean_command(b)}</NMakeCleanCommandLine>
125 <NMakeIncludeSearchPath>${xml:b.includes_search_path}</NMakeIncludeSearchPath>
126 <NMakePreprocessorDefinitions>${xml:b.preprocessor_definitions};$(NMakePreprocessorDefinitions)</NMakePreprocessorDefinitions>
127 <IncludePath>${xml:b.includes_search_path}</IncludePath>
128 <ExecutablePath>$(ExecutablePath)</ExecutablePath>
129
130 ${if getattr(b, 'output_file', None)}
131 <NMakeOutput>${xml:b.output_file}</NMakeOutput>
132 ${endif}
133 ${if getattr(b, 'deploy_dir', None)}
134 <RemoteRoot>${xml:b.deploy_dir}</RemoteRoot>
135 ${endif}
136 </PropertyGroup>
137 ${endfor}
138
139 ${for b in project.build_properties}
140 ${if getattr(b, 'deploy_dir', None)}
141 <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='${b.configuration}|${b.platform}'">
142 <Deploy>
143 <DeploymentType>CopyToHardDrive</DeploymentType>
144 </Deploy>
145 </ItemDefinitionGroup>
146 ${endif}
147 ${endfor}
148
149 <ItemGroup>
150 ${for x in project.source}
151 <${project.get_key(x)} Include='${x.abspath()}' />
152 ${endfor}
153 </ItemGroup>
154 <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
155 <ImportGroup Label="ExtensionTargets">
156 </ImportGroup>
157 </Project>
158 '''
159
160 FILTER_TEMPLATE = '''<?xml version="1.0" encoding="UTF-8"?>
161 <Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
162 <ItemGroup>
163 ${for x in project.source}
164 <${project.get_key(x)} Include="${x.abspath()}">
165 <Filter>${project.get_filter_name(x.parent)}</Filter>
166 </${project.get_key(x)}>
167 ${endfor}
168 </ItemGroup>
169 <ItemGroup>
170 ${for x in project.dirs()}
171 <Filter Include="${project.get_filter_name(x)}">
172 <UniqueIdentifier>{${project.make_uuid(x.abspath())}}</UniqueIdentifier>
173 </Filter>
174 ${endfor}
175 </ItemGroup>
176 </Project>
177 '''
178
179 PROJECT_2008_TEMPLATE = r'''<?xml version="1.0" encoding="UTF-8"?>
180 <VisualStudioProject ProjectType="Visual C++" Version="9,00"
181 Name="${xml: project.name}" ProjectGUID="{${project.uuid}}"
182 Keyword="MakeFileProj"
183 TargetFrameworkVersion="196613">
184 <Platforms>
185 ${if project.build_properties}
186 ${for b in project.build_properties}
187 <Platform Name="${xml: b.platform}" />
188 ${endfor}
189 ${else}
190 <Platform Name="Win32" />
191 ${endif}
192 </Platforms>
193 <ToolFiles>
194 </ToolFiles>
195 <Configurations>
196 ${if project.build_properties}
197 ${for b in project.build_properties}
198 <Configuration
199 Name="${xml: b.configuration}|${xml: b.platform}"
200 IntermediateDirectory="$ConfigurationName"
201 OutputDirectory="${xml: b.outdir}"
202 ConfigurationType="0">
203 <Tool
204 Name="VCNMakeTool"
205 BuildCommandLine="${xml: project.get_build_command(b)}"
206 ReBuildCommandLine="${xml: project.get_rebuild_command(b)}"
207 CleanCommandLine="${xml: project.get_clean_command(b)}"
208 ${if getattr(b, 'output_file', None)}
209 Output="${xml: b.output_file}"
210 ${endif}
211 PreprocessorDefinitions="${xml: b.preprocessor_definitions}"
212 IncludeSearchPath="${xml: b.includes_search_path}"
213 ForcedIncludes=""
214 ForcedUsingAssemblies=""
215 AssemblySearchPath=""
216 CompileAsManaged=""
217 />
218 </Configuration>
219 ${endfor}
220 ${else}
221 <Configuration Name="Release|Win32" >
222 </Configuration>
223 ${endif}
224 </Configurations>
225 <References>
226 </References>
227 <Files>
228 ${project.display_filter()}
229 </Files>
230 </VisualStudioProject>
231 '''
232
233 SOLUTION_TEMPLATE = '''Microsoft Visual Studio Solution File, Format Version ${project.numver}
234 # Visual Studio ${project.vsver}
235 ${for p in project.all_projects}
236 Project("{${p.ptype()}}") = "${p.name}", "${p.title}", "{${p.uuid}}"
237 EndProject${endfor}
238 Global
239 GlobalSection(SolutionConfigurationPlatforms) = preSolution
240 ${if project.all_projects}
241 ${for (configuration, platform) in project.all_projects[0].ctx.project_configurations()}
242 ${configuration}|${platform} = ${configuration}|${platform}
243 ${endfor}
244 ${endif}
245 EndGlobalSection
246 GlobalSection(ProjectConfigurationPlatforms) = postSolution
247 ${for p in project.all_projects}
248 ${if hasattr(p, 'source')}
249 ${for b in p.build_properties}
250 {${p.uuid}}.${b.configuration}|${b.platform}.ActiveCfg = ${b.configuration}|${b.platform}
251 ${if getattr(p, 'is_active', None)}
252 {${p.uuid}}.${b.configuration}|${b.platform}.Build.0 = ${b.configuration}|${b.platform}
253 ${endif}
254 ${endfor}
255 ${endif}
256 ${endfor}
257 EndGlobalSection
258 GlobalSection(SolutionProperties) = preSolution
259 HideSolutionNode = FALSE
260 EndGlobalSection
261 GlobalSection(NestedProjects) = preSolution
262 ${for p in project.all_projects}
263 ${if p.parent}
264 {${p.uuid}} = {${p.parent.uuid}}
265 ${endif}
266 ${endfor}
267 EndGlobalSection
268 EndGlobal
269 '''
270
271 COMPILE_TEMPLATE = '''def f(project):
272 lst = []
273 def xml_escape(value):
274 return value.replace("&", "&amp;").replace('"', "&quot;").replace("'", "&apos;").replace("<", "&lt;").replace(">", "&gt;")
275
276 %s
277
278 #f = open('cmd.txt', 'w')
279 #f.write(str(lst))
280 #f.close()
281 return ''.join(lst)
282 '''
283 reg_act = re.compile(r"(?P<backslash>\\)|(?P<dollar>\$\$)|(?P<subst>\$\{(?P<code>[^}]*?)\})", re.M)
284 def compile_template(line):
285 """
286 Compile a template expression into a python function (like jsps, but way shorter)
287 """
288 extr = []
289 def repl(match):
290 g = match.group
291 if g('dollar'): return "$"
292 elif g('backslash'):
293 return "\\"
294 elif g('subst'):
295 extr.append(g('code'))
296 return "<<|@|>>"
297 return None
298
299 line2 = reg_act.sub(repl, line)
300 params = line2.split('<<|@|>>')
301 assert(extr)
302
303
304 indent = 0
305 buf = []
306 dvars = []
307 app = buf.append
308
309 def app(txt):
310 buf.append(indent * '\t' + txt)
311
312 for x in range(len(extr)):
313 if params[x]:
314 app("lst.append(%r)" % params[x])
315
316 f = extr[x]
317 if f.startswith('if') or f.startswith('for'):
318 app(f + ':')
319 indent += 1
320 elif f.startswith('py:'):
321 app(f[3:])
322 elif f.startswith('endif') or f.startswith('endfor'):
323 indent -= 1
324 elif f.startswith('else') or f.startswith('elif'):
325 indent -= 1
326 app(f + ':')
327 indent += 1
328 elif f.startswith('xml:'):
329 app('lst.append(xml_escape(%s))' % f[4:])
330 else:
331 #app('lst.append((%s) or "cannot find %s")' % (f, f))
332 app('lst.append(%s)' % f)
333
334 if extr:
335 if params[-1]:
336 app("lst.append(%r)" % params[-1])
337
338 fun = COMPILE_TEMPLATE % "\n\t".join(buf)
339 #print(fun)
340 return Task.funex(fun)
341
342
343 re_blank = re.compile('(\n|\r|\\s)*\n', re.M)
344 def rm_blank_lines(txt):
345 txt = re_blank.sub('\r\n', txt)
346 return txt
347
348 BOM = '\xef\xbb\xbf'
349 try:
350 BOM = bytes(BOM, 'iso8859-1') # python 3
351 except:
352 pass
353
354 def stealth_write(self, data, flags='wb'):
355 try:
356 x = unicode
357 except:
358 data = data.encode('utf-8') # python 3
359 else:
360 data = data.decode(sys.getfilesystemencoding(), 'replace')
361 data = data.encode('utf-8')
362
363 if self.name.endswith('.vcproj') or self.name.endswith('.vcxproj'):
364 data = BOM + data
365
366 try:
367 txt = self.read(flags='rb')
368 if txt != data:
369 raise ValueError('must write')
370 except (IOError, ValueError):
371 self.write(data, flags=flags)
372 else:
373 Logs.debug('msvs: skipping %s' % self.abspath())
374 Node.Node.stealth_write = stealth_write
375
376 re_quote = re.compile("[^a-zA-Z0-9-]")
377 def quote(s):
378 return re_quote.sub("_", s)
379
380 def xml_escape(value):
381 return value.replace("&", "&amp;").replace('"', "&quot;").replace("'", "&apos;").replace("<", "&lt;").replace(">", "&gt;")
382
383 def make_uuid(v, prefix = None):
384 """
385 simple utility function
386 """
387 if isinstance(v, dict):
388 keys = list(v.keys())
389 keys.sort()
390 tmp = str([(k, v[k]) for k in keys])
391 else:
392 tmp = str(v)
393 d = Utils.md5(tmp.encode()).hexdigest().upper()
394 if prefix:
395 d = '%s%s' % (prefix, d[8:])
396 gid = uuid.UUID(d, version = 4)
397 return str(gid).upper()
398
399 def diff(node, fromnode):
400 # difference between two nodes, but with "(..)" instead of ".."
401 c1 = node
402 c2 = fromnode
403
404 c1h = c1.height()
405 c2h = c2.height()
406
407 lst = []
408 up = 0
409
410 while c1h > c2h:
411 lst.append(c1.name)
412 c1 = c1.parent
413 c1h -= 1
414
415 while c2h > c1h:
416 up += 1
417 c2 = c2.parent
418 c2h -= 1
419
420 while id(c1) != id(c2):
421 lst.append(c1.name)
422 up += 1
423
424 c1 = c1.parent
425 c2 = c2.parent
426
427 for i in range(up):
428 lst.append('(..)')
429 lst.reverse()
430 return tuple(lst)
431
432 class build_property(object):
433 pass
434
435 class vsnode(object):
436 """
437 Abstract class representing visual studio elements
438 We assume that all visual studio nodes have a uuid and a parent
439 """
440 def __init__(self, ctx):
441 self.ctx = ctx # msvs context
442 self.name = '' # string, mandatory
443 self.vspath = '' # path in visual studio (name for dirs, absolute path for projects)
444 self.uuid = '' # string, mandatory
445 self.parent = None # parent node for visual studio nesting
446
447 def get_waf(self):
448 """
449 Override in subclasses...
450 """
451 return 'cd /d "%s" & %s' % (self.ctx.srcnode.abspath(), getattr(self.ctx, 'waf_command', 'waf.bat'))
452
453 def ptype(self):
454 """
455 Return a special uuid for projects written in the solution file
456 """
457 pass
458
459 def write(self):
460 """
461 Write the project file, by default, do nothing
462 """
463 pass
464
465 def make_uuid(self, val):
466 """
467 Alias for creating uuid values easily (the templates cannot access global variables)
468 """
469 return make_uuid(val)
470
471 class vsnode_vsdir(vsnode):
472 """
473 Nodes representing visual studio folders (which do not match the filesystem tree!)
474 """
475 VS_GUID_SOLUTIONFOLDER = "2150E333-8FDC-42A3-9474-1A3956D46DE8"
476 def __init__(self, ctx, uuid, name, vspath=''):
477 vsnode.__init__(self, ctx)
478 self.title = self.name = name
479 self.uuid = uuid
480 self.vspath = vspath or name
481
482 def ptype(self):
483 return self.VS_GUID_SOLUTIONFOLDER
484
485 class vsnode_project(vsnode):
486 """
487 Abstract class representing visual studio project elements
488 A project is assumed to be writable, and has a node representing the file to write to
489 """
490 VS_GUID_VCPROJ = "8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942"
491 def ptype(self):
492 return self.VS_GUID_VCPROJ
493
494 def __init__(self, ctx, node):
495 vsnode.__init__(self, ctx)
496 self.path = node
497 self.uuid = make_uuid(node.abspath())
498 self.name = node.name
499 self.title = self.path.abspath()
500 self.source = [] # list of node objects
501 self.build_properties = [] # list of properties (nmake commands, output dir, etc)
502
503 def dirs(self):
504 """
505 Get the list of parent folders of the source files (header files included)
506 for writing the filters
507 """
508 lst = []
509 def add(x):
510 if x.height() > self.tg.path.height() and x not in lst:
511 lst.append(x)
512 add(x.parent)
513 for x in self.source:
514 add(x.parent)
515 return lst
516
517 def write(self):
518 Logs.debug('msvs: creating %r' % self.path)
519
520 # first write the project file
521 template1 = compile_template(PROJECT_TEMPLATE)
522 proj_str = template1(self)
523 proj_str = rm_blank_lines(proj_str)
524 self.path.stealth_write(proj_str)
525
526 # then write the filter
527 template2 = compile_template(FILTER_TEMPLATE)
528 filter_str = template2(self)
529 filter_str = rm_blank_lines(filter_str)
530 tmp = self.path.parent.make_node(self.path.name + '.filters')
531 tmp.stealth_write(filter_str)
532
533 def get_key(self, node):
534 """
535 required for writing the source files
536 """
537 name = node.name
538 if name.endswith('.cpp') or name.endswith('.c'):
539 return 'ClCompile'
540 return 'ClInclude'
541
542 def collect_properties(self):
543 """
544 Returns a list of triplet (configuration, platform, output_directory)
545 """
546 ret = []
547 for c in self.ctx.configurations:
548 for p in self.ctx.platforms:
549 x = build_property()
550 x.outdir = ''
551
552 x.configuration = c
553 x.platform = p
554
555 x.preprocessor_definitions = ''
556 x.includes_search_path = ''
557
558 # can specify "deploy_dir" too
559 ret.append(x)
560 self.build_properties = ret
561
562 def get_build_params(self, props):
563 opt = '--execsolution=%s' % self.ctx.get_solution_node().abspath()
564 return (self.get_waf(), opt)
565
566 def get_build_command(self, props):
567 return "%s build %s" % self.get_build_params(props)
568
569 def get_clean_command(self, props):
570 return "%s clean %s" % self.get_build_params(props)
571
572 def get_rebuild_command(self, props):
573 return "%s clean build %s" % self.get_build_params(props)
574
575 def get_filter_name(self, node):
576 lst = diff(node, self.tg.path)
577 return '\\'.join(lst) or '.'
578
579 class vsnode_alias(vsnode_project):
580 def __init__(self, ctx, node, name):
581 vsnode_project.__init__(self, ctx, node)
582 self.name = name
583 self.output_file = ''
584
585 class vsnode_build_all(vsnode_alias):
586 """
587 Fake target used to emulate the behaviour of "make all" (starting one process by target is slow)
588 This is the only alias enabled by default
589 """
590 def __init__(self, ctx, node, name='build_all_projects'):
591 vsnode_alias.__init__(self, ctx, node, name)
592 self.is_active = True
593
594 class vsnode_install_all(vsnode_alias):
595 """
596 Fake target used to emulate the behaviour of "make install"
597 """
598 def __init__(self, ctx, node, name='install_all_projects'):
599 vsnode_alias.__init__(self, ctx, node, name)
600
601 def get_build_command(self, props):
602 return "%s build install %s" % self.get_build_params(props)
603
604 def get_clean_command(self, props):
605 return "%s clean %s" % self.get_build_params(props)
606
607 def get_rebuild_command(self, props):
608 return "%s clean build install %s" % self.get_build_params(props)
609
610 class vsnode_project_view(vsnode_alias):
611 """
612 Fake target used to emulate a file system view
613 """
614 def __init__(self, ctx, node, name='project_view'):
615 vsnode_alias.__init__(self, ctx, node, name)
616 self.tg = self.ctx() # fake one, cannot remove
617 self.exclude_files = Node.exclude_regs + '''
618 waf-1.6.*
619 waf3-1.6.*/**
620 .waf-1.6.*
621 .waf3-1.6.*/**
622 **/*.sdf
623 **/*.suo
624 **/*.ncb
625 **/%s
626 ''' % Options.lockfile
627
628 def collect_source(self):
629 # this is likely to be slow
630 self.source = self.ctx.srcnode.ant_glob('**', excl=self.exclude_files)
631
632 def get_build_command(self, props):
633 params = self.get_build_params(props) + (self.ctx.cmd,)
634 return "%s %s %s" % params
635
636 def get_clean_command(self, props):
637 return ""
638
639 def get_rebuild_command(self, props):
640 return self.get_build_command(props)
641
642 class vsnode_target(vsnode_project):
643 """
644 Visual studio project representing a targets (programs, libraries, etc) and bound
645 to a task generator
646 """
647 def __init__(self, ctx, tg):
648 """
649 A project is more or less equivalent to a file/folder
650 """
651 base = getattr(ctx, 'projects_dir', None) or tg.path
652 node = base.make_node(quote(tg.name) + ctx.project_extension) # the project file as a Node
653 vsnode_project.__init__(self, ctx, node)
654 self.name = quote(tg.name)
655 self.tg = tg # task generator
656
657 def get_build_params(self, props):
658 """
659 Override the default to add the target name
660 """
661 opt = '--execsolution=%s' % self.ctx.get_solution_node().abspath()
662 if getattr(self, 'tg', None):
663 opt += " --targets=%s" % self.tg.name
664 return (self.get_waf(), opt)
665
666 def collect_source(self):
667 tg = self.tg
668 source_files = tg.to_nodes(getattr(tg, 'source', []))
669 include_dirs = Utils.to_list(getattr(tg, 'msvs_includes', []))
670 include_files = []
671 for x in include_dirs:
672 if isinstance(x, str):
673 x = tg.path.find_node(x)
674 if x:
675 lst = [y for y in x.ant_glob(HEADERS_GLOB, flat=False)]
676 include_files.extend(lst)
677
678 # remove duplicates
679 self.source.extend(list(set(source_files + include_files)))
680 self.source.sort(key=lambda x: x.abspath())
681
682 def collect_properties(self):
683 """
684 Visual studio projects are associated with platforms and configurations (for building especially)
685 """
686 super(vsnode_target, self).collect_properties()
687 for x in self.build_properties:
688 x.outdir = self.path.parent.abspath()
689 x.preprocessor_definitions = ''
690 x.includes_search_path = ''
691
692 try:
693 tsk = self.tg.link_task
694 except AttributeError:
695 pass
696 else:
697 x.output_file = tsk.outputs[0].abspath()
698 x.preprocessor_definitions = ';'.join(tsk.env.DEFINES)
699 x.includes_search_path = ';'.join(self.tg.env.INCPATHS)
700
701 class msvs_generator(BuildContext):
702 '''generates a visual studio 2010 solution'''
703 cmd = 'msvs'
704 fun = 'build'
705
706 def init(self):
707 """
708 Some data that needs to be present
709 """
710 if not getattr(self, 'configurations', None):
711 self.configurations = ['Release'] # LocalRelease, RemoteDebug, etc
712 if not getattr(self, 'platforms', None):
713 self.platforms = ['Win32']
714 if not getattr(self, 'all_projects', None):
715 self.all_projects = []
716 if not getattr(self, 'project_extension', None):
717 self.project_extension = '.vcxproj'
718 if not getattr(self, 'projects_dir', None):
719 self.projects_dir = self.srcnode.make_node('.depproj')
720 self.projects_dir.mkdir()
721
722 # bind the classes to the object, so that subclass can provide custom generators
723 if not getattr(self, 'vsnode_vsdir', None):
724 self.vsnode_vsdir = vsnode_vsdir
725 if not getattr(self, 'vsnode_target', None):
726 self.vsnode_target = vsnode_target
727 if not getattr(self, 'vsnode_build_all', None):
728 self.vsnode_build_all = vsnode_build_all
729 if not getattr(self, 'vsnode_install_all', None):
730 self.vsnode_install_all = vsnode_install_all
731 if not getattr(self, 'vsnode_project_view', None):
732 self.vsnode_project_view = vsnode_project_view
733
734 self.numver = '11.00'
735 self.vsver = '2010'
736
737 def execute(self):
738 """
739 Entry point
740 """
741 self.restore()
742 if not self.all_envs:
743 self.load_envs()
744 self.recurse([self.run_dir])
745
746 # user initialization
747 self.init()
748
749 # two phases for creating the solution
750 self.collect_projects() # add project objects into "self.all_projects"
751 self.write_files() # write the corresponding project and solution files
752
753 def collect_projects(self):
754 """
755 Fill the list self.all_projects with project objects
756 Fill the list of build targets
757 """
758 self.collect_targets()
759 self.add_aliases()
760 self.collect_dirs()
761 self.all_projects.sort(key=lambda x: getattr(x, 'path', None) and x.path.abspath() or x.name)
762
763 def write_files(self):
764 """
765 Write the project and solution files from the data collected
766 so far. It is unlikely that you will want to change this
767 """
768 for p in self.all_projects:
769 p.write()
770
771 # and finally write the solution file
772 node = self.get_solution_node()
773 node.parent.mkdir()
774 Logs.warn('Creating %r' % node)
775 template1 = compile_template(SOLUTION_TEMPLATE)
776 sln_str = template1(self)
777 sln_str = rm_blank_lines(sln_str)
778 node.stealth_write(sln_str)
779
780 def get_solution_node(self):
781 """
782 The solution filename is required when writing the .vcproj files
783 return self.solution_node and if it does not exist, make one
784 """
785 try:
786 return self.solution_node
787 except:
788 pass
789
790 solution_name = getattr(self, 'solution_name', None)
791 if not solution_name:
792 solution_name = getattr(Context.g_module, Context.APPNAME, 'project') + '.sln'
793 if os.path.isabs(solution_name):
794 self.solution_node = self.root.make_node(solution_name)
795 else:
796 self.solution_node = self.srcnode.make_node(solution_name)
797 return self.solution_node
798
799 def project_configurations(self):
800 """
801 Helper that returns all the pairs (config,platform)
802 """
803 ret = []
804 for c in self.configurations:
805 for p in self.platforms:
806 ret.append((c, p))
807 return ret
808
809 def collect_targets(self):
810 """
811 Process the list of task generators
812 """
813 for g in self.groups:
814 for tg in g:
815 if not isinstance(tg, TaskGen.task_gen):
816 continue
817
818 if not hasattr(tg, 'msvs_includes'):
819 tg.msvs_includes = tg.to_list(getattr(tg, 'includes', [])) + tg.to_list(getattr(tg, 'export_includes', []))
820 tg.post()
821 if not getattr(tg, 'link_task', None):
822 continue
823
824 p = self.vsnode_target(self, tg)
825 p.collect_source() # delegate this processing
826 p.collect_properties()
827 self.all_projects.append(p)
828
829 def add_aliases(self):
830 """
831 Add a specific target that emulates the "make all" necessary for Visual studio when pressing F7
832 We also add an alias for "make install" (disabled by default)
833 """
834 base = getattr(self, 'projects_dir', None) or self.tg.path
835
836 node_project = base.make_node('build_all_projects' + self.project_extension) # Node
837 p_build = self.vsnode_build_all(self, node_project)
838 p_build.collect_properties()
839 self.all_projects.append(p_build)
840
841 node_project = base.make_node('install_all_projects' + self.project_extension) # Node
842 p_install = self.vsnode_install_all(self, node_project)
843 p_install.collect_properties()
844 self.all_projects.append(p_install)
845
846 node_project = base.make_node('project_view' + self.project_extension) # Node
847 p_view = self.vsnode_project_view(self, node_project)
848 p_view.collect_source()
849 p_view.collect_properties()
850 self.all_projects.append(p_view)
851
852 n = self.vsnode_vsdir(self, make_uuid(self.srcnode.abspath() + 'build_aliases'), "build_aliases")
853 p_build.parent = p_install.parent = p_view.parent = n
854 self.all_projects.append(n)
855
856 def collect_dirs(self):
857 """
858 Create the folder structure in the Visual studio project view
859 """
860 seen = {}
861 def make_parents(proj):
862 # look at a project, try to make a parent
863 if getattr(proj, 'parent', None):
864 # aliases already have parents
865 return
866 x = proj.iter_path
867 if x in seen:
868 proj.parent = seen[x]
869 return
870
871 # There is not vsnode_vsdir for x.
872 # So create a project representing the folder "x"
873 n = proj.parent = seen[x] = self.vsnode_vsdir(self, make_uuid(x.abspath()), x.name)
874 n.iter_path = x.parent
875 self.all_projects.append(n)
876
877 # recurse up to the project directory
878 if x.height() > self.srcnode.height() + 1:
879 make_parents(n)
880
881 for p in self.all_projects[:]: # iterate over a copy of all projects
882 if not getattr(p, 'tg', None):
883 # but only projects that have a task generator
884 continue
885
886 # make a folder for each task generator
887 p.iter_path = p.tg.path
888 make_parents(p)
889
890 def wrap_2008(cls):
891 class dec(cls):
892 def __init__(self, *k, **kw):
893 cls.__init__(self, *k, **kw)
894 self.project_template = PROJECT_2008_TEMPLATE
895
896 def display_filter(self):
897
898 root = build_property()
899 root.subfilters = []
900 root.sourcefiles = []
901 root.source = []
902 root.name = ''
903
904 @Utils.run_once
905 def add_path(lst):
906 if not lst:
907 return root
908 child = build_property()
909 child.subfilters = []
910 child.sourcefiles = []
911 child.source = []
912 child.name = lst[-1]
913
914 par = add_path(lst[:-1])
915 par.subfilters.append(child)
916 return child
917
918 for x in self.source:
919 # this crap is for enabling subclasses to override get_filter_name
920 tmp = self.get_filter_name(x.parent)
921 tmp = tmp != '.' and tuple(tmp.split('\\')) or ()
922 par = add_path(tmp)
923 par.source.append(x)
924
925 def display(n):
926 buf = []
927 for x in n.source:
928 buf.append('<File RelativePath="%s" FileType="%s"/>\n' % (xml_escape(x.abspath()), self.get_key(x)))
929 for x in n.subfilters:
930 buf.append('<Filter Name="%s">' % xml_escape(x.name))
931 buf.append(display(x))
932 buf.append('</Filter>')
933 return '\n'.join(buf)
934
935 return display(root)
936
937 def get_key(self, node):
938 """
939 If you do not want to let visual studio use the default file extensions,
940 override this method to return a value:
941 0: C/C++ Code, 1: C++ Class, 2: C++ Header File, 3: C++ Form,
942 4: C++ Control, 5: Text File, 6: DEF File, 7: IDL File,
943 8: Makefile, 9: RGS File, 10: RC File, 11: RES File, 12: XSD File,
944 13: XML File, 14: HTML File, 15: CSS File, 16: Bitmap, 17: Icon,
945 18: Resx File, 19: BSC File, 20: XSX File, 21: C++ Web Service,
946 22: ASAX File, 23: Asp Page, 24: Document, 25: Discovery File,
947 26: C# File, 27: eFileTypeClassDiagram, 28: MHTML Document,
948 29: Property Sheet, 30: Cursor, 31: Manifest, 32: eFileTypeRDLC
949 """
950 return ''
951
952 def write(self):
953 Logs.debug('msvs: creating %r' % self.path)
954 template1 = compile_template(self.project_template)
955 proj_str = template1(self)
956 proj_str = rm_blank_lines(proj_str)
957 self.path.stealth_write(proj_str)
958
959 return dec
960
961 class msvs_2008_generator(msvs_generator):
962 '''generates a visual studio 2008 solution'''
963 cmd = 'msvs2008'
964 fun = msvs_generator.fun
965
966 def init(self):
967 if not getattr(self, 'project_extension', None):
968 self.project_extension = '_2008.vcproj'
969 if not getattr(self, 'solution_name', None):
970 self.solution_name = getattr(Context.g_module, Context.APPNAME, 'project') + '_2008.sln'
971
972 if not getattr(self, 'vsnode_target', None):
973 self.vsnode_target = wrap_2008(vsnode_target)
974 if not getattr(self, 'vsnode_build_all', None):
975 self.vsnode_build_all = wrap_2008(vsnode_build_all)
976 if not getattr(self, 'vsnode_install_all', None):
977 self.vsnode_install_all = wrap_2008(vsnode_install_all)
978 if not getattr(self, 'vsnode_project_view', None):
979 self.vsnode_project_view = wrap_2008(vsnode_project_view)
980
981 msvs_generator.init(self)
982 self.numver = '10.00'
983 self.vsver = '2008'
984
985 def options(ctx):
986 """
987 If the msvs option is used, try to detect if the build is made from visual studio
988 """
989 ctx.add_option('--execsolution', action='store', help='when building with visual studio, use a build state file')
990
991 old = BuildContext.execute
992 def override_build_state(ctx):
993 def lock(rm, add):
994 uns = ctx.options.execsolution.replace('.sln', rm)
995 uns = ctx.root.make_node(uns)
996 try:
997 uns.delete()
998 except:
999 pass
1000
1001 uns = ctx.options.execsolution.replace('.sln', add)
1002 uns = ctx.root.make_node(uns)
1003 try:
1004 uns.write('')
1005 except:
1006 pass
1007
1008 if ctx.options.execsolution:
1009 ctx.launch_dir = Context.top_dir # force a build for the whole project (invalid cwd when called by visual studio)
1010 lock('.lastbuildstate', '.unsuccessfulbuild')
1011 old(ctx)
1012 lock('.unsuccessfulbuild', '.lastbuildstate')
1013 else:
1014 old(ctx)
1015 BuildContext.execute = override_build_state
1016
0 #! /usr/bin/env python
1 # encoding: utf-8
2 # Thomas Nagy, 2011 (ita)
3
4 """
5 A client for the network cache (playground/netcache/). Launch the server with:
6 ./netcache_server, then use it for the builds by adding the following:
7
8 def options(opt):
9 opt.load('netcache_client')
10
11 The parameters should be present in the environment in the form:
12 NETCACHE=host:port@mode waf configure build
13
14 where:
15 mode: PUSH, PULL, PUSH_PULL
16 host: host where the server resides, for example 127.0.0.1
17 port: by default the server runs on port 51200
18
19 The cache can be enabled for the build only:
20 def options(opt):
21 opt.load('netcache_client', funs=[])
22 def build(bld):
23 bld.setup_netcache('localhost', 51200, 'PUSH_PULL')
24 """
25
26 import os, socket, time, atexit
27 from waflib import Task, Logs, Utils, Build, Options, Runner
28 from waflib.Configure import conf
29
30 BUF = 8192 * 16
31 HEADER_SIZE = 128
32 MODES = ['PUSH', 'PULL', 'PUSH_PULL']
33 STALE_TIME = 30 # seconds
34
35 GET = 'GET'
36 PUT = 'PUT'
37 LST = 'LST'
38 BYE = 'BYE'
39
40 all_sigs_in_cache = (0.0, [])
41
42 active_connections = Runner.Queue(0)
43 def get_connection():
44 # return a new connection... do not forget to release it!
45 try:
46 ret = active_connections.get(block=False)
47 except Exception:
48 ret = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
49 ret.connect(Task.net_cache[:2])
50 return ret
51
52 def release_connection(conn, msg=''):
53 if conn:
54 active_connections.put(conn)
55
56 def close_connection(conn, msg=''):
57 if conn:
58 data = '%s,%s' % (BYE, msg)
59 try:
60 conn.send(data.ljust(HEADER_SIZE))
61 except:
62 pass
63 try:
64 conn.close()
65 except:
66 pass
67
68 def close_all():
69 while active_connections.qsize():
70 conn = active_connections.get()
71 try:
72 close_connection(conn)
73 except:
74 pass
75 atexit.register(close_all)
76
77 def read_header(conn):
78 cnt = 0
79 buf = []
80 while cnt < HEADER_SIZE:
81 data = conn.recv(HEADER_SIZE - cnt)
82 if not data:
83 #import traceback
84 #traceback.print_stack()
85 raise ValueError('connection ended when reading a header %r' % buf)
86 buf.append(data)
87 cnt += len(data)
88 return ''.join(buf)
89
90 def check_cache(conn, ssig):
91 """
92 List the files on the server, this is an optimization because it assumes that
93 concurrent builds are rare
94 """
95 global all_sigs_in_cache
96 if not STALE_TIME:
97 return
98 if time.time() - all_sigs_in_cache[0] > STALE_TIME:
99
100 params = (LST,'')
101 conn.send(','.join(params).ljust(HEADER_SIZE))
102
103 # read what is coming back
104 ret = read_header(conn)
105 size = int(ret.split(',')[0])
106
107 buf = []
108 cnt = 0
109 while cnt < size:
110 data = conn.recv(min(BUF, size-cnt))
111 if not data:
112 raise ValueError('connection ended %r %r' % (cnt, size))
113 buf.append(data)
114 cnt += len(data)
115 all_sigs_in_cache = (time.time(), ''.join(buf).split('\n'))
116 Logs.debug('netcache: server cache has %r entries' % len(all_sigs_in_cache[1]))
117
118 if not ssig in all_sigs_in_cache[1]:
119 raise ValueError('no file %s in cache' % ssig)
120
121 class MissingFile(Exception):
122 pass
123
124 def recv_file(conn, ssig, count, p):
125 check_cache(conn, ssig)
126
127 params = (GET, ssig, str(count))
128 conn.send(','.join(params).ljust(HEADER_SIZE))
129 data = read_header(conn)
130
131 size = int(data.split(',')[0])
132
133 if size == -1:
134 raise MissingFile('no file %s - %s in cache' % (ssig, count))
135
136 # get the file, writing immediately
137 # TODO a tmp file would be better
138 f = open(p, 'wb')
139 cnt = 0
140 while cnt < size:
141 data = conn.recv(min(BUF, size-cnt))
142 if not data:
143 raise ValueError('connection ended %r %r' % (cnt, size))
144 f.write(data)
145 cnt += len(data)
146 f.close()
147
148 def put_data(conn, ssig, cnt, p):
149 #print "pushing %r %r %r" % (ssig, cnt, p)
150 size = os.stat(p).st_size
151 params = (PUT, ssig, str(cnt), str(size))
152 conn.send(','.join(params).ljust(HEADER_SIZE))
153 f = open(p, 'rb')
154 cnt = 0
155 while cnt < size:
156 r = f.read(min(BUF, size-cnt))
157 while r:
158 k = conn.send(r)
159 if not k:
160 raise ValueError('connection ended')
161 cnt += k
162 r = r[k:]
163
164 #def put_data(conn, ssig, cnt, p):
165 # size = os.stat(p).st_size
166 # params = (PUT, ssig, str(cnt), str(size))
167 # conn.send(','.join(params).ljust(HEADER_SIZE))
168 # conn.send(','*size)
169 # params = (BYE, 'he')
170 # conn.send(','.join(params).ljust(HEADER_SIZE))
171
172 def can_retrieve_cache(self):
173 if not Task.net_cache:
174 return False
175 if not self.outputs:
176 return False
177 if Task.net_cache[-1] == 'PUSH':
178 return
179 self.cached = False
180
181 cnt = 0
182 sig = self.signature()
183 ssig = self.uid().encode('hex') + sig.encode('hex')
184
185 conn = None
186 err = False
187 try:
188 try:
189 conn = get_connection()
190 for node in self.outputs:
191 p = node.abspath()
192 recv_file(conn, ssig, cnt, p)
193 cnt += 1
194 except MissingFile as e:
195 Logs.debug('netcache: file is not in the cache %r' % e)
196 err = True
197
198 except Exception as e:
199 Logs.debug('netcache: could not get the files %r' % e)
200 err = True
201
202 # broken connection? remove this one
203 close_connection(conn)
204 conn = None
205 finally:
206 release_connection(conn)
207 if err:
208 return False
209
210 for node in self.outputs:
211 node.sig = sig
212 #if self.generator.bld.progress_bar < 1:
213 # self.generator.bld.to_log('restoring from cache %r\n' % node.abspath())
214
215 self.cached = True
216 return True
217
218 @Utils.run_once
219 def put_files_cache(self):
220 if not Task.net_cache:
221 return
222 if not self.outputs:
223 return
224 if Task.net_cache[-1] == 'PULL':
225 return
226 if getattr(self, 'cached', None):
227 return
228
229 #print "called put_files_cache", id(self)
230 bld = self.generator.bld
231 sig = self.signature()
232 ssig = self.uid().encode('hex') + sig.encode('hex')
233
234 conn = None
235 cnt = 0
236 try:
237 for node in self.outputs:
238 # We could re-create the signature of the task with the signature of the outputs
239 # in practice, this means hashing the output files
240 # this is unnecessary
241 try:
242 if not conn:
243 conn = get_connection()
244 put_data(conn, ssig, cnt, node.abspath())
245 except Exception as e:
246 Logs.debug("netcache: could not push the files %r" % e)
247
248 # broken connection? remove this one
249 close_connection(conn)
250 conn = None
251 cnt += 1
252 finally:
253 release_connection(conn)
254
255 bld.task_sigs[self.uid()] = self.cache_sig
256
257 def hash_env_vars(self, env, vars_lst):
258 if not env.table:
259 env = env.parent
260 if not env:
261 return Utils.SIG_NIL
262
263 idx = str(id(env)) + str(vars_lst)
264 try:
265 cache = self.cache_env
266 except AttributeError:
267 cache = self.cache_env = {}
268 else:
269 try:
270 return self.cache_env[idx]
271 except KeyError:
272 pass
273
274 v = str([env[a] for a in vars_lst])
275 v = v.replace(self.srcnode.abspath(), '') # here
276 m = Utils.md5()
277 m.update(v.encode())
278 ret = m.digest()
279
280 Logs.debug('envhash: %r %r', ret, v)
281
282 cache[idx] = ret
283
284 return ret
285
286 def uid(self):
287 try:
288 return self.uid_
289 except AttributeError:
290 m = Utils.md5()
291 src = self.generator.bld.srcnode
292 up = m.update
293 up(self.__class__.__name__.encode())
294 for x in self.inputs + self.outputs:
295 up(x.path_from(src).encode())
296 self.uid_ = m.digest()
297 return self.uid_
298
299 @conf
300 def setup_netcache(ctx, host, port, mode):
301 Logs.warn('Using the network cache %s, %s, %s' % (host, port, mode))
302 Task.net_cache = (host, port, mode)
303 Task.Task.can_retrieve_cache = can_retrieve_cache
304 Task.Task.put_files_cache = put_files_cache
305 Task.Task.uid = uid
306 Build.BuildContext.hash_env_vars = hash_env_vars
307 ctx.cache_global = Options.cache_global = True
308
309 def options(opt):
310 if not 'NETCACHE' in os.environ:
311 Logs.warn('the network cache is disabled, set NETCACHE=host:port@mode to enable')
312 else:
313 v = os.environ['NETCACHE']
314 if v in MODES:
315 host = socket.gethostname()
316 port = 51200
317 mode = v
318 else:
319 mode = 'PUSH_PULL'
320 host, port = v.split(':')
321 if port.find('@'):
322 port, mode = port.split('@')
323 port = int(port)
324 if not mode in MODES:
325 opt.fatal('Invalid mode %s not in %r' % (mode, MODES))
326 setup_netcache(opt, host, port, mode)
327
0 #!/usr/bin/python
1 # Grygoriy Fuchedzhy 2010
2
3 """
4 Support for converting linked targets to ihex, srec or binary files using
5 objcopy. Use the 'objcopy' feature in conjuction with the 'cc' or 'cxx'
6 feature. The 'objcopy' feature uses the following attributes:
7
8 objcopy_bfdname Target object format name (eg. ihex, srec, binary).
9 Defaults to ihex.
10 objcopy_target File name used for objcopy output. This defaults to the
11 target name with objcopy_bfdname as extension.
12 objcopy_install_path Install path for objcopy_target file. Defaults to ${PREFIX}/fw.
13 objcopy_flags Additional flags passed to objcopy.
14 """
15
16 from waflib.Utils import def_attrs
17 from waflib import Task
18 from waflib.TaskGen import feature, after_method
19
20 class objcopy(Task.Task):
21 run_str = '${OBJCOPY} -O ${TARGET_BFDNAME} ${OBJCOPYFLAGS} ${SRC} ${TGT}'
22 color = 'CYAN'
23
24 @feature('objcopy')
25 @after_method('apply_link')
26 def objcopy(self):
27 def_attrs(self,
28 objcopy_bfdname = 'ihex',
29 objcopy_target = None,
30 objcopy_install_path = "${PREFIX}/firmware",
31 objcopy_flags = '')
32
33 link_output = self.link_task.outputs[0]
34 if not self.objcopy_target:
35 self.objcopy_target = link_output.change_ext('.' + self.objcopy_bfdname).name
36 task = self.create_task('objcopy',
37 src=link_output,
38 tgt=self.path.find_or_declare(self.objcopy_target))
39
40 task.env.append_unique('TARGET_BFDNAME', self.objcopy_bfdname)
41 try:
42 task.env.append_unique('OBJCOPYFLAGS', getattr(self, 'objcopy_flags'))
43 except AttributeError:
44 pass
45
46 if self.objcopy_install_path:
47 self.bld.install_files(self.objcopy_install_path,
48 task.outputs[0],
49 env=task.env.derive())
50
51 def configure(ctx):
52 objcopy = ctx.find_program('objcopy', var='OBJCOPY', mandatory=True)
53
0 #!/usr/bin/env python
1 # encoding: utf-8
2 # Thomas Nagy, 2006-2010 (ita)
3
4 "ocaml support"
5
6 import os, re
7 from waflib import TaskGen, Utils, Task, Build
8 from waflib.Logs import error
9 from waflib.TaskGen import feature, before_method, after_method, extension
10
11 EXT_MLL = ['.mll']
12 EXT_MLY = ['.mly']
13 EXT_MLI = ['.mli']
14 EXT_MLC = ['.c']
15 EXT_ML = ['.ml']
16
17 open_re = re.compile('^\s*open\s+([a-zA-Z]+)(;;){0,1}$', re.M)
18 foo = re.compile(r"""(\(\*)|(\*\))|("(\\.|[^"\\])*"|'(\\.|[^'\\])*'|.[^()*"'\\]*)""", re.M)
19 def filter_comments(txt):
20 meh = [0]
21 def repl(m):
22 if m.group(1): meh[0] += 1
23 elif m.group(2): meh[0] -= 1
24 elif not meh[0]: return m.group(0)
25 return ''
26 return foo.sub(repl, txt)
27
28 def scan(self):
29 node = self.inputs[0]
30 code = filter_comments(node.read())
31
32 global open_re
33 names = []
34 import_iterator = open_re.finditer(code)
35 if import_iterator:
36 for import_match in import_iterator:
37 names.append(import_match.group(1))
38 found_lst = []
39 raw_lst = []
40 for name in names:
41 nd = None
42 for x in self.incpaths:
43 nd = x.find_resource(name.lower()+'.ml')
44 if not nd: nd = x.find_resource(name+'.ml')
45 if nd:
46 found_lst.append(nd)
47 break
48 else:
49 raw_lst.append(name)
50
51 return (found_lst, raw_lst)
52
53 native_lst=['native', 'all', 'c_object']
54 bytecode_lst=['bytecode', 'all']
55
56 @feature('ocaml')
57 def init_ml(self):
58 Utils.def_attrs(self,
59 type = 'all',
60 incpaths_lst = [],
61 bld_incpaths_lst = [],
62 mlltasks = [],
63 mlytasks = [],
64 mlitasks = [],
65 native_tasks = [],
66 bytecode_tasks = [],
67 linktasks = [],
68 bytecode_env = None,
69 native_env = None,
70 compiled_tasks = [],
71 includes = '',
72 uselib = '',
73 are_deps_set = 0)
74
75 @feature('ocaml')
76 @after_method('init_ml')
77 def init_envs_ml(self):
78
79 self.islibrary = getattr(self, 'islibrary', False)
80
81 global native_lst, bytecode_lst
82 self.native_env = None
83 if self.type in native_lst:
84 self.native_env = self.env.derive()
85 if self.islibrary: self.native_env['OCALINKFLAGS'] = '-a'
86
87 self.bytecode_env = None
88 if self.type in bytecode_lst:
89 self.bytecode_env = self.env.derive()
90 if self.islibrary: self.bytecode_env['OCALINKFLAGS'] = '-a'
91
92 if self.type == 'c_object':
93 self.native_env.append_unique('OCALINKFLAGS_OPT', '-output-obj')
94
95 @feature('ocaml')
96 @before_method('apply_vars_ml')
97 @after_method('init_envs_ml')
98 def apply_incpaths_ml(self):
99 inc_lst = self.includes.split()
100 lst = self.incpaths_lst
101 for dir in inc_lst:
102 node = self.path.find_dir(dir)
103 if not node:
104 error("node not found: " + str(dir))
105 continue
106 if not node in lst:
107 lst.append(node)
108 self.bld_incpaths_lst.append(node)
109 # now the nodes are added to self.incpaths_lst
110
111 @feature('ocaml')
112 @before_method('process_source')
113 def apply_vars_ml(self):
114 for i in self.incpaths_lst:
115 if self.bytecode_env:
116 app = self.bytecode_env.append_value
117 app('OCAMLPATH', ['-I', i.bldpath(), '-I', i.srcpath()])
118
119 if self.native_env:
120 app = self.native_env.append_value
121 app('OCAMLPATH', ['-I', i.bldpath(), '-I', i.srcpath()])
122
123 varnames = ['INCLUDES', 'OCAMLFLAGS', 'OCALINKFLAGS', 'OCALINKFLAGS_OPT']
124 for name in self.uselib.split():
125 for vname in varnames:
126 cnt = self.env[vname+'_'+name]
127 if cnt:
128 if self.bytecode_env: self.bytecode_env.append_value(vname, cnt)
129 if self.native_env: self.native_env.append_value(vname, cnt)
130
131 @feature('ocaml')
132 @after_method('process_source')
133 def apply_link_ml(self):
134
135 if self.bytecode_env:
136 ext = self.islibrary and '.cma' or '.run'
137
138 linktask = self.create_task('ocalink')
139 linktask.bytecode = 1
140 linktask.set_outputs(self.path.find_or_declare(self.target + ext))
141 linktask.env = self.bytecode_env
142 self.linktasks.append(linktask)
143
144 if self.native_env:
145 if self.type == 'c_object': ext = '.o'
146 elif self.islibrary: ext = '.cmxa'
147 else: ext = ''
148
149 linktask = self.create_task('ocalinkx')
150 linktask.set_outputs(self.path.find_or_declare(self.target + ext))
151 linktask.env = self.native_env
152 self.linktasks.append(linktask)
153
154 # we produce a .o file to be used by gcc
155 self.compiled_tasks.append(linktask)
156
157 @extension(*EXT_MLL)
158 def mll_hook(self, node):
159 mll_task = self.create_task('ocamllex', node, node.change_ext('.ml'))
160 mll_task.env = self.native_env.derive()
161 self.mlltasks.append(mll_task)
162
163 self.source.append(mll_task.outputs[0])
164
165 @extension(*EXT_MLY)
166 def mly_hook(self, node):
167 mly_task = self.create_task('ocamlyacc', node, [node.change_ext('.ml'), node.change_ext('.mli')])
168 mly_task.env = self.native_env.derive()
169 self.mlytasks.append(mly_task)
170 self.source.append(mly_task.outputs[0])
171
172 task = self.create_task('ocamlcmi', mly_task.outputs[1], mly_task.outputs[1].change_ext('.cmi'))
173 task.env = self.native_env.derive()
174
175 @extension(*EXT_MLI)
176 def mli_hook(self, node):
177 task = self.create_task('ocamlcmi', node, node.change_ext('.cmi'))
178 task.env = self.native_env.derive()
179 self.mlitasks.append(task)
180
181 @extension(*EXT_MLC)
182 def mlc_hook(self, node):
183 task = self.create_task('ocamlcc', node, node.change_ext('.o'))
184 task.env = self.native_env.derive()
185 self.compiled_tasks.append(task)
186
187 @extension(*EXT_ML)
188 def ml_hook(self, node):
189 if self.native_env:
190 task = self.create_task('ocamlx', node, node.change_ext('.cmx'))
191 task.env = self.native_env.derive()
192 task.incpaths = self.bld_incpaths_lst
193 self.native_tasks.append(task)
194
195 if self.bytecode_env:
196 task = self.create_task('ocaml', node, node.change_ext('.cmo'))
197 task.env = self.bytecode_env.derive()
198 task.bytecode = 1
199 task.incpaths = self.bld_incpaths_lst
200 self.bytecode_tasks.append(task)
201
202 def compile_may_start(self):
203
204 if not getattr(self, 'flag_deps', ''):
205 self.flag_deps = 1
206
207 # the evil part is that we can only compute the dependencies after the
208 # source files can be read (this means actually producing the source files)
209 if getattr(self, 'bytecode', ''): alltasks = self.generator.bytecode_tasks
210 else: alltasks = self.generator.native_tasks
211
212 self.signature() # ensure that files are scanned - unfortunately
213 tree = self.generator.bld
214 env = self.env
215 for node in self.inputs:
216 lst = tree.node_deps[self.uid()]
217 for depnode in lst:
218 for t in alltasks:
219 if t == self: continue
220 if depnode in t.inputs:
221 self.set_run_after(t)
222
223 # TODO necessary to get the signature right - for now
224 delattr(self, 'cache_sig')
225 self.signature()
226
227 return Task.Task.runnable_status(self)
228
229 class ocamlx(Task.Task):
230 """native caml compilation"""
231 color = 'GREEN'
232 run_str = '${OCAMLOPT} ${OCAMLPATH} ${OCAMLFLAGS} ${OCAMLINCLUDES} -c -o ${TGT} ${SRC}'
233 scan = scan
234 runnable_status = compile_may_start
235
236 class ocaml(Task.Task):
237 """bytecode caml compilation"""
238 color = 'GREEN'
239 run_str = '${OCAMLC} ${OCAMLPATH} ${OCAMLFLAGS} ${OCAMLINCLUDES} -c -o ${TGT} ${SRC}'
240 scan = scan
241 runnable_status = compile_may_start
242
243 class ocamlcmi(Task.Task):
244 """interface generator (the .i files?)"""
245 color = 'BLUE'
246 run_str = '${OCAMLC} ${OCAMLPATH} ${OCAMLINCLUDES} -o ${TGT} -c ${SRC}'
247 before = ['ocamlcc', 'ocaml', 'ocamlcc']
248
249 class ocamlcc(Task.Task):
250 """ocaml to c interfaces"""
251 color = 'GREEN'
252 run_str = 'cd ${TGT[0].bld_dir()} && ${OCAMLOPT} ${OCAMLFLAGS} ${OCAMLPATH} ${OCAMLINCLUDES} -c ${SRC[0].abspath()}'
253
254 class ocamllex(Task.Task):
255 """lexical generator"""
256 color = 'BLUE'
257 run_str = '${OCAMLLEX} ${SRC} -o ${TGT}'
258 before = ['ocamlcmi', 'ocaml', 'ocamlcc']
259
260 class ocamlyacc(Task.Task):
261 """parser generator"""
262 color = 'BLUE'
263 run_str = '${OCAMLYACC} -b ${TGT[0].bld_base(env)} ${SRC}'
264 before = ['ocamlcmi', 'ocaml', 'ocamlcc']
265
266 def link_may_start(self):
267
268 if getattr(self, 'bytecode', 0): alltasks = self.generator.bytecode_tasks
269 else: alltasks = self.generator.native_tasks
270
271 for x in alltasks:
272 if not x.hasrun:
273 return Task.ASK_LATER
274
275 if not getattr(self, 'order', ''):
276
277 # now reorder the inputs given the task dependencies
278 # this part is difficult, we do not have a total order on the tasks
279 # if the dependencies are wrong, this may not stop
280 seen = []
281 pendant = []+alltasks
282 while pendant:
283 task = pendant.pop(0)
284 if task in seen: continue
285 for x in task.run_after:
286 if not x in seen:
287 pendant.append(task)
288 break
289 else:
290 seen.append(task)
291 self.inputs = [x.outputs[0] for x in seen]
292 self.order = 1
293 return Task.Task.runnable_status(self)
294
295 class ocalink(Task.Task):
296 """bytecode caml link"""
297 color = 'YELLOW'
298 run_str = '${OCAMLC} -o ${TGT} ${OCAMLINCLUDES} ${OCALINKFLAGS} ${SRC}'
299 runnable_status = link_may_start
300 after = ['ocaml', 'ocamlcc']
301
302 class ocalinkx(Task.Task):
303 """native caml link"""
304 color = 'YELLOW'
305 run_str = '${OCAMLOPT} -o ${TGT} ${OCAMLINCLUDES} ${OCALINKFLAGS_OPT} ${SRC}'
306 runnable_status = link_may_start
307 after = ['ocamlx', 'ocamlcc']
308
309 def configure(conf):
310 opt = conf.find_program('ocamlopt', var='OCAMLOPT', mandatory=False)
311 occ = conf.find_program('ocamlc', var='OCAMLC', mandatory=False)
312 if (not opt) or (not occ):
313 conf.fatal('The objective caml compiler was not found:\ninstall it or make it available in your PATH')
314
315 v = conf.env
316 v['OCAMLC'] = occ
317 v['OCAMLOPT'] = opt
318 v['OCAMLLEX'] = conf.find_program('ocamllex', var='OCAMLLEX', mandatory=False)
319 v['OCAMLYACC'] = conf.find_program('ocamlyacc', var='OCAMLYACC', mandatory=False)
320 v['OCAMLFLAGS'] = ''
321 v['OCAMLLIB'] = conf.cmd_and_log(conf.env['OCAMLC']+' -where').strip()+os.sep
322 v['LIBPATH_OCAML'] = conf.cmd_and_log(conf.env['OCAMLC']+' -where').strip()+os.sep
323 v['INCLUDES_OCAML'] = conf.cmd_and_log(conf.env['OCAMLC']+' -where').strip()+os.sep
324 v['LIB_OCAML'] = 'camlrun'
325
0 #! /usr/bin/env python
1 # encoding: utf-8
2 # Thomas Nagy, 2011
3
4 """
5 Obtain packages, unpack them in a location, and add associated uselib variables
6 (CFLAGS_pkgname, LIBPATH_pkgname, etc).
7
8 The default is use a Dependencies.txt file in the source directory.
9
10 This is a work in progress.
11
12 Usage:
13
14 def options(opt):
15 opt.load('package')
16
17 def configure(conf):
18 conf.load_packages()
19 """
20
21 from waflib import Logs
22 from waflib.Configure import conf
23
24 try:
25 from urllib import request
26 except:
27 from urllib import urlopen
28 else:
29 urlopen = request.urlopen
30
31
32 CACHEVAR = 'WAFCACHE_PACKAGE'
33
34 @conf
35 def get_package_cache_dir(self):
36 cache = None
37 if CACHEVAR in conf.environ:
38 cache = conf.environ[CACHEVAR]
39 cache = self.root.make_node(cache)
40 elif self.env[CACHEVAR]:
41 cache = self.env[CACHEVAR]
42 cache = self.root.make_node(cache)
43 else:
44 cache = self.srcnode.make_node('.wafcache_package')
45 cache.mkdir()
46 return cache
47
48 @conf
49 def download_archive(self, src, dst):
50 for x in self.env.PACKAGE_REPO:
51 url = '/'.join((x, src))
52 try:
53 web = urlopen(url)
54 try:
55 if web.getcode() != 200:
56 continue
57 except AttributeError:
58 pass
59 except Exception:
60 # on python3 urlopen throws an exception
61 # python 2.3 does not have getcode and throws an exception to fail
62 continue
63 else:
64 tmp = self.root.make_node(dst)
65 tmp.write(web.read())
66 Logs.warn('Downloaded %s from %s' % (tmp.abspath(), url))
67 break
68 else:
69 self.fatal('Could not get the package %s' % src)
70
71 @conf
72 def load_packages(self):
73 cache = self.get_package_cache_dir()
74 # read the dependencies, get the archives, ..
75
0 #! /usr/bin/env python
1 # encoding: utf-8
2 # Thomas Nagy, 2007-2010 (ita)
3
4 """
5 Debugging helper for parallel compilation, outputs
6 a file named pdebug.svg in the source directory::
7
8 def options(opt):
9 opt.load('parallel_debug')
10 def configure(conf):
11 conf.load('parallel_debug')
12 def build(bld):
13 ...
14 """
15
16 import os, time, sys
17 try: from Queue import Queue
18 except: from queue import Queue
19 from waflib import Runner, Options, Utils, Task, Logs, Errors
20
21 #import random
22 #random.seed(100)
23
24 def options(opt):
25 opt.add_option('--dtitle', action='store', default='Parallel build representation for %r' % ' '.join(sys.argv),
26 help='title for the svg diagram', dest='dtitle')
27 opt.add_option('--dwidth', action='store', type='int', help='diagram width', default=800, dest='dwidth')
28 opt.add_option('--dtime', action='store', type='float', help='recording interval in seconds', default=0.009, dest='dtime')
29 opt.add_option('--dband', action='store', type='int', help='band width', default=22, dest='dband')
30 opt.add_option('--dmaxtime', action='store', type='float', help='maximum time, for drawing fair comparisons', default=0, dest='dmaxtime')
31
32 # red #ff4d4d
33 # green #4da74d
34 # lila #a751ff
35
36 color2code = {
37 'GREEN' : '#4da74d',
38 'YELLOW' : '#fefe44',
39 'PINK' : '#a751ff',
40 'RED' : '#cc1d1d',
41 'BLUE' : '#6687bb',
42 'CYAN' : '#34e2e2',
43 }
44
45 mp = {}
46 info = [] # list of (text,color)
47
48 def map_to_color(name):
49 if name in mp:
50 return mp[name]
51 try:
52 cls = Task.classes[name]
53 except KeyError:
54 return color2code['RED']
55 if cls.color in mp:
56 return mp[cls.color]
57 if cls.color in color2code:
58 return color2code[cls.color]
59 return color2code['RED']
60
61 def process(self):
62 m = self.master
63 if m.stop:
64 m.out.put(self)
65 return
66
67 self.master.set_running(1, id(Utils.threading.currentThread()), self)
68
69 # remove the task signature immediately before it is executed
70 # in case of failure the task will be executed again
71 try:
72 del self.generator.bld.task_sigs[self.uid()]
73 except:
74 pass
75
76 try:
77 self.generator.bld.returned_tasks.append(self)
78 self.log_display(self.generator.bld)
79 ret = self.run()
80 except Exception:
81 self.err_msg = Utils.ex_stack()
82 self.hasrun = Task.EXCEPTION
83
84 # TODO cleanup
85 m.error_handler(self)
86 m.out.put(self)
87 return
88
89 if ret:
90 self.err_code = ret
91 self.hasrun = Task.CRASHED
92 else:
93 try:
94 self.post_run()
95 except Errors.WafError:
96 pass
97 except Exception:
98 self.err_msg = Utils.ex_stack()
99 self.hasrun = Task.EXCEPTION
100 else:
101 self.hasrun = Task.SUCCESS
102 if self.hasrun != Task.SUCCESS:
103 m.error_handler(self)
104
105 self.master.set_running(-1, id(Utils.threading.currentThread()), self)
106 m.out.put(self)
107 Task.TaskBase.process_back = Task.TaskBase.process
108 Task.TaskBase.process = process
109
110 old_start = Runner.Parallel.start
111 def do_start(self):
112 try:
113 Options.options.dband
114 except AttributeError:
115 self.bld.fatal('use def options(opt): opt.load("parallel_debug")!')
116
117 self.taskinfo = Queue()
118 old_start(self)
119 if self.dirty:
120 process_colors(self)
121 Runner.Parallel.start = do_start
122
123 def set_running(self, by, i, tsk):
124 self.taskinfo.put( (i, id(tsk), time.time(), tsk.__class__.__name__, self.processed, self.count, by) )
125 Runner.Parallel.set_running = set_running
126
127 def name2class(name):
128 return name.replace(' ', '_').replace('.', '_')
129
130 def process_colors(producer):
131 # first, cast the parameters
132 tmp = []
133 try:
134 while True:
135 tup = producer.taskinfo.get(False)
136 tmp.append(list(tup))
137 except:
138 pass
139
140 try:
141 ini = float(tmp[0][2])
142 except:
143 return
144
145 if not info:
146 seen = []
147 for x in tmp:
148 name = x[3]
149 if not name in seen:
150 seen.append(name)
151 else:
152 continue
153
154 info.append((name, map_to_color(name)))
155 info.sort(key=lambda x: x[0])
156
157 thread_count = 0
158 acc = []
159 for x in tmp:
160 thread_count += x[6]
161 acc.append("%d %d %f %r %d %d %d" % (x[0], x[1], x[2] - ini, x[3], x[4], x[5], thread_count))
162 data_node = producer.bld.path.make_node('pdebug.dat')
163 data_node.write('\n'.join(acc))
164
165 tmp = [lst[:2] + [float(lst[2]) - ini] + lst[3:] for lst in tmp]
166
167 st = {}
168 for l in tmp:
169 if not l[0] in st:
170 st[l[0]] = len(st.keys())
171 tmp = [ [st[lst[0]]] + lst[1:] for lst in tmp ]
172 THREAD_AMOUNT = len(st.keys())
173
174 st = {}
175 for l in tmp:
176 if not l[1] in st:
177 st[l[1]] = len(st.keys())
178 tmp = [ [lst[0]] + [st[lst[1]]] + lst[2:] for lst in tmp ]
179
180
181 BAND = Options.options.dband
182
183 seen = {}
184 acc = []
185 for x in range(len(tmp)):
186 line = tmp[x]
187 id = line[1]
188
189 if id in seen:
190 continue
191 seen[id] = True
192
193 begin = line[2]
194 thread_id = line[0]
195 for y in range(x + 1, len(tmp)):
196 line = tmp[y]
197 if line[1] == id:
198 end = line[2]
199 #print id, thread_id, begin, end
200 #acc.append( ( 10*thread_id, 10*(thread_id+1), 10*begin, 10*end ) )
201 acc.append( (BAND * begin, BAND*thread_id, BAND*end - BAND*begin, BAND, line[3]) )
202 break
203
204 if Options.options.dmaxtime < 0.1:
205 gwidth = 1
206 for x in tmp:
207 m = BAND * x[2]
208 if m > gwidth:
209 gwidth = m
210 else:
211 gwidth = BAND * Options.options.dmaxtime
212
213 ratio = float(Options.options.dwidth) / gwidth
214 gwidth = Options.options.dwidth
215
216 gheight = BAND * (THREAD_AMOUNT + len(info) + 1.5)
217
218 out = []
219
220 out.append("""<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>
221 <!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.0//EN\"
222 \"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd\">
223 <svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" version=\"1.0\"
224 x=\"%r\" y=\"%r\" width=\"%r\" height=\"%r\"
225 id=\"svg602\" xml:space=\"preserve\">
226
227 <style type='text/css' media='screen'>
228 g.over rect { stroke:#FF0000; fill-opacity:0.4 }
229 </style>
230
231 <script type='text/javascript'><![CDATA[
232 var svg = document.getElementsByTagName('svg')[0];
233
234 svg.addEventListener('mouseover', function(e) {
235 var g = e.target.parentNode;
236 var x = document.getElementById('r_' + g.id);
237 if (x) {
238 g.setAttribute('class', g.getAttribute('class') + ' over');
239 x.setAttribute('class', x.getAttribute('class') + ' over');
240 showInfo(e, g.id);
241 }
242 }, false);
243
244 svg.addEventListener('mouseout', function(e) {
245 var g = e.target.parentNode;
246 var x = document.getElementById('r_' + g.id);
247 if (x) {
248 g.setAttribute('class', g.getAttribute('class').replace(' over', ''));
249 x.setAttribute('class', x.getAttribute('class').replace(' over', ''));
250 hideInfo(e);
251 }
252 }, false);
253
254 function showInfo(evt, txt) {
255 tooltip = document.getElementById('tooltip');
256
257 var t = document.getElementById('tooltiptext');
258 t.firstChild.data = txt;
259
260 var x = evt.clientX + 9;
261 if (x > 250) { x -= t.getComputedTextLength() + 16; }
262 var y = evt.clientY + 20;
263 tooltip.setAttribute("transform", "translate(" + x + "," + y + ")");
264 tooltip.setAttributeNS(null, "visibility", "visible");
265
266 var r = document.getElementById('tooltiprect');
267 r.setAttribute('width', t.getComputedTextLength() + 6);
268 }
269
270 function hideInfo(evt) {
271 var tooltip = document.getElementById('tooltip');
272 tooltip.setAttributeNS(null,"visibility","hidden");
273 }
274 ]]></script>
275
276 <!-- inkscape requires a big rectangle or it will not export the pictures properly -->
277 <rect
278 x='%r' y='%r'
279 width='%r' height='%r'
280 style=\"font-size:10;fill:#ffffff;fill-opacity:0.01;fill-rule:evenodd;stroke:#ffffff;\"
281 />\n
282
283 """ % (0, 0, gwidth + 4, gheight + 4, 0, 0, gwidth + 4, gheight + 4))
284
285 # main title
286 if Options.options.dtitle:
287 out.append("""<text x="%d" y="%d" style="font-size:15px; text-anchor:middle; font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans">%s</text>
288 """ % (gwidth/2, gheight - 5, Options.options.dtitle))
289
290 # the rectangles
291
292 groups = {}
293 for (x, y, w, h, clsname) in acc:
294 try:
295 groups[clsname].append((x, y, w, h))
296 except:
297 groups[clsname] = [(x, y, w, h)]
298 for cls in groups:
299 out.append("<g id='%s'>\n" % name2class(cls))
300
301 for (x, y, w, h) in groups[cls]:
302 out.append("""<rect
303 x='%r' y='%r'
304 width='%r' height='%r'
305 style=\"font-size:10;fill:%s;fill-rule:evenodd;stroke:#000000;stroke-width:0.4;\"
306 />\n""" % (2 + x*ratio, 2 + y, w*ratio, h, map_to_color(cls)))
307 out.append("</g>\n")
308
309 # output the caption
310 cnt = THREAD_AMOUNT
311
312 for (text, color) in info:
313 # caption box
314 b = BAND/2
315 out.append("""<g id='r_%s'><rect
316 x='%r' y='%r'
317 width='%r' height='%r'
318 style=\"font-size:10;fill:%s;fill-rule:evenodd;stroke:#000000;stroke-width:0.4;\"
319 />\n""" % (name2class(text), 2 + BAND, 5 + (cnt + 0.5) * BAND, b, b, color))
320
321 # caption text
322 out.append("""<text
323 style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
324 x="%r" y="%d">%s</text></g>\n""" % (2 + 2 * BAND, 5 + (cnt + 0.5) * BAND + 10, text))
325 cnt += 1
326
327 out.append("""
328 <g transform="translate(0,0)" visibility="hidden" id="tooltip">
329 <rect id="tooltiprect" y="-15" x="-3" width="1" height="20" style="stroke:black;fill:#edefc2;stroke-width:1"/>
330 <text id="tooltiptext" style="font-family:Arial; font-size:12;fill:black;"> </text>
331 </g>""")
332
333 out.append("\n</svg>")
334
335 node = producer.bld.path.make_node('pdebug.svg')
336 node.write("".join(out))
337 Logs.warn('Created the diagram %r' % node.abspath())
338
339 p = node.parent.abspath()
340 producer.bld.exec_command(['convert', p + os.sep + 'pdebug.svg', p + os.sep + 'pdebug.png'])
341
0 #! /usr/bin/env python
1 # encoding: utf-8
2 #
3 # written by Sylvain Rouquette, 2011
4
5 '''
6 Install pep8 module:
7 $ easy_install pep8
8 or
9 $ pip install pep8
10
11 To add the boost tool to the waf file:
12 $ ./waf-light --tools=compat15,pep8
13 or, if you have waf >= 1.6.2
14 $ ./waf update --files=pep8
15
16
17 Then add this to your wscript:
18
19 [at]extension('.py', 'wscript')
20 def run_pep8(self, node):
21 self.create_task('Pep8', node)
22
23 '''
24
25 import threading
26 from waflib import TaskGen, Task, Options
27
28 pep8 = __import__('pep8')
29
30
31 class Pep8(Task.Task):
32 color = 'PINK'
33 lock = threading.Lock()
34
35 def check_options(self):
36 if pep8.options:
37 return
38 pep8.options = Options.options
39 pep8.options.prog = 'pep8'
40 excl = pep8.options.exclude.split(',')
41 pep8.options.exclude = [s.rstrip('/') for s in excl]
42 if pep8.options.filename:
43 pep8.options.filename = pep8.options.filename.split(',')
44 if pep8.options.select:
45 pep8.options.select = pep8.options.select.split(',')
46 else:
47 pep8.options.select = []
48 if pep8.options.ignore:
49 pep8.options.ignore = pep8.options.ignore.split(',')
50 elif pep8.options.select:
51 # Ignore all checks which are not explicitly selected
52 pep8.options.ignore = ['']
53 elif pep8.options.testsuite or pep8.options.doctest:
54 # For doctest and testsuite, all checks are required
55 pep8.options.ignore = []
56 else:
57 # The default choice: ignore controversial checks
58 pep8.options.ignore = pep8.DEFAULT_IGNORE.split(',')
59 pep8.options.physical_checks = pep8.find_checks('physical_line')
60 pep8.options.logical_checks = pep8.find_checks('logical_line')
61 pep8.options.counters = dict.fromkeys(pep8.BENCHMARK_KEYS, 0)
62 pep8.options.messages = {}
63
64 def run(self):
65 with Pep8.lock:
66 self.check_options()
67 pep8.input_file(self.inputs[0].abspath())
68 return 0 if not pep8.get_count() else -1
69
70
71 def options(opt):
72 opt.add_option('-q', '--quiet', default=0, action='count',
73 help="report only file names, or nothing with -qq")
74 opt.add_option('-r', '--repeat', action='store_true',
75 help="show all occurrences of the same error")
76 opt.add_option('--exclude', metavar='patterns',
77 default=pep8.DEFAULT_EXCLUDE,
78 help="exclude files or directories which match these "
79 "comma separated patterns (default: %s)" %
80 pep8.DEFAULT_EXCLUDE,
81 dest='exclude')
82 opt.add_option('--filename', metavar='patterns', default='*.py',
83 help="when parsing directories, only check filenames "
84 "matching these comma separated patterns (default: "
85 "*.py)")
86 opt.add_option('--select', metavar='errors', default='',
87 help="select errors and warnings (e.g. E,W6)")
88 opt.add_option('--ignore', metavar='errors', default='',
89 help="skip errors and warnings (e.g. E4,W)")
90 opt.add_option('--show-source', action='store_true',
91 help="show source code for each error")
92 opt.add_option('--show-pep8', action='store_true',
93 help="show text of PEP 8 for each error")
94 opt.add_option('--statistics', action='store_true',
95 help="count errors and warnings")
96 opt.add_option('--count', action='store_true',
97 help="print total number of errors and warnings "
98 "to standard error and set exit code to 1 if "
99 "total is not null")
100 opt.add_option('--benchmark', action='store_true',
101 help="measure processing speed")
102 opt.add_option('--testsuite', metavar='dir',
103 help="run regression tests from dir")
104 opt.add_option('--doctest', action='store_true',
105 help="run doctest on myself")
0 #!/usr/bin/env python
1 # encoding: utf-8
2 # Antoine Dechaume 2011
3
4 """
5 Detect the PGI C compiler
6 """
7
8 import sys, re
9 from waflib.Configure import conf
10 from waflib.Tools.compiler_c import c_compiler
11 c_compiler['linux'].append('pgicc')
12
13 @conf
14 def find_pgi_compiler(conf, var, name):
15 """
16 Find the program name, and execute it to ensure it really is itself.
17 """
18 if sys.platform == 'cygwin':
19 conf.fatal('The PGI compiler does not work on Cygwin')
20
21 v = conf.env
22 cc = None
23 if v[var]: cc = v[var]
24 elif var in conf.environ: cc = conf.environ[var]
25 if not cc: cc = conf.find_program(name, var=var)
26 if not cc: conf.fatal('PGI Compiler (%s) was not found' % name)
27 cc = conf.cmd_to_list(cc)
28
29 v[var + '_VERSION'] = conf.get_pgi_version(cc)
30 v[var] = cc
31 v[var + '_NAME'] = 'pgi'
32
33 @conf
34 def get_pgi_version(conf, cc):
35 """Find the version of a pgi compiler."""
36 version_re = re.compile(r"The Portland Group", re.I).search
37 cmd = cc + ['-V', '-E'] # Issue 1078, prevent wrappers from linking
38
39 try:
40 out, err = conf.cmd_and_log(cmd, output=0)
41 except Exception:
42 conf.fatal('Could not find pgi compiler %r' % cmd)
43
44 if out: match = version_re(out)
45 else: match = version_re(err)
46
47 if not match:
48 conf.fatal('Could not verify PGI signature')
49
50 cmd = cc + ['-help=variable']
51 try:
52 out, err = conf.cmd_and_log(cmd, output=0)
53 except Exception:
54 conf.fatal('Could not find pgi compiler %r' % cmd)
55
56 version = re.findall('^COMPVER\s*=(.*)', out, re.M)
57 if len(version) != 1:
58 conf.fatal('Could not determine the compiler version')
59 return version[0]
60
61 def configure(conf):
62 conf.find_pgi_compiler('CC', 'pgcc')
63 conf.find_ar()
64 conf.gcc_common_flags()
65 conf.cc_load_tools()
66 conf.cc_add_flags()
67 conf.link_add_flags()
68
0 #!/usr/bin/env python
1 # encoding: utf-8
2 # Antoine Dechaume 2011
3
4 """
5 Detect the PGI C++ compiler
6 """
7
8 import sys, re
9 from waflib.Configure import conf
10 from waflib.Tools.compiler_cxx import cxx_compiler
11 cxx_compiler['linux'].append('pgicxx')
12
13 from waflib.extras import pgicc
14
15 def configure(conf):
16 conf.find_pgi_compiler('CXX', 'pgCC')
17 conf.find_ar()
18 conf.gxx_common_flags()
19 conf.cxx_load_tools()
20 conf.cxx_add_flags()
21 conf.link_add_flags()
0 #! /usr/bin/env python
1
2 """
3 Illustrate how to override a class method to do something
4
5 In this case, print the commands being executed as strings
6 (the commands are usually lists, so this can be misleading)
7 """
8
9 import sys
10 from waflib import Context, Utils, Logs
11
12 def exec_command(self, cmd, **kw):
13 subprocess = Utils.subprocess
14 kw['shell'] = isinstance(cmd, str)
15
16 txt = cmd
17 if isinstance(cmd, list):
18 txt = ' '.join(cmd)
19
20 print(txt)
21 Logs.debug('runner_env: kw=%s' % kw)
22
23 try:
24 if self.logger:
25 # warning: may deadlock with a lot of output (subprocess limitation)
26
27 self.logger.info(cmd)
28
29 kw['stdout'] = kw['stderr'] = subprocess.PIPE
30 p = subprocess.Popen(cmd, **kw)
31 (out, err) = p.communicate()
32 if out:
33 self.logger.debug('out: %s' % out.decode(sys.stdout.encoding or 'iso8859-1'))
34 if err:
35 self.logger.error('err: %s' % err.decode(sys.stdout.encoding or 'iso8859-1'))
36 return p.returncode
37 else:
38 p = subprocess.Popen(cmd, **kw)
39 return p.wait()
40 except OSError:
41 return -1
42
43 Context.Context.exec_command = exec_command
44
45
0 #! /usr/bin/env python
1 # per rosengren 2011
2
3 from os import environ, path
4 from waflib import TaskGen, Utils
5
6 def options(opt):
7 grp = opt.add_option_group('Oracle ProC Options')
8 grp.add_option('--oracle_home', action='store', default=environ.get('PROC_ORACLE'), help='Path to Oracle installation home (has bin/lib)')
9 grp.add_option('--tns_admin', action='store', default=environ.get('TNS_ADMIN'), help='Directory containing server list (TNS_NAMES.ORA)')
10 grp.add_option('--connection', action='store', default='dummy-user/dummy-password@dummy-server', help='Format: user/password@server')
11
12 def configure(cnf):
13 env = cnf.env
14 if not env.PROC_ORACLE:
15 env.PROC_ORACLE = cnf.options.oracle_home
16 if not env.PROC_TNS_ADMIN:
17 env.PROC_TNS_ADMIN = cnf.options.tns_admin
18 if not env.PROC_CONNECTION:
19 env.PROC_CONNECTION = cnf.options.connection
20 cnf.find_program('proc', var='PROC', path_list=env.PROC_ORACLE + path.sep + 'bin')
21
22 def proc(tsk):
23 env = tsk.env
24 gen = tsk.generator
25 bld = gen.bld
26 inc_nodes = gen.to_incnodes(Utils.to_list(getattr(gen,'includes',[])) + env['INCLUDES'])
27
28 # FIXME the if-else construct will not work in python 2
29 cmd = (
30 [env.PROC] +
31 ['SQLCHECK=SEMANTICS'] +
32 (['SYS_INCLUDE=(' + ','.join(env.PROC_INCLUDES) + ')']
33 if env.PROC_INCLUDES else []) +
34 ['INCLUDE=(' + ','.join(
35 [i.bldpath() for i in inc_nodes]
36 ) + ')'] +
37 ['userid=' + env.PROC_CONNECTION] +
38 ['INAME=' + tsk.inputs[0].bldpath()] +
39 ['ONAME=' + tsk.outputs[0].bldpath()]
40 )
41 exec_env = {
42 'ORACLE_HOME': env.PROC_ORACLE,
43 'LD_LIBRARY_PATH': env.PROC_ORACLE + path.sep + 'lib',
44 }
45 if env.PROC_TNS_ADMIN:
46 exec_env['TNS_ADMIN'] = env.PROC_TNS_ADMIN
47 return tsk.exec_command(cmd, env=exec_env)
48
49 TaskGen.declare_chain(
50 name = 'proc',
51 rule = proc,
52 ext_in = '.pc',
53 ext_out = '.c',
54 )
55
0 #!/usr/bin/env python
1 # encoding: utf-8
2 # Jérôme Carretero 2011 (zougloub)
3 # QNX neutrino compatibility functions
4
5 import sys, os
6 from waflib import Utils
7
8 class Popen(object):
9 """
10 Popen cannot work on QNX from a threaded program:
11 Forking in threads is not implemented in neutrino.
12
13 Python's os.popen / spawn / fork won't work when running in threads (they will if in the main program thread)
14
15 In waf, this happens mostly in build.
16 And the use cases can be replaced by os.system() calls.
17 """
18 __slots__ = ["prog", "kw", "popen", "verbose"]
19 verbose = 0
20 def __init__(self, prog, **kw):
21 try:
22 self.prog = prog
23 self.kw = kw
24 self.popen = None
25 if Popen.verbose:
26 sys.stdout.write("Popen created: %r, kw=%r..." % (prog, kw))
27
28 do_delegate = kw.get('stdout', None) == -1 and kw.get('stderr', None) == -1
29 if do_delegate:
30 if Popen.verbose:
31 print("Delegating to real Popen")
32 self.popen = self.real_Popen(prog, **kw)
33 else:
34 if Popen.verbose:
35 print("Emulating")
36 except Exception as e:
37 if Popen.verbose:
38 print("Exception: %s" % e)
39 raise
40
41 def __getattr__(self, name):
42 if Popen.verbose:
43 sys.stdout.write("Getattr: %s..." % name)
44 if name in Popen.__slots__:
45 if Popen.verbose:
46 print("In slots!")
47 return object.__getattr__(self, name)
48 else:
49 if self.popen is not None:
50 if Popen.verbose:
51 print("from Popen")
52 return getattr(self.popen, name)
53 else:
54 if name == "wait":
55 return self.emu_wait
56 else:
57 raise Exception("subprocess emulation: not implemented: %s" % name)
58
59 def emu_wait(self):
60 if Popen.verbose:
61 print("emulated wait (%r kw=%r)" % (self.prog, self.kw))
62 if isinstance(self.prog, str):
63 cmd = self.prog
64 else:
65 cmd = " ".join(self.prog)
66 if 'cwd' in self.kw:
67 cmd = 'cd "%s" && %s' % (self.kw['cwd'], cmd)
68 return os.system(cmd)
69
70 if sys.platform == "qnx6":
71 Popen.real_Popen = Utils.subprocess.Popen
72 Utils.subprocess.Popen = Popen
73
0 #! /usr/bin/env python
1 # encoding: utf-8
2
3 """
4 Waf 1.6
5
6 Try to detect if the project directory was relocated, and if it was,
7 change the node representing the project directory. Just call:
8
9 waf configure build
10
11 Note that if the project directory name changes, the signatures for the tasks using
12 files in that directory will change, causing a partial build.
13 """
14
15 import os
16 from waflib import Build, ConfigSet, Task, Utils, Errors
17 from waflib.TaskGen import feature, before_method, after_method
18
19 EXTRA_LOCK = '.old_srcdir'
20
21 old1 = Build.BuildContext.store
22 def store(self):
23 old1(self)
24 db = os.path.join(self.variant_dir, EXTRA_LOCK)
25 env = ConfigSet.ConfigSet()
26 env.SRCDIR = self.srcnode.abspath()
27 env.store(db)
28 Build.BuildContext.store = store
29
30 old2 = Build.BuildContext.init_dirs
31 def init_dirs(self):
32
33 if not (os.path.isabs(self.top_dir) and os.path.isabs(self.out_dir)):
34 raise Errors.WafError('The project was not configured: run "waf configure" first!')
35
36 srcdir = None
37 db = os.path.join(self.variant_dir, EXTRA_LOCK)
38 env = ConfigSet.ConfigSet()
39 try:
40 env.load(db)
41 srcdir = env.SRCDIR
42 except:
43 pass
44
45 if srcdir:
46 d = self.root.find_node(srcdir)
47 if d and srcdir != self.top_dir and getattr(d, 'children', ''):
48 srcnode = self.root.make_node(self.top_dir)
49 print("relocating the source directory %r -> %r" % (srcdir, self.top_dir))
50 srcnode.children = {}
51
52 for (k, v) in d.children.items():
53 srcnode.children[k] = v
54 v.parent = srcnode
55 d.children = {}
56
57 old2(self)
58
59 Build.BuildContext.init_dirs = init_dirs
60
61
62 def uid(self):
63 try:
64 return self.uid_
65 except AttributeError:
66 # this is not a real hot zone, but we want to avoid surprizes here
67 m = Utils.md5()
68 up = m.update
69 up(self.__class__.__name__.encode())
70 for x in self.inputs + self.outputs:
71 up(x.path_from(x.ctx.srcnode).encode())
72 self.uid_ = m.digest()
73 return self.uid_
74 Task.Task.uid = uid
75
76 @feature('c', 'cxx', 'd', 'go', 'asm', 'fc', 'includes')
77 @after_method('propagate_uselib_vars', 'process_source')
78 def apply_incpaths(self):
79 lst = self.to_incnodes(self.to_list(getattr(self, 'includes', [])) + self.env['INCLUDES'])
80 self.includes_nodes = lst
81 bld = self.bld
82 self.env['INCPATHS'] = [x.is_child_of(bld.srcnode) and x.path_from(bld.bldnode) or x.abspath() for x in lst]
83
84
0 #!/usr/bin/env python
1 # encoding: utf-8
2 # Laurent Birtz, 2011
3 # moved the code into a separate tool (ita)
4
5 """
6 There are several things here:
7 - a different command-line option management making options persistent
8 - the review command to display the options set
9
10 Assumptions:
11 - configuration options are not always added to the right group (and do not count on the users to do it...)
12 - the options are persistent between the executions (waf options are NOT persistent by design), even for the configuration
13 - when the options change, the build is invalidated (forcing a reconfiguration)
14 """
15
16 import os, textwrap, shutil
17 from waflib import Logs, Context, ConfigSet, Options, Build, Configure
18
19 class Odict(dict):
20 """Ordered dictionary"""
21 def __init__(self, data=None):
22 self._keys = []
23 dict.__init__(self)
24 if data:
25 # we were provided a regular dict
26 if isinstance(data, dict):
27 self.append_from_dict(data)
28
29 # we were provided a tuple list
30 elif type(data) == list:
31 self.append_from_plist(data)
32
33 # we were provided invalid input
34 else:
35 raise Exception("expected a dict or a tuple list")
36
37 def append_from_dict(self, dict):
38 map(self.__setitem__, dict.keys(), dict.values())
39
40 def append_from_plist(self, plist):
41 for pair in plist:
42 if len(pair) != 2:
43 raise Exception("invalid pairs list")
44 for (k, v) in plist:
45 self.__setitem__(k, v)
46
47 def __delitem__(self, key):
48 if not key in self._keys:
49 raise KeyError(key)
50 dict.__delitem__(self, key)
51 self._keys.remove(key)
52
53 def __setitem__(self, key, item):
54 dict.__setitem__(self, key, item)
55 if key not in self._keys:
56 self._keys.append(key)
57
58 def clear(self):
59 dict.clear(self)
60 self._keys = []
61
62 def copy(self):
63 return Odict(self.plist())
64
65 def items(self):
66 return zip(self._keys, self.values())
67
68 def keys(self):
69 return list(self._keys) # return a copy of the list
70
71 def values(self):
72 return map(self.get, self._keys)
73
74 def plist(self):
75 p = []
76 for k, v in self.items():
77 p.append( (k, v) )
78 return p
79
80 def __str__(self):
81 s = "{"
82 l = len(self._keys)
83 for k, v in self.items():
84 l -= 1
85 strkey = str(k)
86 if isinstance(k, basestring): strkey = "'"+strkey+"'"
87 strval = str(v)
88 if isinstance(v, basestring): strval = "'"+strval+"'"
89 s += strkey + ":" + strval
90 if l > 0: s += ", "
91 s += "}"
92 return s
93
94 review_options = Odict()
95 """
96 Ordered dictionary mapping configuration option names to their optparse option.
97 """
98
99 review_defaults = {}
100 """
101 Dictionary mapping configuration option names to their default value.
102 """
103
104 old_review_set = None
105 """
106 Review set containing the configuration values before parsing the command line.
107 """
108
109 new_review_set = None
110 """
111 Review set containing the configuration values after parsing the command line.
112 """
113
114 class OptionsReview(Options.OptionsContext):
115 def __init__(self, **kw):
116 super(self.__class__, self).__init__(**kw)
117
118 def prepare_config_review(self):
119 """
120 Find the configuration options that are reviewable, detach
121 their default value from their optparse object and store them
122 into the review dictionaries.
123 """
124 gr = self.get_option_group('configure options')
125 for opt in gr.option_list:
126 if opt.action != 'store' or opt.dest in ("out", "top"):
127 continue
128 review_options[opt.dest] = opt
129 review_defaults[opt.dest] = opt.default
130 if gr.defaults.has_key(opt.dest):
131 del gr.defaults[opt.dest]
132 opt.default = None
133
134 def parse_args(self):
135 self.prepare_config_review()
136 self.parser.get_option('--prefix').help = 'installation prefix'
137 super(OptionsReview, self).parse_args()
138 Context.create_context('review').refresh_review_set()
139
140 class ReviewContext(Context.Context):
141 '''reviews the configuration values'''
142
143 cmd = 'review'
144
145 def __init__(self, **kw):
146 super(self.__class__, self).__init__(**kw)
147
148 out = Options.options.out
149 if not out:
150 out = getattr(Context.g_module, Context.OUT, None)
151 if not out:
152 out = Options.lockfile.replace('.lock-waf', '')
153 self.build_path = (os.path.isabs(out) and self.root or self.path).make_node(out).abspath()
154 """Path to the build directory"""
155
156 self.cache_path = os.path.join(self.build_path, Build.CACHE_DIR)
157 """Path to the cache directory"""
158
159 self.review_path = os.path.join(self.cache_path, 'review.cache')
160 """Path to the review cache file"""
161
162 def execute(self):
163 """
164 Display and store the review set. Invalidate the cache as required.
165 """
166 if not self.compare_review_set(old_review_set, new_review_set):
167 self.invalidate_cache()
168 self.store_review_set(new_review_set)
169 print(self.display_review_set(new_review_set))
170
171 def invalidate_cache(self):
172 """Invalidate the cache to prevent bad builds."""
173 try:
174 Logs.warn("Removing the cached configuration since the options have changed")
175 shutil.rmtree(self.cache_path)
176 except:
177 pass
178
179 def refresh_review_set(self):
180 """
181 Obtain the old review set and the new review set, and import the new set.
182 """
183 global old_review_set, new_review_set
184 old_review_set = self.load_review_set()
185 new_review_set = self.update_review_set(old_review_set)
186 self.import_review_set(new_review_set)
187
188 def load_review_set(self):
189 """
190 Load and return the review set from the cache if it exists.
191 Otherwise, return an empty set.
192 """
193 if os.path.isfile(self.review_path):
194 return ConfigSet.ConfigSet(self.review_path)
195 return ConfigSet.ConfigSet()
196
197 def store_review_set(self, review_set):
198 """
199 Store the review set specified in the cache.
200 """
201 if not os.path.isdir(self.cache_path):
202 os.makedirs(self.cache_path)
203 review_set.store(self.review_path)
204
205 def update_review_set(self, old_set):
206 """
207 Merge the options passed on the command line with those imported
208 from the previous review set and return the corresponding
209 preview set.
210 """
211
212 # Convert value to string. It's important that 'None' maps to
213 # the empty string.
214 def val_to_str(val):
215 if val == None or val == '':
216 return ''
217 return str(val)
218
219 new_set = ConfigSet.ConfigSet()
220 opt_dict = Options.options.__dict__
221
222 for name in review_options.keys():
223 # the option is specified explicitly on the command line
224 if name in opt_dict:
225 # if the option is the default, pretend it was never specified
226 if val_to_str(opt_dict[name]) != val_to_str(review_defaults[name]):
227 new_set[name] = opt_dict[name]
228 # the option was explicitly specified in a previous command
229 elif name in old_set:
230 new_set[name] = old_set[name]
231
232 return new_set
233
234 def import_review_set(self, review_set):
235 """
236 Import the actual value of the reviewable options in the option
237 dictionary, given the current review set.
238 """
239 for name in review_options.keys():
240 if name in review_set:
241 value = review_set[name]
242 else:
243 value = review_defaults[name]
244 setattr(Options.options, name, value)
245
246 def compare_review_set(self, set1, set2):
247 """
248 Return true if the review sets specified are equal.
249 """
250 if len(set1.keys()) != len(set2.keys()): return False
251 for key in set1.keys():
252 if not key in set2 or set1[key] != set2[key]:
253 return False
254 return True
255
256 def display_review_set(self, review_set):
257 """
258 Return the string representing the review set specified.
259 """
260 term_width = Logs.get_term_cols()
261 lines = []
262 for dest in review_options.keys():
263 opt = review_options[dest]
264 name = ", ".join(opt._short_opts + opt._long_opts)
265 help = opt.help
266 actual = None
267 if dest in review_set: actual = review_set[dest]
268 default = review_defaults[dest]
269 lines.append(self.format_option(name, help, actual, default, term_width))
270 return "Configuration:\n\n" + "\n\n".join(lines) + "\n"
271
272 def format_option(self, name, help, actual, default, term_width):
273 """
274 Return the string representing the option specified.
275 """
276 def val_to_str(val):
277 if val == None or val == '':
278 return "(void)"
279 return str(val)
280
281 max_name_len = 20
282 sep_len = 2
283
284 w = textwrap.TextWrapper()
285 w.width = term_width - 1
286 if w.width < 60: w.width = 60
287
288 out = ""
289
290 # format the help
291 out += w.fill(help) + "\n"
292
293 # format the name
294 name_len = len(name)
295 out += Logs.colors.CYAN + name + Logs.colors.NORMAL
296
297 # set the indentation used when the value wraps to the next line
298 w.subsequent_indent = " ".rjust(max_name_len + sep_len)
299 w.width -= (max_name_len + sep_len)
300
301 # the name string is too long, switch to the next line
302 if name_len > max_name_len:
303 out += "\n" + w.subsequent_indent
304
305 # fill the remaining of the line with spaces
306 else:
307 out += " ".rjust(max_name_len + sep_len - name_len)
308
309 # format the actual value, if there is one
310 if actual != None:
311 out += Logs.colors.BOLD + w.fill(val_to_str(actual)) + Logs.colors.NORMAL + "\n" + w.subsequent_indent
312
313 # format the default value
314 default_fmt = val_to_str(default)
315 if actual != None:
316 default_fmt = "default: " + default_fmt
317 out += Logs.colors.NORMAL + w.fill(default_fmt) + Logs.colors.NORMAL
318
319 return out
320
321 # Monkey-patch ConfigurationContext.execute() to have it store the review set.
322 old_configure_execute = Configure.ConfigurationContext.execute
323 def new_configure_execute(self):
324 old_configure_execute(self)
325 Context.create_context('review').store_review_set(new_review_set)
326 Configure.ConfigurationContext.execute = new_configure_execute
327
0 #!/usr/bin/env python
1 # encoding: utf-8
2 # Mark Coggeshall, 2010
3
4 "SAS support"
5
6 import os, re
7 from waflib import Utils, Task, TaskGen, Runner, Build, Errors, Node
8 from waflib.TaskGen import feature, before_method
9 from waflib.Logs import error, warn, debug
10
11 sas_fun, _ = Task.compile_fun('sas -sysin ${SRCFILE} -log ${LOGFILE} -print ${LSTFILE}', shell=False)
12
13 class sas(Task.Task):
14 vars = ['SAS', 'SASFLAGS']
15 def run(task):
16 command = 'SAS'
17 env = task.env
18 bld = task.generator.bld
19
20 fun = sas_fun
21
22 node = task.inputs[0]
23 logfilenode = node.change_ext('.log')
24 lstfilenode = node.change_ext('.lst')
25
26 # set the cwd
27 task.cwd = task.inputs[0].parent.get_src().abspath()
28 debug('runner: %s on %s' % (command, node.abspath))
29
30 SASINPUTS = node.parent.get_bld().abspath() + os.pathsep + node.parent.get_src().abspath() + os.pathsep
31 task.env.env = {'SASINPUTS': SASINPUTS}
32
33 task.env.SRCFILE = node.abspath()
34 task.env.LOGFILE = logfilenode.abspath()
35 task.env.LSTFILE = lstfilenode.abspath()
36 ret = fun(task)
37 if ret:
38 error('Running %s on %r returned a non-zero exit' % (command, node))
39 error('SRCFILE = %r' % node)
40 error('LOGFILE = %r' % logfilenode)
41 error('LSTFILE = %r' % lstfilenode)
42 return ret
43
44 @feature('sas')
45 @before_method('process_source')
46 def apply_sas(self):
47 if not getattr(self, 'type', None) in ['sas']:
48 self.type = 'sas'
49
50 self.env['logdir'] = getattr(self, 'logdir', 'log')
51 self.env['lstdir'] = getattr(self, 'lstdir', 'lst')
52
53 deps_lst = []
54
55 if getattr(self, 'deps', None):
56 deps = self.to_list(self.deps)
57 for filename in deps:
58 n = self.path.find_resource(filename)
59 if not n: n = self.bld.root.find_resource(filename)
60 if not n: raise Errors.WafError('cannot find input file %s for processing' % filename)
61 if not n in deps_lst: deps_lst.append(n)
62
63 for node in self.to_nodes(self.source):
64 if self.type == 'sas':
65 task = self.create_task('sas', src=node)
66 task.dep_nodes = deps_lst
67 self.source = []
68
69 def configure(self):
70 self.find_program('sas', var='SAS', mandatory=False)
71
0 #!/usr/bin/env python
1 # encoding: utf-8
2 # Thomas Nagy, 2010 (ita)
3
4 """
5 Scala support
6
7 scalac outputs files a bit where it wants to
8 """
9
10 import os, re
11 from waflib.Configure import conf
12 from waflib import TaskGen, Task, Utils, Options, Build, Errors, Node
13 from waflib.TaskGen import feature, before_method, after_method
14
15 from waflib.Tools import ccroot
16 ccroot.USELIB_VARS['scalac'] = set(['CLASSPATH', 'SCALACFLAGS'])
17
18 from waflib.Tools import javaw
19
20 @feature('scalac')
21 @before_method('process_source')
22 def apply_scalac(self):
23
24 Utils.def_attrs(self, jarname='', classpath='',
25 sourcepath='.', srcdir='.',
26 jar_mf_attributes={}, jar_mf_classpath=[])
27
28 nodes_lst = []
29
30 outdir = getattr(self, 'outdir', None)
31 if outdir:
32 if not isinstance(outdir, Node.Node):
33 outdir = self.path.get_bld().make_node(self.outdir)
34 else:
35 outdir = self.path.get_bld()
36 outdir.mkdir()
37 self.env['OUTDIR'] = outdir.abspath()
38
39 self.scalac_task = tsk = self.create_task('scalac')
40 tmp = []
41
42 srcdir = getattr(self, 'srcdir', '')
43 if isinstance(srcdir, Node.Node):
44 srcdir = [srcdir]
45 for x in Utils.to_list(srcdir):
46 if isinstance(x, Node.Node):
47 y = x
48 else:
49 y = self.path.find_dir(x)
50 if not y:
51 self.bld.fatal('Could not find the folder %s from %s' % (x, self.path))
52 tmp.append(y)
53 tsk.srcdir = tmp
54
55 # reuse some code
56 feature('scalac')(javaw.use_javac_files)
57 after_method('apply_scalac')(javaw.use_javac_files)
58
59 feature('scalac')(javaw.set_classpath)
60 after_method('apply_scalac', 'use_scalac_files')(javaw.set_classpath)
61
62
63 SOURCE_RE = '**/*.scala'
64 class scalac(javaw.javac):
65 color = 'GREEN'
66 vars = ['CLASSPATH', 'SCALACFLAGS', 'SCALAC', 'OUTDIR']
67
68 def runnable_status(self):
69 """
70 Wait for dependent tasks to be complete, then read the file system to find the input nodes.
71 """
72 for t in self.run_after:
73 if not t.hasrun:
74 return Task.ASK_LATER
75
76 if not self.inputs:
77 global SOURCE_RE
78 self.inputs = []
79 for x in self.srcdir:
80 self.inputs.extend(x.ant_glob(SOURCE_RE, remove=False))
81 return super(javaw.javac, self).runnable_status()
82
83 def run(self):
84 """
85 Execute the scalac compiler
86 """
87 env = self.env
88 gen = self.generator
89 bld = gen.bld
90 wd = bld.bldnode.abspath()
91 def to_list(xx):
92 if isinstance(xx, str): return [xx]
93 return xx
94 self.last_cmd = lst = []
95 lst.extend(to_list(env['SCALAC']))
96 lst.extend(['-classpath'])
97 lst.extend(to_list(env['CLASSPATH']))
98 lst.extend(['-d'])
99 lst.extend(to_list(env['OUTDIR']))
100 lst.extend(to_list(env['SCALACFLAGS']))
101 lst.extend([a.abspath() for a in self.inputs])
102 lst = [x for x in lst if x]
103 try:
104 self.out = self.generator.bld.cmd_and_log(lst, cwd=wd, env=env.env or None, output=0, quiet=0)[1]
105 except:
106 self.generator.bld.cmd_and_log(lst, cwd=wd, env=env.env or None)
107
108 def configure(self):
109 """
110 Detect the scalac program
111 """
112 # If SCALA_HOME is set, we prepend it to the path list
113 java_path = self.environ['PATH'].split(os.pathsep)
114 v = self.env
115
116 if 'SCALA_HOME' in self.environ:
117 java_path = [os.path.join(self.environ['SCALA_HOME'], 'bin')] + java_path
118 self.env['SCALA_HOME'] = [self.environ['SCALA_HOME']]
119
120 for x in 'scalac scala'.split():
121 self.find_program(x, var=x.upper(), path_list=java_path)
122 self.env[x.upper()] = self.cmd_to_list(self.env[x.upper()])
123
124 if 'CLASSPATH' in self.environ:
125 v['CLASSPATH'] = self.environ['CLASSPATH']
126
127 v.SCALACFLAGS = ['-verbose']
128 if not v['SCALAC']: self.fatal('scalac is required for compiling scala classes')
129
0 #! /usr/bin/env python
1 # Thomas Nagy, 2011 (ita)
2
3 """
4 Create _moc.cpp files
5
6 The builds are 30-40% faster when .moc files are included,
7 you should NOT use this tool. If you really
8 really want it:
9
10 def configure(conf):
11 conf.load('compiler_cxx qt4')
12 conf.load('slow_qt4')
13
14 See playground/slow_qt/wscript for a complete example.
15 """
16
17 from waflib.TaskGen import extension
18 from waflib import Task
19 import waflib.Tools.qt4
20 import waflib.Tools.cxx
21
22 @extension(*waflib.Tools.qt4.EXT_QT4)
23 def cxx_hook(self, node):
24 self.create_compiled_task('cxx_qt', node)
25
26 class cxx_qt(waflib.Tools.cxx.cxx):
27 def runnable_status(self):
28 ret = waflib.Tools.cxx.cxx.runnable_status(self)
29 if ret != Task.ASK_LATER and not getattr(self, 'moc_done', None):
30
31 try:
32 cache = self.generator.moc_cache
33 except AttributeError:
34 cache = self.generator.moc_cache = {}
35
36 deps = self.generator.bld.node_deps[self.uid()]
37 for x in [self.inputs[0]] + deps:
38 if x.read().find('Q_OBJECT') > 0:
39
40 # process "foo.h -> foo.moc" only if "foo.cpp" is in the sources for the current task generator
41 # this code will work because it is in the main thread (runnable_status)
42 if x.name.rfind('.') > -1: # a .h file...
43 name = x.name[:x.name.rfind('.')]
44 for tsk in self.generator.compiled_tasks:
45 if tsk.inputs and tsk.inputs[0].name.startswith(name):
46 break
47 else:
48 # no corresponding file, continue
49 continue
50
51 # the file foo.cpp could be compiled for a static and a shared library - hence the %number in the name
52 cxx_node = x.parent.get_bld().make_node(x.name.replace('.', '_') + '_%d_moc.cpp' % self.generator.idx)
53 if cxx_node in cache:
54 continue
55 cache[cxx_node] = self
56
57 tsk = Task.classes['moc'](env=self.env, generator=self.generator)
58 tsk.set_inputs(x)
59 tsk.set_outputs(cxx_node)
60
61 if x.name.endswith('.cpp'):
62 # moc is trying to be too smart but it is too dumb:
63 # why forcing the #include when Q_OBJECT is in the cpp file?
64 gen = self.generator.bld.producer
65 gen.outstanding.insert(0, tsk)
66 gen.total += 1
67 self.set_run_after(tsk)
68 else:
69 cxxtsk = Task.classes['cxx'](env=self.env, generator=self.generator)
70 cxxtsk.set_inputs(tsk.outputs)
71 cxxtsk.set_outputs(cxx_node.change_ext('.o'))
72 cxxtsk.set_run_after(tsk)
73
74 try:
75 self.more_tasks.extend([tsk, cxxtsk])
76 except AttributeError:
77 self.more_tasks = [tsk, cxxtsk]
78
79 try:
80 link = self.generator.link_task
81 except:
82 pass
83 else:
84 link.set_run_after(cxxtsk)
85 link.inputs.extend(cxxtsk.outputs)
86
87 self.moc_done = True
88
89 for t in self.run_after:
90 if not t.hasrun:
91 return Task.ASK_LATER
92
93 return ret
94
0 #! /usr/bin/env python
1 # Thomas Nagy, 2011
2
3 # Try to cancel the tasks that cannot run with the option -k when an error occurs:
4 # 1 direct file dependencies
5 # 2 tasks listed in the before/after/ext_in/ext_out attributes
6
7 from waflib import Task, Runner
8
9 Task.CANCELED = 4
10
11 def cancel_next(self, tsk):
12 if not isinstance(tsk, Task.TaskBase):
13 return
14 if tsk.hasrun >= Task.SKIPPED:
15 # normal execution, no need to do anything here
16 return
17
18 try:
19 canceled_tasks, canceled_nodes = self.canceled_tasks, self.canceled_nodes
20 except AttributeError:
21 canceled_tasks = self.canceled_tasks = set([])
22 canceled_nodes = self.canceled_nodes = set([])
23
24 try:
25 canceled_nodes.update(tsk.outputs)
26 except AttributeError:
27 pass
28
29 try:
30 canceled_tasks.add(tsk)
31 except AttributeError:
32 pass
33
34 def get_out(self):
35 tsk = self.out.get()
36 if not self.stop:
37 self.add_more_tasks(tsk)
38 self.count -= 1
39 self.dirty = True
40 self.cancel_next(tsk) # new code
41
42 def error_handler(self, tsk):
43 if not self.bld.keep:
44 self.stop = True
45 self.error.append(tsk)
46 self.cancel_next(tsk) # new code
47
48 Runner.Parallel.cancel_next = cancel_next
49 Runner.Parallel.get_out = get_out
50 Runner.Parallel.error_handler = error_handler
51
52 def get_next_task(self):
53 tsk = self.get_next_task_smart_continue()
54 if not tsk:
55 return tsk
56
57 try:
58 canceled_tasks, canceled_nodes = self.canceled_tasks, self.canceled_nodes
59 except AttributeError:
60 pass
61 else:
62 # look in the tasks that this one is waiting on
63 # if one of them was canceled, cancel this one too
64 for x in tsk.run_after:
65 if x in canceled_tasks:
66 tsk.hasrun = Task.CANCELED
67 self.cancel_next(tsk)
68 break
69 else:
70 # so far so good, now consider the nodes
71 for x in getattr(tsk, 'inputs', []) + getattr(tsk, 'deps', []):
72 if x in canceled_nodes:
73 tsk.hasrun = Task.CANCELED
74 self.cancel_next(tsk)
75 break
76 return tsk
77
78 Runner.Parallel.get_next_task_smart_continue = Runner.Parallel.get_next_task
79 Runner.Parallel.get_next_task = get_next_task
80
0 #! /usr/bin/env python
1 # per rosengren 2011
2
3 from waflib.TaskGen import feature, after_method
4 from waflib.Task import Task, always_run
5 from os.path import basename, isabs
6 from os import tmpfile, linesep
7
8 def options(opt):
9 grp = opt.add_option_group('Softlink Libraries Options')
10 grp.add_option('--exclude', default='/usr/lib,/lib', help='No symbolic links are created for libs within [%default]')
11
12 def configure(cnf):
13 cnf.find_program('ldd')
14 if not cnf.env.SOFTLINK_EXCLUDE:
15 cnf.env.SOFTLINK_EXCLUDE = cnf.options.exclude.split(',')
16
17 @feature('softlink_libs')
18 @after_method('process_rule')
19 def add_finder(self):
20 tgt = self.path.find_or_declare(self.target)
21 self.create_task('sll_finder', tgt=tgt)
22 self.create_task('sll_installer', tgt=tgt)
23 always_run(sll_installer)
24
25 class sll_finder(Task):
26 ext_out = 'softlink_libs'
27 def run(self):
28 bld = self.generator.bld
29 linked=[]
30 target_paths = []
31 for g in bld.groups:
32 for tgen in g:
33 # FIXME it might be better to check if there is a link_task (getattr?)
34 target_paths += [tgen.path.get_bld().bldpath()]
35 linked += [t.outputs[0].bldpath()
36 for t in getattr(tgen, 'tasks', [])
37 if t.__class__.__name__ in
38 ['cprogram', 'cshlib', 'cxxprogram', 'cxxshlib']]
39 lib_list = []
40 if len(linked):
41 cmd = [self.env.LDD] + linked
42 # FIXME add DYLD_LIBRARY_PATH+PATH for osx+win32
43 ldd_env = {'LD_LIBRARY_PATH': ':'.join(target_paths + self.env.LIBPATH)}
44 # FIXME the with syntax will not work in python 2
45 with tmpfile() as result:
46 self.exec_command(cmd, env=ldd_env, stdout=result)
47 result.seek(0)
48 for line in result.readlines():
49 words = line.split()
50 if len(words) < 3 or words[1] != '=>': continue
51 lib = words[2]
52 if lib == 'not': continue
53 if any([lib.startswith(p) for p in
54 [bld.bldnode.abspath(), '('] +
55 self.env.SOFTLINK_EXCLUDE]):
56 continue
57 if not isabs(lib):
58 continue
59 lib_list.append(lib)
60 lib_list = sorted(set(lib_list))
61 self.outputs[0].write(linesep.join(lib_list + self.env.DYNAMIC_LIBS))
62 return 0
63
64 class sll_installer(Task):
65 ext_in = 'softlink_libs'
66 def run(self):
67 tgt = self.outputs[0]
68 self.generator.bld.install_files('${LIBDIR}', tgt, postpone=False)
69 lib_list=tgt.read().split()
70 for lib in lib_list:
71 self.generator.bld.symlink_as('${LIBDIR}/'+basename(lib), lib, postpone=False)
72 return 0
73
0 # borrowed from python 2.5.2c1
1 # Copyright (c) 2003-2005 by Peter Astrand <astrand@lysator.liu.se>
2 # Licensed to PSF under a Contributor Agreement.
3
4 import sys
5 mswindows = (sys.platform == "win32")
6
7 import os
8 import types
9 import traceback
10 import gc
11
12 class CalledProcessError(Exception):
13 def __init__(self, returncode, cmd):
14 self.returncode = returncode
15 self.cmd = cmd
16 def __str__(self):
17 return "Command '%s' returned non-zero exit status %d" % (self.cmd, self.returncode)
18
19 if mswindows:
20 import threading
21 import msvcrt
22 if 0:
23 import pywintypes
24 from win32api import GetStdHandle, STD_INPUT_HANDLE, \
25 STD_OUTPUT_HANDLE, STD_ERROR_HANDLE
26 from win32api import GetCurrentProcess, DuplicateHandle, \
27 GetModuleFileName, GetVersion
28 from win32con import DUPLICATE_SAME_ACCESS, SW_HIDE
29 from win32pipe import CreatePipe
30 from win32process import CreateProcess, STARTUPINFO, \
31 GetExitCodeProcess, STARTF_USESTDHANDLES, \
32 STARTF_USESHOWWINDOW, CREATE_NEW_CONSOLE
33 from win32event import WaitForSingleObject, INFINITE, WAIT_OBJECT_0
34 else:
35 from _subprocess import *
36 class STARTUPINFO:
37 dwFlags = 0
38 hStdInput = None
39 hStdOutput = None
40 hStdError = None
41 wShowWindow = 0
42 class pywintypes:
43 error = IOError
44 else:
45 import select
46 import errno
47 import fcntl
48 import pickle
49
50 __all__ = ["Popen", "PIPE", "STDOUT", "call", "check_call", "CalledProcessError"]
51
52 try:
53 MAXFD = os.sysconf("SC_OPEN_MAX")
54 except:
55 MAXFD = 256
56
57 try:
58 False
59 except NameError:
60 False = 0
61 True = 1
62
63 _active = []
64
65 def _cleanup():
66 for inst in _active[:]:
67 if inst.poll(_deadstate=sys.maxint) >= 0:
68 try:
69 _active.remove(inst)
70 except ValueError:
71 pass
72
73 PIPE = -1
74 STDOUT = -2
75
76
77 def call(*popenargs, **kwargs):
78 return Popen(*popenargs, **kwargs).wait()
79
80 def check_call(*popenargs, **kwargs):
81 retcode = call(*popenargs, **kwargs)
82 cmd = kwargs.get("args")
83 if cmd is None:
84 cmd = popenargs[0]
85 if retcode:
86 raise CalledProcessError(retcode, cmd)
87 return retcode
88
89
90 def list2cmdline(seq):
91 result = []
92 needquote = False
93 for arg in seq:
94 bs_buf = []
95
96 if result:
97 result.append(' ')
98
99 needquote = (" " in arg) or ("\t" in arg) or arg == ""
100 if needquote:
101 result.append('"')
102
103 for c in arg:
104 if c == '\\':
105 bs_buf.append(c)
106 elif c == '"':
107 result.append('\\' * len(bs_buf)*2)
108 bs_buf = []
109 result.append('\\"')
110 else:
111 if bs_buf:
112 result.extend(bs_buf)
113 bs_buf = []
114 result.append(c)
115
116 if bs_buf:
117 result.extend(bs_buf)
118
119 if needquote:
120 result.extend(bs_buf)
121 result.append('"')
122
123 return ''.join(result)
124
125 class Popen(object):
126 def __init__(self, args, bufsize=0, executable=None,
127 stdin=None, stdout=None, stderr=None,
128 preexec_fn=None, close_fds=False, shell=False,
129 cwd=None, env=None, universal_newlines=False,
130 startupinfo=None, creationflags=0):
131 _cleanup()
132
133 self._child_created = False
134 if not isinstance(bufsize, (int, long)):
135 raise TypeError("bufsize must be an integer")
136
137 if mswindows:
138 if preexec_fn is not None:
139 raise ValueError("preexec_fn is not supported on Windows platforms")
140 if close_fds:
141 raise ValueError("close_fds is not supported on Windows platforms")
142 else:
143 if startupinfo is not None:
144 raise ValueError("startupinfo is only supported on Windows platforms")
145 if creationflags != 0:
146 raise ValueError("creationflags is only supported on Windows platforms")
147
148 self.stdin = None
149 self.stdout = None
150 self.stderr = None
151 self.pid = None
152 self.returncode = None
153 self.universal_newlines = universal_newlines
154
155 (p2cread, p2cwrite,
156 c2pread, c2pwrite,
157 errread, errwrite) = self._get_handles(stdin, stdout, stderr)
158
159 self._execute_child(args, executable, preexec_fn, close_fds,
160 cwd, env, universal_newlines,
161 startupinfo, creationflags, shell,
162 p2cread, p2cwrite,
163 c2pread, c2pwrite,
164 errread, errwrite)
165
166 if mswindows:
167 if stdin is None and p2cwrite is not None:
168 os.close(p2cwrite)
169 p2cwrite = None
170 if stdout is None and c2pread is not None:
171 os.close(c2pread)
172 c2pread = None
173 if stderr is None and errread is not None:
174 os.close(errread)
175 errread = None
176
177 if p2cwrite:
178 self.stdin = os.fdopen(p2cwrite, 'wb', bufsize)
179 if c2pread:
180 if universal_newlines:
181 self.stdout = os.fdopen(c2pread, 'rU', bufsize)
182 else:
183 self.stdout = os.fdopen(c2pread, 'rb', bufsize)
184 if errread:
185 if universal_newlines:
186 self.stderr = os.fdopen(errread, 'rU', bufsize)
187 else:
188 self.stderr = os.fdopen(errread, 'rb', bufsize)
189
190
191 def _translate_newlines(self, data):
192 data = data.replace("\r\n", "\n")
193 data = data.replace("\r", "\n")
194 return data
195
196
197 def __del__(self, sys=sys):
198 if not self._child_created:
199 return
200 self.poll(_deadstate=sys.maxint)
201 if self.returncode is None and _active is not None:
202 _active.append(self)
203
204
205 def communicate(self, input=None):
206 if [self.stdin, self.stdout, self.stderr].count(None) >= 2:
207 stdout = None
208 stderr = None
209 if self.stdin:
210 if input:
211 self.stdin.write(input)
212 self.stdin.close()
213 elif self.stdout:
214 stdout = self.stdout.read()
215 elif self.stderr:
216 stderr = self.stderr.read()
217 self.wait()
218 return (stdout, stderr)
219
220 return self._communicate(input)
221
222
223 if mswindows:
224 def _get_handles(self, stdin, stdout, stderr):
225 if stdin is None and stdout is None and stderr is None:
226 return (None, None, None, None, None, None)
227
228 p2cread, p2cwrite = None, None
229 c2pread, c2pwrite = None, None
230 errread, errwrite = None, None
231
232 if stdin is None:
233 p2cread = GetStdHandle(STD_INPUT_HANDLE)
234 if p2cread is not None:
235 pass
236 elif stdin is None or stdin == PIPE:
237 p2cread, p2cwrite = CreatePipe(None, 0)
238 p2cwrite = p2cwrite.Detach()
239 p2cwrite = msvcrt.open_osfhandle(p2cwrite, 0)
240 elif isinstance(stdin, int):
241 p2cread = msvcrt.get_osfhandle(stdin)
242 else:
243 p2cread = msvcrt.get_osfhandle(stdin.fileno())
244 p2cread = self._make_inheritable(p2cread)
245
246 if stdout is None:
247 c2pwrite = GetStdHandle(STD_OUTPUT_HANDLE)
248 if c2pwrite is not None:
249 pass
250 elif stdout is None or stdout == PIPE:
251 c2pread, c2pwrite = CreatePipe(None, 0)
252 c2pread = c2pread.Detach()
253 c2pread = msvcrt.open_osfhandle(c2pread, 0)
254 elif isinstance(stdout, int):
255 c2pwrite = msvcrt.get_osfhandle(stdout)
256 else:
257 c2pwrite = msvcrt.get_osfhandle(stdout.fileno())
258 c2pwrite = self._make_inheritable(c2pwrite)
259
260 if stderr is None:
261 errwrite = GetStdHandle(STD_ERROR_HANDLE)
262 if errwrite is not None:
263 pass
264 elif stderr is None or stderr == PIPE:
265 errread, errwrite = CreatePipe(None, 0)
266 errread = errread.Detach()
267 errread = msvcrt.open_osfhandle(errread, 0)
268 elif stderr == STDOUT:
269 errwrite = c2pwrite
270 elif isinstance(stderr, int):
271 errwrite = msvcrt.get_osfhandle(stderr)
272 else:
273 errwrite = msvcrt.get_osfhandle(stderr.fileno())
274 errwrite = self._make_inheritable(errwrite)
275
276 return (p2cread, p2cwrite,
277 c2pread, c2pwrite,
278 errread, errwrite)
279 def _make_inheritable(self, handle):
280 return DuplicateHandle(GetCurrentProcess(), handle, GetCurrentProcess(), 0, 1, DUPLICATE_SAME_ACCESS)
281
282 def _find_w9xpopen(self):
283 w9xpopen = os.path.join(os.path.dirname(GetModuleFileName(0)), "w9xpopen.exe")
284 if not os.path.exists(w9xpopen):
285 w9xpopen = os.path.join(os.path.dirname(sys.exec_prefix), "w9xpopen.exe")
286 if not os.path.exists(w9xpopen):
287 raise RuntimeError("Cannot locate w9xpopen.exe, which is needed for Popen to work with your shell or platform.")
288 return w9xpopen
289
290 def _execute_child(self, args, executable, preexec_fn, close_fds,
291 cwd, env, universal_newlines,
292 startupinfo, creationflags, shell,
293 p2cread, p2cwrite,
294 c2pread, c2pwrite,
295 errread, errwrite):
296
297 if not isinstance(args, types.StringTypes):
298 args = list2cmdline(args)
299
300 if startupinfo is None:
301 startupinfo = STARTUPINFO()
302 if None not in (p2cread, c2pwrite, errwrite):
303 startupinfo.dwFlags |= STARTF_USESTDHANDLES
304 startupinfo.hStdInput = p2cread
305 startupinfo.hStdOutput = c2pwrite
306 startupinfo.hStdError = errwrite
307
308 if shell:
309 startupinfo.dwFlags |= STARTF_USESHOWWINDOW
310 startupinfo.wShowWindow = SW_HIDE
311 comspec = os.environ.get("COMSPEC", "cmd.exe")
312 args = comspec + " /c " + args
313 if (GetVersion() >= 0x80000000L or
314 os.path.basename(comspec).lower() == "command.com"):
315 w9xpopen = self._find_w9xpopen()
316 args = '"%s" %s' % (w9xpopen, args)
317 creationflags |= CREATE_NEW_CONSOLE
318
319 try:
320 hp, ht, pid, tid = CreateProcess(executable, args, None, None, 1, creationflags, env, cwd, startupinfo)
321 except pywintypes.error, e:
322 raise WindowsError(*e.args)
323
324 self._child_created = True
325 self._handle = hp
326 self.pid = pid
327 ht.Close()
328
329 if p2cread is not None:
330 p2cread.Close()
331 if c2pwrite is not None:
332 c2pwrite.Close()
333 if errwrite is not None:
334 errwrite.Close()
335
336
337 def poll(self, _deadstate=None):
338 if self.returncode is None:
339 if WaitForSingleObject(self._handle, 0) == WAIT_OBJECT_0:
340 self.returncode = GetExitCodeProcess(self._handle)
341 return self.returncode
342
343
344 def wait(self):
345 if self.returncode is None:
346 obj = WaitForSingleObject(self._handle, INFINITE)
347 self.returncode = GetExitCodeProcess(self._handle)
348 return self.returncode
349
350 def _readerthread(self, fh, buffer):
351 buffer.append(fh.read())
352
353 def _communicate(self, input):
354 stdout = None
355 stderr = None
356
357 if self.stdout:
358 stdout = []
359 stdout_thread = threading.Thread(target=self._readerthread, args=(self.stdout, stdout))
360 stdout_thread.setDaemon(True)
361 stdout_thread.start()
362 if self.stderr:
363 stderr = []
364 stderr_thread = threading.Thread(target=self._readerthread, args=(self.stderr, stderr))
365 stderr_thread.setDaemon(True)
366 stderr_thread.start()
367
368 if self.stdin:
369 if input is not None:
370 self.stdin.write(input)
371 self.stdin.close()
372
373 if self.stdout:
374 stdout_thread.join()
375 if self.stderr:
376 stderr_thread.join()
377
378 if stdout is not None:
379 stdout = stdout[0]
380 if stderr is not None:
381 stderr = stderr[0]
382
383 if self.universal_newlines and hasattr(file, 'newlines'):
384 if stdout:
385 stdout = self._translate_newlines(stdout)
386 if stderr:
387 stderr = self._translate_newlines(stderr)
388
389 self.wait()
390 return (stdout, stderr)
391
392 else:
393 def _get_handles(self, stdin, stdout, stderr):
394 p2cread, p2cwrite = None, None
395 c2pread, c2pwrite = None, None
396 errread, errwrite = None, None
397
398 if stdin is None:
399 pass
400 elif stdin == PIPE:
401 p2cread, p2cwrite = os.pipe()
402 elif isinstance(stdin, int):
403 p2cread = stdin
404 else:
405 p2cread = stdin.fileno()
406
407 if stdout is None:
408 pass
409 elif stdout == PIPE:
410 c2pread, c2pwrite = os.pipe()
411 elif isinstance(stdout, int):
412 c2pwrite = stdout
413 else:
414 c2pwrite = stdout.fileno()
415
416 if stderr is None:
417 pass
418 elif stderr == PIPE:
419 errread, errwrite = os.pipe()
420 elif stderr == STDOUT:
421 errwrite = c2pwrite
422 elif isinstance(stderr, int):
423 errwrite = stderr
424 else:
425 errwrite = stderr.fileno()
426
427 return (p2cread, p2cwrite, c2pread, c2pwrite, errread, errwrite)
428
429 def _set_cloexec_flag(self, fd):
430 try:
431 cloexec_flag = fcntl.FD_CLOEXEC
432 except AttributeError:
433 cloexec_flag = 1
434
435 old = fcntl.fcntl(fd, fcntl.F_GETFD)
436 fcntl.fcntl(fd, fcntl.F_SETFD, old | cloexec_flag)
437
438 def _close_fds(self, but):
439 for i in xrange(3, MAXFD):
440 if i == but:
441 continue
442 try:
443 os.close(i)
444 except:
445 pass
446
447 def _execute_child(self, args, executable, preexec_fn, close_fds,
448 cwd, env, universal_newlines, startupinfo, creationflags, shell,
449 p2cread, p2cwrite, c2pread, c2pwrite, errread, errwrite):
450
451 if isinstance(args, types.StringTypes):
452 args = [args]
453 else:
454 args = list(args)
455
456 if shell:
457 args = ["/bin/sh", "-c"] + args
458
459 if executable is None:
460 executable = args[0]
461
462 errpipe_read, errpipe_write = os.pipe()
463 self._set_cloexec_flag(errpipe_write)
464
465 gc_was_enabled = gc.isenabled()
466 gc.disable()
467 try:
468 self.pid = os.fork()
469 except:
470 if gc_was_enabled:
471 gc.enable()
472 raise
473 self._child_created = True
474 if self.pid == 0:
475 try:
476 if p2cwrite:
477 os.close(p2cwrite)
478 if c2pread:
479 os.close(c2pread)
480 if errread:
481 os.close(errread)
482 os.close(errpipe_read)
483
484 if p2cread:
485 os.dup2(p2cread, 0)
486 if c2pwrite:
487 os.dup2(c2pwrite, 1)
488 if errwrite:
489 os.dup2(errwrite, 2)
490
491 if p2cread and p2cread not in (0,):
492 os.close(p2cread)
493 if c2pwrite and c2pwrite not in (p2cread, 1):
494 os.close(c2pwrite)
495 if errwrite and errwrite not in (p2cread, c2pwrite, 2):
496 os.close(errwrite)
497
498 if close_fds:
499 self._close_fds(but=errpipe_write)
500
501 if cwd is not None:
502 os.chdir(cwd)
503
504 if preexec_fn:
505 apply(preexec_fn)
506
507 if env is None:
508 os.execvp(executable, args)
509 else:
510 os.execvpe(executable, args, env)
511
512 except:
513 exc_type, exc_value, tb = sys.exc_info()
514 exc_lines = traceback.format_exception(exc_type, exc_value, tb)
515 exc_value.child_traceback = ''.join(exc_lines)
516 os.write(errpipe_write, pickle.dumps(exc_value))
517
518 os._exit(255)
519
520 if gc_was_enabled:
521 gc.enable()
522 os.close(errpipe_write)
523 if p2cread and p2cwrite:
524 os.close(p2cread)
525 if c2pwrite and c2pread:
526 os.close(c2pwrite)
527 if errwrite and errread:
528 os.close(errwrite)
529
530 data = os.read(errpipe_read, 1048576)
531 os.close(errpipe_read)
532 if data != "":
533 os.waitpid(self.pid, 0)
534 child_exception = pickle.loads(data)
535 raise child_exception
536
537 def _handle_exitstatus(self, sts):
538 if os.WIFSIGNALED(sts):
539 self.returncode = -os.WTERMSIG(sts)
540 elif os.WIFEXITED(sts):
541 self.returncode = os.WEXITSTATUS(sts)
542 else:
543 raise RuntimeError("Unknown child exit status!")
544
545 def poll(self, _deadstate=None):
546 if self.returncode is None:
547 try:
548 pid, sts = os.waitpid(self.pid, os.WNOHANG)
549 if pid == self.pid:
550 self._handle_exitstatus(sts)
551 except os.error:
552 if _deadstate is not None:
553 self.returncode = _deadstate
554 return self.returncode
555
556 def wait(self):
557 if self.returncode is None:
558 pid, sts = os.waitpid(self.pid, 0)
559 self._handle_exitstatus(sts)
560 return self.returncode
561
562 def _communicate(self, input):
563 read_set = []
564 write_set = []
565 stdout = None
566 stderr = None
567
568 if self.stdin:
569 self.stdin.flush()
570 if input:
571 write_set.append(self.stdin)
572 else:
573 self.stdin.close()
574 if self.stdout:
575 read_set.append(self.stdout)
576 stdout = []
577 if self.stderr:
578 read_set.append(self.stderr)
579 stderr = []
580
581 input_offset = 0
582 while read_set or write_set:
583 rlist, wlist, xlist = select.select(read_set, write_set, [])
584
585 if self.stdin in wlist:
586 bytes_written = os.write(self.stdin.fileno(), buffer(input, input_offset, 512))
587 input_offset += bytes_written
588 if input_offset >= len(input):
589 self.stdin.close()
590 write_set.remove(self.stdin)
591
592 if self.stdout in rlist:
593 data = os.read(self.stdout.fileno(), 1024)
594 if data == "":
595 self.stdout.close()
596 read_set.remove(self.stdout)
597 stdout.append(data)
598
599 if self.stderr in rlist:
600 data = os.read(self.stderr.fileno(), 1024)
601 if data == "":
602 self.stderr.close()
603 read_set.remove(self.stderr)
604 stderr.append(data)
605
606 if stdout is not None:
607 stdout = ''.join(stdout)
608 if stderr is not None:
609 stderr = ''.join(stderr)
610
611 if self.universal_newlines and hasattr(file, 'newlines'):
612 if stdout:
613 stdout = self._translate_newlines(stdout)
614 if stderr:
615 stderr = self._translate_newlines(stderr)
616
617 self.wait()
618 return (stdout, stderr)
619
0 #! /usr/bin/env python
1 # encoding: UTF-8
2 # Petar Forai
3 # Thomas Nagy 2008-2010 (ita)
4
5 import re
6 from waflib import Task, Utils, Logs
7 from waflib.TaskGen import extension, feature, after_method
8 from waflib.Configure import conf
9 from waflib.Tools import c_preproc
10
11 """
12 tasks have to be added dynamically:
13 - swig interface files may be created at runtime
14 - the module name may be unknown in advance
15 """
16
17 SWIG_EXTS = ['.swig', '.i']
18
19 re_module = re.compile('%module(?:\s*\(.*\))?\s+(.+)', re.M)
20
21 re_1 = re.compile(r'^%module.*?\s+([\w]+)\s*?$', re.M)
22 re_2 = re.compile('%include "(.*)"', re.M)
23 re_3 = re.compile('#include "(.*)"', re.M)
24
25 class swig(Task.Task):
26 color = 'BLUE'
27 run_str = '${SWIG} ${SWIGFLAGS} ${SWIGPATH_ST:INCPATHS} ${DEFINES_ST:DEFINES} ${SRC}'
28 ext_out = ['.h'] # might produce .h files although it is not mandatory
29
30 def runnable_status(self):
31 for t in self.run_after:
32 if not t.hasrun:
33 return Task.ASK_LATER
34
35 if not getattr(self, 'init_outputs', None):
36 self.init_outputs = True
37 if not getattr(self, 'module', None):
38 # search the module name
39 txt = self.inputs[0].read()
40 m = re_module.search(txt)
41 if not m:
42 raise ValueError("could not find the swig module name")
43 self.module = m.group(1)
44
45 swig_c(self)
46
47 # add the language-specific output files as nodes
48 # call funs in the dict swig_langs
49 for x in self.env['SWIGFLAGS']:
50 # obtain the language
51 x = x[1:]
52 try:
53 fun = swig_langs[x]
54 except KeyError:
55 pass
56 else:
57 fun(self)
58
59 return super(swig, self).runnable_status()
60
61 def scan(self):
62 "scan for swig dependencies, climb the .i files"
63 env = self.env
64
65 lst_src = []
66
67 seen = []
68 to_see = [self.inputs[0]]
69
70 while to_see:
71 node = to_see.pop(0)
72 if node in seen:
73 continue
74 seen.append(node)
75 lst_src.append(node)
76
77 # read the file
78 code = node.read()
79 code = c_preproc.re_nl.sub('', code)
80 code = c_preproc.re_cpp.sub(c_preproc.repl, code)
81
82 # find .i files and project headers
83 names = re_2.findall(code) + re_3.findall(code)
84 for n in names:
85 for d in self.generator.includes_nodes + [node.parent]:
86 u = d.find_resource(n)
87 if u:
88 to_see.append(u)
89 break
90 else:
91 Logs.warn('could not find %r' % n)
92
93 return (lst_src, [])
94
95 # provide additional language processing
96 swig_langs = {}
97 def swigf(fun):
98 swig_langs[fun.__name__.replace('swig_', '')] = fun
99 swig.swigf = swigf
100
101 def swig_c(self):
102 ext = '.swigwrap_%d.c' % self.generator.idx
103 flags = self.env['SWIGFLAGS']
104 if '-c++' in flags:
105 ext += 'xx'
106 out_node = self.inputs[0].parent.find_or_declare(self.module + ext)
107
108 if '-c++' in flags:
109 c_tsk = self.generator.cxx_hook(out_node)
110 else:
111 c_tsk = self.generator.c_hook(out_node)
112
113 c_tsk.set_run_after(self)
114
115 ge = self.generator.bld.producer
116 ge.outstanding.insert(0, c_tsk)
117 ge.total += 1
118
119 try:
120 ltask = self.generator.link_task
121 except AttributeError:
122 pass
123 else:
124 ltask.set_run_after(c_tsk)
125 ltask.inputs.append(c_tsk.outputs[0])
126
127 self.outputs.append(out_node)
128
129 if not '-o' in self.env['SWIGFLAGS']:
130 self.env.append_value('SWIGFLAGS', ['-o', self.outputs[0].abspath()])
131
132 @swigf
133 def swig_python(tsk):
134 tsk.set_outputs(tsk.inputs[0].parent.find_or_declare(tsk.module + '.py'))
135
136 @swigf
137 def swig_ocaml(tsk):
138 tsk.set_outputs(tsk.inputs[0].parent.find_or_declare(tsk.module + '.ml'))
139 tsk.set_outputs(tsk.inputs[0].parent.find_or_declare(tsk.module + '.mli'))
140
141 @extension(*SWIG_EXTS)
142 def i_file(self, node):
143 # the task instance
144 tsk = self.create_task('swig')
145 tsk.set_inputs(node)
146 tsk.module = getattr(self, 'swig_module', None)
147
148 flags = self.to_list(getattr(self, 'swig_flags', []))
149 tsk.env.append_value('SWIGFLAGS', flags)
150
151 # looks like this is causing problems
152 #if not '-outdir' in flags:
153 # tsk.env.append_value('SWIGFLAGS', ['-outdir', node.parent.abspath()])
154
155 @conf
156 def check_swig_version(self):
157 """Check for a minimum swig version like conf.check_swig_version('1.3.28')
158 or conf.check_swig_version((1,3,28)) """
159 reg_swig = re.compile(r'SWIG Version\s(.*)', re.M)
160 swig_out = self.cmd_and_log('%s -version' % self.env['SWIG'])
161
162 swigver = tuple([int(s) for s in reg_swig.findall(swig_out)[0].split('.')])
163 self.env['SWIG_VERSION'] = swigver
164 msg = 'Checking for swig version'
165 self.msg(msg, '.'.join(map(str, swigver)))
166 return swigver
167
168 def configure(conf):
169 swig = conf.find_program('swig', var='SWIG')
170 conf.env.SWIGPATH_ST = '-I%s'
171
0 #! /usr/bin/env python
1 # encoding: utf-8
2
3 """
4 this tool supports the export_symbols_regex to export the symbols in a shared library.
5 by default, all symbols are exported by gcc, and nothing by msvc.
6 to use the tool, do something like:
7
8 def build(ctx):
9 ctx(features='c cshlib syms', source='a.c b.c', export_symbols_regex='mylib_.*', target='testlib')
10
11 only the symbols starting with 'mylib_' will be exported.
12 """
13
14 import re
15 from waflib.Context import STDOUT
16 from waflib.Task import Task
17 from waflib.Errors import WafError
18 from waflib.TaskGen import feature, after_method
19
20 class gen_sym(Task):
21 def run(self):
22 obj = self.inputs[0]
23 if 'msvc' in (self.env.CC_NAME, self.env.CXX_NAME):
24 re_nm = re.compile(r'External\s+\|\s+_(' + self.generator.export_symbols_regex + r')\b')
25 cmd = ['dumpbin', '/symbols', obj.abspath()]
26 else:
27 if self.env.DEST_BINFMT == 'pe': #gcc uses nm, and has a preceding _ on windows
28 re_nm = re.compile(r'T\s+_(' + self.generator.export_symbols_regex + r')\b')
29 else:
30 re_nm = re.compile(r'T\s+(' + self.generator.export_symbols_regex + r')\b')
31 cmd = ['nm', '-g', obj.abspath()]
32 syms = re_nm.findall(self.generator.bld.cmd_and_log(cmd, quiet=STDOUT))
33 self.outputs[0].write('%r' % syms)
34
35 class compile_sym(Task):
36 def run(self):
37 syms = {}
38 for x in self.inputs:
39 slist = eval(x.read())
40 for s in slist:
41 syms[s] = 1
42 lsyms = syms.keys()
43 lsyms.sort()
44 if self.env.DEST_BINFMT == 'pe':
45 self.outputs[0].write('EXPORTS\n' + '\n'.join(lsyms))
46 elif self.env.DEST_BINFMT == 'elf':
47 self.outputs[0].write('{ global:\n' + ';\n'.join(lsyms) + ";\nlocal: *; };\n")
48 else:
49 raise WafError('NotImplemented')
50
51 @feature('syms')
52 @after_method('process_source', 'process_use', 'apply_link', 'process_uselib_local')
53 def do_the_symbol_stuff(self):
54 ins = [x.outputs[0] for x in self.compiled_tasks]
55 self.gen_sym_tasks = [self.create_task('gen_sym', x, x.change_ext('.%d.sym' % self.idx)) for x in ins]
56
57 tsk = self.create_task('compile_sym',
58 [x.outputs[0] for x in self.gen_sym_tasks],
59 self.path.find_or_declare(getattr(self, 'sym_filename', self.target + '.def')))
60 self.link_task.set_run_after(tsk)
61 self.link_task.dep_nodes = [tsk.outputs[0]]
62 if 'msvc' in (self.env.CC_NAME, self.env.CXX_NAME):
63 self.link_task.env.append_value('LINKFLAGS', ['/def:' + tsk.outputs[0].bldpath()])
64 elif self.env.DEST_BINFMT == 'pe': #gcc on windows takes *.def as an additional input
65 self.link_task.inputs.append(tsk.outputs[0])
66 elif self.env.DEST_BINFMT == 'elf':
67 self.link_task.env.append_value('LINKFLAGS', ['-Wl,-version-script', '-Wl,' + tsk.outputs[0].bldpath()])
68 else:
69 raise WafError('NotImplemented')
70
0 #! /usr/bin/env python
1 # encoding: utf-8
2
3 """
4 Force the execution output to be synchronized
5 May deadlock with a lot of output (subprocess limitation)
6 """
7
8 import sys
9 from waflib.Build import BuildContext
10 from waflib import Utils, Logs
11
12 def exec_command(self, cmd, **kw):
13 subprocess = Utils.subprocess
14 kw['shell'] = isinstance(cmd, str)
15 Logs.debug('runner: %r' % cmd)
16 Logs.debug('runner_env: kw=%s' % kw)
17 try:
18 kw['stdout'] = kw['stderr'] = subprocess.PIPE
19 p = subprocess.Popen(cmd, **kw)
20 (out, err) = p.communicate()
21 if out:
22 sys.stdout.write(out.decode(sys.stdout.encoding or 'iso8859-1'))
23 if err:
24 sys.stdout.write(err.decode(sys.stdout.encoding or 'iso8859-1'))
25 return p.returncode
26 except OSError:
27 return -1
28
29 BuildContext.exec_command = exec_command
30
0 #! /usr/bin/env python
1 # encoding: UTF-8
2 # Nicolas Joseph 2009
3
4 """
5 ported from waf 1.5:
6 TODO: tabs vs spaces
7 """
8
9 from waflib import Task, Utils, Node, Errors
10 from waflib.TaskGen import feature, extension, after_method
11 from Logs import debug, warn, error
12
13 VALADOC_STR = '${VALADOC}'
14
15 class valadoc(Task.Task):
16 vars = ['VALADOC', 'VALADOCFLAGS']
17 color = 'BLUE'
18 after = ['cprogram', 'cstlib', 'cshlib', 'cxxprogram', 'cxxstlib', 'cxxshlib']
19 quiet = True # no outputs .. this is weird
20
21 def __init__(self, *k, **kw):
22 Task.Task.__init__(*k, **kw)
23 self.output_dir = ''
24 self.doclet = ''
25 self.package_name = ''
26 self.package_version = ''
27 self.files = []
28 self.protected = True
29 self.private = False
30 self.inherit = False
31 self.deps = False
32 self.enable_non_null_experimental = False
33 self.force = False
34
35 def run(self):
36 if not self.env['VALADOCFLAGS']:
37 self.env['VALADOCFLAGS'] = ''
38 cmd = [Utils.subst_vars(VALADOC_STR, self.env)]
39 cmd.append ('-o %s' % self.output_dir)
40 if getattr(self, 'doclet', None):
41 cmd.append ('--doclet %s' % self.doclet)
42 cmd.append ('--package-name %s' % self.package_name)
43 if getattr(self, 'version', None):
44 cmd.append ('--package-version %s' % self.package_version)
45 if getattr(self, 'packages', None):
46 for package in self.packages:
47 cmd.append ('--pkg %s' % package)
48 if getattr(self, 'vapi_dirs', None):
49 for vapi_dir in self.vapi_dirs:
50 cmd.append ('--vapidir %s' % vapi_dir)
51 if not getattr(self, 'protected', None):
52 cmd.append ('--no-protected')
53 if getattr(self, 'private', None):
54 cmd.append ('--private')
55 if getattr(self, 'inherit', None):
56 cmd.append ('--inherit')
57 if getattr(self, 'deps', None):
58 cmd.append ('--deps')
59 if getattr(self, 'enable_non_null_experimental', None):
60 cmd.append ('--enable-non-null-experimental')
61 if getattr(self, 'force', None):
62 cmd.append ('--force')
63 cmd.append (' '.join ([x.relpath_gen (self.generator.bld.bldnode) for x in self.files]))
64 return self.generator.bld.exec_command(' '.join(cmd))
65
66 @feature('valadoc')
67 def process_valadoc(self):
68 task = self.create_task('valadoc')
69 if getattr(self, 'output_dir', None):
70 task.output_dir = self.output_dir
71 else:
72 Errors.WafError('no output directory')
73 if getattr(self, 'doclet', None):
74 task.doclet = self.doclet
75 else:
76 Errors.WafError('no doclet directory')
77 if getattr(self, 'package_name', None):
78 task.package_name = self.package_name
79 else:
80 Errors.WafError('no package name')
81 if getattr(self, 'package_version', None):
82 task.package_version = self.package_version
83 if getattr(self, 'packages', None):
84 task.packages = Utils.to_list(self.packages)
85 if getattr(self, 'vapi_dirs', None):
86 task.vapi_dirs = Utils.to_list(self.vapi_dirs)
87 if getattr(self, 'files', None):
88 task.files = self.files
89 else:
90 Errors.WafError('no input file')
91 if getattr(self, 'protected', None):
92 task.protected = self.protected
93 if getattr(self, 'private', None):
94 task.private = self.private
95 if getattr(self, 'inherit', None):
96 task.inherit = self.inherit
97 if getattr(self, 'deps', None):
98 task.deps = self.deps
99 if getattr(self, 'enable_non_null_experimental', None):
100 task.enable_non_null_experimental = self.enable_non_null_experimental
101 if getattr(self, 'force', None):
102 task.force = self.force
103
104 def configure(conf):
105 conf.find_program('valadoc', errmsg='You must install valadoc <http://live.gnome.org/Valadoc> for generate the API documentation')
106
0 #! /usr/bin/env python
1 # encoding: utf-8
2 # Thomas Nagy, 2010 (ita)
3
4 """
5 This tool modifies the task signature scheme to store and obtain
6 information about the task execution (why it must run, etc)::
7
8 def configure(conf):
9 conf.load('why')
10
11 After adding the tool, a full rebuild is necessary.
12 """
13
14 from waflib import Task, Utils, Logs, Errors
15
16 def signature(self):
17 # compute the result one time, and suppose the scan_signature will give the good result
18 try: return self.cache_sig
19 except AttributeError: pass
20
21 self.m = Utils.md5()
22 self.m.update(self.hcode.encode())
23 id_sig = self.m.digest()
24
25 # explicit deps
26 self.sig_explicit_deps()
27 exp_sig = self.m.digest()
28
29 # env vars
30 self.sig_vars()
31 var_sig = self.m.digest()
32
33 # implicit deps / scanner results
34 if self.scan:
35 try:
36 self.sig_implicit_deps()
37 except Errors.TaskRescan:
38 return self.signature()
39
40 ret = self.cache_sig = self.m.digest() + id_sig + exp_sig + var_sig
41 return ret
42
43
44 Task.Task.signature = signature
45
46 old = Task.Task.runnable_status
47 def runnable_status(self):
48 ret = old(self)
49 if ret == Task.RUN_ME:
50 try:
51 old_sigs = self.generator.bld.task_sigs[self.uid()]
52 except:
53 Logs.debug("task: task must run as no previous signature exists")
54 else:
55 new_sigs = self.cache_sig
56 def v(x):
57 return Utils.to_hex(x)
58
59 Logs.debug("Task %r" % self)
60 msgs = ['Task must run', '* Task code', '* Source file or manual dependency', '* Configuration data variable']
61 tmp = 'task: -> %s: %s %s'
62 for x in range(len(msgs)):
63 l = len(Utils.SIG_NIL)
64 a = new_sigs[x*l : (x+1)*l]
65 b = old_sigs[x*l : (x+1)*l]
66 if (a != b):
67 Logs.debug(tmp % (msgs[x].ljust(35), v(a), v(b)))
68 if x > 0:
69 break
70 return ret
71 Task.Task.runnable_status = runnable_status
72
0 #! /usr/bin/env python
1 # encoding: utf-8
2 # XCode 3/XCode 4 generator for Waf
3 # Nicolas Mercier 2011
4
5 """
6 Usage:
7
8 def options(opt):
9 opt.load('xcode')
10
11 $ waf configure xcode
12 """
13
14 # TODO: support iOS projects
15
16 from waflib import Context, TaskGen, Build, Utils
17 import os, sys, random, time
18
19 HEADERS_GLOB = '**/(*.h|*.hpp|*.H|*.inl)'
20
21 MAP_EXT = {
22 '.h' : "sourcecode.c.h",
23
24 '.hh': "sourcecode.cpp.h",
25 '.inl': "sourcecode.cpp.h",
26 '.hpp': "sourcecode.cpp.h",
27
28 '.c': "sourcecode.c.c",
29
30 '.m': "sourcecode.c.objc",
31
32 '.mm': "sourcecode.cpp.objcpp",
33
34 '.cc': "sourcecode.cpp.cpp",
35
36 '.cpp': "sourcecode.cpp.cpp",
37 '.C': "sourcecode.cpp.cpp",
38 '.cxx': "sourcecode.cpp.cpp",
39 '.c++': "sourcecode.cpp.cpp",
40
41 '.l': "sourcecode.lex", # luthor
42 '.ll': "sourcecode.lex",
43
44 '.y': "sourcecode.yacc",
45 '.yy': "sourcecode.yacc",
46
47 '.plist': "text.plist.xml",
48 ".nib": "wrapper.nib",
49 ".xib": "text.xib",
50 }
51
52
53 part1 = 0
54 part2 = 10000
55 part3 = 0
56 id = 562000999
57 def newid():
58 global id
59 id = id + 1
60 return "%04X%04X%04X%012d" % (0, 10000, 0, id)
61
62 class XCodeNode:
63 def __init__(self):
64 self._id = newid()
65
66 def tostring(self, value):
67 if isinstance(value, dict):
68 result = "{\n"
69 for k,v in value.items():
70 result = result + "\t\t\t%s = %s;\n" % (k, self.tostring(v))
71 result = result + "\t\t}"
72 return result
73 elif isinstance(value, str):
74 return "\"%s\"" % value
75 elif isinstance(value, list):
76 result = "(\n"
77 for i in value:
78 result = result + "\t\t\t%s,\n" % self.tostring(i)
79 result = result + "\t\t)"
80 return result
81 elif isinstance(value, XCodeNode):
82 return value._id
83 else:
84 return str(value)
85
86 def write_recursive(self, value, file):
87 if isinstance(value, dict):
88 for k,v in value.items():
89 self.write_recursive(v, file)
90 elif isinstance(value, list):
91 for i in value:
92 self.write_recursive(i, file)
93 elif isinstance(value, XCodeNode):
94 value.write(file)
95
96 def write(self, file):
97 for attribute,value in self.__dict__.items():
98 if attribute[0] != '_':
99 self.write_recursive(value, file)
100
101 w = file.write
102 w("\t%s = {\n" % self._id)
103 w("\t\tisa = %s;\n" % self.__class__.__name__)
104 for attribute,value in self.__dict__.items():
105 if attribute[0] != '_':
106 w("\t\t%s = %s;\n" % (attribute, self.tostring(value)))
107 w("\t};\n\n")
108
109
110
111 # Configurations
112 class XCBuildConfiguration(XCodeNode):
113 def __init__(self, name, settings = {}, env=None):
114 XCodeNode.__init__(self)
115 self.baseConfigurationReference = ""
116 self.buildSettings = settings
117 self.name = name
118 if env and env.ARCH:
119 settings['ARCHS'] = " ".join(env.ARCH)
120
121
122 class XCConfigurationList(XCodeNode):
123 def __init__(self, settings):
124 XCodeNode.__init__(self)
125 self.buildConfigurations = settings
126 self.defaultConfigurationIsVisible = 0
127 self.defaultConfigurationName = settings and settings[0].name or ""
128
129 # Group/Files
130 class PBXFileReference(XCodeNode):
131 def __init__(self, name, path, filetype = '', sourcetree = "SOURCE_ROOT"):
132 XCodeNode.__init__(self)
133 self.fileEncoding = 4
134 if not filetype:
135 _, ext = os.path.splitext(name)
136 filetype = MAP_EXT.get(ext, 'text')
137 self.lastKnownFileType = filetype
138 self.name = name
139 self.path = path
140 self.sourceTree = sourcetree
141
142 class PBXGroup(XCodeNode):
143 def __init__(self, name, sourcetree = "<group>"):
144 XCodeNode.__init__(self)
145 self.children = []
146 self.name = name
147 self.sourceTree = sourcetree
148
149 def add(self, root, sources):
150 folders = {}
151 def folder(n):
152 if n == root:
153 return self
154 try:
155 return folders[n]
156 except KeyError:
157 f = PBXGroup(n.name)
158 p = folder(n.parent)
159 folders[n] = f
160 p.children.append(f)
161 return f
162 for s in sources:
163 f = folder(s.parent)
164 source = PBXFileReference(s.name, s.abspath())
165 f.children.append(source)
166
167
168 # Targets
169 class PBXLegacyTarget(XCodeNode):
170 def __init__(self, action, target=''):
171 XCodeNode.__init__(self)
172 self.buildConfigurationList = XCConfigurationList([XCBuildConfiguration('waf', {})])
173 if not target:
174 self.buildArgumentsString = "%s %s" % (sys.argv[0], action)
175 else:
176 self.buildArgumentsString = "%s %s --targets=%s" % (sys.argv[0], action, target)
177 self.buildPhases = []
178 self.buildToolPath = sys.executable
179 self.buildWorkingDirectory = ""
180 self.dependencies = []
181 self.name = target or action
182 self.productName = target or action
183 self.passBuildSettingsInEnvironment = 0
184
185 class PBXShellScriptBuildPhase(XCodeNode):
186 def __init__(self, action, target):
187 XCodeNode.__init__(self)
188 self.buildActionMask = 2147483647
189 self.files = []
190 self.inputPaths = []
191 self.outputPaths = []
192 self.runOnlyForDeploymentPostProcessing = 0
193 self.shellPath = "/bin/sh"
194 self.shellScript = "%s %s %s --targets=%s" % (sys.executable, sys.argv[0], action, target)
195
196 class PBXNativeTarget(XCodeNode):
197 def __init__(self, action, target, node, env):
198 XCodeNode.__init__(self)
199 conf = XCBuildConfiguration('waf', {'PRODUCT_NAME':target, 'CONFIGURATION_BUILD_DIR':node.parent.abspath()}, env)
200 self.buildConfigurationList = XCConfigurationList([conf])
201 self.buildPhases = [PBXShellScriptBuildPhase(action, target)]
202 self.buildRules = []
203 self.dependencies = []
204 self.name = target
205 self.productName = target
206 self.productType = "com.apple.product-type.application"
207 self.productReference = PBXFileReference(target, node.abspath(), 'wrapper.application', 'BUILT_PRODUCTS_DIR')
208
209 # Root project object
210 class PBXProject(XCodeNode):
211 def __init__(self, name, version):
212 XCodeNode.__init__(self)
213 self.buildConfigurationList = XCConfigurationList([XCBuildConfiguration('waf', {})])
214 self.compatibilityVersion = version[0]
215 self.hasScannedForEncodings = 1;
216 self.mainGroup = PBXGroup(name)
217 self.projectRoot = ""
218 self.projectDirPath = ""
219 self.targets = []
220 self._objectVersion = version[1]
221 self._output = PBXGroup('out')
222 self.mainGroup.children.append(self._output)
223
224 def write(self, file):
225 w = file.write
226 w("// !$*UTF8*$!\n")
227 w("{\n")
228 w("\tarchiveVersion = 1;\n")
229 w("\tclasses = {\n")
230 w("\t};\n")
231 w("\tobjectVersion = %d;\n" % self._objectVersion)
232 w("\tobjects = {\n\n")
233
234 XCodeNode.write(self, file)
235
236 w("\t};\n")
237 w("\trootObject = %s;\n" % self._id)
238 w("}\n")
239
240 def add_task_gen(self, tg):
241 if not getattr(tg, 'mac_app', False):
242 self.targets.append(PBXLegacyTarget('build', tg.name))
243 else:
244 target = PBXNativeTarget('build', tg.name, tg.link_task.outputs[0].change_ext('.app'), tg.env)
245 self.targets.append(target)
246 self._output.children.append(target.productReference)
247
248 class xcode(Build.BuildContext):
249 cmd = 'xcode'
250 fun = 'build'
251
252 def collect_source(self, tg):
253 source_files = tg.to_nodes(getattr(tg, 'source', []))
254 plist_files = tg.to_nodes(getattr(tg, 'mac_plist', []))
255 resource_files = [tg.path.find_node(i) for i in Utils.to_list(getattr(tg, 'mac_resources', []))]
256 include_dirs = Utils.to_list(getattr(tg, 'includes', [])) + Utils.to_list(getattr(tg, 'export_dirs', []))
257 include_files = []
258 for x in include_dirs:
259 if not isinstance(x, str):
260 include_files.append(x)
261 continue
262 d = tg.path.find_node(x)
263 if d:
264 lst = [y for y in d.ant_glob(HEADERS_GLOB, flat=False)]
265 include_files.extend(lst)
266
267 # remove duplicates
268 source = list(set(source_files + plist_files + resource_files + include_files))
269 source.sort(key=lambda x: x.abspath())
270 return source
271
272 def execute(self):
273 """
274 Entry point
275 """
276 self.restore()
277 if not self.all_envs:
278 self.load_envs()
279 self.recurse([self.run_dir])
280
281 appname = getattr(Context.g_module, Context.APPNAME, os.path.basename(self.srcnode.abspath()))
282 p = PBXProject(appname, ('Xcode 3.2', 46))
283
284 for g in self.groups:
285 for tg in g:
286 if not isinstance(tg, TaskGen.task_gen):
287 continue
288
289 tg.post()
290
291 features = Utils.to_list(getattr(tg, 'features', ''))
292
293 group = PBXGroup(tg.name)
294 group.add(tg.path, self.collect_source(tg))
295 p.mainGroup.children.append(group)
296
297 if 'cprogram' or 'cxxprogram' in features:
298 p.add_task_gen(tg)
299
300
301 # targets that don't produce the executable but that you might want to run
302 p.targets.append(PBXLegacyTarget('configure'))
303 p.targets.append(PBXLegacyTarget('dist'))
304 p.targets.append(PBXLegacyTarget('install'))
305 p.targets.append(PBXLegacyTarget('check'))
306 node = self.srcnode.make_node('%s.xcodeproj' % appname)
307 node.mkdir()
308 node = node.make_node('project.pbxproj')
309 p.write(open(node.abspath(), 'w'))
310
311
0 #!/usr/bin/env python
1 # encoding: utf-8
2 # Thomas Nagy, 2010 (ita)
3
4 """
5 burn a book, save a tree
6 """
7
8 import os
9 all_modifs = {}
10
11 def fixdir(dir):
12 """call all the substitution functions on the waf folders"""
13 global all_modifs
14 for k in all_modifs:
15 for v in all_modifs[k]:
16 modif(os.path.join(dir, 'waflib'), k, v)
17
18 def modif(dir, name, fun):
19 """execute a substitution function"""
20 if name == '*':
21 lst = []
22 for y in '. Tools extras'.split():
23 for x in os.listdir(os.path.join(dir, y)):
24 if x.endswith('.py'):
25 lst.append(y + os.sep + x)
26 for x in lst:
27 modif(dir, x, fun)
28 return
29
30 filename = os.path.join(dir, name)
31 f = open(filename, 'r')
32 txt = f.read()
33 f.close()
34
35 txt = fun(txt)
36
37 f = open(filename, 'w')
38 f.write(txt)
39 f.close()
40
41 def subst(*k):
42 """register a substitution function"""
43 def do_subst(fun):
44 global all_modifs
45 for x in k:
46 try:
47 all_modifs[x].append(fun)
48 except KeyError:
49 all_modifs[x] = [fun]
50 return fun
51 return do_subst
52
53 @subst('*')
54 def r1(code):
55 "utf-8 fixes for python < 2.6"
56 code = code.replace('as e:', ',e:')
57 code = code.replace(".decode(sys.stdout.encoding or 'iso8859-1')", '')
58 code = code.replace('.encode()', '')
59 return code
60
61 @subst('Runner.py')
62 def r4(code):
63 "generator syntax"
64 code = code.replace('next(self.biter)', 'self.biter.next()')
65 return code
66
0 #! /usr/bin/env python
1 # encoding: utf-8
2 # Oliver Sauder, 2010
3
4 import os
5 import random
6 import signal
7 import subprocess
8 import tempfile
9 import time
10 import traceback
11 from subprocess import PIPE, Popen
12
13 import Logs
14 import Options
15 from waflib.Build import BuildContext
16 from waflib.Tools import waf_unit_test
17
18 NAME = 'Diodon'
19 VERSION = '1.8.0'
20 APPNAME = 'diodon'
21 WEBSITE = 'https://launchpad.net/diodon'
22 COPYRIGHT = 'Copyright \xc2\xa9 2010-2018 Diodon Team'
23 BUSNAME = 'net.launchpad.Diodon'
24 BUSOBJECTPATH = '/net/launchpad/diodon'
25
26 VERSION_MAJOR_MINOR = '.'.join(VERSION.split('.')[0:2])
27 VERSION_MAJOR = '.'.join(VERSION.split('.')[0:1])
28 top = '.'
29 out = '_build_'
30
31
32 class CustomBuildContext(BuildContext):
33 zeitgeist_process = None
34 display_process = None
35
36
37 def options(opt):
38 opt.tool_options('compiler_c')
39 opt.tool_options('waf_unit_test')
40 opt.tool_options('vala')
41 opt.tool_options('gnu_dirs')
42 opt.tool_options('intltool')
43 opt.tool_options('glib2')
44 opt.add_option('--update-po', action='store_true', default=False, dest='update_po', help='Update localization files')
45 opt.add_option('--debug', action='store_true', default=False, dest='debug', help='Debug mode')
46 opt.add_option('--disable-indicator-plugin', action='store_true', default=False, dest='disable_indicator', help='Disable build of indicator plugin')
47 opt.add_option('--enable-unityscope', action='store_true', default=False, dest='enable_unityscope', help='Enable build of unity scope')
48 opt.add_option('--build-doc', action='store_true', default=False, dest='doc', help='Build the api documentation')
49 opt.add_option('--skiptests', action='store_true', default=False, dest='skiptests', help='Skip unit tests')
50
51
52 def configure(conf):
53 conf.load('compiler_c intltool gnu_dirs glib2 waf_unit_test')
54 if Options.options.doc:
55 conf.load('valadoc')
56
57 conf.load('vala', funs='')
58 conf.check_vala(min_version=(0, 30, 0))
59
60 conf.check_cfg(package='gdk-3.0', uselib_store='GDK', atleast_version='3.0.8', mandatory=1, args='--cflags --libs')
61 conf.check_cfg(package='gdk-x11-3.0', uselib_store='GDKX', atleast_version='3.0.8', mandatory=1, args='--cflags --libs')
62 conf.check_cfg(package='libpeas-1.0', uselib_store='PEAS', atleast_version='1.1.0', mandatory=1, args='--cflags --libs')
63 conf.check_cfg(package='libpeas-gtk-1.0', uselib_store='PEASGTK', atleast_version='1.1.0', mandatory=1, args='--cflags --libs')
64 conf.check_cfg(package='gio-2.0', uselib_store='GIO', atleast_version='2.32.0', mandatory=1, args='--cflags --libs')
65 conf.check_cfg(package='gio-unix-2.0', uselib_store='GIOUNIX', atleast_version='2.32.0', mandatory=1, args='--cflags --libs')
66 conf.check_cfg(package='glib-2.0', uselib_store='GLIB', atleast_version='2.32.0', mandatory=1, args='--cflags --libs')
67 conf.check_cfg(package='gtk+-3.0', uselib_store='GTK', atleast_version='3.10.0', mandatory=1, args='--cflags --libs')
68 conf.check_cfg(package='xtst', uselib_store='XTST', atleast_version='1.2.0', mandatory=1, args='--cflags --libs')
69 conf.check_cfg(package='zeitgeist-2.0', uselib_store='ZEITGEIST', atleast_version='0.9.14', mandatory=1, args='--cflags --libs')
70
71 conf.find_program('Xvfb', var='XVFB')
72
73 # FIXME: waf throws up when assigning an empty string
74 # we need a better way of configuring plugins which are enabled
75 # by default anyway
76 ACTIVE_PLUGINS = ' '
77 # check if indicator plugin should be built
78 conf.env['INDICATOR'] = not(Options.options.disable_indicator)
79 if not(Options.options.disable_indicator):
80 conf.check_cfg(package='appindicator3-0.1', uselib_store='APPINDICATOR', atleast_version='0.3.0', mandatory=1, args='--cflags --libs')
81 ACTIVE_PLUGINS = "'indicator'"
82
83 # check if unity scope plugin should be built
84 conf.env['UNITYSCOPE'] = Options.options.enable_unityscope
85 if Options.options.enable_unityscope:
86 conf.check_cfg(package='unity', uselib_store='UNITY', atleast_version='7.1.0', mandatory=1, args='--cflags --libs')
87
88 # FIXME: conf.env and conf.define should not both be needed?
89 conf.define('PACKAGE_NAME', APPNAME)
90 conf.env['PACKAGE_NAME'] = APPNAME
91 conf.define('ACTIVE_PLUGINS', ACTIVE_PLUGINS)
92 conf.env['ACTIVE_PLUGINS'] = ACTIVE_PLUGINS
93 conf.define('GETTEXT_PACKAGE', APPNAME)
94 conf.env['GETTEXT_PACKAGE'] = APPNAME
95 conf.define('VERSION', VERSION)
96 conf.env['VERSION'] = VERSION
97 conf.define('COPYRIGHT', COPYRIGHT)
98 conf.define('WEBSITE', WEBSITE)
99 conf.define('APPNAME', NAME)
100 conf.define('BUSNAME', BUSNAME)
101 conf.env['BUSNAME'] = BUSNAME
102 conf.define('BUSOBJECTPATH', BUSOBJECTPATH)
103 conf.env['BUSOBJECTPATH'] = BUSOBJECTPATH
104 conf.define('SHAREDIR', os.path.join(conf.env['DATADIR'], APPNAME))
105 conf.define('LIBDIR_DIODON', os.path.join(conf.env['LIBDIR'], APPNAME))
106 conf.env['LIBDIR_DIODON'] = os.path.join(conf.env['LIBDIR'], APPNAME)
107 conf.define('PLUGINS_DIR', os.path.join(conf.env['LIBDIR'], APPNAME, 'plugins'))
108 conf.env['PLUGINS_DIR'] = os.path.join(conf.env['LIBDIR'], APPNAME, 'plugins')
109 conf.define('PLUGINS_DATA_DIR', os.path.join(conf.env['DATADIR'], APPNAME, 'plugins'))
110 conf.define('TEST_DATA_DIR', conf.path.abspath() + '/tests/data/')
111
112 # set 'default' variant
113 conf.define('DEBUG', 0)
114 # honor preset CFLAGS env vars
115 if not conf.env['CFLAGS']:
116 conf.env['CFLAGS'] += ['-O2']
117 # in any case we need to ignore warnings as C-code is generated
118 conf.env['CFLAGS'] += ['-w']
119 conf.env['VALAFLAGS'] = ['--disable-assert']
120
121 # set some debug relevant config values
122 if Options.options.debug:
123 conf.define('DEBUG', 1)
124 conf.env['CFLAGS'] += ['-O0', '-g3', '-w']
125 conf.env['VALAFLAGS'] = ['-g', '-v', '--enable-checking']
126
127 conf.write_config_header('config.h', remove=False)
128
129
130 def build(ctx):
131 ctx.add_subdirs('po data libdiodon plugins diodon')
132
133 if ctx.env['UNITYSCOPE']:
134 ctx.add_subdirs('unity-scope-diodon')
135
136 if not Options.options.skiptests:
137 ctx.add_subdirs('tests')
138 if ctx.cmd == 'build':
139 ctx.add_pre_fun(setup_tests)
140 ctx.add_post_fun(teardown_tests)
141
142 if ctx.env['VALADOC']:
143 ctx.add_subdirs('doc')
144 ctx.add_post_fun(post)
145
146 # to execute all tests:
147 # $ waf --alltests
148 # to set this behaviour permanenly:
149 ctx.options.all_tests = True
150
151
152 def setup_tests(ctx):
153 ctx.display_process = start_display(ctx)
154
155 # only when integration tests are run does the zeitgeist service
156 # need to be started
157 if getattr(Options.options, 'testcmd', False):
158 ctx.zeitgeist_process = start_zeitgeist_daemon(ctx)
159
160
161 def teardown_tests(ctx):
162 stop_display(ctx)
163
164 if ctx.zeitgeist_process:
165 stop_zeitgeist_daemon(ctx.zeitgeist_process)
166
167 # write test summary
168 waf_unit_test.summary(ctx)
169
170 # Ensure that all tests have passed, if not log errors
171 lst = getattr(ctx, 'utest_results', [])
172 if lst:
173 tfail = len([x for x in lst if x[1]])
174 if tfail:
175 for (filename, returncode, stdout, stderr) in lst:
176 Logs.warn(stdout)
177 Logs.warn(stderr)
178
179 ctx.fatal("Some test failed.")
180
181
182 def start_display(ctx):
183 devnull = open("/dev/null", "w")
184 display = ":%d" % random.randint(20, 100)
185 display_process = Popen([ctx.env.get_flat('XVFB'), display, "-screen", "0", "1024x768x8"], stderr=devnull, stdout=devnull)
186 # give the display some time to wake up
187 time.sleep(1)
188 err = display_process.poll()
189 if err:
190 raise RuntimeError("Could not start Xvfb on display %s, got err=%i" % (display, err))
191
192 os.environ.update({"DISPLAY": display})
193 return display_process
194
195
196 def stop_display(ctx):
197 os.kill(ctx.display_process.pid, signal.SIGKILL)
198 ctx.display_process.wait()
199
200
201 # TODO: is this really the best spot to start the zeitgeist daemon?
202 def start_zeitgeist_daemon(ctx):
203 """
204 start zeitgeist daemon writing to temporary data path
205 """
206 zg_env = os.environ.copy()
207 datapath = tempfile.mkdtemp(prefix="zeitgeist.datapath.")
208 zg_env.update({
209 "ZEITGEIST_DATABASE_PATH": ":memory:",
210 "ZEITGEIST_DATA_PATH": datapath,
211 "XDG_CACHE_HOME": os.path.join(datapath, "cache"),
212 })
213 args = {'env': zg_env}
214 args['stderr'] = PIPE
215 args['stdout'] = PIPE
216 zeitgeist_process = Popen(('zeitgeist-daemon', '--replace', '--no-datahub'), **args)
217
218 # give the process some time to wake up
219 time.sleep(1)
220
221 # raise runtime error if process failed to start
222 error = zeitgeist_process.poll()
223 if error:
224 error = "zeitgeist-daemon exits with error %i." % (error)
225 raise RuntimeError(error)
226
227 Logs.info("Started Zeitgeist Daemon with pid %u" % zeitgeist_process.pid)
228 return zeitgeist_process
229
230
231 def stop_zeitgeist_daemon(zeitgeist_process):
232 """
233 Kill started test zeitgeist daemon
234 """
235 os.kill(zeitgeist_process.pid, signal.SIGKILL)
236 zeitgeist_process.wait()
237 Logs.info("Stopped Zeitgeist Daemon with pid %u" % zeitgeist_process.pid)
238
239
240 def post(ctx):
241 if ctx.cmd == 'install':
242 ctx.exec_command('/sbin/ldconfig')
243
244
245 def dist(ctx):
246 # set the compression type to gzip (default is bz2)
247 ctx.algo = "tar.gz"
248
249
250 def shutdown(self):
251 if Options.options.update_po:
252 os.chdir('./po')
253 try:
254 try:
255 size_old = os.stat(APPNAME + '.pot').st_size
256 except:
257 size_old = 0
258 subprocess.call(['intltool-update', '-p', '-g', APPNAME])
259 size_new = os.stat(APPNAME + '.pot').st_size
260 if size_new != size_old:
261 Logs.info("Updated po template.")
262 try:
263 command = 'intltool-update -r -g %s' % APPNAME
264 self.exec_command(command)
265 Logs.info("Updated translations.")
266 except:
267 Logs.error("Failed to update translations.")
268 except:
269 traceback.print_exc(file=open("errlog.txt", "a"))
270 Logs.error("Failed to generate po template.")
271 Logs.errors("Make sure intltool is installed.")
272 os.chdir('..')